From 9e59d6c0c4b9bdd6f67f9887a9d0e004b66e6e2d Mon Sep 17 00:00:00 2001 From: Nathan Bierema Date: Sun, 10 Nov 2024 17:16:01 -0500 Subject: [PATCH 1/7] TSL: Support defined color spaces in ColorSpaceNode --- types/three/src/nodes/display/ColorSpaceFunctions.d.ts | 4 ++-- types/three/src/nodes/display/ColorSpaceNode.d.ts | 8 +++++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/types/three/src/nodes/display/ColorSpaceFunctions.d.ts b/types/three/src/nodes/display/ColorSpaceFunctions.d.ts index b828686f5..a4bd01216 100644 --- a/types/three/src/nodes/display/ColorSpaceFunctions.d.ts +++ b/types/three/src/nodes/display/ColorSpaceFunctions.d.ts @@ -1,6 +1,6 @@ import Node from "../core/Node.js"; import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; -export const sRGBToLinearSRGB: (color: NodeRepresentation) => ShaderNodeObject; +export const sRGBTransferEOTF: (color: NodeRepresentation) => ShaderNodeObject; -export const linearSRGBTosRGB: (color: NodeRepresentation) => ShaderNodeObject; +export const sRGBTransferOETF: (color: NodeRepresentation) => ShaderNodeObject; diff --git a/types/three/src/nodes/display/ColorSpaceNode.d.ts b/types/three/src/nodes/display/ColorSpaceNode.d.ts index 0990e0227..c0de945da 100644 --- a/types/three/src/nodes/display/ColorSpaceNode.d.ts +++ b/types/three/src/nodes/display/ColorSpaceNode.d.ts @@ -24,7 +24,7 @@ export default class ColorSpaceNode extends TempNode { target: string, ); - getColorSpace(nodeBuilder: NodeBuilder, colorSpace: WorkingOrOutputColorSpace): string; + resolveColorSpace(nodeBuilder: NodeBuilder, colorSpace: WorkingOrOutputColorSpace): string; } export const toOutputColorSpace: ( @@ -43,6 +43,12 @@ export const colorSpaceToWorking: ( colorSpace: string, ) => ShaderNodeObject; +export const convertColorSpace: ( + node: NodeRepresentation, + sourceColorSpace: string, + targetColorSpace: string, +) => ShaderNodeObject; + declare module "../tsl/TSLCore.js" { interface NodeElements { toOutputColorSpace: typeof toOutputColorSpace; From cafe8662c66a2147e269bd13b0e06ef947ceeb96 Mon Sep 17 00:00:00 2001 From: Nathan Bierema Date: Sun, 10 Nov 2024 17:16:19 -0500 Subject: [PATCH 2/7] Update three.js --- three.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/three.js b/three.js index 04ddcb918..cb29f6f17 160000 --- a/three.js +++ b/three.js @@ -1 +1 @@ -Subproject commit 04ddcb9189eca17fa92143170498081ec23a5dbb +Subproject commit cb29f6f17ee47ca6d5741b309150317716cbfc70 From f05b917f2c28fc94af351db789380932aeddece5 Mon Sep 17 00:00:00 2001 From: Nathan Bierema Date: Sun, 10 Nov 2024 17:16:30 -0500 Subject: [PATCH 3/7] Add src --- src-testing/src/Three.Legacy.d.ts | 20 + src-testing/src/Three.WebGPU.Nodes.d.ts | 205 +++ src-testing/src/Three.WebGPU.d.ts | 206 +++ src-testing/src/Three.d.ts | 214 +++ .../src/animation/AnimationAction.d.ts | 86 + src-testing/src/animation/AnimationClip.d.ts | 59 + src-testing/src/animation/AnimationMixer.d.ts | 39 + .../src/animation/AnimationObjectGroup.d.ts | 17 + src-testing/src/animation/AnimationUtils.d.ts | 60 + src-testing/src/animation/KeyframeTrack.d.ts | 55 + .../src/animation/PropertyBinding.d.ts | 43 + src-testing/src/animation/PropertyMixer.d.ts | 17 + .../tracks/BooleanKeyframeTrack.d.ts | 10 + .../animation/tracks/ColorKeyframeTrack.d.ts | 11 + .../animation/tracks/NumberKeyframeTrack.d.ts | 11 + .../tracks/QuaternionKeyframeTrack.d.ts | 11 + .../animation/tracks/StringKeyframeTrack.d.ts | 10 + .../animation/tracks/VectorKeyframeTrack.d.ts | 11 + src-testing/src/audio/Audio.d.ts | 273 ++++ src-testing/src/audio/AudioAnalyser.d.ts | 58 + src-testing/src/audio/AudioContext.d.ts | 19 + src-testing/src/audio/AudioListener.d.ts | 96 ++ src-testing/src/audio/PositionalAudio.d.ts | 101 ++ src-testing/src/cameras/ArrayCamera.d.ts | 32 + src-testing/src/cameras/Camera.d.ts | 74 + src-testing/src/cameras/CubeCamera.d.ts | 68 + .../src/cameras/OrthographicCamera.d.ts | 174 ++ .../src/cameras/PerspectiveCamera.d.ts | 254 +++ src-testing/src/cameras/StereoCamera.d.ts | 50 + src-testing/src/constants.d.ts | 918 +++++++++++ src-testing/src/core/BufferAttribute.d.ts | 622 +++++++ src-testing/src/core/BufferGeometry.d.ts | 433 +++++ src-testing/src/core/Clock.d.ts | 72 + src-testing/src/core/EventDispatcher.d.ts | 82 + src-testing/src/core/GLBufferAttribute.d.ts | 121 ++ .../src/core/InstancedBufferAttribute.d.ts | 32 + .../src/core/InstancedBufferGeometry.d.ts | 37 + .../src/core/InstancedInterleavedBuffer.d.ts | 22 + src-testing/src/core/InterleavedBuffer.d.ts | 150 ++ .../src/core/InterleavedBufferAttribute.d.ts | 201 +++ src-testing/src/core/Layers.d.ts | 72 + src-testing/src/core/Object3D.d.ts | 674 ++++++++ src-testing/src/core/Raycaster.d.ts | 208 +++ src-testing/src/core/RenderTarget.d.ts | 95 ++ src-testing/src/core/Uniform.d.ts | 38 + src-testing/src/core/UniformsGroup.d.ts | 33 + src-testing/src/extras/Controls.d.ts | 54 + src-testing/src/extras/DataUtils.d.ts | 22 + src-testing/src/extras/Earcut.d.ts | 15 + src-testing/src/extras/ImageUtils.d.ts | 32 + src-testing/src/extras/PMREMGenerator.d.ts | 82 + src-testing/src/extras/ShapeUtils.d.ts | 25 + src-testing/src/extras/TextureUtils.d.ts | 42 + src-testing/src/extras/core/Curve.d.ts | 162 ++ src-testing/src/extras/core/CurvePath.d.ts | 77 + .../src/extras/core/Interpolations.d.ts | 36 + src-testing/src/extras/core/Path.d.ts | 166 ++ src-testing/src/extras/core/Shape.d.ts | 86 + src-testing/src/extras/core/ShapePath.d.ts | 98 ++ src-testing/src/extras/curves/ArcCurve.d.ts | 41 + .../src/extras/curves/CatmullRomCurve3.d.ts | 77 + .../src/extras/curves/CubicBezierCurve.d.ts | 72 + .../src/extras/curves/CubicBezierCurve3.d.ts | 72 + src-testing/src/extras/curves/Curves.d.ts | 10 + .../src/extras/curves/EllipseCurve.d.ts | 115 ++ src-testing/src/extras/curves/LineCurve.d.ts | 42 + src-testing/src/extras/curves/LineCurve3.d.ts | 42 + .../extras/curves/QuadraticBezierCurve.d.ts | 64 + .../extras/curves/QuadraticBezierCurve3.d.ts | 64 + .../src/extras/curves/SplineCurve.d.ts | 52 + src-testing/src/geometries/BoxGeometry.d.ts | 59 + .../src/geometries/CapsuleGeometry.d.ts | 48 + .../src/geometries/CircleGeometry.d.ts | 51 + src-testing/src/geometries/ConeGeometry.d.ts | 64 + .../src/geometries/CylinderGeometry.d.ts | 64 + .../src/geometries/DodecahedronGeometry.d.ts | 25 + src-testing/src/geometries/EdgesGeometry.d.ts | 41 + .../src/geometries/ExtrudeGeometry.d.ts | 152 ++ src-testing/src/geometries/Geometries.d.ts | 21 + .../src/geometries/IcosahedronGeometry.d.ts | 26 + src-testing/src/geometries/LatheGeometry.d.ts | 55 + .../src/geometries/OctahedronGeometry.d.ts | 25 + src-testing/src/geometries/PlaneGeometry.d.ts | 48 + .../src/geometries/PolyhedronGeometry.d.ts | 54 + src-testing/src/geometries/RingGeometry.d.ts | 59 + src-testing/src/geometries/ShapeGeometry.d.ts | 53 + .../src/geometries/SphereGeometry.d.ts | 67 + .../src/geometries/TetrahedronGeometry.d.ts | 25 + src-testing/src/geometries/TorusGeometry.d.ts | 49 + .../src/geometries/TorusKnotGeometry.d.ts | 59 + src-testing/src/geometries/TubeGeometry.d.ts | 86 + .../src/geometries/WireframeGeometry.d.ts | 40 + src-testing/src/helpers/ArrowHelper.d.ts | 93 ++ src-testing/src/helpers/AxesHelper.d.ts | 50 + src-testing/src/helpers/Box3Helper.d.ts | 44 + src-testing/src/helpers/BoxHelper.d.ts | 64 + src-testing/src/helpers/CameraHelper.d.ts | 80 + .../src/helpers/DirectionalLightHelper.d.ts | 81 + src-testing/src/helpers/GridHelper.d.ts | 47 + .../src/helpers/HemisphereLightHelper.d.ts | 72 + src-testing/src/helpers/PlaneHelper.d.ts | 50 + src-testing/src/helpers/PointLightHelper.d.ts | 73 + src-testing/src/helpers/PolarGridHelper.d.ts | 55 + src-testing/src/helpers/SkeletonHelper.d.ts | 78 + src-testing/src/helpers/SpotLightHelper.d.ts | 77 + src-testing/src/lights/AmbientLight.d.ts | 36 + src-testing/src/lights/DirectionalLight.d.ts | 103 ++ .../src/lights/DirectionalLightShadow.d.ts | 73 + src-testing/src/lights/HemisphereLight.d.ts | 61 + src-testing/src/lights/Light.d.ts | 82 + src-testing/src/lights/LightProbe.d.ts | 47 + src-testing/src/lights/LightShadow.d.ts | 169 ++ src-testing/src/lights/PointLight.d.ts | 102 ++ src-testing/src/lights/PointLightShadow.d.ts | 22 + src-testing/src/lights/RectAreaLight.d.ts | 82 + src-testing/src/lights/SpotLight.d.ts | 164 ++ src-testing/src/lights/SpotLightShadow.d.ts | 72 + .../src/lights/webgpu/IESSpotLight.d.ts | 6 + src-testing/src/loaders/AnimationLoader.d.ts | 9 + src-testing/src/loaders/AudioLoader.d.ts | 6 + .../src/loaders/BufferGeometryLoader.d.ts | 10 + src-testing/src/loaders/Cache.d.ts | 21 + .../src/loaders/CompressedTextureLoader.d.ts | 14 + .../src/loaders/CubeTextureLoader.d.ts | 14 + .../src/loaders/DataTextureLoader.d.ts | 14 + src-testing/src/loaders/FileLoader.d.ts | 19 + .../src/loaders/ImageBitmapLoader.d.ts | 22 + src-testing/src/loaders/ImageLoader.d.ts | 17 + src-testing/src/loaders/Loader.d.ts | 50 + src-testing/src/loaders/LoaderUtils.d.ts | 10 + src-testing/src/loaders/LoadingManager.d.ts | 69 + src-testing/src/loaders/MaterialLoader.d.ts | 21 + src-testing/src/loaders/ObjectLoader.d.ts | 35 + src-testing/src/loaders/TextureLoader.d.ts | 18 + src-testing/src/loaders/nodes/NodeLoader.d.ts | 21 + .../src/loaders/nodes/NodeMaterialLoader.d.ts | 11 + .../src/loaders/nodes/NodeObjectLoader.d.ts | 22 + .../src/materials/LineBasicMaterial.d.ts | 55 + .../src/materials/LineDashedMaterial.d.ts | 35 + src-testing/src/materials/Material.d.ts | 629 ++++++++ src-testing/src/materials/Materials.d.ts | 18 + .../src/materials/MeshBasicMaterial.d.ts | 134 ++ .../src/materials/MeshDepthMaterial.d.ts | 71 + .../src/materials/MeshDistanceMaterial.d.ts | 57 + .../src/materials/MeshLambertMaterial.d.ts | 199 +++ .../src/materials/MeshMatcapMaterial.d.ts | 112 ++ .../src/materials/MeshNormalMaterial.d.ts | 88 + .../src/materials/MeshPhongMaterial.d.ts | 223 +++ .../src/materials/MeshPhysicalMaterial.d.ts | 231 +++ .../src/materials/MeshStandardMaterial.d.ts | 213 +++ .../src/materials/MeshToonMaterial.d.ts | 173 ++ src-testing/src/materials/PointsMaterial.d.ts | 56 + .../src/materials/RawShaderMaterial.d.ts | 12 + src-testing/src/materials/ShaderMaterial.d.ts | 162 ++ src-testing/src/materials/ShadowMaterial.d.ts | 34 + src-testing/src/materials/SpriteMaterial.d.ts | 61 + .../nodes/InstancedPointsNodeMaterial.d.ts | 33 + .../materials/nodes/Line2NodeMaterial.d.ts | 53 + .../nodes/LineBasicNodeMaterial.d.ts | 22 + .../nodes/LineDashedNodeMaterial.d.ts | 29 + .../nodes/MeshBasicNodeMaterial.d.ts | 36 + .../nodes/MeshLambertNodeMaterial.d.ts | 49 + .../nodes/MeshMatcapNodeMaterial.d.ts | 32 + .../nodes/MeshNormalNodeMaterial.d.ts | 28 + .../nodes/MeshPhongNodeMaterial.d.ts | 56 + .../nodes/MeshPhysicalNodeMaterial.d.ts | 93 ++ .../materials/nodes/MeshSSSNodeMaterial.d.ts | 16 + .../nodes/MeshStandardNodeMaterial.d.ts | 56 + .../materials/nodes/MeshToonNodeMaterial.d.ts | 42 + .../src/materials/nodes/NodeMaterial.ts | 535 +++++++ .../src/materials/nodes/NodeMaterials.d.ts | 18 + .../materials/nodes/PointsNodeMaterial.d.ts | 21 + .../materials/nodes/ShadowNodeMaterial.d.ts | 17 + .../materials/nodes/SpriteNodeMaterial.d.ts | 26 + .../materials/nodes/VolumeNodeMaterial.d.ts | 10 + .../nodes/manager/NodeMaterialObserver.ts | 308 ++++ src-testing/src/math/Box2.d.ts | 48 + src-testing/src/math/Box3.d.ts | 66 + src-testing/src/math/Color.d.ts | 375 +++++ src-testing/src/math/ColorManagement.d.ts | 49 + src-testing/src/math/Cylindrical.d.ts | 26 + src-testing/src/math/Euler.d.ts | 50 + src-testing/src/math/Frustum.d.ts | 30 + src-testing/src/math/Interpolant.d.ts | 10 + src-testing/src/math/Line3.d.ts | 29 + src-testing/src/math/MathUtils.d.ts | 137 ++ src-testing/src/math/Matrix2.d.ts | 53 + src-testing/src/math/Matrix3.d.ts | 184 +++ src-testing/src/math/Matrix4.d.ts | 284 ++++ src-testing/src/math/Plane.d.ts | 47 + src-testing/src/math/Quaternion.d.ts | 189 +++ src-testing/src/math/Ray.d.ts | 60 + src-testing/src/math/Sphere.d.ts | 47 + src-testing/src/math/Spherical.d.ts | 27 + src-testing/src/math/SphericalHarmonics3.d.ts | 50 + src-testing/src/math/Triangle.d.ts | 110 ++ src-testing/src/math/Vector2.d.ts | 321 ++++ src-testing/src/math/Vector3.d.ts | 301 ++++ src-testing/src/math/Vector4.d.ts | 239 +++ .../math/interpolants/CubicInterpolant.d.ts | 7 + .../interpolants/DiscreteInterpolant.d.ts | 7 + .../math/interpolants/LinearInterpolant.d.ts | 7 + .../QuaternionLinearInterpolant.d.ts | 7 + src-testing/src/nodes/Nodes.ts | 144 ++ src-testing/src/nodes/TSL.d.ts | 156 ++ .../src/nodes/accessors/AccessorsUtils.d.ts | 9 + .../src/nodes/accessors/BatchNode.d.ts | 13 + .../src/nodes/accessors/Bitangent.d.ts | 9 + .../nodes/accessors/BufferAttributeNode.ts | 135 ++ .../src/nodes/accessors/BufferNode.d.ts | 17 + src-testing/src/nodes/accessors/Camera.d.ts | 14 + .../src/nodes/accessors/ClippingNode.d.ts | 16 + .../src/nodes/accessors/CubeTextureNode.d.ts | 28 + .../src/nodes/accessors/InstanceNode.d.ts | 13 + .../src/nodes/accessors/MaterialNode.d.ts | 129 ++ .../nodes/accessors/MaterialProperties.d.ts | 4 + .../accessors/MaterialReferenceNode.d.ts | 15 + .../src/nodes/accessors/ModelNode.d.ts | 24 + .../accessors/ModelViewProjectionNode.d.ts | 8 + .../src/nodes/accessors/MorphNode.d.ts | 15 + src-testing/src/nodes/accessors/Normal.d.ts | 25 + .../src/nodes/accessors/Object3DNode.d.ts | 22 + .../src/nodes/accessors/PointUVNode.d.ts | 10 + src-testing/src/nodes/accessors/Position.d.ts | 10 + .../nodes/accessors/ReferenceBaseNode.d.ts | 27 + .../src/nodes/accessors/ReferenceNode.d.ts | 29 + .../src/nodes/accessors/ReflectVector.d.ts | 9 + .../accessors/RendererReferenceNode.d.ts | 15 + .../src/nodes/accessors/SceneNode.d.ts | 20 + .../src/nodes/accessors/SkinningNode.d.ts | 30 + .../nodes/accessors/StorageBufferNode.d.ts | 38 + .../nodes/accessors/StorageTextureNode.d.ts | 40 + src-testing/src/nodes/accessors/Tangent.d.ts | 12 + .../src/nodes/accessors/Texture3DNode.d.ts | 17 + .../src/nodes/accessors/TextureBicubic.d.ts | 4 + .../src/nodes/accessors/TextureNode.ts | 370 +++++ .../src/nodes/accessors/TextureSizeNode.d.ts | 18 + src-testing/src/nodes/accessors/UV.d.ts | 4 + .../src/nodes/accessors/UniformArrayNode.d.ts | 30 + .../src/nodes/accessors/UserDataNode.d.ts | 15 + .../src/nodes/accessors/VelocityNode.d.ts | 20 + .../src/nodes/accessors/VertexColorNode.d.ts | 12 + src-testing/src/nodes/code/CodeNode.ts | 68 + .../src/nodes/code/ExpressionNode.d.ts | 9 + .../src/nodes/code/FunctionCallNode.d.ts | 25 + src-testing/src/nodes/code/FunctionNode.ts | 87 + .../src/nodes/code/ScriptableNode.d.ts | 22 + .../src/nodes/code/ScriptableValueNode.d.ts | 10 + src-testing/src/nodes/core/AssignNode.d.ts | 18 + src-testing/src/nodes/core/AttributeNode.d.ts | 16 + src-testing/src/nodes/core/BypassNode.d.ts | 18 + src-testing/src/nodes/core/CacheNode.d.ts | 20 + src-testing/src/nodes/core/ConstNode.d.ts | 9 + src-testing/src/nodes/core/ContextNode.ts | 61 + src-testing/src/nodes/core/IndexNode.d.ts | 28 + src-testing/src/nodes/core/InputNode.ts | 67 + src-testing/src/nodes/core/LightingModel.d.ts | 46 + src-testing/src/nodes/core/MRTNode.d.ts | 24 + src-testing/src/nodes/core/Node.ts | 401 +++++ src-testing/src/nodes/core/NodeAttribute.ts | 11 + src-testing/src/nodes/core/NodeBuilder.ts | 1208 ++++++++++++++ src-testing/src/nodes/core/NodeCache.ts | 26 + src-testing/src/nodes/core/NodeCode.ts | 11 + src-testing/src/nodes/core/NodeFrame.ts | 127 ++ src-testing/src/nodes/core/NodeFunction.ts | 16 + .../src/nodes/core/NodeFunctionInput.d.ts | 7 + src-testing/src/nodes/core/NodeParser.ts | 7 + src-testing/src/nodes/core/NodeUniform.ts | 27 + src-testing/src/nodes/core/NodeUtils.ts | 171 ++ src-testing/src/nodes/core/NodeVar.ts | 10 + src-testing/src/nodes/core/NodeVarying.ts | 13 + .../src/nodes/core/OutputStructNode.d.ts | 12 + src-testing/src/nodes/core/ParameterNode.d.ts | 12 + src-testing/src/nodes/core/PropertyNode.d.ts | 43 + src-testing/src/nodes/core/StackNode.ts | 89 + src-testing/src/nodes/core/StructTypeNode.ts | 20 + src-testing/src/nodes/core/TempNode.d.ts | 10 + src-testing/src/nodes/core/UniformGroup.d.ts | 7 + .../src/nodes/core/UniformGroupNode.ts | 47 + src-testing/src/nodes/core/UniformNode.ts | 91 ++ src-testing/src/nodes/core/VarNode.d.ts | 31 + src-testing/src/nodes/core/VaryingNode.d.ts | 21 + src-testing/src/nodes/core/constants.ts | 28 + src-testing/src/nodes/display/BlendMode.d.ts | 10 + .../src/nodes/display/BumpMapNode.d.ts | 16 + .../src/nodes/display/ColorAdjustment.d.ts | 56 + .../nodes/display/ColorSpaceFunctions.d.ts | 6 + .../src/nodes/display/ColorSpaceNode.d.ts | 60 + .../src/nodes/display/FrontFacingNode.d.ts | 12 + .../src/nodes/display/NormalMapNode.d.ts | 17 + src-testing/src/nodes/display/PassNode.d.ts | 71 + .../src/nodes/display/PosterizeNode.d.ts | 14 + .../src/nodes/display/RenderOutputNode.d.ts | 28 + src-testing/src/nodes/display/ScreenNode.d.ts | 48 + .../nodes/display/ToneMappingFunctions.d.ts | 14 + .../src/nodes/display/ToneMappingNode.d.ts | 32 + .../nodes/display/ToonOutlinePassNode.d.ts | 24 + .../src/nodes/display/ViewportDepthNode.d.ts | 36 + .../display/ViewportDepthTextureNode.d.ts | 14 + .../display/ViewportSharedTextureNode.d.ts | 14 + .../nodes/display/ViewportTextureNode.d.ts | 28 + src-testing/src/nodes/fog/FogExp2Node.d.ts | 14 + src-testing/src/nodes/fog/FogNode.ts | 38 + src-testing/src/nodes/fog/FogRangeNode.d.ts | 19 + .../src/nodes/functions/BSDF/BRDF_GGX.d.ts | 15 + .../nodes/functions/BSDF/BRDF_Lambert.d.ts | 7 + .../src/nodes/functions/BSDF/BRDF_Sheen.d.ts | 7 + .../src/nodes/functions/BSDF/DFGApprox.d.ts | 11 + .../src/nodes/functions/BSDF/D_GGX.d.ts | 10 + .../functions/BSDF/D_GGX_Anisotropic.d.ts | 10 + .../src/nodes/functions/BSDF/F_Schlick.d.ts | 7 + src-testing/src/nodes/functions/BSDF/LTC.d.ts | 9 + .../nodes/functions/BSDF/Schlick_to_F0.d.ts | 10 + .../functions/BSDF/V_GGX_SmithCorrelated.d.ts | 11 + .../V_GGX_SmithCorrelated_Anisotropic.d.ts | 16 + .../nodes/functions/BasicLightingModel.d.ts | 7 + .../nodes/functions/PhongLightingModel.d.ts | 7 + .../functions/PhysicalLightingModel.d.ts | 30 + .../src/nodes/functions/ShadowMaskModel.d.ts | 9 + .../nodes/functions/ToonLightingModel.d.ts | 4 + .../material/getGeometryRoughness.d.ts | 6 + .../functions/material/getRoughness.d.ts | 7 + .../functions/material/getShIrradianceAt.d.ts | 6 + src-testing/src/nodes/geometry/RangeNode.d.ts | 19 + src-testing/src/nodes/gpgpu/ComputeNode.ts | 75 + src-testing/src/nodes/lighting/AONode.d.ts | 8 + .../src/nodes/lighting/AmbientLightNode.d.ts | 8 + .../src/nodes/lighting/AnalyticLightNode.d.ts | 8 + .../nodes/lighting/BasicEnvironmentNode.d.ts | 10 + .../src/nodes/lighting/BasicLightMapNode.d.ts | 8 + .../nodes/lighting/DirectionalLightNode.d.ts | 8 + .../src/nodes/lighting/EnvironmentNode.ts | 114 ++ .../nodes/lighting/HemisphereLightNode.d.ts | 13 + .../src/nodes/lighting/IESSpotLightNode.d.ts | 5 + .../src/nodes/lighting/IrradianceNode.d.ts | 8 + src-testing/src/nodes/lighting/LightNode.d.ts | 18 + .../src/nodes/lighting/LightProbeNode.d.ts | 11 + .../src/nodes/lighting/LightUtils.d.ts | 9 + .../src/nodes/lighting/LightingContextNode.ts | 57 + .../src/nodes/lighting/LightingNode.d.ts | 7 + src-testing/src/nodes/lighting/LightsNode.ts | 200 +++ .../src/nodes/lighting/PointLightNode.d.ts | 20 + .../src/nodes/lighting/RectAreaLightNode.d.ts | 21 + .../src/nodes/lighting/ShadowNode.d.ts | 12 + .../src/nodes/lighting/SpotLightNode.d.ts | 15 + .../src/nodes/materialx/MaterialXNodes.d.ts | 107 ++ .../src/nodes/materialx/lib/mx_hsv.d.ts | 6 + .../src/nodes/materialx/lib/mx_noise.d.ts | 359 +++++ .../materialx/lib/mx_transform_color.d.ts | 4 + .../src/nodes/math/ConditionalNode.d.ts | 39 + src-testing/src/nodes/math/Hash.d.ts | 4 + src-testing/src/nodes/math/MathNode.d.ts | 273 ++++ src-testing/src/nodes/math/MathUtils.d.ts | 6 + src-testing/src/nodes/math/OperatorNode.d.ts | 97 ++ src-testing/src/nodes/math/TriNoise3D.d.ts | 12 + .../src/nodes/parsers/GLSLNodeFunction.d.ts | 9 + .../src/nodes/parsers/GLSLNodeParser.d.ts | 8 + src-testing/src/nodes/pmrem/PMREMNode.d.ts | 22 + src-testing/src/nodes/pmrem/PMREMUtils.d.ts | 28 + src-testing/src/nodes/procedural/Checker.d.ts | 4 + src-testing/src/nodes/tsl/TSLBase.d.ts | 21 + src-testing/src/nodes/tsl/TSLCore.ts | 533 ++++++ .../src/nodes/utils/ArrayElementNode.d.ts | 9 + src-testing/src/nodes/utils/ConvertNode.d.ts | 7 + src-testing/src/nodes/utils/CubeMapNode.d.ts | 13 + src-testing/src/nodes/utils/Discard.d.ts | 11 + .../src/nodes/utils/EquirectUVNode.d.ts | 8 + .../nodes/utils/FunctionOverloadingNode.d.ts | 13 + src-testing/src/nodes/utils/JoinNode.d.ts | 10 + src-testing/src/nodes/utils/LoopNode.d.ts | 22 + src-testing/src/nodes/utils/MatcapUVNode.d.ts | 8 + .../src/nodes/utils/MaxMipLevelNode.d.ts | 14 + src-testing/src/nodes/utils/Oscillators.d.ts | 7 + src-testing/src/nodes/utils/Packing.d.ts | 5 + .../src/nodes/utils/PostProcessingUtils.d.ts | 45 + src-testing/src/nodes/utils/RTTNode.d.ts | 45 + .../src/nodes/utils/ReflectorNode.d.ts | 45 + src-testing/src/nodes/utils/RemapNode.d.ts | 36 + src-testing/src/nodes/utils/RotateNode.d.ts | 15 + src-testing/src/nodes/utils/SetNode.d.ts | 11 + src-testing/src/nodes/utils/SplitNode.d.ts | 15 + .../src/nodes/utils/SpriteSheetUVNode.d.ts | 16 + src-testing/src/nodes/utils/SpriteUtils.d.ts | 6 + .../nodes/utils/StorageArrayElementNode.d.ts | 19 + src-testing/src/nodes/utils/Timer.d.ts | 21 + .../nodes/utils/TriplanarTexturesNode.d.ts | 36 + src-testing/src/nodes/utils/UVUtils.d.ts | 14 + .../src/nodes/utils/ViewportUtils.d.ts | 4 + src-testing/src/objects/BatchedMesh.d.ts | 275 ++++ src-testing/src/objects/Bone.d.ts | 36 + src-testing/src/objects/Group.d.ts | 37 + src-testing/src/objects/InstancedMesh.d.ts | 179 +++ src-testing/src/objects/LOD.d.ts | 111 ++ src-testing/src/objects/Line.d.ts | 87 + src-testing/src/objects/LineLoop.d.ts | 40 + src-testing/src/objects/LineSegments.d.ts | 41 + src-testing/src/objects/Mesh.d.ts | 94 ++ src-testing/src/objects/Points.d.ts | 66 + src-testing/src/objects/Skeleton.d.ts | 120 ++ src-testing/src/objects/SkinnedMesh.d.ts | 160 ++ src-testing/src/objects/Sprite.d.ts | 65 + .../src/renderers/WebGL3DRenderTarget.d.ts | 29 + .../src/renderers/WebGLArrayRenderTarget.d.ts | 29 + .../src/renderers/WebGLCubeRenderTarget.d.ts | 18 + .../src/renderers/WebGLRenderTarget.d.ts | 8 + src-testing/src/renderers/WebGLRenderer.d.ts | 558 +++++++ src-testing/src/renderers/common/Animation.ts | 38 + .../src/renderers/common/Attributes.ts | 56 + src-testing/src/renderers/common/Backend.ts | 170 ++ .../src/renderers/common/Background.ts | 133 ++ src-testing/src/renderers/common/BindGroup.ts | 14 + src-testing/src/renderers/common/Binding.ts | 17 + src-testing/src/renderers/common/Bindings.ts | 160 ++ src-testing/src/renderers/common/Buffer.ts | 28 + .../src/renderers/common/BufferUtils.ts | 23 + .../src/renderers/common/BundleGroup.ts | 20 + src-testing/src/renderers/common/ChainMap.ts | 43 + .../src/renderers/common/ClippingContext.ts | 136 ++ src-testing/src/renderers/common/Color4.ts | 27 + .../src/renderers/common/ComputePipeline.ts | 13 + src-testing/src/renderers/common/Constants.ts | 15 + .../src/renderers/common/CubeRenderTarget.ts | 71 + src-testing/src/renderers/common/DataMap.ts | 38 + .../src/renderers/common/Geometries.ts | 199 +++ .../IndirectStorageBufferAttribute.d.ts | 10 + src-testing/src/renderers/common/Info.ts | 95 ++ .../src/renderers/common/Lighting.d.ts | 15 + src-testing/src/renderers/common/Pipeline.ts | 9 + src-testing/src/renderers/common/Pipelines.ts | 270 ++++ .../src/renderers/common/PostProcessing.d.ts | 21 + .../renderers/common/PostProcessingUtils.d.ts | 66 + .../src/renderers/common/ProgrammableStage.ts | 16 + .../src/renderers/common/QuadMesh.d.ts | 16 + .../src/renderers/common/RenderBundle.ts | 12 + .../src/renderers/common/RenderBundles.ts | 28 + .../src/renderers/common/RenderContext.ts | 56 + .../src/renderers/common/RenderContexts.ts | 47 + .../src/renderers/common/RenderList.ts | 142 ++ .../src/renderers/common/RenderLists.ts | 30 + .../src/renderers/common/RenderObject.ts | 350 ++++ .../src/renderers/common/RenderObjects.ts | 107 ++ .../src/renderers/common/RenderPipeline.ts | 12 + src-testing/src/renderers/common/Renderer.ts | 1425 +++++++++++++++++ .../src/renderers/common/SampledTexture.ts | 68 + src-testing/src/renderers/common/Sampler.ts | 14 + .../src/renderers/common/StorageBuffer.ts | 13 + .../common/StorageBufferAttribute.d.ts | 7 + .../StorageInstancedBufferAttribute.d.ts | 8 + .../src/renderers/common/StorageTexture.d.ts | 5 + src-testing/src/renderers/common/Textures.ts | 294 ++++ src-testing/src/renderers/common/Uniform.ts | 105 ++ .../src/renderers/common/UniformBuffer.ts | 11 + .../src/renderers/common/UniformsGroup.ts | 277 ++++ .../renderers/common/extras/PMREMGenerator.ts | 657 ++++++++ .../common/nodes/NodeBuilderState.ts | 55 + .../src/renderers/common/nodes/NodeLibrary.ts | 76 + .../common/nodes/NodeSampledTexture.d.ts | 29 + .../renderers/common/nodes/NodeSampler.d.ts | 12 + .../src/renderers/common/nodes/NodeUniform.ts | 103 ++ .../common/nodes/NodeUniformsGroup.ts | 30 + .../src/renderers/common/nodes/Nodes.ts | 433 +++++ .../common/nodes/StandardNodeLibrary.d.ts | 5 + .../src/renderers/shaders/ShaderChunk.d.ts | 143 ++ .../src/renderers/shaders/ShaderLib.d.ts | 29 + .../src/renderers/shaders/UniformsLib.d.ts | 189 +++ .../src/renderers/shaders/UniformsUtils.d.ts | 14 + .../renderers/webgl-fallback/WebGLBackend.ts | 1349 ++++++++++++++++ .../webgl-fallback/nodes/GLSLNodeBuilder.ts | 812 ++++++++++ .../src/renderers/webgl/WebGLAttributes.d.ts | 21 + .../renderers/webgl/WebGLBindingStates.d.ts | 26 + .../renderers/webgl/WebGLBufferRenderer.d.ts | 21 + .../renderers/webgl/WebGLCapabilities.d.ts | 48 + .../src/renderers/webgl/WebGLClipping.d.ts | 26 + .../src/renderers/webgl/WebGLCubeMaps.d.ts | 8 + .../src/renderers/webgl/WebGLCubeUVMaps.d.ts | 9 + .../src/renderers/webgl/WebGLExtensions.d.ts | 7 + .../src/renderers/webgl/WebGLGeometries.d.ts | 13 + .../webgl/WebGLIndexedBufferRenderer.d.ts | 15 + .../src/renderers/webgl/WebGLInfo.d.ts | 39 + .../src/renderers/webgl/WebGLLights.d.ts | 49 + .../src/renderers/webgl/WebGLObjects.d.ts | 6 + .../src/renderers/webgl/WebGLProgram.d.ts | 30 + .../src/renderers/webgl/WebGLPrograms.d.ts | 233 +++ .../src/renderers/webgl/WebGLProperties.d.ts | 9 + .../src/renderers/webgl/WebGLRenderLists.d.ts | 66 + .../src/renderers/webgl/WebGLShader.d.ts | 1 + .../src/renderers/webgl/WebGLShadowMap.d.ts | 38 + .../src/renderers/webgl/WebGLState.d.ts | 116 ++ .../src/renderers/webgl/WebGLTextures.d.ts | 30 + .../src/renderers/webgl/WebGLUniforms.d.ts | 12 + .../renderers/webgl/WebGLUniformsGroups.d.ts | 17 + .../src/renderers/webgl/WebGLUtils.d.ts | 11 + .../src/renderers/webgpu/WebGPUBackend.ts | 1297 +++++++++++++++ .../webgpu/WebGPURenderer.Nodes.d.ts | 12 + .../src/renderers/webgpu/WebGPURenderer.ts | 46 + .../webgpu/nodes/BasicNodeLibrary.ts | 61 + .../webgpu/nodes/StandardNodeLibrary.ts | 107 ++ .../renderers/webgpu/nodes/WGSLNodeBuilder.ts | 1178 ++++++++++++++ .../webgpu/nodes/WGSLNodeFunction.ts | 142 ++ .../renderers/webgpu/nodes/WGSLNodeParser.ts | 10 + .../webgpu/utils/WebGPUConstants.d.ts | 328 ++++ .../src/renderers/webxr/WebXRController.d.ts | 63 + .../renderers/webxr/WebXRDepthSensing.d.ts | 22 + .../src/renderers/webxr/WebXRManager.d.ts | 85 + src-testing/src/scenes/Fog.d.ts | 77 + src-testing/src/scenes/FogExp2.d.ts | 66 + src-testing/src/scenes/Scene.d.ts | 118 ++ src-testing/src/textures/CanvasTexture.d.ts | 51 + .../src/textures/CompressedArrayTexture.d.ts | 68 + .../src/textures/CompressedCubeTexture.d.ts | 13 + .../src/textures/CompressedTexture.d.ts | 94 ++ src-testing/src/textures/CubeTexture.d.ts | 89 + src-testing/src/textures/Data3DTexture.d.ts | 96 ++ .../src/textures/DataArrayTexture.d.ts | 123 ++ src-testing/src/textures/DataTexture.d.ts | 112 ++ src-testing/src/textures/DepthTexture.d.ts | 104 ++ .../src/textures/FramebufferTexture.d.ts | 62 + src-testing/src/textures/Source.d.ts | 75 + src-testing/src/textures/Texture.d.ts | 476 ++++++ src-testing/src/textures/VideoTexture.d.ts | 90 ++ src-testing/src/textures/types.d.ts | 9 + src-testing/src/utils.d.ts | 3 + 522 files changed, 42350 insertions(+) create mode 100644 src-testing/src/Three.Legacy.d.ts create mode 100644 src-testing/src/Three.WebGPU.Nodes.d.ts create mode 100644 src-testing/src/Three.WebGPU.d.ts create mode 100644 src-testing/src/Three.d.ts create mode 100644 src-testing/src/animation/AnimationAction.d.ts create mode 100644 src-testing/src/animation/AnimationClip.d.ts create mode 100644 src-testing/src/animation/AnimationMixer.d.ts create mode 100644 src-testing/src/animation/AnimationObjectGroup.d.ts create mode 100644 src-testing/src/animation/AnimationUtils.d.ts create mode 100644 src-testing/src/animation/KeyframeTrack.d.ts create mode 100644 src-testing/src/animation/PropertyBinding.d.ts create mode 100644 src-testing/src/animation/PropertyMixer.d.ts create mode 100644 src-testing/src/animation/tracks/BooleanKeyframeTrack.d.ts create mode 100644 src-testing/src/animation/tracks/ColorKeyframeTrack.d.ts create mode 100644 src-testing/src/animation/tracks/NumberKeyframeTrack.d.ts create mode 100644 src-testing/src/animation/tracks/QuaternionKeyframeTrack.d.ts create mode 100644 src-testing/src/animation/tracks/StringKeyframeTrack.d.ts create mode 100644 src-testing/src/animation/tracks/VectorKeyframeTrack.d.ts create mode 100644 src-testing/src/audio/Audio.d.ts create mode 100644 src-testing/src/audio/AudioAnalyser.d.ts create mode 100644 src-testing/src/audio/AudioContext.d.ts create mode 100644 src-testing/src/audio/AudioListener.d.ts create mode 100644 src-testing/src/audio/PositionalAudio.d.ts create mode 100644 src-testing/src/cameras/ArrayCamera.d.ts create mode 100644 src-testing/src/cameras/Camera.d.ts create mode 100644 src-testing/src/cameras/CubeCamera.d.ts create mode 100644 src-testing/src/cameras/OrthographicCamera.d.ts create mode 100644 src-testing/src/cameras/PerspectiveCamera.d.ts create mode 100644 src-testing/src/cameras/StereoCamera.d.ts create mode 100644 src-testing/src/constants.d.ts create mode 100644 src-testing/src/core/BufferAttribute.d.ts create mode 100644 src-testing/src/core/BufferGeometry.d.ts create mode 100644 src-testing/src/core/Clock.d.ts create mode 100644 src-testing/src/core/EventDispatcher.d.ts create mode 100644 src-testing/src/core/GLBufferAttribute.d.ts create mode 100644 src-testing/src/core/InstancedBufferAttribute.d.ts create mode 100644 src-testing/src/core/InstancedBufferGeometry.d.ts create mode 100644 src-testing/src/core/InstancedInterleavedBuffer.d.ts create mode 100644 src-testing/src/core/InterleavedBuffer.d.ts create mode 100644 src-testing/src/core/InterleavedBufferAttribute.d.ts create mode 100644 src-testing/src/core/Layers.d.ts create mode 100644 src-testing/src/core/Object3D.d.ts create mode 100644 src-testing/src/core/Raycaster.d.ts create mode 100644 src-testing/src/core/RenderTarget.d.ts create mode 100644 src-testing/src/core/Uniform.d.ts create mode 100644 src-testing/src/core/UniformsGroup.d.ts create mode 100644 src-testing/src/extras/Controls.d.ts create mode 100644 src-testing/src/extras/DataUtils.d.ts create mode 100644 src-testing/src/extras/Earcut.d.ts create mode 100644 src-testing/src/extras/ImageUtils.d.ts create mode 100644 src-testing/src/extras/PMREMGenerator.d.ts create mode 100644 src-testing/src/extras/ShapeUtils.d.ts create mode 100644 src-testing/src/extras/TextureUtils.d.ts create mode 100644 src-testing/src/extras/core/Curve.d.ts create mode 100644 src-testing/src/extras/core/CurvePath.d.ts create mode 100644 src-testing/src/extras/core/Interpolations.d.ts create mode 100644 src-testing/src/extras/core/Path.d.ts create mode 100644 src-testing/src/extras/core/Shape.d.ts create mode 100644 src-testing/src/extras/core/ShapePath.d.ts create mode 100644 src-testing/src/extras/curves/ArcCurve.d.ts create mode 100644 src-testing/src/extras/curves/CatmullRomCurve3.d.ts create mode 100644 src-testing/src/extras/curves/CubicBezierCurve.d.ts create mode 100644 src-testing/src/extras/curves/CubicBezierCurve3.d.ts create mode 100644 src-testing/src/extras/curves/Curves.d.ts create mode 100644 src-testing/src/extras/curves/EllipseCurve.d.ts create mode 100644 src-testing/src/extras/curves/LineCurve.d.ts create mode 100644 src-testing/src/extras/curves/LineCurve3.d.ts create mode 100644 src-testing/src/extras/curves/QuadraticBezierCurve.d.ts create mode 100644 src-testing/src/extras/curves/QuadraticBezierCurve3.d.ts create mode 100644 src-testing/src/extras/curves/SplineCurve.d.ts create mode 100644 src-testing/src/geometries/BoxGeometry.d.ts create mode 100644 src-testing/src/geometries/CapsuleGeometry.d.ts create mode 100644 src-testing/src/geometries/CircleGeometry.d.ts create mode 100644 src-testing/src/geometries/ConeGeometry.d.ts create mode 100644 src-testing/src/geometries/CylinderGeometry.d.ts create mode 100644 src-testing/src/geometries/DodecahedronGeometry.d.ts create mode 100644 src-testing/src/geometries/EdgesGeometry.d.ts create mode 100644 src-testing/src/geometries/ExtrudeGeometry.d.ts create mode 100644 src-testing/src/geometries/Geometries.d.ts create mode 100644 src-testing/src/geometries/IcosahedronGeometry.d.ts create mode 100644 src-testing/src/geometries/LatheGeometry.d.ts create mode 100644 src-testing/src/geometries/OctahedronGeometry.d.ts create mode 100644 src-testing/src/geometries/PlaneGeometry.d.ts create mode 100644 src-testing/src/geometries/PolyhedronGeometry.d.ts create mode 100644 src-testing/src/geometries/RingGeometry.d.ts create mode 100644 src-testing/src/geometries/ShapeGeometry.d.ts create mode 100644 src-testing/src/geometries/SphereGeometry.d.ts create mode 100644 src-testing/src/geometries/TetrahedronGeometry.d.ts create mode 100644 src-testing/src/geometries/TorusGeometry.d.ts create mode 100644 src-testing/src/geometries/TorusKnotGeometry.d.ts create mode 100644 src-testing/src/geometries/TubeGeometry.d.ts create mode 100644 src-testing/src/geometries/WireframeGeometry.d.ts create mode 100644 src-testing/src/helpers/ArrowHelper.d.ts create mode 100644 src-testing/src/helpers/AxesHelper.d.ts create mode 100644 src-testing/src/helpers/Box3Helper.d.ts create mode 100644 src-testing/src/helpers/BoxHelper.d.ts create mode 100644 src-testing/src/helpers/CameraHelper.d.ts create mode 100644 src-testing/src/helpers/DirectionalLightHelper.d.ts create mode 100644 src-testing/src/helpers/GridHelper.d.ts create mode 100644 src-testing/src/helpers/HemisphereLightHelper.d.ts create mode 100644 src-testing/src/helpers/PlaneHelper.d.ts create mode 100644 src-testing/src/helpers/PointLightHelper.d.ts create mode 100644 src-testing/src/helpers/PolarGridHelper.d.ts create mode 100644 src-testing/src/helpers/SkeletonHelper.d.ts create mode 100644 src-testing/src/helpers/SpotLightHelper.d.ts create mode 100644 src-testing/src/lights/AmbientLight.d.ts create mode 100644 src-testing/src/lights/DirectionalLight.d.ts create mode 100644 src-testing/src/lights/DirectionalLightShadow.d.ts create mode 100644 src-testing/src/lights/HemisphereLight.d.ts create mode 100644 src-testing/src/lights/Light.d.ts create mode 100644 src-testing/src/lights/LightProbe.d.ts create mode 100644 src-testing/src/lights/LightShadow.d.ts create mode 100644 src-testing/src/lights/PointLight.d.ts create mode 100644 src-testing/src/lights/PointLightShadow.d.ts create mode 100644 src-testing/src/lights/RectAreaLight.d.ts create mode 100644 src-testing/src/lights/SpotLight.d.ts create mode 100644 src-testing/src/lights/SpotLightShadow.d.ts create mode 100644 src-testing/src/lights/webgpu/IESSpotLight.d.ts create mode 100644 src-testing/src/loaders/AnimationLoader.d.ts create mode 100644 src-testing/src/loaders/AudioLoader.d.ts create mode 100644 src-testing/src/loaders/BufferGeometryLoader.d.ts create mode 100644 src-testing/src/loaders/Cache.d.ts create mode 100644 src-testing/src/loaders/CompressedTextureLoader.d.ts create mode 100644 src-testing/src/loaders/CubeTextureLoader.d.ts create mode 100644 src-testing/src/loaders/DataTextureLoader.d.ts create mode 100644 src-testing/src/loaders/FileLoader.d.ts create mode 100644 src-testing/src/loaders/ImageBitmapLoader.d.ts create mode 100644 src-testing/src/loaders/ImageLoader.d.ts create mode 100644 src-testing/src/loaders/Loader.d.ts create mode 100644 src-testing/src/loaders/LoaderUtils.d.ts create mode 100644 src-testing/src/loaders/LoadingManager.d.ts create mode 100644 src-testing/src/loaders/MaterialLoader.d.ts create mode 100644 src-testing/src/loaders/ObjectLoader.d.ts create mode 100644 src-testing/src/loaders/TextureLoader.d.ts create mode 100644 src-testing/src/loaders/nodes/NodeLoader.d.ts create mode 100644 src-testing/src/loaders/nodes/NodeMaterialLoader.d.ts create mode 100644 src-testing/src/loaders/nodes/NodeObjectLoader.d.ts create mode 100644 src-testing/src/materials/LineBasicMaterial.d.ts create mode 100644 src-testing/src/materials/LineDashedMaterial.d.ts create mode 100644 src-testing/src/materials/Material.d.ts create mode 100644 src-testing/src/materials/Materials.d.ts create mode 100644 src-testing/src/materials/MeshBasicMaterial.d.ts create mode 100644 src-testing/src/materials/MeshDepthMaterial.d.ts create mode 100644 src-testing/src/materials/MeshDistanceMaterial.d.ts create mode 100644 src-testing/src/materials/MeshLambertMaterial.d.ts create mode 100644 src-testing/src/materials/MeshMatcapMaterial.d.ts create mode 100644 src-testing/src/materials/MeshNormalMaterial.d.ts create mode 100644 src-testing/src/materials/MeshPhongMaterial.d.ts create mode 100644 src-testing/src/materials/MeshPhysicalMaterial.d.ts create mode 100644 src-testing/src/materials/MeshStandardMaterial.d.ts create mode 100644 src-testing/src/materials/MeshToonMaterial.d.ts create mode 100644 src-testing/src/materials/PointsMaterial.d.ts create mode 100644 src-testing/src/materials/RawShaderMaterial.d.ts create mode 100644 src-testing/src/materials/ShaderMaterial.d.ts create mode 100644 src-testing/src/materials/ShadowMaterial.d.ts create mode 100644 src-testing/src/materials/SpriteMaterial.d.ts create mode 100644 src-testing/src/materials/nodes/InstancedPointsNodeMaterial.d.ts create mode 100644 src-testing/src/materials/nodes/Line2NodeMaterial.d.ts create mode 100644 src-testing/src/materials/nodes/LineBasicNodeMaterial.d.ts create mode 100644 src-testing/src/materials/nodes/LineDashedNodeMaterial.d.ts create mode 100644 src-testing/src/materials/nodes/MeshBasicNodeMaterial.d.ts create mode 100644 src-testing/src/materials/nodes/MeshLambertNodeMaterial.d.ts create mode 100644 src-testing/src/materials/nodes/MeshMatcapNodeMaterial.d.ts create mode 100644 src-testing/src/materials/nodes/MeshNormalNodeMaterial.d.ts create mode 100644 src-testing/src/materials/nodes/MeshPhongNodeMaterial.d.ts create mode 100644 src-testing/src/materials/nodes/MeshPhysicalNodeMaterial.d.ts create mode 100644 src-testing/src/materials/nodes/MeshSSSNodeMaterial.d.ts create mode 100644 src-testing/src/materials/nodes/MeshStandardNodeMaterial.d.ts create mode 100644 src-testing/src/materials/nodes/MeshToonNodeMaterial.d.ts create mode 100644 src-testing/src/materials/nodes/NodeMaterial.ts create mode 100644 src-testing/src/materials/nodes/NodeMaterials.d.ts create mode 100644 src-testing/src/materials/nodes/PointsNodeMaterial.d.ts create mode 100644 src-testing/src/materials/nodes/ShadowNodeMaterial.d.ts create mode 100644 src-testing/src/materials/nodes/SpriteNodeMaterial.d.ts create mode 100644 src-testing/src/materials/nodes/VolumeNodeMaterial.d.ts create mode 100644 src-testing/src/materials/nodes/manager/NodeMaterialObserver.ts create mode 100644 src-testing/src/math/Box2.d.ts create mode 100644 src-testing/src/math/Box3.d.ts create mode 100644 src-testing/src/math/Color.d.ts create mode 100644 src-testing/src/math/ColorManagement.d.ts create mode 100644 src-testing/src/math/Cylindrical.d.ts create mode 100644 src-testing/src/math/Euler.d.ts create mode 100644 src-testing/src/math/Frustum.d.ts create mode 100644 src-testing/src/math/Interpolant.d.ts create mode 100644 src-testing/src/math/Line3.d.ts create mode 100644 src-testing/src/math/MathUtils.d.ts create mode 100644 src-testing/src/math/Matrix2.d.ts create mode 100644 src-testing/src/math/Matrix3.d.ts create mode 100644 src-testing/src/math/Matrix4.d.ts create mode 100644 src-testing/src/math/Plane.d.ts create mode 100644 src-testing/src/math/Quaternion.d.ts create mode 100644 src-testing/src/math/Ray.d.ts create mode 100644 src-testing/src/math/Sphere.d.ts create mode 100644 src-testing/src/math/Spherical.d.ts create mode 100644 src-testing/src/math/SphericalHarmonics3.d.ts create mode 100644 src-testing/src/math/Triangle.d.ts create mode 100644 src-testing/src/math/Vector2.d.ts create mode 100644 src-testing/src/math/Vector3.d.ts create mode 100644 src-testing/src/math/Vector4.d.ts create mode 100644 src-testing/src/math/interpolants/CubicInterpolant.d.ts create mode 100644 src-testing/src/math/interpolants/DiscreteInterpolant.d.ts create mode 100644 src-testing/src/math/interpolants/LinearInterpolant.d.ts create mode 100644 src-testing/src/math/interpolants/QuaternionLinearInterpolant.d.ts create mode 100644 src-testing/src/nodes/Nodes.ts create mode 100644 src-testing/src/nodes/TSL.d.ts create mode 100644 src-testing/src/nodes/accessors/AccessorsUtils.d.ts create mode 100644 src-testing/src/nodes/accessors/BatchNode.d.ts create mode 100644 src-testing/src/nodes/accessors/Bitangent.d.ts create mode 100644 src-testing/src/nodes/accessors/BufferAttributeNode.ts create mode 100644 src-testing/src/nodes/accessors/BufferNode.d.ts create mode 100644 src-testing/src/nodes/accessors/Camera.d.ts create mode 100644 src-testing/src/nodes/accessors/ClippingNode.d.ts create mode 100644 src-testing/src/nodes/accessors/CubeTextureNode.d.ts create mode 100644 src-testing/src/nodes/accessors/InstanceNode.d.ts create mode 100644 src-testing/src/nodes/accessors/MaterialNode.d.ts create mode 100644 src-testing/src/nodes/accessors/MaterialProperties.d.ts create mode 100644 src-testing/src/nodes/accessors/MaterialReferenceNode.d.ts create mode 100644 src-testing/src/nodes/accessors/ModelNode.d.ts create mode 100644 src-testing/src/nodes/accessors/ModelViewProjectionNode.d.ts create mode 100644 src-testing/src/nodes/accessors/MorphNode.d.ts create mode 100644 src-testing/src/nodes/accessors/Normal.d.ts create mode 100644 src-testing/src/nodes/accessors/Object3DNode.d.ts create mode 100644 src-testing/src/nodes/accessors/PointUVNode.d.ts create mode 100644 src-testing/src/nodes/accessors/Position.d.ts create mode 100644 src-testing/src/nodes/accessors/ReferenceBaseNode.d.ts create mode 100644 src-testing/src/nodes/accessors/ReferenceNode.d.ts create mode 100644 src-testing/src/nodes/accessors/ReflectVector.d.ts create mode 100644 src-testing/src/nodes/accessors/RendererReferenceNode.d.ts create mode 100644 src-testing/src/nodes/accessors/SceneNode.d.ts create mode 100644 src-testing/src/nodes/accessors/SkinningNode.d.ts create mode 100644 src-testing/src/nodes/accessors/StorageBufferNode.d.ts create mode 100644 src-testing/src/nodes/accessors/StorageTextureNode.d.ts create mode 100644 src-testing/src/nodes/accessors/Tangent.d.ts create mode 100644 src-testing/src/nodes/accessors/Texture3DNode.d.ts create mode 100644 src-testing/src/nodes/accessors/TextureBicubic.d.ts create mode 100644 src-testing/src/nodes/accessors/TextureNode.ts create mode 100644 src-testing/src/nodes/accessors/TextureSizeNode.d.ts create mode 100644 src-testing/src/nodes/accessors/UV.d.ts create mode 100644 src-testing/src/nodes/accessors/UniformArrayNode.d.ts create mode 100644 src-testing/src/nodes/accessors/UserDataNode.d.ts create mode 100644 src-testing/src/nodes/accessors/VelocityNode.d.ts create mode 100644 src-testing/src/nodes/accessors/VertexColorNode.d.ts create mode 100644 src-testing/src/nodes/code/CodeNode.ts create mode 100644 src-testing/src/nodes/code/ExpressionNode.d.ts create mode 100644 src-testing/src/nodes/code/FunctionCallNode.d.ts create mode 100644 src-testing/src/nodes/code/FunctionNode.ts create mode 100644 src-testing/src/nodes/code/ScriptableNode.d.ts create mode 100644 src-testing/src/nodes/code/ScriptableValueNode.d.ts create mode 100644 src-testing/src/nodes/core/AssignNode.d.ts create mode 100644 src-testing/src/nodes/core/AttributeNode.d.ts create mode 100644 src-testing/src/nodes/core/BypassNode.d.ts create mode 100644 src-testing/src/nodes/core/CacheNode.d.ts create mode 100644 src-testing/src/nodes/core/ConstNode.d.ts create mode 100644 src-testing/src/nodes/core/ContextNode.ts create mode 100644 src-testing/src/nodes/core/IndexNode.d.ts create mode 100644 src-testing/src/nodes/core/InputNode.ts create mode 100644 src-testing/src/nodes/core/LightingModel.d.ts create mode 100644 src-testing/src/nodes/core/MRTNode.d.ts create mode 100644 src-testing/src/nodes/core/Node.ts create mode 100644 src-testing/src/nodes/core/NodeAttribute.ts create mode 100644 src-testing/src/nodes/core/NodeBuilder.ts create mode 100644 src-testing/src/nodes/core/NodeCache.ts create mode 100644 src-testing/src/nodes/core/NodeCode.ts create mode 100644 src-testing/src/nodes/core/NodeFrame.ts create mode 100644 src-testing/src/nodes/core/NodeFunction.ts create mode 100644 src-testing/src/nodes/core/NodeFunctionInput.d.ts create mode 100644 src-testing/src/nodes/core/NodeParser.ts create mode 100644 src-testing/src/nodes/core/NodeUniform.ts create mode 100644 src-testing/src/nodes/core/NodeUtils.ts create mode 100644 src-testing/src/nodes/core/NodeVar.ts create mode 100644 src-testing/src/nodes/core/NodeVarying.ts create mode 100644 src-testing/src/nodes/core/OutputStructNode.d.ts create mode 100644 src-testing/src/nodes/core/ParameterNode.d.ts create mode 100644 src-testing/src/nodes/core/PropertyNode.d.ts create mode 100644 src-testing/src/nodes/core/StackNode.ts create mode 100644 src-testing/src/nodes/core/StructTypeNode.ts create mode 100644 src-testing/src/nodes/core/TempNode.d.ts create mode 100644 src-testing/src/nodes/core/UniformGroup.d.ts create mode 100644 src-testing/src/nodes/core/UniformGroupNode.ts create mode 100644 src-testing/src/nodes/core/UniformNode.ts create mode 100644 src-testing/src/nodes/core/VarNode.d.ts create mode 100644 src-testing/src/nodes/core/VaryingNode.d.ts create mode 100644 src-testing/src/nodes/core/constants.ts create mode 100644 src-testing/src/nodes/display/BlendMode.d.ts create mode 100644 src-testing/src/nodes/display/BumpMapNode.d.ts create mode 100644 src-testing/src/nodes/display/ColorAdjustment.d.ts create mode 100644 src-testing/src/nodes/display/ColorSpaceFunctions.d.ts create mode 100644 src-testing/src/nodes/display/ColorSpaceNode.d.ts create mode 100644 src-testing/src/nodes/display/FrontFacingNode.d.ts create mode 100644 src-testing/src/nodes/display/NormalMapNode.d.ts create mode 100644 src-testing/src/nodes/display/PassNode.d.ts create mode 100644 src-testing/src/nodes/display/PosterizeNode.d.ts create mode 100644 src-testing/src/nodes/display/RenderOutputNode.d.ts create mode 100644 src-testing/src/nodes/display/ScreenNode.d.ts create mode 100644 src-testing/src/nodes/display/ToneMappingFunctions.d.ts create mode 100644 src-testing/src/nodes/display/ToneMappingNode.d.ts create mode 100644 src-testing/src/nodes/display/ToonOutlinePassNode.d.ts create mode 100644 src-testing/src/nodes/display/ViewportDepthNode.d.ts create mode 100644 src-testing/src/nodes/display/ViewportDepthTextureNode.d.ts create mode 100644 src-testing/src/nodes/display/ViewportSharedTextureNode.d.ts create mode 100644 src-testing/src/nodes/display/ViewportTextureNode.d.ts create mode 100644 src-testing/src/nodes/fog/FogExp2Node.d.ts create mode 100644 src-testing/src/nodes/fog/FogNode.ts create mode 100644 src-testing/src/nodes/fog/FogRangeNode.d.ts create mode 100644 src-testing/src/nodes/functions/BSDF/BRDF_GGX.d.ts create mode 100644 src-testing/src/nodes/functions/BSDF/BRDF_Lambert.d.ts create mode 100644 src-testing/src/nodes/functions/BSDF/BRDF_Sheen.d.ts create mode 100644 src-testing/src/nodes/functions/BSDF/DFGApprox.d.ts create mode 100644 src-testing/src/nodes/functions/BSDF/D_GGX.d.ts create mode 100644 src-testing/src/nodes/functions/BSDF/D_GGX_Anisotropic.d.ts create mode 100644 src-testing/src/nodes/functions/BSDF/F_Schlick.d.ts create mode 100644 src-testing/src/nodes/functions/BSDF/LTC.d.ts create mode 100644 src-testing/src/nodes/functions/BSDF/Schlick_to_F0.d.ts create mode 100644 src-testing/src/nodes/functions/BSDF/V_GGX_SmithCorrelated.d.ts create mode 100644 src-testing/src/nodes/functions/BSDF/V_GGX_SmithCorrelated_Anisotropic.d.ts create mode 100644 src-testing/src/nodes/functions/BasicLightingModel.d.ts create mode 100644 src-testing/src/nodes/functions/PhongLightingModel.d.ts create mode 100644 src-testing/src/nodes/functions/PhysicalLightingModel.d.ts create mode 100644 src-testing/src/nodes/functions/ShadowMaskModel.d.ts create mode 100644 src-testing/src/nodes/functions/ToonLightingModel.d.ts create mode 100644 src-testing/src/nodes/functions/material/getGeometryRoughness.d.ts create mode 100644 src-testing/src/nodes/functions/material/getRoughness.d.ts create mode 100644 src-testing/src/nodes/functions/material/getShIrradianceAt.d.ts create mode 100644 src-testing/src/nodes/geometry/RangeNode.d.ts create mode 100644 src-testing/src/nodes/gpgpu/ComputeNode.ts create mode 100644 src-testing/src/nodes/lighting/AONode.d.ts create mode 100644 src-testing/src/nodes/lighting/AmbientLightNode.d.ts create mode 100644 src-testing/src/nodes/lighting/AnalyticLightNode.d.ts create mode 100644 src-testing/src/nodes/lighting/BasicEnvironmentNode.d.ts create mode 100644 src-testing/src/nodes/lighting/BasicLightMapNode.d.ts create mode 100644 src-testing/src/nodes/lighting/DirectionalLightNode.d.ts create mode 100644 src-testing/src/nodes/lighting/EnvironmentNode.ts create mode 100644 src-testing/src/nodes/lighting/HemisphereLightNode.d.ts create mode 100644 src-testing/src/nodes/lighting/IESSpotLightNode.d.ts create mode 100644 src-testing/src/nodes/lighting/IrradianceNode.d.ts create mode 100644 src-testing/src/nodes/lighting/LightNode.d.ts create mode 100644 src-testing/src/nodes/lighting/LightProbeNode.d.ts create mode 100644 src-testing/src/nodes/lighting/LightUtils.d.ts create mode 100644 src-testing/src/nodes/lighting/LightingContextNode.ts create mode 100644 src-testing/src/nodes/lighting/LightingNode.d.ts create mode 100644 src-testing/src/nodes/lighting/LightsNode.ts create mode 100644 src-testing/src/nodes/lighting/PointLightNode.d.ts create mode 100644 src-testing/src/nodes/lighting/RectAreaLightNode.d.ts create mode 100644 src-testing/src/nodes/lighting/ShadowNode.d.ts create mode 100644 src-testing/src/nodes/lighting/SpotLightNode.d.ts create mode 100644 src-testing/src/nodes/materialx/MaterialXNodes.d.ts create mode 100644 src-testing/src/nodes/materialx/lib/mx_hsv.d.ts create mode 100644 src-testing/src/nodes/materialx/lib/mx_noise.d.ts create mode 100644 src-testing/src/nodes/materialx/lib/mx_transform_color.d.ts create mode 100644 src-testing/src/nodes/math/ConditionalNode.d.ts create mode 100644 src-testing/src/nodes/math/Hash.d.ts create mode 100644 src-testing/src/nodes/math/MathNode.d.ts create mode 100644 src-testing/src/nodes/math/MathUtils.d.ts create mode 100644 src-testing/src/nodes/math/OperatorNode.d.ts create mode 100644 src-testing/src/nodes/math/TriNoise3D.d.ts create mode 100644 src-testing/src/nodes/parsers/GLSLNodeFunction.d.ts create mode 100644 src-testing/src/nodes/parsers/GLSLNodeParser.d.ts create mode 100644 src-testing/src/nodes/pmrem/PMREMNode.d.ts create mode 100644 src-testing/src/nodes/pmrem/PMREMUtils.d.ts create mode 100644 src-testing/src/nodes/procedural/Checker.d.ts create mode 100644 src-testing/src/nodes/tsl/TSLBase.d.ts create mode 100644 src-testing/src/nodes/tsl/TSLCore.ts create mode 100644 src-testing/src/nodes/utils/ArrayElementNode.d.ts create mode 100644 src-testing/src/nodes/utils/ConvertNode.d.ts create mode 100644 src-testing/src/nodes/utils/CubeMapNode.d.ts create mode 100644 src-testing/src/nodes/utils/Discard.d.ts create mode 100644 src-testing/src/nodes/utils/EquirectUVNode.d.ts create mode 100644 src-testing/src/nodes/utils/FunctionOverloadingNode.d.ts create mode 100644 src-testing/src/nodes/utils/JoinNode.d.ts create mode 100644 src-testing/src/nodes/utils/LoopNode.d.ts create mode 100644 src-testing/src/nodes/utils/MatcapUVNode.d.ts create mode 100644 src-testing/src/nodes/utils/MaxMipLevelNode.d.ts create mode 100644 src-testing/src/nodes/utils/Oscillators.d.ts create mode 100644 src-testing/src/nodes/utils/Packing.d.ts create mode 100644 src-testing/src/nodes/utils/PostProcessingUtils.d.ts create mode 100644 src-testing/src/nodes/utils/RTTNode.d.ts create mode 100644 src-testing/src/nodes/utils/ReflectorNode.d.ts create mode 100644 src-testing/src/nodes/utils/RemapNode.d.ts create mode 100644 src-testing/src/nodes/utils/RotateNode.d.ts create mode 100644 src-testing/src/nodes/utils/SetNode.d.ts create mode 100644 src-testing/src/nodes/utils/SplitNode.d.ts create mode 100644 src-testing/src/nodes/utils/SpriteSheetUVNode.d.ts create mode 100644 src-testing/src/nodes/utils/SpriteUtils.d.ts create mode 100644 src-testing/src/nodes/utils/StorageArrayElementNode.d.ts create mode 100644 src-testing/src/nodes/utils/Timer.d.ts create mode 100644 src-testing/src/nodes/utils/TriplanarTexturesNode.d.ts create mode 100644 src-testing/src/nodes/utils/UVUtils.d.ts create mode 100644 src-testing/src/nodes/utils/ViewportUtils.d.ts create mode 100644 src-testing/src/objects/BatchedMesh.d.ts create mode 100644 src-testing/src/objects/Bone.d.ts create mode 100644 src-testing/src/objects/Group.d.ts create mode 100644 src-testing/src/objects/InstancedMesh.d.ts create mode 100644 src-testing/src/objects/LOD.d.ts create mode 100644 src-testing/src/objects/Line.d.ts create mode 100644 src-testing/src/objects/LineLoop.d.ts create mode 100644 src-testing/src/objects/LineSegments.d.ts create mode 100644 src-testing/src/objects/Mesh.d.ts create mode 100644 src-testing/src/objects/Points.d.ts create mode 100644 src-testing/src/objects/Skeleton.d.ts create mode 100644 src-testing/src/objects/SkinnedMesh.d.ts create mode 100644 src-testing/src/objects/Sprite.d.ts create mode 100644 src-testing/src/renderers/WebGL3DRenderTarget.d.ts create mode 100644 src-testing/src/renderers/WebGLArrayRenderTarget.d.ts create mode 100644 src-testing/src/renderers/WebGLCubeRenderTarget.d.ts create mode 100644 src-testing/src/renderers/WebGLRenderTarget.d.ts create mode 100644 src-testing/src/renderers/WebGLRenderer.d.ts create mode 100644 src-testing/src/renderers/common/Animation.ts create mode 100644 src-testing/src/renderers/common/Attributes.ts create mode 100644 src-testing/src/renderers/common/Backend.ts create mode 100644 src-testing/src/renderers/common/Background.ts create mode 100644 src-testing/src/renderers/common/BindGroup.ts create mode 100644 src-testing/src/renderers/common/Binding.ts create mode 100644 src-testing/src/renderers/common/Bindings.ts create mode 100644 src-testing/src/renderers/common/Buffer.ts create mode 100644 src-testing/src/renderers/common/BufferUtils.ts create mode 100644 src-testing/src/renderers/common/BundleGroup.ts create mode 100644 src-testing/src/renderers/common/ChainMap.ts create mode 100644 src-testing/src/renderers/common/ClippingContext.ts create mode 100644 src-testing/src/renderers/common/Color4.ts create mode 100644 src-testing/src/renderers/common/ComputePipeline.ts create mode 100644 src-testing/src/renderers/common/Constants.ts create mode 100644 src-testing/src/renderers/common/CubeRenderTarget.ts create mode 100644 src-testing/src/renderers/common/DataMap.ts create mode 100644 src-testing/src/renderers/common/Geometries.ts create mode 100644 src-testing/src/renderers/common/IndirectStorageBufferAttribute.d.ts create mode 100644 src-testing/src/renderers/common/Info.ts create mode 100644 src-testing/src/renderers/common/Lighting.d.ts create mode 100644 src-testing/src/renderers/common/Pipeline.ts create mode 100644 src-testing/src/renderers/common/Pipelines.ts create mode 100644 src-testing/src/renderers/common/PostProcessing.d.ts create mode 100644 src-testing/src/renderers/common/PostProcessingUtils.d.ts create mode 100644 src-testing/src/renderers/common/ProgrammableStage.ts create mode 100644 src-testing/src/renderers/common/QuadMesh.d.ts create mode 100644 src-testing/src/renderers/common/RenderBundle.ts create mode 100644 src-testing/src/renderers/common/RenderBundles.ts create mode 100644 src-testing/src/renderers/common/RenderContext.ts create mode 100644 src-testing/src/renderers/common/RenderContexts.ts create mode 100644 src-testing/src/renderers/common/RenderList.ts create mode 100644 src-testing/src/renderers/common/RenderLists.ts create mode 100644 src-testing/src/renderers/common/RenderObject.ts create mode 100644 src-testing/src/renderers/common/RenderObjects.ts create mode 100644 src-testing/src/renderers/common/RenderPipeline.ts create mode 100644 src-testing/src/renderers/common/Renderer.ts create mode 100644 src-testing/src/renderers/common/SampledTexture.ts create mode 100644 src-testing/src/renderers/common/Sampler.ts create mode 100644 src-testing/src/renderers/common/StorageBuffer.ts create mode 100644 src-testing/src/renderers/common/StorageBufferAttribute.d.ts create mode 100644 src-testing/src/renderers/common/StorageInstancedBufferAttribute.d.ts create mode 100644 src-testing/src/renderers/common/StorageTexture.d.ts create mode 100644 src-testing/src/renderers/common/Textures.ts create mode 100644 src-testing/src/renderers/common/Uniform.ts create mode 100644 src-testing/src/renderers/common/UniformBuffer.ts create mode 100644 src-testing/src/renderers/common/UniformsGroup.ts create mode 100644 src-testing/src/renderers/common/extras/PMREMGenerator.ts create mode 100644 src-testing/src/renderers/common/nodes/NodeBuilderState.ts create mode 100644 src-testing/src/renderers/common/nodes/NodeLibrary.ts create mode 100644 src-testing/src/renderers/common/nodes/NodeSampledTexture.d.ts create mode 100644 src-testing/src/renderers/common/nodes/NodeSampler.d.ts create mode 100644 src-testing/src/renderers/common/nodes/NodeUniform.ts create mode 100644 src-testing/src/renderers/common/nodes/NodeUniformsGroup.ts create mode 100644 src-testing/src/renderers/common/nodes/Nodes.ts create mode 100644 src-testing/src/renderers/common/nodes/StandardNodeLibrary.d.ts create mode 100644 src-testing/src/renderers/shaders/ShaderChunk.d.ts create mode 100644 src-testing/src/renderers/shaders/ShaderLib.d.ts create mode 100644 src-testing/src/renderers/shaders/UniformsLib.d.ts create mode 100644 src-testing/src/renderers/shaders/UniformsUtils.d.ts create mode 100644 src-testing/src/renderers/webgl-fallback/WebGLBackend.ts create mode 100644 src-testing/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.ts create mode 100644 src-testing/src/renderers/webgl/WebGLAttributes.d.ts create mode 100644 src-testing/src/renderers/webgl/WebGLBindingStates.d.ts create mode 100644 src-testing/src/renderers/webgl/WebGLBufferRenderer.d.ts create mode 100644 src-testing/src/renderers/webgl/WebGLCapabilities.d.ts create mode 100644 src-testing/src/renderers/webgl/WebGLClipping.d.ts create mode 100644 src-testing/src/renderers/webgl/WebGLCubeMaps.d.ts create mode 100644 src-testing/src/renderers/webgl/WebGLCubeUVMaps.d.ts create mode 100644 src-testing/src/renderers/webgl/WebGLExtensions.d.ts create mode 100644 src-testing/src/renderers/webgl/WebGLGeometries.d.ts create mode 100644 src-testing/src/renderers/webgl/WebGLIndexedBufferRenderer.d.ts create mode 100644 src-testing/src/renderers/webgl/WebGLInfo.d.ts create mode 100644 src-testing/src/renderers/webgl/WebGLLights.d.ts create mode 100644 src-testing/src/renderers/webgl/WebGLObjects.d.ts create mode 100644 src-testing/src/renderers/webgl/WebGLProgram.d.ts create mode 100644 src-testing/src/renderers/webgl/WebGLPrograms.d.ts create mode 100644 src-testing/src/renderers/webgl/WebGLProperties.d.ts create mode 100644 src-testing/src/renderers/webgl/WebGLRenderLists.d.ts create mode 100644 src-testing/src/renderers/webgl/WebGLShader.d.ts create mode 100644 src-testing/src/renderers/webgl/WebGLShadowMap.d.ts create mode 100644 src-testing/src/renderers/webgl/WebGLState.d.ts create mode 100644 src-testing/src/renderers/webgl/WebGLTextures.d.ts create mode 100644 src-testing/src/renderers/webgl/WebGLUniforms.d.ts create mode 100644 src-testing/src/renderers/webgl/WebGLUniformsGroups.d.ts create mode 100644 src-testing/src/renderers/webgl/WebGLUtils.d.ts create mode 100644 src-testing/src/renderers/webgpu/WebGPUBackend.ts create mode 100644 src-testing/src/renderers/webgpu/WebGPURenderer.Nodes.d.ts create mode 100644 src-testing/src/renderers/webgpu/WebGPURenderer.ts create mode 100644 src-testing/src/renderers/webgpu/nodes/BasicNodeLibrary.ts create mode 100644 src-testing/src/renderers/webgpu/nodes/StandardNodeLibrary.ts create mode 100644 src-testing/src/renderers/webgpu/nodes/WGSLNodeBuilder.ts create mode 100644 src-testing/src/renderers/webgpu/nodes/WGSLNodeFunction.ts create mode 100644 src-testing/src/renderers/webgpu/nodes/WGSLNodeParser.ts create mode 100644 src-testing/src/renderers/webgpu/utils/WebGPUConstants.d.ts create mode 100644 src-testing/src/renderers/webxr/WebXRController.d.ts create mode 100644 src-testing/src/renderers/webxr/WebXRDepthSensing.d.ts create mode 100644 src-testing/src/renderers/webxr/WebXRManager.d.ts create mode 100644 src-testing/src/scenes/Fog.d.ts create mode 100644 src-testing/src/scenes/FogExp2.d.ts create mode 100644 src-testing/src/scenes/Scene.d.ts create mode 100644 src-testing/src/textures/CanvasTexture.d.ts create mode 100644 src-testing/src/textures/CompressedArrayTexture.d.ts create mode 100644 src-testing/src/textures/CompressedCubeTexture.d.ts create mode 100644 src-testing/src/textures/CompressedTexture.d.ts create mode 100644 src-testing/src/textures/CubeTexture.d.ts create mode 100644 src-testing/src/textures/Data3DTexture.d.ts create mode 100644 src-testing/src/textures/DataArrayTexture.d.ts create mode 100644 src-testing/src/textures/DataTexture.d.ts create mode 100644 src-testing/src/textures/DepthTexture.d.ts create mode 100644 src-testing/src/textures/FramebufferTexture.d.ts create mode 100644 src-testing/src/textures/Source.d.ts create mode 100644 src-testing/src/textures/Texture.d.ts create mode 100644 src-testing/src/textures/VideoTexture.d.ts create mode 100644 src-testing/src/textures/types.d.ts create mode 100644 src-testing/src/utils.d.ts diff --git a/src-testing/src/Three.Legacy.d.ts b/src-testing/src/Three.Legacy.d.ts new file mode 100644 index 000000000..07f4743b9 --- /dev/null +++ b/src-testing/src/Three.Legacy.d.ts @@ -0,0 +1,20 @@ +import { RenderTargetOptions } from "./core/RenderTarget.js"; +import { WebGLRenderTarget } from "./renderers/WebGLRenderTarget.js"; +import { Texture } from "./textures/Texture.js"; + +/** + * @deprecated THREE.WebGLMultipleRenderTargets has been deprecated and will be removed in r172. Use THREE.WebGLRenderTarget and set the "count" parameter to enable MRT. + */ +export class WebGLMultipleRenderTargets extends WebGLRenderTarget { + readonly isWebGLMultipleRenderTargets: true; + + /** + * @deprecated THREE.WebGLMultipleRenderTargets has been deprecated and will be removed in r172. Use THREE.WebGLRenderTarget and set the "count" parameter to enable MRT. + * @param width The width of the render target. + * @param height The height of the render target. + * @param count The number of render targets. + * @param options object that holds texture parameters for an auto-generated target texture and depthBuffer/stencilBuffer booleans. + * For an explanation of the texture parameters see {@link Texture}. + */ + constructor(width?: number, height?: number, count?: number, options?: RenderTargetOptions); +} diff --git a/src-testing/src/Three.WebGPU.Nodes.d.ts b/src-testing/src/Three.WebGPU.Nodes.d.ts new file mode 100644 index 000000000..ac876f6fe --- /dev/null +++ b/src-testing/src/Three.WebGPU.Nodes.d.ts @@ -0,0 +1,205 @@ +export * from "./animation/AnimationAction.js"; +export * from "./animation/AnimationClip.js"; +export * from "./animation/AnimationMixer.js"; +export * from "./animation/AnimationObjectGroup.js"; +export { AnimationUtils } from "./animation/AnimationUtils.js"; +export * from "./animation/KeyframeTrack.js"; +export * from "./animation/PropertyBinding.js"; +export * from "./animation/PropertyMixer.js"; +export * from "./animation/tracks/BooleanKeyframeTrack.js"; +export * from "./animation/tracks/ColorKeyframeTrack.js"; +export * from "./animation/tracks/NumberKeyframeTrack.js"; +export * from "./animation/tracks/QuaternionKeyframeTrack.js"; +export * from "./animation/tracks/StringKeyframeTrack.js"; +export * from "./animation/tracks/VectorKeyframeTrack.js"; +export * from "./audio/Audio.js"; +export * from "./audio/AudioAnalyser.js"; +export * from "./audio/AudioContext.js"; +export * from "./audio/AudioListener.js"; +export * from "./audio/PositionalAudio.js"; +export * from "./cameras/ArrayCamera.js"; +export * from "./cameras/Camera.js"; +export * from "./cameras/CubeCamera.js"; +export * from "./cameras/OrthographicCamera.js"; +export * from "./cameras/PerspectiveCamera.js"; +export * from "./cameras/StereoCamera.js"; +export * from "./constants.js"; +export * from "./core/BufferAttribute.js"; +export * from "./core/BufferGeometry.js"; +export * from "./core/Clock.js"; +export * from "./core/EventDispatcher.js"; +export * from "./core/GLBufferAttribute.js"; +export * from "./core/InstancedBufferAttribute.js"; +export * from "./core/InstancedBufferGeometry.js"; +export * from "./core/InstancedInterleavedBuffer.js"; +export * from "./core/InterleavedBuffer.js"; +export * from "./core/InterleavedBufferAttribute.js"; +export * from "./core/Layers.js"; +export * from "./core/Object3D.js"; +export * from "./core/Raycaster.js"; +export * from "./core/RenderTarget.js"; +export * from "./core/Uniform.js"; +export * from "./core/UniformsGroup.js"; +export * from "./extras/Controls.js"; +export * from "./extras/core/Curve.js"; +export * from "./extras/core/CurvePath.js"; +export * from "./extras/core/Path.js"; +export * from "./extras/core/Shape.js"; +export * from "./extras/core/ShapePath.js"; +export * from "./extras/curves/Curves.js"; +export { DataUtils } from "./extras/DataUtils.js"; +export * from "./extras/ImageUtils.js"; +// export * from "./extras/PMREMGenerator.js"; +export * from "./extras/ShapeUtils.js"; +export { TextureUtils } from "./extras/TextureUtils.js"; +export * from "./geometries/Geometries.js"; +export * from "./helpers/ArrowHelper.js"; +export * from "./helpers/AxesHelper.js"; +export * from "./helpers/Box3Helper.js"; +export * from "./helpers/BoxHelper.js"; +export * from "./helpers/CameraHelper.js"; +export * from "./helpers/DirectionalLightHelper.js"; +export * from "./helpers/GridHelper.js"; +export * from "./helpers/HemisphereLightHelper.js"; +export * from "./helpers/PlaneHelper.js"; +export * from "./helpers/PointLightHelper.js"; +export * from "./helpers/PolarGridHelper.js"; +export * from "./helpers/SkeletonHelper.js"; +export * from "./helpers/SpotLightHelper.js"; +export * from "./lights/AmbientLight.js"; +export * from "./lights/DirectionalLight.js"; +export type { DirectionalLightShadow } from "./lights/DirectionalLightShadow.js"; +export * from "./lights/HemisphereLight.js"; +export * from "./lights/Light.js"; +export * from "./lights/LightProbe.js"; +export type { LightShadow, LightShadowJSON } from "./lights/LightShadow.js"; +export * from "./lights/PointLight.js"; +export type { PointLightShadow } from "./lights/PointLightShadow.js"; +export * from "./lights/RectAreaLight.js"; +export * from "./lights/SpotLight.js"; +export type { SpotLightShadow } from "./lights/SpotLightShadow.js"; +export * from "./loaders/AnimationLoader.js"; +export * from "./loaders/AudioLoader.js"; +export * from "./loaders/BufferGeometryLoader.js"; +export * from "./loaders/Cache.js"; +export * from "./loaders/CompressedTextureLoader.js"; +export * from "./loaders/CubeTextureLoader.js"; +export * from "./loaders/DataTextureLoader.js"; +export * from "./loaders/FileLoader.js"; +export * from "./loaders/ImageBitmapLoader.js"; +export * from "./loaders/ImageLoader.js"; +export * from "./loaders/Loader.js"; +export * from "./loaders/LoaderUtils.js"; +export * from "./loaders/LoadingManager.js"; +export * from "./loaders/MaterialLoader.js"; +export * from "./loaders/ObjectLoader.js"; +export * from "./loaders/TextureLoader.js"; +export * from "./materials/Materials.js"; +export * from "./materials/nodes/NodeMaterials.js"; +export * from "./math/Box2.js"; +export * from "./math/Box3.js"; +export * from "./math/Color.js"; +export { ColorManagement, ColorSpaceDefinition } from "./math/ColorManagement.js"; +export * from "./math/Cylindrical.js"; +export * from "./math/Euler.js"; +export * from "./math/Frustum.js"; +export * from "./math/Interpolant.js"; +export * from "./math/interpolants/CubicInterpolant.js"; +export * from "./math/interpolants/DiscreteInterpolant.js"; +export * from "./math/interpolants/LinearInterpolant.js"; +export * from "./math/interpolants/QuaternionLinearInterpolant.js"; +export * from "./math/Line3.js"; +export { MathUtils } from "./math/MathUtils.js"; +export * from "./math/Matrix2.js"; +export * from "./math/Matrix3.js"; +export * from "./math/Matrix4.js"; +export * from "./math/Plane.js"; +export * from "./math/Quaternion.js"; +export * from "./math/Ray.js"; +export * from "./math/Sphere.js"; +export * from "./math/Spherical.js"; +export * from "./math/SphericalHarmonics3.js"; +export * from "./math/Triangle.js"; +export * from "./math/Vector2.js"; +export * from "./math/Vector3.js"; +export * from "./math/Vector4.js"; +export * from "./objects/BatchedMesh.js"; +export * from "./objects/Bone.js"; +export * from "./objects/Group.js"; +export * from "./objects/InstancedMesh.js"; +export * from "./objects/Line.js"; +export * from "./objects/LineLoop.js"; +export * from "./objects/LineSegments.js"; +export * from "./objects/LOD.js"; +export * from "./objects/Mesh.js"; +export * from "./objects/Points.js"; +export * from "./objects/Skeleton.js"; +export * from "./objects/SkinnedMesh.js"; +export * from "./objects/Sprite.js"; +// export * from "./renderers/shaders/ShaderChunk.js"; +// export * from "./renderers/shaders/ShaderLib.js"; +// export * from "./renderers/shaders/UniformsLib.js"; +// export { UniformsUtils } from './renderers/shaders/UniformsUtils.js'; +export type { WebGLProgramParameters, WebGLProgramParametersWithUniforms } from "./renderers/webgl/WebGLPrograms.js"; +export type { WebGLShadowMap } from "./renderers/webgl/WebGLShadowMap.js"; +// export * from "./renderers/webgl/WebGLUtils.js"; +export * from "./renderers/WebGL3DRenderTarget.js"; +export * from "./renderers/WebGLArrayRenderTarget.js"; +export * from "./renderers/WebGLCubeRenderTarget.js"; +// export * from "./renderers/WebGLRenderer.js"; +export * from "./renderers/WebGLRenderTarget.js"; +export type { + WebXRController, + WebXRSpaceEventMap, + XRControllerEventType, + XRGripSpace, + XRHandInputState, + XRHandJoints, + XRHandSpace, + XRJointSpace, + XRTargetRaySpace, +} from "./renderers/webxr/WebXRController.js"; +export type { WebXRDepthSensing } from "./renderers/webxr/WebXRDepthSensing.js"; +export type { + WebXRArrayCamera, + WebXRCamera, + WebXRManager, + WebXRManagerEventMap, +} from "./renderers/webxr/WebXRManager.js"; +export * from "./scenes/Fog.js"; +export * from "./scenes/FogExp2.js"; +export * from "./scenes/Scene.js"; +export * from "./textures/CanvasTexture.js"; +export * from "./textures/CompressedArrayTexture.js"; +export * from "./textures/CompressedCubeTexture.js"; +export * from "./textures/CompressedTexture.js"; +export * from "./textures/CubeTexture.js"; +export * from "./textures/Data3DTexture.js"; +export * from "./textures/DataArrayTexture.js"; +export * from "./textures/DataTexture.js"; +export * from "./textures/DepthTexture.js"; +export * from "./textures/FramebufferTexture.js"; +export * from "./textures/Source.js"; +export * from "./textures/Texture.js"; +export * from "./textures/VideoTexture.js"; +export * from "./Three.Legacy.js"; +export { createCanvasElement } from "./utils.js"; + +export { default as IESSpotLight } from "./lights/webgpu/IESSpotLight.js"; +export { default as NodeLoader } from "./loaders/nodes/NodeLoader.js"; +export { default as NodeMaterialLoader } from "./loaders/nodes/NodeMaterialLoader.js"; +export { default as NodeObjectLoader } from "./loaders/nodes/NodeObjectLoader.js"; +export * from "./nodes/Nodes.js"; +export * from "./nodes/TSL.js"; +export { default as PMREMGenerator } from "./renderers/common/extras/PMREMGenerator.js"; +export { default as PostProcessing } from "./renderers/common/PostProcessing.js"; +import * as PostProcessingUtils from "./renderers/common/PostProcessingUtils.js"; +export { PostProcessingUtils }; +export { default as IndirectStorageBufferAttribute } from "./renderers/common/IndirectStorageBufferAttribute.js"; +export { default as Lighting } from "./renderers/common/Lighting.js"; +export { default as QuadMesh } from "./renderers/common/QuadMesh.js"; +export type { default as Renderer } from "./renderers/common/Renderer.js"; +export { default as StorageBufferAttribute } from "./renderers/common/StorageBufferAttribute.js"; +export { default as StorageInstancedBufferAttribute } from "./renderers/common/StorageInstancedBufferAttribute.js"; +export { default as StorageTexture } from "./renderers/common/StorageTexture.js"; +export { default as WebGPURenderer } from "./renderers/webgpu/WebGPURenderer.Nodes.js"; diff --git a/src-testing/src/Three.WebGPU.d.ts b/src-testing/src/Three.WebGPU.d.ts new file mode 100644 index 000000000..254ef5332 --- /dev/null +++ b/src-testing/src/Three.WebGPU.d.ts @@ -0,0 +1,206 @@ +export * from "./animation/AnimationAction.js"; +export * from "./animation/AnimationClip.js"; +export * from "./animation/AnimationMixer.js"; +export * from "./animation/AnimationObjectGroup.js"; +export { AnimationUtils } from "./animation/AnimationUtils.js"; +export * from "./animation/KeyframeTrack.js"; +export * from "./animation/PropertyBinding.js"; +export * from "./animation/PropertyMixer.js"; +export * from "./animation/tracks/BooleanKeyframeTrack.js"; +export * from "./animation/tracks/ColorKeyframeTrack.js"; +export * from "./animation/tracks/NumberKeyframeTrack.js"; +export * from "./animation/tracks/QuaternionKeyframeTrack.js"; +export * from "./animation/tracks/StringKeyframeTrack.js"; +export * from "./animation/tracks/VectorKeyframeTrack.js"; +export * from "./audio/Audio.js"; +export * from "./audio/AudioAnalyser.js"; +export * from "./audio/AudioContext.js"; +export * from "./audio/AudioListener.js"; +export * from "./audio/PositionalAudio.js"; +export * from "./cameras/ArrayCamera.js"; +export * from "./cameras/Camera.js"; +export * from "./cameras/CubeCamera.js"; +export * from "./cameras/OrthographicCamera.js"; +export * from "./cameras/PerspectiveCamera.js"; +export * from "./cameras/StereoCamera.js"; +export * from "./constants.js"; +export * from "./core/BufferAttribute.js"; +export * from "./core/BufferGeometry.js"; +export * from "./core/Clock.js"; +export * from "./core/EventDispatcher.js"; +export * from "./core/GLBufferAttribute.js"; +export * from "./core/InstancedBufferAttribute.js"; +export * from "./core/InstancedBufferGeometry.js"; +export * from "./core/InstancedInterleavedBuffer.js"; +export * from "./core/InterleavedBuffer.js"; +export * from "./core/InterleavedBufferAttribute.js"; +export * from "./core/Layers.js"; +export * from "./core/Object3D.js"; +export * from "./core/Raycaster.js"; +export * from "./core/RenderTarget.js"; +export * from "./core/Uniform.js"; +export * from "./core/UniformsGroup.js"; +export * from "./extras/Controls.js"; +export * from "./extras/core/Curve.js"; +export * from "./extras/core/CurvePath.js"; +export * from "./extras/core/Path.js"; +export * from "./extras/core/Shape.js"; +export * from "./extras/core/ShapePath.js"; +export * from "./extras/curves/Curves.js"; +export { DataUtils } from "./extras/DataUtils.js"; +export * from "./extras/ImageUtils.js"; +// export * from "./extras/PMREMGenerator.js"; +export * from "./extras/ShapeUtils.js"; +export { TextureUtils } from "./extras/TextureUtils.js"; +export * from "./geometries/Geometries.js"; +export * from "./helpers/ArrowHelper.js"; +export * from "./helpers/AxesHelper.js"; +export * from "./helpers/Box3Helper.js"; +export * from "./helpers/BoxHelper.js"; +export * from "./helpers/CameraHelper.js"; +export * from "./helpers/DirectionalLightHelper.js"; +export * from "./helpers/GridHelper.js"; +export * from "./helpers/HemisphereLightHelper.js"; +export * from "./helpers/PlaneHelper.js"; +export * from "./helpers/PointLightHelper.js"; +export * from "./helpers/PolarGridHelper.js"; +export * from "./helpers/SkeletonHelper.js"; +export * from "./helpers/SpotLightHelper.js"; +export * from "./lights/AmbientLight.js"; +export * from "./lights/DirectionalLight.js"; +export type { DirectionalLightShadow } from "./lights/DirectionalLightShadow.js"; +export * from "./lights/HemisphereLight.js"; +export * from "./lights/Light.js"; +export * from "./lights/LightProbe.js"; +export type { LightShadow, LightShadowJSON } from "./lights/LightShadow.js"; +export * from "./lights/PointLight.js"; +export type { PointLightShadow } from "./lights/PointLightShadow.js"; +export * from "./lights/RectAreaLight.js"; +export * from "./lights/SpotLight.js"; +export type { SpotLightShadow } from "./lights/SpotLightShadow.js"; +export * from "./loaders/AnimationLoader.js"; +export * from "./loaders/AudioLoader.js"; +export * from "./loaders/BufferGeometryLoader.js"; +export * from "./loaders/Cache.js"; +export * from "./loaders/CompressedTextureLoader.js"; +export * from "./loaders/CubeTextureLoader.js"; +export * from "./loaders/DataTextureLoader.js"; +export * from "./loaders/FileLoader.js"; +export * from "./loaders/ImageBitmapLoader.js"; +export * from "./loaders/ImageLoader.js"; +export * from "./loaders/Loader.js"; +export * from "./loaders/LoaderUtils.js"; +export * from "./loaders/LoadingManager.js"; +export * from "./loaders/MaterialLoader.js"; +export * from "./loaders/ObjectLoader.js"; +export * from "./loaders/TextureLoader.js"; +export * from "./materials/Materials.js"; +export * from "./math/Box2.js"; +export * from "./math/Box3.js"; +export * from "./math/Color.js"; +export { ColorManagement, ColorSpaceDefinition } from "./math/ColorManagement.js"; +export * from "./math/Cylindrical.js"; +export * from "./math/Euler.js"; +export * from "./math/Frustum.js"; +export * from "./math/Interpolant.js"; +export * from "./math/interpolants/CubicInterpolant.js"; +export * from "./math/interpolants/DiscreteInterpolant.js"; +export * from "./math/interpolants/LinearInterpolant.js"; +export * from "./math/interpolants/QuaternionLinearInterpolant.js"; +export * from "./math/Line3.js"; +export { MathUtils } from "./math/MathUtils.js"; +export * from "./math/Matrix2.js"; +export * from "./math/Matrix3.js"; +export * from "./math/Matrix4.js"; +export * from "./math/Plane.js"; +export * from "./math/Quaternion.js"; +export * from "./math/Ray.js"; +export * from "./math/Sphere.js"; +export * from "./math/Spherical.js"; +export * from "./math/SphericalHarmonics3.js"; +export * from "./math/Triangle.js"; +export * from "./math/Vector2.js"; +export * from "./math/Vector3.js"; +export * from "./math/Vector4.js"; +export * from "./objects/BatchedMesh.js"; +export * from "./objects/Bone.js"; +export * from "./objects/Group.js"; +export * from "./objects/InstancedMesh.js"; +export * from "./objects/Line.js"; +export * from "./objects/LineLoop.js"; +export * from "./objects/LineSegments.js"; +export * from "./objects/LOD.js"; +export * from "./objects/Mesh.js"; +export * from "./objects/Points.js"; +export * from "./objects/Skeleton.js"; +export * from "./objects/SkinnedMesh.js"; +export * from "./objects/Sprite.js"; +// export * from "./renderers/shaders/ShaderChunk.js"; +// export * from "./renderers/shaders/ShaderLib.js"; +// export * from "./renderers/shaders/UniformsLib.js"; +// export { UniformsUtils } from './renderers/shaders/UniformsUtils.js'; +export type { WebGLProgramParameters, WebGLProgramParametersWithUniforms } from "./renderers/webgl/WebGLPrograms.js"; +export type { WebGLShadowMap } from "./renderers/webgl/WebGLShadowMap.js"; +// export * from "./renderers/webgl/WebGLUtils.js"; +export * from "./renderers/WebGL3DRenderTarget.js"; +export * from "./renderers/WebGLArrayRenderTarget.js"; +export * from "./renderers/WebGLCubeRenderTarget.js"; +// export * from "./renderers/WebGLRenderer.js"; +export * from "./renderers/WebGLRenderTarget.js"; +export type { + WebXRController, + WebXRSpaceEventMap, + XRControllerEventType, + XRGripSpace, + XRHandInputState, + XRHandJoints, + XRHandSpace, + XRJointSpace, + XRTargetRaySpace, +} from "./renderers/webxr/WebXRController.js"; +export type { WebXRDepthSensing } from "./renderers/webxr/WebXRDepthSensing.js"; +export type { + WebXRArrayCamera, + WebXRCamera, + WebXRManager, + WebXRManagerEventMap, +} from "./renderers/webxr/WebXRManager.js"; +export * from "./scenes/Fog.js"; +export * from "./scenes/FogExp2.js"; +export * from "./scenes/Scene.js"; +export * from "./textures/CanvasTexture.js"; +export * from "./textures/CompressedArrayTexture.js"; +export * from "./textures/CompressedCubeTexture.js"; +export * from "./textures/CompressedTexture.js"; +export * from "./textures/CubeTexture.js"; +export * from "./textures/Data3DTexture.js"; +export * from "./textures/DataArrayTexture.js"; +export * from "./textures/DataTexture.js"; +export * from "./textures/DepthTexture.js"; +export * from "./textures/FramebufferTexture.js"; +export * from "./textures/Source.js"; +export * from "./textures/Texture.js"; +export * from "./textures/VideoTexture.js"; +export * from "./Three.Legacy.js"; +export { createCanvasElement } from "./utils.js"; + +export { default as IESSpotLight } from "./lights/webgpu/IESSpotLight.js"; +export { default as NodeLoader } from "./loaders/nodes/NodeLoader.js"; +export { default as NodeMaterialLoader } from "./loaders/nodes/NodeMaterialLoader.js"; +export { default as NodeObjectLoader } from "./loaders/nodes/NodeObjectLoader.js"; +export * from "./materials/nodes/NodeMaterials.js"; +export * from "./nodes/Nodes.js"; +export * from "./nodes/TSL.js"; +export { default as BundleGroup } from "./renderers/common/BundleGroup.js"; +export { default as PMREMGenerator } from "./renderers/common/extras/PMREMGenerator.js"; +export { default as PostProcessing } from "./renderers/common/PostProcessing.js"; +import * as PostProcessingUtils from "./renderers/common/PostProcessingUtils.js"; +export { PostProcessingUtils }; +export { default as IndirectStorageBufferAttribute } from "./renderers/common/IndirectStorageBufferAttribute.js"; +export { default as Lighting } from "./renderers/common/Lighting.js"; +export { default as QuadMesh } from "./renderers/common/QuadMesh.js"; +export type { default as Renderer } from "./renderers/common/Renderer.js"; +export { default as StorageBufferAttribute } from "./renderers/common/StorageBufferAttribute.js"; +export { default as StorageInstancedBufferAttribute } from "./renderers/common/StorageInstancedBufferAttribute.js"; +export { default as StorageTexture } from "./renderers/common/StorageTexture.js"; +export { default as WebGPURenderer } from "./renderers/webgpu/WebGPURenderer.js"; diff --git a/src-testing/src/Three.d.ts b/src-testing/src/Three.d.ts new file mode 100644 index 000000000..ade1c92b9 --- /dev/null +++ b/src-testing/src/Three.d.ts @@ -0,0 +1,214 @@ +export * from "./animation/AnimationAction.js"; +export * from "./animation/AnimationClip.js"; +export * from "./animation/AnimationMixer.js"; +export * from "./animation/AnimationObjectGroup.js"; +export { AnimationUtils } from "./animation/AnimationUtils.js"; +export * from "./animation/KeyframeTrack.js"; +export * from "./animation/PropertyBinding.js"; +export * from "./animation/PropertyMixer.js"; +export * from "./animation/tracks/BooleanKeyframeTrack.js"; +export * from "./animation/tracks/ColorKeyframeTrack.js"; +export * from "./animation/tracks/NumberKeyframeTrack.js"; +export * from "./animation/tracks/QuaternionKeyframeTrack.js"; +export * from "./animation/tracks/StringKeyframeTrack.js"; +export * from "./animation/tracks/VectorKeyframeTrack.js"; +export * from "./audio/Audio.js"; +export * from "./audio/AudioAnalyser.js"; +export * from "./audio/AudioContext.js"; +export * from "./audio/AudioListener.js"; +export * from "./audio/PositionalAudio.js"; +export * from "./cameras/ArrayCamera.js"; +export * from "./cameras/Camera.js"; +export * from "./cameras/CubeCamera.js"; +export * from "./cameras/OrthographicCamera.js"; +export * from "./cameras/PerspectiveCamera.js"; +export * from "./cameras/StereoCamera.js"; +export * from "./constants.js"; +export * from "./core/BufferAttribute.js"; +export * from "./core/BufferGeometry.js"; +export * from "./core/Clock.js"; +export * from "./core/EventDispatcher.js"; +export * from "./core/GLBufferAttribute.js"; +export * from "./core/InstancedBufferAttribute.js"; +export * from "./core/InstancedBufferGeometry.js"; +export * from "./core/InstancedInterleavedBuffer.js"; +export * from "./core/InterleavedBuffer.js"; +export * from "./core/InterleavedBufferAttribute.js"; +export * from "./core/Layers.js"; +export * from "./core/Object3D.js"; +export * from "./core/Raycaster.js"; +export * from "./core/RenderTarget.js"; +export * from "./core/Uniform.js"; +export * from "./core/UniformsGroup.js"; +export * from "./extras/Controls.js"; +export * from "./extras/core/Curve.js"; +export * from "./extras/core/CurvePath.js"; +export * from "./extras/core/Path.js"; +export * from "./extras/core/Shape.js"; +export * from "./extras/core/ShapePath.js"; +export * from "./extras/curves/Curves.js"; +export { DataUtils } from "./extras/DataUtils.js"; +export * from "./extras/ImageUtils.js"; +export * from "./extras/PMREMGenerator.js"; +export * from "./extras/ShapeUtils.js"; +export { TextureUtils } from "./extras/TextureUtils.js"; +export * from "./geometries/Geometries.js"; +export * from "./helpers/ArrowHelper.js"; +export * from "./helpers/AxesHelper.js"; +export * from "./helpers/Box3Helper.js"; +export * from "./helpers/BoxHelper.js"; +export * from "./helpers/CameraHelper.js"; +export * from "./helpers/DirectionalLightHelper.js"; +export * from "./helpers/GridHelper.js"; +export * from "./helpers/HemisphereLightHelper.js"; +export * from "./helpers/PlaneHelper.js"; +export * from "./helpers/PointLightHelper.js"; +export * from "./helpers/PolarGridHelper.js"; +export * from "./helpers/SkeletonHelper.js"; +export * from "./helpers/SpotLightHelper.js"; +export * from "./lights/AmbientLight.js"; +export * from "./lights/DirectionalLight.js"; +export type { DirectionalLightShadow } from "./lights/DirectionalLightShadow.js"; +export * from "./lights/HemisphereLight.js"; +export * from "./lights/Light.js"; +export * from "./lights/LightProbe.js"; +export type { LightShadow, LightShadowJSON } from "./lights/LightShadow.js"; +export * from "./lights/PointLight.js"; +export type { PointLightShadow } from "./lights/PointLightShadow.js"; +export * from "./lights/RectAreaLight.js"; +export * from "./lights/SpotLight.js"; +export type { SpotLightShadow } from "./lights/SpotLightShadow.js"; +export * from "./loaders/AnimationLoader.js"; +export * from "./loaders/AudioLoader.js"; +export * from "./loaders/BufferGeometryLoader.js"; +export * from "./loaders/Cache.js"; +export * from "./loaders/CompressedTextureLoader.js"; +export * from "./loaders/CubeTextureLoader.js"; +export * from "./loaders/DataTextureLoader.js"; +export * from "./loaders/FileLoader.js"; +export * from "./loaders/ImageBitmapLoader.js"; +export * from "./loaders/ImageLoader.js"; +export * from "./loaders/Loader.js"; +export * from "./loaders/LoaderUtils.js"; +export * from "./loaders/LoadingManager.js"; +export * from "./loaders/MaterialLoader.js"; +export * from "./loaders/ObjectLoader.js"; +export * from "./loaders/TextureLoader.js"; +export * from "./materials/Materials.js"; +export * from "./math/Box2.js"; +export * from "./math/Box3.js"; +export * from "./math/Color.js"; +export { ColorManagement, ColorSpaceDefinition } from "./math/ColorManagement.js"; +export * from "./math/Cylindrical.js"; +export * from "./math/Euler.js"; +export * from "./math/Frustum.js"; +export * from "./math/Interpolant.js"; +export * from "./math/interpolants/CubicInterpolant.js"; +export * from "./math/interpolants/DiscreteInterpolant.js"; +export * from "./math/interpolants/LinearInterpolant.js"; +export * from "./math/interpolants/QuaternionLinearInterpolant.js"; +export * from "./math/Line3.js"; +export { MathUtils } from "./math/MathUtils.js"; +export * from "./math/Matrix2.js"; +export * from "./math/Matrix3.js"; +export * from "./math/Matrix4.js"; +export * from "./math/Plane.js"; +export * from "./math/Quaternion.js"; +export * from "./math/Ray.js"; +export * from "./math/Sphere.js"; +export * from "./math/Spherical.js"; +export * from "./math/SphericalHarmonics3.js"; +export * from "./math/Triangle.js"; +export * from "./math/Vector2.js"; +export * from "./math/Vector3.js"; +export * from "./math/Vector4.js"; +export * from "./objects/BatchedMesh.js"; +export * from "./objects/Bone.js"; +export * from "./objects/Group.js"; +export * from "./objects/InstancedMesh.js"; +export * from "./objects/Line.js"; +export * from "./objects/LineLoop.js"; +export * from "./objects/LineSegments.js"; +export * from "./objects/LOD.js"; +export * from "./objects/Mesh.js"; +export * from "./objects/Points.js"; +export * from "./objects/Skeleton.js"; +export * from "./objects/SkinnedMesh.js"; +export * from "./objects/Sprite.js"; +export * from "./renderers/shaders/ShaderChunk.js"; +export * from "./renderers/shaders/ShaderLib.js"; +export * from "./renderers/shaders/UniformsLib.js"; +export { UniformsUtils } from "./renderers/shaders/UniformsUtils.js"; +export type { WebGLAttributes } from "./renderers/webgl/WebGLAttributes.js"; +export type { WebGLBindingStates } from "./renderers/webgl/WebGLBindingStates.js"; +export type { WebGLBufferRenderer } from "./renderers/webgl/WebGLBufferRenderer.js"; +export type { WebGLCapabilities, WebGLCapabilitiesParameters } from "./renderers/webgl/WebGLCapabilities.js"; +export type { WebGLClipping } from "./renderers/webgl/WebGLClipping.js"; +export type { WebGLCubeMaps } from "./renderers/webgl/WebGLCubeMaps.js"; +export type { WebGLCubeUVMaps } from "./renderers/webgl/WebGLCubeUVMaps.js"; +export type { WebGLExtensions } from "./renderers/webgl/WebGLExtensions.js"; +export type { WebGLGeometries } from "./renderers/webgl/WebGLGeometries.js"; +export type { WebGLIndexedBufferRenderer } from "./renderers/webgl/WebGLIndexedBufferRenderer.js"; +export type { WebGLInfo } from "./renderers/webgl/WebGLInfo.js"; +export type { WebGLLights, WebGLLightsState } from "./renderers/webgl/WebGLLights.js"; +export type { WebGLObjects } from "./renderers/webgl/WebGLObjects.js"; +export type { WebGLProgram } from "./renderers/webgl/WebGLProgram.js"; +export type { + WebGLProgramParameters, + WebGLProgramParametersWithUniforms, + WebGLPrograms, +} from "./renderers/webgl/WebGLPrograms.js"; +export type { WebGLProperties } from "./renderers/webgl/WebGLProperties.js"; +export type { RenderItem, WebGLRenderList, WebGLRenderLists } from "./renderers/webgl/WebGLRenderLists.js"; +export type { WebGLShader } from "./renderers/webgl/WebGLShader.js"; +export type { WebGLShadowMap } from "./renderers/webgl/WebGLShadowMap.js"; +export type { + WebGLColorBuffer, + WebGLDepthBuffer, + WebGLState, + WebGLStencilBuffer, +} from "./renderers/webgl/WebGLState.js"; +export type { WebGLTextures } from "./renderers/webgl/WebGLTextures.js"; +export type { WebGLUniforms } from "./renderers/webgl/WebGLUniforms.js"; +export * from "./renderers/webgl/WebGLUtils.js"; +export * from "./renderers/WebGL3DRenderTarget.js"; +export * from "./renderers/WebGLArrayRenderTarget.js"; +export * from "./renderers/WebGLCubeRenderTarget.js"; +export * from "./renderers/WebGLRenderer.js"; +export * from "./renderers/WebGLRenderTarget.js"; +export type { + WebXRController, + WebXRSpaceEventMap, + XRControllerEventType, + XRGripSpace, + XRHandInputState, + XRHandJoints, + XRHandSpace, + XRJointSpace, + XRTargetRaySpace, +} from "./renderers/webxr/WebXRController.js"; +export type { WebXRDepthSensing } from "./renderers/webxr/WebXRDepthSensing.js"; +export type { + WebXRArrayCamera, + WebXRCamera, + WebXRManager, + WebXRManagerEventMap, +} from "./renderers/webxr/WebXRManager.js"; +export * from "./scenes/Fog.js"; +export * from "./scenes/FogExp2.js"; +export * from "./scenes/Scene.js"; +export * from "./textures/CanvasTexture.js"; +export * from "./textures/CompressedArrayTexture.js"; +export * from "./textures/CompressedCubeTexture.js"; +export * from "./textures/CompressedTexture.js"; +export * from "./textures/CubeTexture.js"; +export * from "./textures/Data3DTexture.js"; +export * from "./textures/DataArrayTexture.js"; +export * from "./textures/DataTexture.js"; +export * from "./textures/DepthTexture.js"; +export * from "./textures/FramebufferTexture.js"; +export * from "./textures/Source.js"; +export * from "./textures/Texture.js"; +export * from "./textures/VideoTexture.js"; +export * from "./Three.Legacy.js"; +export { createCanvasElement } from "./utils.js"; diff --git a/src-testing/src/animation/AnimationAction.d.ts b/src-testing/src/animation/AnimationAction.d.ts new file mode 100644 index 000000000..3fa3852a2 --- /dev/null +++ b/src-testing/src/animation/AnimationAction.d.ts @@ -0,0 +1,86 @@ +import { AnimationActionLoopStyles, AnimationBlendMode } from "../constants.js"; +import { Object3D } from "../core/Object3D.js"; +import { AnimationClip } from "./AnimationClip.js"; +import { AnimationMixer } from "./AnimationMixer.js"; +// Animation //////////////////////////////////////////////////////////////////////////////////////// + +export class AnimationAction { + constructor(mixer: AnimationMixer, clip: AnimationClip, localRoot?: Object3D, blendMode?: AnimationBlendMode); + + blendMode: AnimationBlendMode; + + /** + * @default THREE.LoopRepeat + */ + loop: AnimationActionLoopStyles; + + /** + * @default 0 + */ + time: number; + + /** + * @default 1 + */ + timeScale: number; + + /** + * @default 1 + */ + weight: number; + + /** + * @default Infinity + */ + repetitions: number; + + /** + * @default false + */ + paused: boolean; + + /** + * @default true + */ + enabled: boolean; + + /** + * @default false + */ + clampWhenFinished: boolean; + + /** + * @default true + */ + zeroSlopeAtStart: boolean; + + /** + * @default true + */ + zeroSlopeAtEnd: boolean; + + play(): AnimationAction; + stop(): AnimationAction; + reset(): AnimationAction; + isRunning(): boolean; + isScheduled(): boolean; + startAt(time: number): AnimationAction; + setLoop(mode: AnimationActionLoopStyles, repetitions: number): AnimationAction; + setEffectiveWeight(weight: number): AnimationAction; + getEffectiveWeight(): number; + fadeIn(duration: number): AnimationAction; + fadeOut(duration: number): AnimationAction; + crossFadeFrom(fadeOutAction: AnimationAction, duration: number, warp: boolean): AnimationAction; + crossFadeTo(fadeInAction: AnimationAction, duration: number, warp: boolean): AnimationAction; + stopFading(): AnimationAction; + setEffectiveTimeScale(timeScale: number): AnimationAction; + getEffectiveTimeScale(): number; + setDuration(duration: number): AnimationAction; + syncWith(action: AnimationAction): AnimationAction; + halt(duration: number): AnimationAction; + warp(statTimeScale: number, endTimeScale: number, duration: number): AnimationAction; + stopWarping(): AnimationAction; + getMixer(): AnimationMixer; + getClip(): AnimationClip; + getRoot(): Object3D; +} diff --git a/src-testing/src/animation/AnimationClip.d.ts b/src-testing/src/animation/AnimationClip.d.ts new file mode 100644 index 000000000..4efc3df72 --- /dev/null +++ b/src-testing/src/animation/AnimationClip.d.ts @@ -0,0 +1,59 @@ +import { AnimationBlendMode } from "../constants.js"; +import { Vector3 } from "../math/Vector3.js"; +import { Bone } from "../objects/Bone.js"; +import { KeyframeTrack, KeyframeTrackJSON } from "./KeyframeTrack.js"; + +export interface AnimationClipJSON { + name: string; + duration: number; + tracks: KeyframeTrackJSON[]; + uuid: string; + blendMode: AnimationBlendMode; +} + +export interface MorphTarget { + name: string; + vertices: Vector3[]; +} + +export class AnimationClip { + constructor(name?: string, duration?: number, tracks?: KeyframeTrack[], blendMode?: AnimationBlendMode); + + name: string; + tracks: KeyframeTrack[]; + + /** + * @default THREE.NormalAnimationBlendMode + */ + blendMode: AnimationBlendMode; + + /** + * @default -1 + */ + duration: number; + uuid: string; + results: any[]; + + resetDuration(): AnimationClip; + trim(): AnimationClip; + validate(): boolean; + optimize(): AnimationClip; + clone(): this; + toJSON(clip: AnimationClip): any; + + static CreateFromMorphTargetSequence( + name: string, + morphTargetSequence: MorphTarget[], + fps: number, + noLoop: boolean, + ): AnimationClip; + static findByName(clipArray: AnimationClip[], name: string): AnimationClip; + static CreateClipsFromMorphTargetSequences( + morphTargets: MorphTarget[], + fps: number, + noLoop: boolean, + ): AnimationClip[]; + static parse(json: AnimationClipJSON): AnimationClip; + static parseAnimation(animation: AnimationClipJSON, bones: Bone[]): AnimationClip; + static toJSON(clip: AnimationClip): AnimationClipJSON; +} diff --git a/src-testing/src/animation/AnimationMixer.d.ts b/src-testing/src/animation/AnimationMixer.d.ts new file mode 100644 index 000000000..95712d893 --- /dev/null +++ b/src-testing/src/animation/AnimationMixer.d.ts @@ -0,0 +1,39 @@ +import { AnimationBlendMode } from "../constants.js"; +import { EventDispatcher } from "../core/EventDispatcher.js"; +import { Object3D } from "../core/Object3D.js"; +import { AnimationAction } from "./AnimationAction.js"; +import { AnimationClip } from "./AnimationClip.js"; +import { AnimationObjectGroup } from "./AnimationObjectGroup.js"; + +export interface AnimationMixerEventMap { + loop: { action: AnimationAction; loopDelta: number }; + finished: { action: AnimationAction; direction: number }; +} + +export class AnimationMixer extends EventDispatcher { + constructor(root: Object3D | AnimationObjectGroup); + + /** + * @default 0 + */ + time: number; + + /** + * @default 1.0 + */ + timeScale: number; + + clipAction( + clip: AnimationClip, + root?: Object3D | AnimationObjectGroup, + blendMode?: AnimationBlendMode, + ): AnimationAction; + existingAction(clip: AnimationClip, root?: Object3D | AnimationObjectGroup): AnimationAction | null; + stopAllAction(): AnimationMixer; + update(deltaTime: number): AnimationMixer; + setTime(timeInSeconds: number): AnimationMixer; + getRoot(): Object3D | AnimationObjectGroup; + uncacheClip(clip: AnimationClip): void; + uncacheRoot(root: Object3D | AnimationObjectGroup): void; + uncacheAction(clip: AnimationClip, root?: Object3D | AnimationObjectGroup): void; +} diff --git a/src-testing/src/animation/AnimationObjectGroup.d.ts b/src-testing/src/animation/AnimationObjectGroup.d.ts new file mode 100644 index 000000000..9d4f29ca9 --- /dev/null +++ b/src-testing/src/animation/AnimationObjectGroup.d.ts @@ -0,0 +1,17 @@ +export class AnimationObjectGroup { + constructor(...args: any[]); + + uuid: string; + stats: { + bindingsPerObject: number; + objects: { + total: number; + inUse: number; + }; + }; + readonly isAnimationObjectGroup: true; + + add(...args: any[]): void; + remove(...args: any[]): void; + uncache(...args: any[]): void; +} diff --git a/src-testing/src/animation/AnimationUtils.d.ts b/src-testing/src/animation/AnimationUtils.d.ts new file mode 100644 index 000000000..4a712ed30 --- /dev/null +++ b/src-testing/src/animation/AnimationUtils.d.ts @@ -0,0 +1,60 @@ +import { AnimationClip } from "./AnimationClip.js"; + +declare function convertArray(array: any, type: any, forceClone: boolean): any; + +declare function isTypedArray(object: any): boolean; + +declare function getKeyframeOrder(times: number[]): number[]; + +declare function sortedArray(values: any[], stride: number, order: number[]): any[]; + +declare function flattenJSON(jsonKeys: string[], times: any[], values: any[], valuePropertyName: string): void; + +/** + * @param sourceClip + * @param name + * @param startFrame + * @param endFrame + * @param [fps=30] + */ +declare function subclip( + sourceClip: AnimationClip, + name: string, + startFrame: number, + endFrame: number, + fps?: number, +): AnimationClip; + +/** + * @param targetClip + * @param [referenceFrame=0] + * @param [referenceClip=targetClip] + * @param [fps=30] + */ +declare function makeClipAdditive( + targetClip: AnimationClip, + referenceFrame?: number, + referenceClip?: AnimationClip, + fps?: number, +): AnimationClip; + +declare const AnimationUtils: { + convertArray: typeof convertArray; + isTypedArray: typeof isTypedArray; + getKeyframeOrder: typeof getKeyframeOrder; + sortedArray: typeof sortedArray; + flattenJSON: typeof flattenJSON; + subclip: typeof subclip; + makeClipAdditive: typeof makeClipAdditive; +}; + +export { + AnimationUtils, + convertArray, + flattenJSON, + getKeyframeOrder, + isTypedArray, + makeClipAdditive, + sortedArray, + subclip, +}; diff --git a/src-testing/src/animation/KeyframeTrack.d.ts b/src-testing/src/animation/KeyframeTrack.d.ts new file mode 100644 index 000000000..2a48e2651 --- /dev/null +++ b/src-testing/src/animation/KeyframeTrack.d.ts @@ -0,0 +1,55 @@ +import { InterpolationModes } from "../constants.js"; +import { Interpolant } from "../math/Interpolant.js"; +import { CubicInterpolant } from "../math/interpolants/CubicInterpolant.js"; +import { DiscreteInterpolant } from "../math/interpolants/DiscreteInterpolant.js"; +import { LinearInterpolant } from "../math/interpolants/LinearInterpolant.js"; + +export interface KeyframeTrackJSON { + name: string; + times: number[]; + values: number[]; + interpolation?: InterpolationModes; + type: string; +} + +export class KeyframeTrack { + /** + * @param name + * @param times + * @param values + * @param [interpolation=THREE.InterpolateLinear] + */ + constructor(name: string, times: ArrayLike, values: ArrayLike, interpolation?: InterpolationModes); + + name: string; + times: Float32Array; + values: Float32Array; + + ValueTypeName: string; + TimeBufferType: Float32Array; + ValueBufferType: Float32Array; + + /** + * @default THREE.InterpolateLinear + */ + DefaultInterpolation: InterpolationModes; + + InterpolantFactoryMethodDiscrete(result: any): DiscreteInterpolant; + InterpolantFactoryMethodLinear(result: any): LinearInterpolant; + InterpolantFactoryMethodSmooth(result: any): CubicInterpolant; + + setInterpolation(interpolation: InterpolationModes): KeyframeTrack; + getInterpolation(): InterpolationModes; + createInterpolant(): Interpolant; + + getValueSize(): number; + + shift(timeOffset: number): KeyframeTrack; + scale(timeScale: number): KeyframeTrack; + trim(startTime: number, endTime: number): KeyframeTrack; + validate(): boolean; + optimize(): KeyframeTrack; + clone(): this; + + static toJSON(track: KeyframeTrack): KeyframeTrackJSON; +} diff --git a/src-testing/src/animation/PropertyBinding.d.ts b/src-testing/src/animation/PropertyBinding.d.ts new file mode 100644 index 000000000..fec777634 --- /dev/null +++ b/src-testing/src/animation/PropertyBinding.d.ts @@ -0,0 +1,43 @@ +export interface ParseTrackNameResults { + nodeName: string; + objectName: string; + objectIndex: string; + propertyName: string; + propertyIndex: string; +} + +declare class Composite { + constructor(targetGroup: any, path: any, parsedPath?: any); + + getValue(array: any, offset: number): any; + setValue(array: any, offset: number): void; + bind(): void; + unbind(): void; +} + +declare class PropertyBinding { + constructor(rootNode: any, path: string, parsedPath?: any); + + path: string; + parsedPath: any; + node: any; + rootNode: any; + + getValue(targetArray: any, offset: number): any; + setValue(sourceArray: any, offset: number): void; + bind(): void; + unbind(): void; + + BindingType: { [bindingType: string]: number }; + Versioning: { [versioning: string]: number }; + + GetterByBindingType: Array<() => void>; + SetterByBindingTypeAndVersioning: Array void>>; + + static create(root: any, path: any, parsedPath?: any): PropertyBinding | Composite; + static sanitizeNodeName(name: string): string; + static parseTrackName(trackName: string): ParseTrackNameResults; + static findNode(root: any, nodeName: string): any; +} + +export { PropertyBinding }; diff --git a/src-testing/src/animation/PropertyMixer.d.ts b/src-testing/src/animation/PropertyMixer.d.ts new file mode 100644 index 000000000..f413291fa --- /dev/null +++ b/src-testing/src/animation/PropertyMixer.d.ts @@ -0,0 +1,17 @@ +export class PropertyMixer { + constructor(binding: any, typeName: string, valueSize: number); + + binding: any; + valueSize: number; + buffer: any; + cumulativeWeight: number; + cumulativeWeightAdditive: number; + useCount: number; + referenceCount: number; + + accumulate(accuIndex: number, weight: number): void; + accumulateAdditive(weight: number): void; + apply(accuIndex: number): void; + saveOriginalState(): void; + restoreOriginalState(): void; +} diff --git a/src-testing/src/animation/tracks/BooleanKeyframeTrack.d.ts b/src-testing/src/animation/tracks/BooleanKeyframeTrack.d.ts new file mode 100644 index 000000000..45b65448a --- /dev/null +++ b/src-testing/src/animation/tracks/BooleanKeyframeTrack.d.ts @@ -0,0 +1,10 @@ +import { KeyframeTrack } from "../KeyframeTrack.js"; + +export class BooleanKeyframeTrack extends KeyframeTrack { + constructor(name: string, times: ArrayLike, values: ArrayLike); + + /** + * @default 'bool' + */ + ValueTypeName: string; +} diff --git a/src-testing/src/animation/tracks/ColorKeyframeTrack.d.ts b/src-testing/src/animation/tracks/ColorKeyframeTrack.d.ts new file mode 100644 index 000000000..60d0fe9f7 --- /dev/null +++ b/src-testing/src/animation/tracks/ColorKeyframeTrack.d.ts @@ -0,0 +1,11 @@ +import { InterpolationModes } from "../../constants.js"; +import { KeyframeTrack } from "../KeyframeTrack.js"; + +export class ColorKeyframeTrack extends KeyframeTrack { + constructor(name: string, times: ArrayLike, values: ArrayLike, interpolation?: InterpolationModes); + + /** + * @default 'color' + */ + ValueTypeName: string; +} diff --git a/src-testing/src/animation/tracks/NumberKeyframeTrack.d.ts b/src-testing/src/animation/tracks/NumberKeyframeTrack.d.ts new file mode 100644 index 000000000..e27ff0337 --- /dev/null +++ b/src-testing/src/animation/tracks/NumberKeyframeTrack.d.ts @@ -0,0 +1,11 @@ +import { InterpolationModes } from "../../constants.js"; +import { KeyframeTrack } from "../KeyframeTrack.js"; + +export class NumberKeyframeTrack extends KeyframeTrack { + constructor(name: string, times: ArrayLike, values: ArrayLike, interpolation?: InterpolationModes); + + /** + * @default 'number' + */ + ValueTypeName: string; +} diff --git a/src-testing/src/animation/tracks/QuaternionKeyframeTrack.d.ts b/src-testing/src/animation/tracks/QuaternionKeyframeTrack.d.ts new file mode 100644 index 000000000..29942bad5 --- /dev/null +++ b/src-testing/src/animation/tracks/QuaternionKeyframeTrack.d.ts @@ -0,0 +1,11 @@ +import { InterpolationModes } from "../../constants.js"; +import { KeyframeTrack } from "../KeyframeTrack.js"; + +export class QuaternionKeyframeTrack extends KeyframeTrack { + constructor(name: string, times: ArrayLike, values: ArrayLike, interpolation?: InterpolationModes); + + /** + * @default 'quaternion' + */ + ValueTypeName: string; +} diff --git a/src-testing/src/animation/tracks/StringKeyframeTrack.d.ts b/src-testing/src/animation/tracks/StringKeyframeTrack.d.ts new file mode 100644 index 000000000..9bbfd2027 --- /dev/null +++ b/src-testing/src/animation/tracks/StringKeyframeTrack.d.ts @@ -0,0 +1,10 @@ +import { KeyframeTrack } from "../KeyframeTrack.js"; + +export class StringKeyframeTrack extends KeyframeTrack { + constructor(name: string, times: ArrayLike, values: ArrayLike); + + /** + * @default 'string' + */ + ValueTypeName: string; +} diff --git a/src-testing/src/animation/tracks/VectorKeyframeTrack.d.ts b/src-testing/src/animation/tracks/VectorKeyframeTrack.d.ts new file mode 100644 index 000000000..0909d4493 --- /dev/null +++ b/src-testing/src/animation/tracks/VectorKeyframeTrack.d.ts @@ -0,0 +1,11 @@ +import { InterpolationModes } from "../../constants.js"; +import { KeyframeTrack } from "../KeyframeTrack.js"; + +export class VectorKeyframeTrack extends KeyframeTrack { + constructor(name: string, times: ArrayLike, values: ArrayLike, interpolation?: InterpolationModes); + + /** + * @default 'vector' + */ + ValueTypeName: string; +} diff --git a/src-testing/src/audio/Audio.d.ts b/src-testing/src/audio/Audio.d.ts new file mode 100644 index 000000000..63a944b5e --- /dev/null +++ b/src-testing/src/audio/Audio.d.ts @@ -0,0 +1,273 @@ +import { Object3D } from "../core/Object3D.js"; +import { AudioContext } from "./AudioContext.js"; +import { AudioListener } from "./AudioListener.js"; + +// Extras / Audio ///////////////////////////////////////////////////////////////////// + +/** + * Create a non-positional ( global ) {@link Audio} object. + * This uses the {@link https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API | Web {@link Audio} API}. + * @example + * ```typescript + * // create an AudioListener and add it to the camera + * const listener = new THREE.AudioListener(); + * camera.add(listener); + * // create a global {@link Audio} source + * const sound = new THREE.Audio(listener); + * // load a sound and set it as the {@link Audio} object's buffer + * const audioLoader = new THREE.AudioLoader(); + * audioLoader.load('sounds/ambient.ogg', function (buffer) { + * sound.setBuffer(buffer); + * sound.setLoop(true); + * sound.setVolume(0.5); + * sound.play(); + * }); + * ``` + * @see Example: {@link https://threejs.org/examples/#webaudio_sandbox | webaudio / sandbox } + * @see Example: {@link https://threejs.org/examples/#webaudio_visualizer | webaudio / visualizer } + * @see {@link https://threejs.org/docs/index.html#api/en/audio/Audio | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/audio/Audio.js | Source} + */ +export class Audio extends Object3D { + /** + * Create a new instance of {@link Audio} + * @param listener (required) {@link AudioListener | AudioListener} instance. + */ + constructor(listener: AudioListener); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `Audio` + */ + readonly type: string | "Audio"; + + /** + * A reference to the listener object of this audio. + */ + listener: AudioListener; + + /** + * The {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioContext | AudioContext} of the {@link AudioListener | listener} given in the constructor. + */ + context: AudioContext; + + /** + * A {@link https://developer.mozilla.org/en-US/docs/Web/API/GainNode | GainNode} created using + * {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioContext/createGain | AudioContext.createGain}(). + */ + gain: GainNode; + + /** + * Whether to start playback automatically. + * @defaultValue `false` + */ + autoplay: boolean; + + buffer: AudioBuffer | null; + + /** + * Modify pitch, measured in cents. +/- 100 is a semitone. +/- 1200 is an octave. + * @defaultValue `0` + */ + detune: number; + + /** + * @default false + */ + loop: boolean; + + /** + * @default 0 + */ + loopStart: number; + + /** + * @default 0 + */ + loopEnd: number; + + /** + * An offset to the time within the {@link Audio} buffer that playback should begin. + * Same as the {@link Audio.offset | offset} parameter of {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/start | AudioBufferSourceNode.start()}. + * @defaultValue `0` + */ + offset: number; + + /** + * Overrides the duration of the audio. Same as the {@link Audio.duration | duration} parameter of + * {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/start | AudioBufferSourceNode.start()}. + * @defaultValue `undefined` _to play the whole buffer_. + */ + duration: number | undefined; + + /** + * Speed of playback. + * @defaultValue `1` + */ + playbackRate: number; + + /** + * Whether the {@link Audio} is currently playing. + * @defaultValue `false` + */ + isPlaying: boolean; + + /** + * Whether playback can be controlled using the {@link Audio.play | play}(), {@link Audio.pause | pause}() etc. methods. + * @defaultValue `true` + */ + hasPlaybackControl: boolean; + + /** + * Type of the {@link Audio} source. + * @defaultValue 'empty'. + */ + sourceType: string; + + /** + * An {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode | AudioBufferSourceNode} created using + * {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioContext/createBufferSource | AudioContext.createBufferSource()}. + */ + source: AudioScheduledSourceNode | null; + + /** + * Represents an array of {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioNode | AudioNodes}. + * Can be used to apply a variety of low-order filters to create more complex sound effects. + * In most cases, the array contains instances of {@link https://developer.mozilla.org/en-US/docs/Web/API/BiquadFilterNode | BiquadFilterNodes}. + * Filters are set via {@link THREE.Audio.setFilter | Audio.setFilter} or {@link THREE.Audio.setFilters | Audio.setFilters}. + * @defaultValue `[]` + */ + filters: AudioNode[]; + + /** + * Return the {@link Audio.gain | gainNode}. + */ + getOutput(): NodeType; + + /** + * Setup the {@link Audio.source | source} to the audioBuffer, and sets {@link Audio.sourceType | sourceType} to 'audioNode'. + * @remarks Also sets {@link Audio.hasPlaybackControl | hasPlaybackControl} to false. + */ + setNodeSource(audioNode: AudioScheduledSourceNode): this; + + /** + * Applies the given object of type {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement | HTMLMediaElement} as the source of this audio. + * @remarks Also sets {@link Audio.hasPlaybackControl | hasPlaybackControl} to false. + */ + setMediaElementSource(mediaElement: HTMLMediaElement): this; + + /** + * Applies the given object of type {@link https://developer.mozilla.org/en-US/docs/Web/API/MediaStream | MediaStream} as the source of this audio. + * @remarks Also sets {@link Audio.hasPlaybackControl | hasPlaybackControl} to false. + */ + setMediaStreamSource(mediaStream: MediaStream): this; + + /** + * Setup the {@link Audio.source | source} to the audioBuffer, and sets {@link Audio.sourceType | sourceType} to 'buffer'. + * @remarks If {@link Audio.autoplay | autoplay}, also starts playback. + */ + setBuffer(audioBuffer: AudioBuffer): this; + + /** + * If {@link Audio.hasPlaybackControl | hasPlaybackControl} is true, starts playback. + */ + play(delay?: number): this; + + /** + * If {@link Audio.hasPlaybackControl | hasPlaybackControl} is true, pauses playback. + */ + pause(): this; + + /** + * If {@link Audio.hasPlaybackControl | hasPlaybackControl} is enabled, stops playback. + * @param delay (optional) - The delay, in seconds, at which the audio should start playing. + */ + stop(delay?: number): this; + + /** + * Called automatically when playback finished. + */ + onEnded(): void; + + /** + * Connect to the {@link THREE.Audio.source | Audio.source} + * @remarks This is used internally on initialisation and when setting / removing filters. + */ + connect(): this; + /** + * Disconnect from the {@link THREE.Audio.source | Audio.source} + * @remarks This is used internally when setting / removing filters. + */ + disconnect(): this; + + /** + * Returns the detuning of oscillation in cents. + */ + getDetune(): number; + /** + * Defines the detuning of oscillation in cents. + * @param value Expects a `Float` + */ + setDetune(value: number): this; + + /** + * Returns the first element of the {@link Audio.filters | filters} array. + */ + getFilter(): AudioNode; + /** + * Applies a single filter node to the audio. + */ + setFilter(filter: AudioNode): this; + + /** + * Returns the {@link Audio.filters | filters} array. + */ + getFilters(): AudioNode[]; + /** + * Applies an array of filter nodes to the audio. + * @param value Arrays of filters. + */ + setFilters(value: AudioNode[]): this; + + /** + * Return the value of {@link Audio.playbackRate | playbackRate}. + */ + getPlaybackRate(): number; + /** + * If {@link Audio.hasPlaybackControl | hasPlaybackControl} is enabled, set the {@link Audio.playbackRate | playbackRate} to `value`. + * @param value Expects a `Float` + */ + setPlaybackRate(value: number): this; + + /** + * Return the value of {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/loop | source.loop} (whether playback should loop). + */ + getLoop(): boolean; + /** + * Set {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/loop | source.loop} to `value` (whether playback should loop). + * @param value + */ + setLoop(value: boolean): this; + + /** + * Set {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/loopStart | source.loopStart} to `value`. + * @param value Expects a `Float` + */ + setLoopStart(value: number): this; + /** + * Set {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/loopEnd | source.loopEnd} to `value`. + * @param value Expects a `Float` + */ + setLoopEnd(value: number): this; + + /** + * Return the current volume. + */ + getVolume(): number; + /** + * Set the volume. + * @param value Expects a `Float` + */ + setVolume(value: number): this; +} diff --git a/src-testing/src/audio/AudioAnalyser.d.ts b/src-testing/src/audio/AudioAnalyser.d.ts new file mode 100644 index 000000000..474583ec7 --- /dev/null +++ b/src-testing/src/audio/AudioAnalyser.d.ts @@ -0,0 +1,58 @@ +import { Audio } from "./Audio.js"; + +/** + * Create a {@link AudioAnalyser} object, which uses an {@link https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode | AnalyserNode} to analyse audio data. + * This uses the {@link https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API | Web Audio API}. + * @example + * ```typescript + * // create an AudioListener and add it to the camera + * const listener = new THREE.AudioListener(); + * camera.add(listener); + * // create an Audio source + * const sound = new THREE.Audio(listener); + * // load a sound and set it as the Audio object's buffer + * const audioLoader = new THREE.AudioLoader(); + * audioLoader.load('sounds/ambient.ogg', function (buffer) { + * sound.setBuffer(buffer); + * sound.setLoop(true); + * sound.setVolume(0.5); + * sound.play(); + * }); + * // create an AudioAnalyser, passing in the sound and desired fftSize + * const analyser = new THREE.AudioAnalyser(sound, 32); + * // get the average frequency of the sound + * const data = analyser.getAverageFrequency(); + * ``` + * @see Example: {@link https://threejs.org/examples/#webaudio_sandbox | webaudio / sandbox } + * @see Example: {@link https://threejs.org/examples/#webaudio_visualizer | webaudio / visualizer } + * @see {@link https://threejs.org/docs/index.html#api/en/audio/AudioAnalyser | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/audio/AudioAnalyser.js | Source} + */ +export class AudioAnalyser { + /** + * Create a new {@link {@link AudioAnalyser} | AudioAnalyser}. + * @param audio + * @param fftSize See {@link https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode/fftSize | AnalyserNode.fftSize }. Expects a `unsigned integer`. Default `2048`. + */ + constructor(audio: Audio, fftSize?: number); + + /** + * An {@link https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode | AnalyserNode} used to analyze audio. + */ + analyser: AnalyserNode; + + /** + * A Uint8Array with size determined by {@link https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode/frequencyBinCount | analyser.frequencyBinCount} used to hold analysis data. + */ + data: Uint8Array; + + /** + * Uses the Web Audio's {@link https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode/getByteFrequencyData | getByteFrequencyData} method + */ + getFrequencyData(): Uint8Array; + + /** + * Get the average of the frequencies returned by the {@link AudioAnalyser.getFrequencyData | getFrequencyData} method. + */ + getAverageFrequency(): number; +} diff --git a/src-testing/src/audio/AudioContext.d.ts b/src-testing/src/audio/AudioContext.d.ts new file mode 100644 index 000000000..50a7f3d6e --- /dev/null +++ b/src-testing/src/audio/AudioContext.d.ts @@ -0,0 +1,19 @@ +/** + * This contains methods for setting up an {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioContext | AudioContext}. + * Used internally by the {@link AudioListener | AudioListener} and {@link AudioLoader | AudioLoader} classes. + * This uses the {@link https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API | Web Audio API}. + * @see {@link https://threejs.org/docs/index.html#api/en/audio/AudioContext | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/audio/AudioContext.js | Source} + */ +export namespace AudioContext { + /** + * Return the value of the variable `context` in the outer scope, if defined, otherwise set it to a new {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioContext | AudioContext}. + */ + function getContext(): AudioContext; + + /** + * Set the variable `context` in the outer scope to `value`. + * @param value + */ + function setContext(context: AudioContext): void; +} diff --git a/src-testing/src/audio/AudioListener.d.ts b/src-testing/src/audio/AudioListener.d.ts new file mode 100644 index 000000000..a49e4d5c7 --- /dev/null +++ b/src-testing/src/audio/AudioListener.d.ts @@ -0,0 +1,96 @@ +import { Object3D } from "../core/Object3D.js"; +import { AudioContext } from "./AudioContext.js"; + +/** + * The {@link AudioListener} represents a virtual {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioListener | listener} of the all positional and non-positional audio effects in the scene. + * A three.js application usually creates a single instance of {@link AudioListener} * @remarks + * It is a mandatory construtor parameter for audios entities like {@link Audio | Audio} and {@link PositionalAudio | PositionalAudio}. + * In most cases, the listener object is a child of the camera + * So the 3D transformation of the camera represents the 3D transformation of the listener. + * @example + * ```typescript + * // create an {@link AudioListener} and add it to the camera + * const listener = new THREE.AudioListener(); + * camera.add(listener); + * // create a global audio source + * const sound = new THREE.Audio(listener); + * // load a sound and set it as the Audio object's buffer + * const audioLoader = new THREE.AudioLoader(); + * audioLoader.load('sounds/ambient.ogg', function (buffer) { + * sound.setBuffer(buffer); + * sound.setLoop(true); + * sound.setVolume(0.5); + * sound.play(); + * }); + * ``` + * @see Example: {@link https://threejs.org/examples/#webaudio_sandbox | webaudio / sandbox } + * @see Example: {@link https://threejs.org/examples/#webaudio_timing | webaudio / timing } + * @see Example: {@link https://threejs.org/examples/#webaudio_visualizer | webaudio / visualizer } + * @see {@link https://threejs.org/docs/index.html#api/en/audio/AudioListener | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/audio/AudioListener.js | Source} + */ +export class AudioListener extends Object3D { + /** + * Create a new AudioListener. + */ + constructor(); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `AudioListener` + */ + readonly type: string | "AudioListener"; + + /** + * The {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioContext | AudioContext} of the {@link {@link AudioListener} | listener} given in the constructor. + */ + context: AudioContext; + + /** + * A {@link https://developer.mozilla.org/en-US/docs/Web/API/GainNode | GainNode} created using + * {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioContext/createGain | AudioContext.createGain()}. + */ + gain: GainNode; + + /** + * @defaultValue `null` + */ + filter: AudioNode; + + /** + * Time delta value for audio entities. Use in context of {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioParam/linearRampToValueAtTime | AudioParam.linearRampToValueAtTimeDefault()}. + * @defaultValue `0` + */ + timeDelta: number; + + /** + * Return the {@link AudioListener.gain | gainNode}. + */ + getInput(): GainNode; + /** + * Set the {@link AudioListener.filter | filter} property to `null`. + */ + removeFilter(): this; + + /** + * Returns the value of the {@link AudioListener.filter | filter} property. + */ + getFilter(): AudioNode; + /** + * Set the {@link AudioListener.filter | filter} property to `value`. + * @param value + */ + setFilter(value: AudioNode): this; + + /** + * Return the volume. + */ + getMasterVolume(): number; + + /** + * Set the volume. + * @param value + */ + setMasterVolume(value: number): this; +} diff --git a/src-testing/src/audio/PositionalAudio.d.ts b/src-testing/src/audio/PositionalAudio.d.ts new file mode 100644 index 000000000..d72d10674 --- /dev/null +++ b/src-testing/src/audio/PositionalAudio.d.ts @@ -0,0 +1,101 @@ +import { Audio } from "./Audio.js"; +import { AudioListener } from "./AudioListener.js"; + +/** + * Create a positional audio object. + * This uses the {@link https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API | Web Audio API}. + * @example + * ```typescript + * // create an AudioListener and add it to the camera + * const listener = new THREE.AudioListener(); + * camera.add(listener); + * // create the {@link PositionalAudio} object (passing in the listener) + * const sound = new THREE.PositionalAudio(listener); + * // load a sound and set it as the {@link PositionalAudio} object's buffer + * const audioLoader = new THREE.AudioLoader(); + * audioLoader.load('sounds/song.ogg', function (buffer) { + * sound.setBuffer(buffer); + * sound.setRefDistance(20); + * sound.play(); + * }); + * // create an object for the sound to play from + * const sphere = new THREE.SphereGeometry(20, 32, 16); + * const material = new THREE.MeshPhongMaterial({ + * color: 0xff2200 + * }); + * const mesh = new THREE.Mesh(sphere, material); + * scene.add(mesh); + * // finally add the sound to the mesh + * mesh.add(sound); + * ``` + * @see Example: {@link https://threejs.org/examples/#webaudio_orientation | webaudio / orientation } + * @see Example: {@link https://threejs.org/examples/#webaudio_sandbox | webaudio / sandbox } + * @see Example: {@link https://threejs.org/examples/#webaudio_timing | webaudio / timing } + * @see {@link https://threejs.org/docs/index.html#api/en/audio/PositionalAudio | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/audio/PositionalAudio.js | Source} + */ +export class PositionalAudio extends Audio { + /** + * Create a new instance of {@link PositionalAudio} + * @param listener (required) {@link AudioListener | AudioListener} instance. + */ + constructor(listener: AudioListener); + + /** + * The PositionalAudio's {@link https://developer.mozilla.org/en-US/docs/Web/API/PannerNode | PannerNode}. + */ + panner: PannerNode; + + /** + * Returns the {@link PositionalAudio.panner | panner}. + */ + getOutput(): PannerNode; + + /** + * Returns the value of {@link https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/refDistance | panner.refDistance}. + */ + getRefDistance(): number; + /** + * Sets the value of {@link https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/refDistance | panner.refDistance}. + * @param value Expects a `Float` + */ + setRefDistance(value: number): this; + + /** + * Returns the value of {@link https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/rolloffFactor | panner.rolloffFactor}. + */ + getRolloffFactor(): number; + /** + * Sets the value of {@link https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/rolloffFactor | panner.rolloffFactor}. + * @param value Expects a `Float` + */ + setRolloffFactor(value: number): this; + + /** + * Returns the value of {@link https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/distanceModel | panner.distanceModel}. + */ + getDistanceModel(): string; + /** + * Sets the value of {@link https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/distanceModel | panner.distanceModel}. + * @param value + */ + setDistanceModel(value: string): this; + + /** + * Returns the value of {@link https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/maxDistance | panner.maxDistance}. + */ + getMaxDistance(): number; + /** + * Sets the value of {@link https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/maxDistance | panner.maxDistance}. + * @param value Expects a `Float` + */ + setMaxDistance(value: number): this; + + /** + * This method can be used in order to transform an omnidirectional sound into a {@link https://developer.mozilla.org/en-US/docs/Web/API/PannerNode | directional sound}. + * @param coneInnerAngle Expects a `Float` + * @param coneOuterAngle Expects a `Float` + * @param coneOuterGain Expects a `Float` + */ + setDirectionalCone(coneInnerAngle: number, coneOuterAngle: number, coneOuterGain: number): this; +} diff --git a/src-testing/src/cameras/ArrayCamera.d.ts b/src-testing/src/cameras/ArrayCamera.d.ts new file mode 100644 index 000000000..e9e9a221d --- /dev/null +++ b/src-testing/src/cameras/ArrayCamera.d.ts @@ -0,0 +1,32 @@ +import { PerspectiveCamera } from "./PerspectiveCamera.js"; + +/** + * {@link ArrayCamera} can be used in order to efficiently render a scene with a predefined set of cameras + * @remarks + * This is an important performance aspect for rendering VR scenes. + * An instance of {@link ArrayCamera} always has an array of sub cameras + * It's mandatory to define for each sub camera the `viewport` property which determines the part of the viewport that is rendered with this camera. + * @see Example: {@link https://threejs.org/examples/#webgl_camera_array | camera / array } + * @see {@link https://threejs.org/docs/index.html#api/en/cameras/ArrayCamera | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/cameras/ArrayCamera.js | Source} + */ +export class ArrayCamera extends PerspectiveCamera { + /** + * An array of cameras. + * @param array. Default `[]`. + */ + constructor(cameras?: PerspectiveCamera[]); + + /** + * Read-only flag to check if a given object is of type {@link ArrayCamera}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isArrayCamera: true; + + /** + * An array of cameras. + * @defaultValue `[]` + */ + cameras: PerspectiveCamera[]; +} diff --git a/src-testing/src/cameras/Camera.d.ts b/src-testing/src/cameras/Camera.d.ts new file mode 100644 index 000000000..b49add52e --- /dev/null +++ b/src-testing/src/cameras/Camera.d.ts @@ -0,0 +1,74 @@ +import { CoordinateSystem } from "../constants.js"; +import { Layers } from "../core/Layers.js"; +import { Object3D } from "../core/Object3D.js"; +import { Matrix4 } from "../math/Matrix4.js"; +import { Vector3 } from "../math/Vector3.js"; +import { Vector4 } from "../math/Vector4.js"; + +/** + * Abstract base class for cameras + * @remarks + * This class should always be inherited when you build a new camera. + * @see {@link https://threejs.org/docs/index.html#api/en/cameras/Camera | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/cameras/Camera.js | Source} + */ +export class Camera extends Object3D { + /** + * @remarks + * Note that this class is not intended to be called directly; you probably want a + * {@link THREE.PerspectiveCamera | PerspectiveCamera} or + * {@link THREE.OrthographicCamera | OrthographicCamera} instead. + */ + constructor(); + + /** + * Read-only flag to check if a given object is of type {@link Camera}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isCamera: true; + + /** + * @override + * @defaultValue `Camera` + */ + override readonly type: string | "Camera"; + + /** + * @override + * The {@link THREE.Layers | layers} that the {@link Camera} is a member of. + * @remarks Objects must share at least one layer with the {@link Camera} to be n when the camera's viewpoint is rendered. + * @defaultValue `new THREE.Layers()` + */ + override layers: Layers; + + /** + * This is the inverse of matrixWorld. + * @remarks MatrixWorld contains the Matrix which has the world transform of the {@link Camera} . + * @defaultValue {@link THREE.Matrix4 | `new THREE.Matrix4()`} + */ + matrixWorldInverse: Matrix4; + + /** + * This is the matrix which contains the projection. + * @defaultValue {@link THREE.Matrix4 | `new THREE.Matrix4()`} + */ + projectionMatrix: Matrix4; + + /** + * This is the inverse of projectionMatrix. + * @defaultValue {@link THREE.Matrix4 | `new THREE.Matrix4()`} + */ + projectionMatrixInverse: Matrix4; + + coordinateSystem: CoordinateSystem; + + viewport?: Vector4; + + /** + * Returns a {@link THREE.Vector3 | Vector3} representing the world space direction in which the {@link Camera} is looking. + * @remarks Note: A {@link Camera} looks down its local, negative z-axis. + * @param target The result will be copied into this Vector3. + */ + getWorldDirection(target: Vector3): Vector3; +} diff --git a/src-testing/src/cameras/CubeCamera.d.ts b/src-testing/src/cameras/CubeCamera.d.ts new file mode 100644 index 000000000..e6e82fb19 --- /dev/null +++ b/src-testing/src/cameras/CubeCamera.d.ts @@ -0,0 +1,68 @@ +import { CoordinateSystem } from "../constants.js"; +import { Object3D } from "../core/Object3D.js"; +import { WebGLCubeRenderTarget } from "../renderers/WebGLCubeRenderTarget.js"; +import { WebGLRenderer } from "../renderers/WebGLRenderer.js"; + +/** + * Creates **6** {@link THREE.PerspectiveCamera | cameras} that render to a {@link THREE.WebGLCubeRenderTarget | WebGLCubeRenderTarget}. + * @remarks The cameras are added to the {@link children} array. + * @example + * ```typescript + * // Create cube render target + * const cubeRenderTarget = new THREE.WebGLCubeRenderTarget( 128, { generateMipmaps: true, minFilter: THREE.LinearMipmapLinearFilter } ); + * + * // Create cube camera + * const cubeCamera = new THREE.CubeCamera( 1, 100000, cubeRenderTarget ); + * scene.add( cubeCamera ); + * + * // Create car + * const chromeMaterial = new THREE.MeshLambertMaterial( { color: 0xffffff, envMap: cubeRenderTarget.texture } ); + * const car = new THREE.Mesh( carGeometry, chromeMaterial ); + * scene.add( car ); + * + * // Update the render target cube + * car.visible = false; + * cubeCamera.position.copy( car.position ); + * cubeCamera.update( renderer, scene ); + * + * // Render the scene + * car.visible = true; + * renderer.render( scene, camera ); + * ``` + * @see Example: {@link https://threejs.org/examples/#webgl_materials_cubemap_dynamic | materials / cubemap / dynamic } + * @see {@link https://threejs.org/docs/index.html#api/en/cameras/CubeCamera | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/cameras/CubeCamera.js | Source} + */ +export class CubeCamera extends Object3D { + /** + * Constructs a {@link CubeCamera} that contains 6 {@link PerspectiveCamera | PerspectiveCameras} that render to a {@link THREE.WebGLCubeRenderTarget | WebGLCubeRenderTarget}. + * @param near The near clipping distance. + * @param far The far clipping distance. + * @param renderTarget The destination cube render target. + */ + constructor(near: number, far: number, renderTarget: WebGLCubeRenderTarget); + + /** + * @override + * @defaultValue `CubeCamera` + */ + override readonly type: string | "CubeCamera"; + + /** + * The destination cube render target. + */ + renderTarget: WebGLCubeRenderTarget; + + coordinateSystem: CoordinateSystem; + + activeMipmapLevel: number; + + updateCoordinateSystem(): void; + + /** + * Call this to update the {@link CubeCamera.renderTarget | renderTarget}. + * @param renderer The current WebGL renderer + * @param scene The current scene + */ + update(renderer: WebGLRenderer, scene: Object3D): void; +} diff --git a/src-testing/src/cameras/OrthographicCamera.d.ts b/src-testing/src/cameras/OrthographicCamera.d.ts new file mode 100644 index 000000000..745d11416 --- /dev/null +++ b/src-testing/src/cameras/OrthographicCamera.d.ts @@ -0,0 +1,174 @@ +import { JSONMeta, Object3DJSON, Object3DJSONObject } from "../core/Object3D.js"; +import { Camera } from "./Camera.js"; + +export interface OrthographicCameraJSONObject extends Object3DJSONObject { + zoom: number; + left: number; + right: number; + top: number; + bottom: number; + near: number; + far: number; + + view?: { + enabled: boolean; + fullWidth: number; + fullHeight: number; + offsetX: number; + offsetY: number; + width: number; + height: number; + }; +} + +export interface OrthographicCameraJSON extends Object3DJSON { + object: OrthographicCameraJSONObject; +} + +/** + * Camera that uses {@link https://en.wikipedia.org/wiki/Orthographic_projection | orthographic projection}. + * In this projection mode, an object's size in the rendered image stays constant regardless of its distance from the camera. + * This can be useful for rendering 2D scenes and UI elements, amongst other things. + * @example + * ```typescript + * const camera = new THREE.OrthographicCamera(width / -2, width / 2, height / 2, height / -2, 1, 1000); + * scene.add(camera); + * ``` + * @see Example: {@link https://threejs.org/examples/#webgl_camera | camera } + * @see Example: {@link https://threejs.org/examples/#webgl_interactive_cubes_ortho | interactive / cubes / ortho } + * @see Example: {@link https://threejs.org/examples/#webgl_materials_cubemap_dynamic | materials / cubemap / dynamic } + * @see Example: {@link https://threejs.org/examples/#webgl_postprocessing_advanced | postprocessing / advanced } + * @see Example: {@link https://threejs.org/examples/#webgl_postprocessing_dof2 | postprocessing / dof2 } + * @see Example: {@link https://threejs.org/examples/#webgl_postprocessing_godrays | postprocessing / godrays } + * @see Example: {@link https://threejs.org/examples/#webgl_rtt | rtt } + * @see Example: {@link https://threejs.org/examples/#webgl_shaders_tonemapping | shaders / tonemapping } + * @see Example: {@link https://threejs.org/examples/#webgl_shadowmap | shadowmap } + * @see {@link https://threejs.org/docs/index.html#api/en/cameras/OrthographicCamera | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/cameras/OrthographicCamera.js | Source} + */ +export class OrthographicCamera extends Camera { + /** + * Creates a new {@link OrthographicCamera}. + * @remarks Together these define the camera's {@link https://en.wikipedia.org/wiki/Viewing_frustum | viewing frustum}. + * @param left Camera frustum left plane. Default `-1`. + * @param right Camera frustum right plane. Default `1`. + * @param top Camera frustum top plane. Default `1`. + * @param bottom Camera frustum bottom plane. Default `-1`. + * @param near Camera frustum near plane. Default `0.1`. + * @param far Camera frustum far plane. Default `2000`. + */ + constructor(left?: number, right?: number, top?: number, bottom?: number, near?: number, far?: number); + + /** + * Read-only flag to check if a given object is of type {@link OrthographicCamera}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isOrthographicCamera: true; + + /** + * @override + * @defaultValue `OrthographicCamera` + */ + override readonly type: string | "OrthographicCamera"; + + /** + * Gets or sets the zoom factor of the camera. + * @defaultValue `1` + */ + zoom: number; + + /** + * Set by {@link setViewOffset | .setViewOffset()}. + * @defaultValue `null` + */ + view: null | { + enabled: boolean; + fullWidth: number; + fullHeight: number; + offsetX: number; + offsetY: number; + width: number; + height: number; + }; + + /** + * Camera frustum left plane. + * @remarks Expects a `Float` + * @defaultValue `-1` + */ + left: number; + + /** + * Camera frustum right plane. + * @remarks Expects a `Float` + * @defaultValue `1` + */ + right: number; + + /** + * Camera frustum top plane. + * @remarks Expects a `Float` + * @defaultValue `1` + */ + top: number; + + /** + * Camera frustum bottom plane. + * @remarks Expects a `Float`. + * @defaultValue `-1` + */ + bottom: number; + + /** + * Camera frustum near plane.`. + * @remarks The valid range is between `0` and the current value of the {@link far | .far} plane. + * @remarks Note that, unlike for the {@link THREE.PerspectiveCamera | PerspectiveCamera}, `0` is a valid value for an {@link THREE.OrthographicCamera | OrthographicCamera's} near plane. + * @remarks Expects a `Float` + * @defaultValue `0.1` + */ + near: number; + + /** + * Camera frustum far plane. + * @remarks Must be greater than the current value of {@link near | .near} plane. + * @remarks Expects a `Float` + * @defaultValue `2000` + */ + far: number; + + /** + * Updates the camera projection matrix + * @remarks Must be called after any change of parameters. + */ + updateProjectionMatrix(): void; + + /** + * Sets an offset in a larger {@link https://en.wikipedia.org/wiki/Viewing_frustum | viewing frustum} + * @remarks + * This is useful for multi-window or multi-monitor/multi-machine setups + * For an example on how to use it see {@link PerspectiveCamera.setViewOffset | PerspectiveCamera}. + * @see {@link THREE.PerspectiveCamera.setViewOffset | PerspectiveCamera}. + * @param fullWidth Full width of multiview setup Expects a `Float`. + * @param fullHeight Full height of multiview setup Expects a `Float`. + * @param x Horizontal offset of subcamera Expects a `Float`. + * @param y Vertical offset of subcamera Expects a `Float`. + * @param width Width of subcamera Expects a `Float`. + * @param height Height of subcamera Expects a `Float`. + */ + setViewOffset( + fullWidth: number, + fullHeight: number, + offsetX: number, + offsetY: number, + width: number, + height: number, + ): void; + + /** + * Removes any offset set by the {@link setViewOffset | .setViewOffset} method. + */ + clearViewOffset(): void; + + toJSON(meta?: JSONMeta): OrthographicCameraJSON; +} diff --git a/src-testing/src/cameras/PerspectiveCamera.d.ts b/src-testing/src/cameras/PerspectiveCamera.d.ts new file mode 100644 index 000000000..60567105f --- /dev/null +++ b/src-testing/src/cameras/PerspectiveCamera.d.ts @@ -0,0 +1,254 @@ +import { JSONMeta, Object3DJSON, Object3DJSONObject } from "../core/Object3D.js"; +import { Vector2 } from "../math/Vector2.js"; +import { Camera } from "./Camera.js"; + +export interface PerspectiveCameraJSONObject extends Object3DJSONObject { + fov: number; + zoom: number; + + near: number; + far: number; + focus: number; + + aspect: number; + + view?: { + enabled: boolean; + fullWidth: number; + fullHeight: number; + offsetX: number; + offsetY: number; + width: number; + height: number; + }; + + filmGauge: number; + filmOffset: number; +} + +export interface PerspectiveCameraJSON extends Object3DJSON { + object: PerspectiveCameraJSONObject; +} + +/** + * Camera that uses {@link https://en.wikipedia.org/wiki/Perspective_(graphical) | perspective projection}. + * This projection mode is designed to mimic the way the human eye sees + * @remarks + * It is the most common projection mode used for rendering a 3D scene. + * @example + * ```typescript + * const camera = new THREE.PerspectiveCamera(45, width / height, 1, 1000); + * scene.add(camera); + * ``` + * @see Example: {@link https://threejs.org/examples/#webgl_animation_skinning_blending | animation / skinning / blending } + * @see Example: {@link https://threejs.org/examples/#webgl_animation_skinning_morph | animation / skinning / morph } + * @see Example: {@link https://threejs.org/examples/#webgl_effects_stereo | effects / stereo } + * @see Example: {@link https://threejs.org/examples/#webgl_interactive_cubes | interactive / cubes } + * @see Example: {@link https://threejs.org/examples/#webgl_loader_collada_skinning | loader / collada / skinning } + * @see {@link https://threejs.org/docs/index.html#api/en/cameras/PerspectiveCamera | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/cameras/PerspectiveCamera.js | Source} + */ +export class PerspectiveCamera extends Camera { + /** + * Creates a new {@link PerspectiveCamera}. + * @remarks Together these define the camera's {@link https://en.wikipedia.org/wiki/Viewing_frustum | viewing frustum}. + * @param fov Camera frustum vertical field of view. Default `50`. + * @param aspect Camera frustum aspect ratio. Default `1`. + * @param near Camera frustum near plane. Default `0.1`. + * @param far Camera frustum far plane. Default `2000`. + */ + constructor(fov?: number, aspect?: number, near?: number, far?: number); + + /** + * Read-only flag to check if a given object is of type {@link Camera}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isPerspectiveCamera: true; + + /** + * @override + * @defaultValue `PerspectiveCamera` + */ + override readonly type: string | "PerspectiveCamera"; + + /** + * Gets or sets the zoom factor of the camera. + * @defaultValue `1` + */ + zoom: number; + + /** + * Camera frustum vertical field of view, from bottom to top of view, in degrees. + * @remarks Expects a `Float` + * @defaultValue `50` + */ + fov: number; + + /** + * Camera frustum aspect ratio, usually the canvas width / canvas height. + * @remarks Expects a `Float` + * @defaultValue `1`, _(square canvas)_. + */ + aspect: number; + + /** + * Camera frustum near plane. + * @remarks The valid range is greater than `0` and less than the current value of the {@link far | .far} plane. + * @remarks Note that, unlike for the {@link THREE.OrthographicCamera | OrthographicCamera}, `0` is **not** a valid value for a {@link PerspectiveCamera |PerspectiveCamera's}. near plane. + * @defaultValue `0.1` + * @remarks Expects a `Float` + */ + near: number; + + /** + * Camera frustum far plane. + * @remarks Must be greater than the current value of {@link near | .near} plane. + * @remarks Expects a `Float` + * @defaultValue `2000` + */ + far: number; + + /** + * Object distance used for stereoscopy and depth-of-field effects. + * @remarks This parameter does not influence the projection matrix unless a {@link THREE.StereoCamera | StereoCamera} is being used. + * @remarks Expects a `Float` + * @defaultValue `10` + */ + focus: number; + + /** + * Frustum window specification or null. + * This is set using the {@link setViewOffset | .setViewOffset} method and cleared using {@link clearViewOffset | .clearViewOffset}. + * @defaultValue `null` + */ + view: null | { + enabled: boolean; + fullWidth: number; + fullHeight: number; + offsetX: number; + offsetY: number; + width: number; + height: number; + }; + + /** + * Film size used for the larger axis. + * This parameter does not influence the projection matrix unless {@link filmOffset | .filmOffset} is set to a nonzero value. + * @remarks Expects a `Float` + * @defaultValue `35`, _millimeters_. + */ + filmGauge: number; + + /** + * Horizontal off-center offset in the same unit as {@link filmGauge | .filmGauge}. + * @remarks Expects a `Float` + * @defaultValue `0` + */ + filmOffset: number; + + /** + * Returns the focal length of the current {@link .fov | fov} in respect to {@link filmGauge | .filmGauge}. + */ + getFocalLength(): number; + + /** + * Sets the FOV by focal length in respect to the current {@link filmGauge | .filmGauge}. + * @remarks By default, the focal length is specified for a `35mm` (full frame) camera. + * @param focalLength Expects a `Float` + */ + setFocalLength(focalLength: number): void; + + /** + * Returns the current vertical field of view angle in degrees considering {@link zoom | .zoom}. + */ + getEffectiveFOV(): number; + + /** + * Returns the width of the image on the film + * @remarks + * If {@link aspect | .aspect}. is greater than or equal to one (landscape format), the result equals {@link filmGauge | .filmGauge}. + */ + getFilmWidth(): number; + + /** + * Returns the height of the image on the film + * @remarks + * If {@link aspect | .aspect}. is less than or equal to one (portrait format), the result equals {@link filmGauge | .filmGauge}. + */ + getFilmHeight(): number; + + /** + * Computes the 2D bounds of the camera's viewable rectangle at a given distance along the viewing direction. + * Sets minTarget and maxTarget to the coordinates of the lower-left and upper-right corners of the view rectangle. + */ + getViewBounds(distance: number, minTarget: Vector2, maxTarget: Vector2): void; + + /** + * Computes the width and height of the camera's viewable rectangle at a given distance along the viewing direction. + * Copies the result into the target Vector2, where x is width and y is height. + */ + getViewSize(distance: number, target: Vector2): Vector2; + + /** + * Sets an offset in a larger frustum. + * @remarks + * This is useful for multi-window or multi-monitor/multi-machine setups. + * + * For example, if you have 3x2 monitors and each monitor is _1920x1080_ and + * the monitors are in grid like this + * ``` + * ┌───┬───┬───┐ + * │ A │ B │ C │ + * ├───┼───┼───┤ + * │ D │ E │ F │ + * └───┴───┴───┘ + * ``` + * then for each monitor you would call it like this + * ```typescript + * const w = 1920; + * const h = 1080; + * const fullWidth = w * 3; + * const fullHeight = h * 2; + * + * // Monitor - A + * camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 0, w, h ); + * // Monitor - B + * camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 0, w, h ); + * // Monitor - C + * camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 0, w, h ); + * // Monitor - D + * camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 1, w, h ); + * // Monitor - E + * camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 1, w, h ); + * // Monitor - F + * camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 1, w, h ); + * ``` + * Note there is no reason monitors have to be the same size or in a grid. + * @param fullWidth Full width of multiview setup Expects a `Float`. + * @param fullHeight Full height of multiview setup Expects a `Float`. + * @param x Horizontal offset of subcamera Expects a `Float`. + * @param y Vertical offset of subcamera Expects a `Float`. + * @param width Width of subcamera Expects a `Float`. + * @param height Height of subcamera Expects a `Float`. + */ + setViewOffset(fullWidth: number, fullHeight: number, x: number, y: number, width: number, height: number): void; + + /** + * Removes any offset set by the {@link setViewOffset | .setViewOffset} method. + */ + clearViewOffset(): void; + + /** + * Updates the camera projection matrix + * @remarks Must be called after any change of parameters. + */ + updateProjectionMatrix(): void; + + /** + * @deprecated Use {@link PerspectiveCamera.setFocalLength | .setFocalLength()} and {@link PerspectiveCamera.filmGauge | .filmGauge} instead. + */ + setLens(focalLength: number, frameHeight?: number): void; + + toJSON(meta?: JSONMeta): PerspectiveCameraJSON; +} diff --git a/src-testing/src/cameras/StereoCamera.d.ts b/src-testing/src/cameras/StereoCamera.d.ts new file mode 100644 index 000000000..3f359e3e0 --- /dev/null +++ b/src-testing/src/cameras/StereoCamera.d.ts @@ -0,0 +1,50 @@ +import { Camera } from "./Camera.js"; +import { PerspectiveCamera } from "./PerspectiveCamera.js"; + +/** + * Dual {@link PerspectiveCamera | PerspectiveCamera}s used for effects such as + * {@link https://en.wikipedia.org/wiki/Anaglyph_3D | 3D Anaglyph} or + * {@link https://en.wikipedia.org/wiki/parallax_barrier | Parallax Barrier}. + * @see Example: {@link https://threejs.org/examples/#webgl_effects_anaglyph | effects / anaglyph } + * @see Example: {@link https://threejs.org/examples/#webgl_effects_parallaxbarrier | effects / parallaxbarrier } + * @see Example: {@link https://threejs.org/examples/#webgl_effects_stereo | effects / stereo } + * @see {@link https://threejs.org/docs/index.html#api/en/cameras/StereoCamera | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/cameras/StereoCamera.js | Source} + */ +export class StereoCamera extends Camera { + constructor(); + + type: "StereoCamera"; + + /** + * @remarks Expects a `Float` + * @defaultValue `1` + */ + aspect: number; + + /** + * @remarks Expects a `Float` + * @defaultValue `0.064` + */ + eyeSep: number; + + /** + * The Left camera. + * A {@link PerspectiveCamera } added to {@link THREE.PerspectiveCamera.layers | layer 1} + * @remarks Objects to be rendered by the **left** camera must also be added to this layer. + */ + cameraL: PerspectiveCamera; + + /** + * The Right camera. + * A {@link PerspectiveCamera } added to {@link THREE.PerspectiveCamera.layers | layer 2} + * @remarks Objects to be rendered by the **right** camera must also be added to this layer. + */ + cameraR: PerspectiveCamera; + + /** + * Update the stereo cameras based on the camera passed in. + * @param camera + */ + update(camera: PerspectiveCamera): void; +} diff --git a/src-testing/src/constants.d.ts b/src-testing/src/constants.d.ts new file mode 100644 index 000000000..f5d26b42a --- /dev/null +++ b/src-testing/src/constants.d.ts @@ -0,0 +1,918 @@ +export const REVISION: string; + +// https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent.button +export enum MOUSE { + LEFT = 0, + MIDDLE = 1, + RIGHT = 2, + ROTATE = 0, + DOLLY = 1, + PAN = 2, +} + +export enum TOUCH { + ROTATE = 0, + PAN = 1, + DOLLY_PAN = 2, + DOLLY_ROTATE = 3, +} + +// GL STATE CONSTANTS +export const CullFaceNone: 0; +export const CullFaceBack: 1; +export const CullFaceFront: 2; +export const CullFaceFrontBack: 3; +export type CullFace = typeof CullFaceNone | typeof CullFaceBack | typeof CullFaceFront | typeof CullFaceFrontBack; + +// Shadowing Type +export const BasicShadowMap: 0; +export const PCFShadowMap: 1; +export const PCFSoftShadowMap: 2; +export const VSMShadowMap: 3; +export type ShadowMapType = typeof BasicShadowMap | typeof PCFShadowMap | typeof PCFSoftShadowMap | typeof VSMShadowMap; + +// MATERIAL CONSTANTS + +// side +export const FrontSide: 0; +export const BackSide: 1; +export const DoubleSide: 2; +/** + * Defines which side of faces will be rendered - front, back or both. + * Default is {@link FrontSide}. + */ +export type Side = typeof FrontSide | typeof BackSide | typeof DoubleSide; + +// blending modes +export const NoBlending: 0; +export const NormalBlending: 1; +export const AdditiveBlending: 2; +export const SubtractiveBlending: 3; +export const MultiplyBlending: 4; +export const CustomBlending: 5; +export type Blending = + | typeof NoBlending + | typeof NormalBlending + | typeof AdditiveBlending + | typeof SubtractiveBlending + | typeof MultiplyBlending + | typeof CustomBlending; + +// custom blending equations +// (numbers start from 100 not to clash with other +// mappings to OpenGL constants defined in Texture.js) +export const AddEquation: 100; +export const SubtractEquation: 101; +export const ReverseSubtractEquation: 102; +export const MinEquation: 103; +export const MaxEquation: 104; +export type BlendingEquation = + | typeof AddEquation + | typeof SubtractEquation + | typeof ReverseSubtractEquation + | typeof MinEquation + | typeof MaxEquation; + +// custom blending factors +export const ZeroFactor: 200; +export const OneFactor: 201; +export const SrcColorFactor: 202; +export const OneMinusSrcColorFactor: 203; +export const SrcAlphaFactor: 204; +export const OneMinusSrcAlphaFactor: 205; +export const DstAlphaFactor: 206; +export const OneMinusDstAlphaFactor: 207; +export const DstColorFactor: 208; +export const OneMinusDstColorFactor: 209; +export const SrcAlphaSaturateFactor: 210; +export const ConstantColorFactor: 211; +export const OneMinusConstantColorFactor: 212; +export const ConstantAlphaFactor: 213; +export const OneMinusConstantAlphaFactor: 214; +export type BlendingDstFactor = + | typeof ZeroFactor + | typeof OneFactor + | typeof SrcColorFactor + | typeof OneMinusSrcColorFactor + | typeof SrcAlphaFactor + | typeof OneMinusSrcAlphaFactor + | typeof DstAlphaFactor + | typeof OneMinusDstAlphaFactor + | typeof DstColorFactor + | typeof OneMinusDstColorFactor + | typeof ConstantColorFactor + | typeof OneMinusConstantColorFactor + | typeof ConstantAlphaFactor + | typeof OneMinusConstantAlphaFactor; +export type BlendingSrcFactor = BlendingDstFactor | typeof SrcAlphaSaturateFactor; + +// depth modes +export const NeverDepth: 0; +export const AlwaysDepth: 1; +export const LessDepth: 2; +export const LessEqualDepth: 3; +export const EqualDepth: 4; +export const GreaterEqualDepth: 5; +export const GreaterDepth: 6; +export const NotEqualDepth: 7; +export type DepthModes = + | typeof NeverDepth + | typeof AlwaysDepth + | typeof LessDepth + | typeof LessEqualDepth + | typeof EqualDepth + | typeof GreaterEqualDepth + | typeof GreaterDepth + | typeof NotEqualDepth; + +// TEXTURE CONSTANTS +// Operations +export const MultiplyOperation: 0; +export const MixOperation: 1; +export const AddOperation: 2; +export type Combine = typeof MultiplyOperation | typeof MixOperation | typeof AddOperation; + +// Tone Mapping modes +export const NoToneMapping: 0; +export const LinearToneMapping: 1; +export const ReinhardToneMapping: 2; +export const CineonToneMapping: 3; +export const ACESFilmicToneMapping: 4; +export const CustomToneMapping: 5; +export const AgXToneMapping: 6; +export const NeutralToneMapping: 7; +export type ToneMapping = + | typeof NoToneMapping + | typeof LinearToneMapping + | typeof ReinhardToneMapping + | typeof CineonToneMapping + | typeof ACESFilmicToneMapping + | typeof CustomToneMapping + | typeof AgXToneMapping + | typeof NeutralToneMapping; + +// Bind modes +export const AttachedBindMode: "attached"; +export const DetachedBindMode: "detached"; +export type BindMode = typeof AttachedBindMode | typeof DetachedBindMode; + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +// Mapping modes + +/** + * Maps the texture using the mesh's UV coordinates. + * @remarks This is the _default_ value and behaver for Texture Mapping. + */ +export const UVMapping: 300; + +/** + * @remarks This is the _default_ value and behaver for Cube Texture Mapping. + */ +export const CubeReflectionMapping: 301; +export const CubeRefractionMapping: 302; +export const CubeUVReflectionMapping: 306; + +export const EquirectangularReflectionMapping: 303; +export const EquirectangularRefractionMapping: 304; + +/** + * Texture Mapping Modes for non-cube Textures + * @remarks {@link UVMapping} is the _default_ value and behaver for Texture Mapping. + * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} + */ +export type Mapping = + | typeof UVMapping + | typeof EquirectangularReflectionMapping + | typeof EquirectangularRefractionMapping; + +/** + * Texture Mapping Modes for cube Textures + * @remarks {@link CubeReflectionMapping} is the _default_ value and behaver for Cube Texture Mapping. + * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} + */ +export type CubeTextureMapping = + | typeof CubeReflectionMapping + | typeof CubeRefractionMapping + | typeof CubeUVReflectionMapping; + +/** + * Texture Mapping Modes for any type of Textures + * @see {@link Mapping} and {@link CubeTextureMapping} + * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} + */ +export type AnyMapping = Mapping | CubeTextureMapping; + +/////////////////////////////////////////////////////////////////////////////// +// Wrapping modes + +/** With {@link RepeatWrapping} the texture will simply repeat to infinity. */ +export const RepeatWrapping: 1000; +/** + * With {@link ClampToEdgeWrapping} the last pixel of the texture stretches to the edge of the mesh. + * @remarks This is the _default_ value and behaver for Wrapping Mapping. + */ +export const ClampToEdgeWrapping: 1001; +/** With {@link MirroredRepeatWrapping} the texture will repeats to infinity, mirroring on each repeat. */ +export const MirroredRepeatWrapping: 1002; + +/** + * Texture Wrapping Modes + * @remarks {@link ClampToEdgeWrapping} is the _default_ value and behaver for Wrapping Mapping. + * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} + */ +export type Wrapping = typeof RepeatWrapping | typeof ClampToEdgeWrapping | typeof MirroredRepeatWrapping; + +/////////////////////////////////////////////////////////////////////////////// +// Filters + +/** {@link NearestFilter} returns the value of the texture element that is nearest (in Manhattan distance) to the specified texture coordinates. */ +export const NearestFilter: 1003; + +/** + * {@link NearestMipmapNearestFilter} chooses the mipmap that most closely matches the size of the pixel being textured + * and uses the {@link NearestFilter} criterion (the texel nearest to the center of the pixel) to produce a texture value. + */ +export const NearestMipmapNearestFilter: 1004; +/** + * {@link NearestMipmapNearestFilter} chooses the mipmap that most closely matches the size of the pixel being textured + * and uses the {@link NearestFilter} criterion (the texel nearest to the center of the pixel) to produce a texture value. + */ +export const NearestMipMapNearestFilter: 1004; + +/** + * {@link NearestMipmapLinearFilter} chooses the two mipmaps that most closely match the size of the pixel being textured + * and uses the {@link NearestFilter} criterion to produce a texture value from each mipmap. + * The final texture value is a weighted average of those two values. + */ +export const NearestMipmapLinearFilter: 1005; +/** + * {@link NearestMipMapLinearFilter} chooses the two mipmaps that most closely match the size of the pixel being textured + * and uses the {@link NearestFilter} criterion to produce a texture value from each mipmap. + * The final texture value is a weighted average of those two values. + */ +export const NearestMipMapLinearFilter: 1005; + +/** + * {@link LinearFilter} returns the weighted average of the four texture elements that are closest to the specified texture coordinates, + * and can include items wrapped or repeated from other parts of a texture, + * depending on the values of {@link THREE.Texture.wrapS | wrapS} and {@link THREE.Texture.wrapT | wrapT}, and on the exact mapping. + */ +export const LinearFilter: 1006; + +/** + * {@link LinearMipmapNearestFilter} chooses the mipmap that most closely matches the size of the pixel being textured and + * uses the {@link LinearFilter} criterion (a weighted average of the four texels that are closest to the center of the pixel) to produce a texture value. + */ +export const LinearMipmapNearestFilter: 1007; +/** + * {@link LinearMipMapNearestFilter} chooses the mipmap that most closely matches the size of the pixel being textured and + * uses the {@link LinearFilter} criterion (a weighted average of the four texels that are closest to the center of the pixel) to produce a texture value. + */ +export const LinearMipMapNearestFilter: 1007; + +/** + * {@link LinearMipmapLinearFilter} is the default and chooses the two mipmaps that most closely match the size of the pixel being textured and + * uses the {@link LinearFilter} criterion to produce a texture value from each mipmap. + * The final texture value is a weighted average of those two values. + */ +export const LinearMipmapLinearFilter: 1008; + +/** + * {@link LinearMipMapLinearFilter} is the default and chooses the two mipmaps that most closely match the size of the pixel being textured and + * uses the {@link LinearFilter} criterion to produce a texture value from each mipmap. + * The final texture value is a weighted average of those two values. + */ +export const LinearMipMapLinearFilter: 1008; + +/** + * Texture Magnification Filter Modes. + * For use with a texture's {@link THREE.Texture.magFilter | magFilter} property, + * these define the texture magnification function to be used when the pixel being textured maps to an area less than or equal to one texture element (texel). + * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} + * @see {@link https://sbcode.net/threejs/mipmaps/ | Texture Mipmaps (non-official)} + */ +export type MagnificationTextureFilter = typeof NearestFilter | typeof LinearFilter; + +/** + * Texture Minification Filter Modes. + * For use with a texture's {@link THREE.Texture.minFilter | minFilter} property, + * these define the texture minifying function that is used whenever the pixel being textured maps to an area greater than one texture element (texel). + * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} + * @see {@link https://sbcode.net/threejs/mipmaps/ | Texture Mipmaps (non-official)} + */ +export type MinificationTextureFilter = + | typeof NearestFilter + | typeof NearestMipmapNearestFilter + | typeof NearestMipMapNearestFilter + | typeof NearestMipmapLinearFilter + | typeof NearestMipMapLinearFilter + | typeof LinearFilter + | typeof LinearMipmapNearestFilter + | typeof LinearMipMapNearestFilter + | typeof LinearMipmapLinearFilter + | typeof LinearMipMapLinearFilter; + +/** + * Texture all Magnification and Minification Filter Modes. + * @see {@link MagnificationTextureFilter} and {@link MinificationTextureFilter} + * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} + * @see {@link https://sbcode.net/threejs/mipmaps/ | Texture Mipmaps (non-official)} + */ +export type TextureFilter = MagnificationTextureFilter | MinificationTextureFilter; + +/////////////////////////////////////////////////////////////////////////////// +// Data types + +export const UnsignedByteType: 1009; +export const ByteType: 1010; +export const ShortType: 1011; +export const UnsignedShortType: 1012; +export const IntType: 1013; +export const UnsignedIntType: 1014; +export const FloatType: 1015; +export const HalfFloatType: 1016; +export const UnsignedShort4444Type: 1017; +export const UnsignedShort5551Type: 1018; +export const UnsignedInt248Type: 1020; +export const UnsignedInt5999Type: 35902; + +export type AttributeGPUType = typeof FloatType | typeof IntType; + +/** + * Texture Types. + * @remarks Must correspond to the correct {@link PixelFormat | format}. + * @see {@link THREE.Texture.type} + * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} + */ +export type TextureDataType = + | typeof UnsignedByteType + | typeof ByteType + | typeof ShortType + | typeof UnsignedShortType + | typeof IntType + | typeof UnsignedIntType + | typeof FloatType + | typeof HalfFloatType + | typeof UnsignedShort4444Type + | typeof UnsignedShort5551Type + | typeof UnsignedInt248Type + | typeof UnsignedInt5999Type; + +/////////////////////////////////////////////////////////////////////////////// +// Pixel formats + +/** {@link AlphaFormat} discards the red, green and blue components and reads just the alpha component. */ +export const AlphaFormat: 1021; + +export const RGBFormat: 1022; + +/** {@link RGBAFormat} is the default and reads the red, green, blue and alpha components. */ +export const RGBAFormat: 1023; + +/** + * {@link LuminanceFormat} reads each element as a single luminance component. + * This is then converted to a floating point, clamped to the range `[0,1]`, and then assembled into an RGBA element by + * placing the luminance value in the red, green and blue channels, and attaching `1.0` to the alpha channel. + */ +export const LuminanceFormat: 1024; + +/** + * {@link LuminanceAlphaFormat} reads each element as a luminance/alpha double. + * The same process occurs as for the {@link LuminanceFormat}, except that the alpha channel may have values other than `1.0`. + */ +export const LuminanceAlphaFormat: 1025; + +/** + * {@link DepthFormat} reads each element as a single depth value, converts it to floating point, and clamps to the range `[0,1]`. + * @remarks This is the default for {@link THREE.DepthTexture}. + */ +export const DepthFormat: 1026; + +/** + * {@link DepthStencilFormat} reads each element is a pair of depth and stencil values. + * The depth component of the pair is interpreted as in {@link DepthFormat}. + * The stencil component is interpreted based on the depth + stencil internal format. + */ +export const DepthStencilFormat: 1027; + +/** + * {@link RedFormat} discards the green and blue components and reads just the red component. + */ +export const RedFormat: 1028; + +/** + * {@link RedIntegerFormat} discards the green and blue components and reads just the red component. + * The texels are read as integers instead of floating point. + */ +export const RedIntegerFormat: 1029; + +/** + * {@link RGFormat} discards the alpha, and blue components and reads the red, and green components. + */ +export const RGFormat: 1030; + +/** + * {@link RGIntegerFormat} discards the alpha, and blue components and reads the red, and green components. + * The texels are read as integers instead of floating point. + */ +export const RGIntegerFormat: 1031; + +/** + * {@link RGBIntegerFormat} discrads the alpha components and reads the red, green, and blue components. + */ +export const RGBIntegerFormat: 1032; + +/** + * {@link RGBAIntegerFormat} reads the red, green, blue and alpha component + * @remarks This is the default for {@link THREE.Texture}. + */ +export const RGBAIntegerFormat: 1033; + +/** + * All Texture Pixel Formats Modes. + * @remarks Note that the texture must have the correct {@link THREE.Texture.type} set, as described in {@link TextureDataType}. + * @see {@link WebGLRenderingContext.texImage2D} for details. + * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} + */ +export type PixelFormat = + | typeof AlphaFormat + | typeof RGBFormat + | typeof RGBAFormat + | typeof LuminanceFormat + | typeof LuminanceAlphaFormat + | typeof DepthFormat + | typeof DepthStencilFormat + | typeof RedFormat + | typeof RedIntegerFormat + | typeof RGFormat + | typeof RGIntegerFormat + | typeof RGBIntegerFormat + | typeof RGBAIntegerFormat; + +/** + * All Texture Pixel Formats Modes for {@link THREE.DepthTexture}. + * @see {@link WebGLRenderingContext.texImage2D} for details. + * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} + */ +export type DepthTexturePixelFormat = typeof DepthFormat | typeof DepthStencilFormat; + +/////////////////////////////////////////////////////////////////////////////// +// Compressed texture formats +// DDS / ST3C Compressed texture formats + +/** + * A DXT1-compressed image in an RGB image format. + * @remarks Require support for the _WEBGL_compressed_texture_s3tc_ WebGL extension. + */ +export const RGB_S3TC_DXT1_Format: 33776; +/** + * A DXT1-compressed image in an RGB image format with a simple on/off alpha value. + * @remarks Require support for the _WEBGL_compressed_texture_s3tc_ WebGL extension. + */ +export const RGBA_S3TC_DXT1_Format: 33777; +/** + * A DXT3-compressed image in an RGBA image format. Compared to a 32-bit RGBA texture, it offers 4:1 compression. + * @remarks Require support for the _WEBGL_compressed_texture_s3tc_ WebGL extension. + */ +export const RGBA_S3TC_DXT3_Format: 33778; +/** + * A DXT5-compressed image in an RGBA image format. It also provides a 4:1 compression, but differs to the DXT3 compression in how the alpha compression is done. + * @remarks Require support for the _WEBGL_compressed_texture_s3tc_ WebGL extension. + */ +export const RGBA_S3TC_DXT5_Format: 33779; + +// PVRTC compressed './texture formats + +/** + * RGB compression in 4-bit mode. One block for each 4×4 pixels. + * @remarks Require support for the _WEBGL_compressed_texture_pvrtc_ WebGL extension. + */ +export const RGB_PVRTC_4BPPV1_Format: 35840; +/** + * RGB compression in 2-bit mode. One block for each 8×4 pixels. + * @remarks Require support for the _WEBGL_compressed_texture_pvrtc_ WebGL extension. + */ +export const RGB_PVRTC_2BPPV1_Format: 35841; +/** + * RGBA compression in 4-bit mode. One block for each 4×4 pixels. + * @remarks Require support for the _WEBGL_compressed_texture_pvrtc_ WebGL extension. + */ +export const RGBA_PVRTC_4BPPV1_Format: 35842; +/** + * RGBA compression in 2-bit mode. One block for each 8×4 pixels. + * @remarks Require support for the _WEBGL_compressed_texture_pvrtc_ WebGL extension. + */ +export const RGBA_PVRTC_2BPPV1_Format: 35843; + +// ETC compressed texture formats + +/** + * @remarks Require support for the _WEBGL_compressed_texture_etc1_ (ETC1) or _WEBGL_compressed_texture_etc_ (ETC2) WebGL extension. + */ +export const RGB_ETC1_Format: 36196; +/** + * @remarks Require support for the _WEBGL_compressed_texture_etc1_ (ETC1) or _WEBGL_compressed_texture_etc_ (ETC2) WebGL extension. + */ +export const RGB_ETC2_Format: 37492; +/** + * @remarks Require support for the _WEBGL_compressed_texture_etc1_ (ETC1) or _WEBGL_compressed_texture_etc_ (ETC2) WebGL extension. + */ +export const RGBA_ETC2_EAC_Format: 37496; + +// ASTC compressed texture formats + +/** + * @remarks Require support for the _WEBGL_compressed_texture_astc_ WebGL extension. + */ +export const RGBA_ASTC_4x4_Format: 37808; +/** + * @remarks Require support for the _WEBGL_compressed_texture_astc_ WebGL extension. + */ +export const RGBA_ASTC_5x4_Format: 37809; +/** + * @remarks Require support for the _WEBGL_compressed_texture_astc_ WebGL extension. + */ +export const RGBA_ASTC_5x5_Format: 37810; +/** + * @remarks Require support for the _WEBGL_compressed_texture_astc_ WebGL extension. + */ +export const RGBA_ASTC_6x5_Format: 37811; +/** + * @remarks Require support for the _WEBGL_compressed_texture_astc_ WebGL extension. + */ +export const RGBA_ASTC_6x6_Format: 37812; +/** + * @remarks Require support for the _WEBGL_compressed_texture_astc_ WebGL extension. + */ +export const RGBA_ASTC_8x5_Format: 37813; +/** + * @remarks Require support for the _WEBGL_compressed_texture_astc_ WebGL extension. + */ +export const RGBA_ASTC_8x6_Format: 37814; +/** + * @remarks Require support for the _WEBGL_compressed_texture_astc_ WebGL extension. + */ +export const RGBA_ASTC_8x8_Format: 37815; +/** + * @remarks Require support for the _WEBGL_compressed_texture_astc_ WebGL extension. + */ +export const RGBA_ASTC_10x5_Format: 37816; +/** + * @remarks Require support for the _WEBGL_compressed_texture_astc_ WebGL extension. + */ +export const RGBA_ASTC_10x6_Format: 37817; +/** + * @remarks Require support for the _WEBGL_compressed_texture_astc_ WebGL extension. + */ +export const RGBA_ASTC_10x8_Format: 37818; +/** + * @remarks Require support for the _WEBGL_compressed_texture_astc_ WebGL extension. + */ +export const RGBA_ASTC_10x10_Format: 37819; +/** + * @remarks Require support for the _WEBGL_compressed_texture_astc_ WebGL extension. + */ +export const RGBA_ASTC_12x10_Format: 37820; +/** + * @remarks Require support for the _WEBGL_compressed_texture_astc_ WebGL extension. + */ +export const RGBA_ASTC_12x12_Format: 37821; + +// BPTC compressed texture formats + +/** + * @remarks Require support for the _EXT_texture_compression_bptc_ WebGL extension. + */ +export const RGBA_BPTC_Format: 36492; +export const RGB_BPTC_SIGNED_Format = 36494; +export const RGB_BPTC_UNSIGNED_Format = 36495; + +// RGTC compressed texture formats +export const RED_RGTC1_Format: 36283; +export const SIGNED_RED_RGTC1_Format: 36284; +export const RED_GREEN_RGTC2_Format: 36285; +export const SIGNED_RED_GREEN_RGTC2_Format: 36286; + +/** + * For use with a {@link THREE.CompressedTexture}'s {@link THREE.CompressedTexture.format | .format} property. + * @remarks Compressed Require support for correct WebGL extension. + */ +export type CompressedPixelFormat = + | typeof RGB_S3TC_DXT1_Format + | typeof RGBA_S3TC_DXT1_Format + | typeof RGBA_S3TC_DXT3_Format + | typeof RGBA_S3TC_DXT5_Format + | typeof RGB_PVRTC_4BPPV1_Format + | typeof RGB_PVRTC_2BPPV1_Format + | typeof RGBA_PVRTC_4BPPV1_Format + | typeof RGBA_PVRTC_2BPPV1_Format + | typeof RGB_ETC1_Format + | typeof RGB_ETC2_Format + | typeof RGBA_ETC2_EAC_Format + | typeof RGBA_ASTC_4x4_Format + | typeof RGBA_ASTC_5x4_Format + | typeof RGBA_ASTC_5x5_Format + | typeof RGBA_ASTC_6x5_Format + | typeof RGBA_ASTC_6x6_Format + | typeof RGBA_ASTC_8x5_Format + | typeof RGBA_ASTC_8x6_Format + | typeof RGBA_ASTC_8x8_Format + | typeof RGBA_ASTC_10x5_Format + | typeof RGBA_ASTC_10x6_Format + | typeof RGBA_ASTC_10x8_Format + | typeof RGBA_ASTC_10x10_Format + | typeof RGBA_ASTC_12x10_Format + | typeof RGBA_ASTC_12x12_Format + | typeof RGBA_BPTC_Format + | typeof RGB_BPTC_SIGNED_Format + | typeof RGB_BPTC_UNSIGNED_Format + | typeof RED_RGTC1_Format + | typeof SIGNED_RED_RGTC1_Format + | typeof RED_GREEN_RGTC2_Format + | typeof SIGNED_RED_GREEN_RGTC2_Format; + +/////////////////////////////////////////////////////////////////////////////// + +/** + * All Possible Texture Pixel Formats Modes. For any Type or SubType of Textures. + * @remarks Note that the texture must have the correct {@link THREE.Texture.type} set, as described in {@link TextureDataType}. + * @see {@link WebGLRenderingContext.texImage2D} for details. + * @see {@link PixelFormat} and {@link DepthTexturePixelFormat} and {@link CompressedPixelFormat} + * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} + */ +export type AnyPixelFormat = PixelFormat | DepthTexturePixelFormat | CompressedPixelFormat; + +/////////////////////////////////////////////////////////////////////////////// +// Loop styles for AnimationAction +export const LoopOnce: 2200; +export const LoopRepeat: 2201; +export const LoopPingPong: 2202; +export type AnimationActionLoopStyles = typeof LoopOnce | typeof LoopRepeat | typeof LoopPingPong; + +// Interpolation +export const InterpolateDiscrete: 2300; +export const InterpolateLinear: 2301; +export const InterpolateSmooth: 2302; +export type InterpolationModes = typeof InterpolateDiscrete | typeof InterpolateLinear | typeof InterpolateSmooth; + +// Interpolant ending modes +export const ZeroCurvatureEnding: 2400; +export const ZeroSlopeEnding: 2401; +export const WrapAroundEnding: 2402; +export type InterpolationEndingModes = typeof ZeroCurvatureEnding | typeof ZeroSlopeEnding | typeof WrapAroundEnding; + +// Animation blending modes +export const NormalAnimationBlendMode: 2500; +export const AdditiveAnimationBlendMode: 2501; +export type AnimationBlendMode = typeof NormalAnimationBlendMode | typeof AdditiveAnimationBlendMode; + +// Triangle Draw modes +export const TrianglesDrawMode: 0; +export const TriangleStripDrawMode: 1; +export const TriangleFanDrawMode: 2; +export type TrianglesDrawModes = typeof TrianglesDrawMode | typeof TriangleStripDrawMode | typeof TriangleFanDrawMode; + +/////////////////////////////////////////////////////////////////////////////// +// Depth packing strategies + +export const BasicDepthPacking: 3200; +export const RGBADepthPacking: 3201; +export const RGBDepthPacking: 3202; +export const RGDepthPacking: 3203; +export type DepthPackingStrategies = + | typeof BasicDepthPacking + | typeof RGBADepthPacking + | typeof RGBDepthPacking + | typeof RGDepthPacking; + +/////////////////////////////////////////////////////////////////////////////// +// Normal Map types + +export const TangentSpaceNormalMap: 0; +export const ObjectSpaceNormalMap: 1; +export type NormalMapTypes = typeof TangentSpaceNormalMap | typeof ObjectSpaceNormalMap; + +export const NoColorSpace: ""; +export const SRGBColorSpace: "srgb"; +export const LinearSRGBColorSpace: "srgb-linear"; +export type ColorSpace = + | typeof NoColorSpace + | typeof SRGBColorSpace + | typeof LinearSRGBColorSpace; + +export const LinearTransfer: "linear"; +export const SRGBTransfer: "srgb"; +export type ColorSpaceTransfer = typeof LinearTransfer | typeof SRGBTransfer; + +// Stencil Op types +export const ZeroStencilOp: 0; +export const KeepStencilOp: 7680; +export const ReplaceStencilOp: 7681; +export const IncrementStencilOp: 7682; +export const DecrementStencilOp: 7283; +export const IncrementWrapStencilOp: 34055; +export const DecrementWrapStencilOp: 34056; +export const InvertStencilOp: 5386; +export type StencilOp = + | typeof ZeroStencilOp + | typeof KeepStencilOp + | typeof ReplaceStencilOp + | typeof IncrementStencilOp + | typeof DecrementStencilOp + | typeof IncrementWrapStencilOp + | typeof DecrementWrapStencilOp + | typeof InvertStencilOp; + +// Stencil Func types +export const NeverStencilFunc: 512; +export const LessStencilFunc: 513; +export const EqualStencilFunc: 514; +export const LessEqualStencilFunc: 515; +export const GreaterStencilFunc: 516; +export const NotEqualStencilFunc: 517; +export const GreaterEqualStencilFunc: 518; +export const AlwaysStencilFunc: 519; +export type StencilFunc = + | typeof NeverStencilFunc + | typeof LessStencilFunc + | typeof EqualStencilFunc + | typeof LessEqualStencilFunc + | typeof GreaterStencilFunc + | typeof NotEqualStencilFunc + | typeof GreaterEqualStencilFunc + | typeof AlwaysStencilFunc; + +export const NeverCompare: 512; +export const LessCompare: 513; +export const EqualCompare: 514; +export const LessEqualCompare: 515; +export const GreaterCompare: 516; +export const NotEqualCompare: 517; +export const GreaterEqualCompare: 518; +export const AlwaysCompare: 519; +export type TextureComparisonFunction = + | typeof NeverCompare + | typeof LessCompare + | typeof EqualCompare + | typeof LessEqualCompare + | typeof GreaterCompare + | typeof NotEqualCompare + | typeof GreaterEqualCompare + | typeof AlwaysCompare; + +// usage types +export const StaticDrawUsage: 35044; +export const DynamicDrawUsage: 35048; +export const StreamDrawUsage: 35040; +export const StaticReadUsage: 35045; +export const DynamicReadUsage: 35049; +export const StreamReadUsage: 35041; +export const StaticCopyUsage: 35046; +export const DynamicCopyUsage: 35050; +export const StreamCopyUsage: 35042; +export type Usage = + | typeof StaticDrawUsage + | typeof DynamicDrawUsage + | typeof StreamDrawUsage + | typeof StaticReadUsage + | typeof DynamicReadUsage + | typeof StreamReadUsage + | typeof StaticCopyUsage + | typeof DynamicCopyUsage + | typeof StreamCopyUsage; + +export const GLSL1: "100"; +export const GLSL3: "300 es"; +export type GLSLVersion = typeof GLSL1 | typeof GLSL3; + +export const WebGLCoordinateSystem: 2000; +export const WebGPUCoordinateSystem: 2001; +export type CoordinateSystem = typeof WebGLCoordinateSystem | typeof WebGPUCoordinateSystem; + +/////////////////////////////////////////////////////////////////////////////// +// Texture - Internal Pixel Formats + +/** + * For use with a texture's {@link THREE.Texture.internalFormat} property, these define how elements of a {@link THREE.Texture}, or texels, are stored on the GPU. + * - `R8` stores the red component on 8 bits. + * - `R8_SNORM` stores the red component on 8 bits. The component is stored as normalized. + * - `R8I` stores the red component on 8 bits. The component is stored as an integer. + * - `R8UI` stores the red component on 8 bits. The component is stored as an unsigned integer. + * - `R16I` stores the red component on 16 bits. The component is stored as an integer. + * - `R16UI` stores the red component on 16 bits. The component is stored as an unsigned integer. + * - `R16F` stores the red component on 16 bits. The component is stored as floating point. + * - `R32I` stores the red component on 32 bits. The component is stored as an integer. + * - `R32UI` stores the red component on 32 bits. The component is stored as an unsigned integer. + * - `R32F` stores the red component on 32 bits. The component is stored as floating point. + * - `RG8` stores the red and green components on 8 bits each. + * - `RG8_SNORM` stores the red and green components on 8 bits each. Every component is stored as normalized. + * - `RG8I` stores the red and green components on 8 bits each. Every component is stored as an integer. + * - `RG8UI` stores the red and green components on 8 bits each. Every component is stored as an unsigned integer. + * - `RG16I` stores the red and green components on 16 bits each. Every component is stored as an integer. + * - `RG16UI` stores the red and green components on 16 bits each. Every component is stored as an unsigned integer. + * - `RG16F` stores the red and green components on 16 bits each. Every component is stored as floating point. + * - `RG32I` stores the red and green components on 32 bits each. Every component is stored as an integer. + * - `RG32UI` stores the red and green components on 32 bits. Every component is stored as an unsigned integer. + * - `RG32F` stores the red and green components on 32 bits. Every component is stored as floating point. + * - `RGB8` stores the red, green, and blue components on 8 bits each. RGB8_SNORM` stores the red, green, and blue components on 8 bits each. Every component is stored as normalized. + * - `RGB8I` stores the red, green, and blue components on 8 bits each. Every component is stored as an integer. + * - `RGB8UI` stores the red, green, and blue components on 8 bits each. Every component is stored as an unsigned integer. + * - `RGB16I` stores the red, green, and blue components on 16 bits each. Every component is stored as an integer. + * - `RGB16UI` stores the red, green, and blue components on 16 bits each. Every component is stored as an unsigned integer. + * - `RGB16F` stores the red, green, and blue components on 16 bits each. Every component is stored as floating point + * - `RGB32I` stores the red, green, and blue components on 32 bits each. Every component is stored as an integer. + * - `RGB32UI` stores the red, green, and blue components on 32 bits each. Every component is stored as an unsigned integer. + * - `RGB32F` stores the red, green, and blue components on 32 bits each. Every component is stored as floating point + * - `R11F_G11F_B10F` stores the red, green, and blue components respectively on 11 bits, 11 bits, and 10bits. Every component is stored as floating point. + * - `RGB565` stores the red, green, and blue components respectively on 5 bits, 6 bits, and 5 bits. + * - `RGB9_E5` stores the red, green, and blue components on 9 bits each. + * - `RGBA8` stores the red, green, blue, and alpha components on 8 bits each. + * - `RGBA8_SNORM` stores the red, green, blue, and alpha components on 8 bits. Every component is stored as normalized. + * - `RGBA8I` stores the red, green, blue, and alpha components on 8 bits each. Every component is stored as an integer. + * - `RGBA8UI` stores the red, green, blue, and alpha components on 8 bits. Every component is stored as an unsigned integer. + * - `RGBA16I` stores the red, green, blue, and alpha components on 16 bits. Every component is stored as an integer. + * - `RGBA16UI` stores the red, green, blue, and alpha components on 16 bits. Every component is stored as an unsigned integer. + * - `RGBA16F` stores the red, green, blue, and alpha components on 16 bits. Every component is stored as floating point. + * - `RGBA32I` stores the red, green, blue, and alpha components on 32 bits. Every component is stored as an integer. + * - `RGBA32UI` stores the red, green, blue, and alpha components on 32 bits. Every component is stored as an unsigned integer. + * - `RGBA32F` stores the red, green, blue, and alpha components on 32 bits. Every component is stored as floating point. + * - `RGB5_A1` stores the red, green, blue, and alpha components respectively on 5 bits, 5 bits, 5 bits, and 1 bit. + * - `RGB10_A2` stores the red, green, blue, and alpha components respectively on 10 bits, 10 bits, 10 bits and 2 bits. + * - `RGB10_A2UI` stores the red, green, blue, and alpha components respectively on 10 bits, 10 bits, 10 bits and 2 bits. Every component is stored as an unsigned integer. + * - `SRGB8` stores the red, green, and blue components on 8 bits each. + * - `SRGB8_ALPHA8` stores the red, green, blue, and alpha components on 8 bits each. + * - `DEPTH_COMPONENT16` stores the depth component on 16bits. + * - `DEPTH_COMPONENT24` stores the depth component on 24bits. + * - `DEPTH_COMPONENT32F` stores the depth component on 32bits. The component is stored as floating point. + * - `DEPTH24_STENCIL8` stores the depth, and stencil components respectively on 24 bits and 8 bits. The stencil component is stored as an unsigned integer. + * - `DEPTH32F_STENCIL8` stores the depth, and stencil components respectively on 32 bits and 8 bits. The depth component is stored as floating point, and the stencil component as an unsigned integer. + * @remark Note that the texture must have the correct {@link THREE.Texture.type} set, as well as the correct {@link THREE.Texture.format}. + * @see {@link WebGLRenderingContext.texImage2D} and {@link WebGLRenderingContext.texImage3D} for more details regarding the possible combination + * of {@link THREE.Texture.format}, {@link THREE.Texture.internalFormat}, and {@link THREE.Texture.type}. + * @see {@link https://registry.khronos.org/webgl/specs/latest/2.0/ | WebGL2 Specification} and + * {@link https://registry.khronos.org/OpenGL/specs/es/3.0/es_spec_3.0.pdf | OpenGL ES 3.0 Specification} For more in-depth information regarding internal formats. + */ +export type PixelFormatGPU = + | "ALPHA" + | "RGB" + | "RGBA" + | "LUMINANCE" + | "LUMINANCE_ALPHA" + | "RED_INTEGER" + | "R8" + | "R8_SNORM" + | "R8I" + | "R8UI" + | "R16I" + | "R16UI" + | "R16F" + | "R32I" + | "R32UI" + | "R32F" + | "RG8" + | "RG8_SNORM" + | "RG8I" + | "RG8UI" + | "RG16I" + | "RG16UI" + | "RG16F" + | "RG32I" + | "RG32UI" + | "RG32F" + | "RGB565" + | "RGB8" + | "RGB8_SNORM" + | "RGB8I" + | "RGB8UI" + | "RGB16I" + | "RGB16UI" + | "RGB16F" + | "RGB32I" + | "RGB32UI" + | "RGB32F" + | "RGB9_E5" + | "SRGB8" + | "R11F_G11F_B10F" + | "RGBA4" + | "RGBA8" + | "RGBA8_SNORM" + | "RGBA8I" + | "RGBA8UI" + | "RGBA16I" + | "RGBA16UI" + | "RGBA16F" + | "RGBA32I" + | "RGBA32UI" + | "RGBA32F" + | "RGB5_A1" + | "RGB10_A2" + | "RGB10_A2UI" + | "SRGB8_ALPHA8" + | "SRGB8" + | "DEPTH_COMPONENT16" + | "DEPTH_COMPONENT24" + | "DEPTH_COMPONENT32F" + | "DEPTH24_STENCIL8" + | "DEPTH32F_STENCIL8"; diff --git a/src-testing/src/core/BufferAttribute.d.ts b/src-testing/src/core/BufferAttribute.d.ts new file mode 100644 index 000000000..01e8e882d --- /dev/null +++ b/src-testing/src/core/BufferAttribute.d.ts @@ -0,0 +1,622 @@ +import { AttributeGPUType, Usage } from "../constants.js"; +import { Matrix3 } from "../math/Matrix3.js"; +import { Matrix4 } from "../math/Matrix4.js"; + +export type TypedArray = + | Int8Array + | Uint8Array + | Uint8ClampedArray + | Int16Array + | Uint16Array + | Int32Array + | Uint32Array + | Float32Array + | Float64Array; + +export interface BufferAttributeJSON { + itemSize: number; + type: string; + array: number[]; + normalized: boolean; + + name?: string; + usage?: Usage; +} + +/** + * This class stores data for an attribute (such as vertex positions, face indices, normals, colors, UVs, and any custom attributes ) + * associated with a {@link THREE.BufferGeometry | BufferGeometry}, which allows for more efficient passing of data to the GPU + * @remarks + * When working with _vector-like_ data, the _`.fromBufferAttribute( attribute, index )`_ helper methods on + * {@link THREE.Vector2.fromBufferAttribute | Vector2}, + * {@link THREE.Vector3.fromBufferAttribute | Vector3}, + * {@link THREE.Vector4.fromBufferAttribute | Vector4}, and + * {@link THREE.Color.fromBufferAttribute | Color} classes may be helpful. + * @see {@link THREE.BufferGeometry | BufferGeometry} for details and a usage examples. + * @see Example: {@link https://threejs.org/examples/#webgl_buffergeometry | WebGL / BufferGeometry - Clean up Memory} + * @see {@link https://threejs.org/docs/index.html#api/en/core/BufferAttribute | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/BufferAttribute.js | Source} + */ +export class BufferAttribute { + /** + * This creates a new {@link THREE.GLBufferAttribute | GLBufferAttribute} object. + * @param array Must be a `TypedArray`. Used to instantiate the buffer. + * This array should have `itemSize * numVertices` elements, where numVertices is the number of vertices in the associated {@link THREE.BufferGeometry | BufferGeometry}. + * @param itemSize the number of values of the {@link array} that should be associated with a particular vertex. + * For instance, if this attribute is storing a 3-component vector (such as a _position_, _normal_, or _color_), + * then itemSize should be `3`. + * @param normalized Applies to integer data only. + * Indicates how the underlying data in the buffer maps to the values in the GLSL code. + * For instance, if {@link array} is an instance of `UInt16Array`, and {@link normalized} is true, + * the values `0` - `+65535` in the array data will be mapped to `0.0f` - `+1.0f` in the GLSL attribute. + * An `Int16Array` (signed) would map from `-32768` - `+32767` to `-1.0f` - `+1.0f`. + * If normalized is false, the values will be converted to floats unmodified, + * i.e. `32767` becomes `32767.0f`. + * Default `false`. + * @throws `TypeError` When the {@link array} is not a `TypedArray`; + */ + constructor(array: TypedArray, itemSize: number, normalized?: boolean); + + /** + * Optional name for this attribute instance. + * @defaultValue '' + */ + name: string; + + /** + * The {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray | TypedArray} holding data stored in the buffer. + * @returns `TypedArray` + */ + array: TypedArray; + + /** + * The length of vectors that are being stored in the {@link BufferAttribute.array | array}. + * @remarks Expects a `Integer` + */ + itemSize: number; + + /** + * Defines the intended usage pattern of the data store for optimization purposes. + * Corresponds to the {@link BufferAttribute.usage | usage} parameter of + * {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/bufferData | WebGLRenderingContext.bufferData}. + * @remarks + * After the initial use of a buffer, its usage cannot be changed. Instead, instantiate a new one and set the desired usage before the next render. + * @see {@link https://threejs.org/docs/index.html#api/en/constants/BufferAttributeUsage | Buffer Attribute Usage Constants} for all possible values. + * @see {@link BufferAttribute.setUsage | setUsage} + * @defaultValue {@link THREE.StaticDrawUsage | THREE.StaticDrawUsage}. + */ + usage: Usage; + + /** + * Configures the bound GPU type for use in shaders. Either {@link FloatType} or {@link IntType}, default is {@link FloatType}. + * + * Note: this only has an effect for integer arrays and is not configurable for float arrays. For lower precision + * float types, see https://threejs.org/docs/#api/en/core/bufferAttributeTypes/BufferAttributeTypes. + */ + gpuType: AttributeGPUType; + + /** + * This can be used to only update some components of stored vectors (for example, just the component related to + * color). Use the {@link .addUpdateRange} function to add ranges to this array. + */ + updateRanges: Array<{ + /** + * Position at which to start update. + */ + start: number; + /** + * The number of components to update. + */ + count: number; + }>; + + /** + * A version number, incremented every time the {@link BufferAttribute.needsUpdate | needsUpdate} property is set to true. + * @remarks Expects a `Integer` + * @defaultValue `0` + */ + version: number; + + /** + * Indicates how the underlying data in the buffer maps to the values in the GLSL shader code. + * @see `constructor` above for details. + * @defaultValue `false` + */ + normalized: boolean; + + /** + * Represents the number of items this buffer attribute stores. It is internally computed by dividing the + * {@link BufferAttribute.array | array}'s length by the {@link BufferAttribute.itemSize | itemSize}. Read-only + * property. + */ + readonly count: number; + + /** + * Flag to indicate that this attribute has changed and should be re-sent to the GPU. + * Set this to true when you modify the value of the array. + * @remarks Setting this to true also increments the {@link BufferAttribute.version | version}. + * @remarks _set-only property_. + */ + set needsUpdate(value: boolean); + + /** + * Read-only flag to check if a given object is of type {@link BufferAttribute}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isBufferAttribute: true; + + /** + * A callback function that is executed after the Renderer has transferred the attribute array data to the GPU. + */ + onUploadCallback: () => void; + + /** + * Sets the value of the {@link onUploadCallback} property. + * @see Example: {@link https://threejs.org/examples/#webgl_buffergeometry | WebGL / BufferGeometry} this is used to free memory after the buffer has been transferred to the GPU. + * @see {@link onUploadCallback} + * @param callback function that is executed after the Renderer has transferred the attribute array data to the GPU. + */ + onUpload(callback: () => void): this; + + /** + * Set {@link BufferAttribute.usage | usage} + * @remarks + * After the initial use of a buffer, its usage cannot be changed. Instead, instantiate a new one and set the desired usage before the next render. + * @see {@link https://threejs.org/docs/index.html#api/en/constants/BufferAttributeUsage | Buffer Attribute Usage Constants} for all possible values. + * @see {@link BufferAttribute.usage | usage} + * @param value Corresponds to the {@link BufferAttribute.usage | usage} parameter of + * {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/bufferData | WebGLRenderingContext.bufferData}. + */ + setUsage(usage: Usage): this; + + /** + * Adds a range of data in the data array to be updated on the GPU. Adds an object describing the range to the + * {@link .updateRanges} array. + */ + addUpdateRange(start: number, count: number): void; + + /** + * Clears the {@link .updateRanges} array. + */ + clearUpdateRanges(): void; + + /** + * @returns a copy of this {@link BufferAttribute}. + */ + clone(): BufferAttribute; + + /** + * Copies another {@link BufferAttribute} to this {@link BufferAttribute}. + * @param bufferAttribute + */ + copy(source: BufferAttribute): this; + + /** + * Copy a vector from bufferAttribute[index2] to {@link BufferAttribute.array | array}[index1]. + * @param index1 + * @param bufferAttribute + * @param index2 + */ + copyAt(index1: number, attribute: BufferAttribute, index2: number): this; + + /** + * Copy the array given here (which can be a normal array or `TypedArray`) into {@link BufferAttribute.array | array}. + * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set | TypedArray.set} for notes on requirements if copying a `TypedArray`. + */ + copyArray(array: ArrayLike): this; + + /** + * Applies matrix {@link Matrix3 | m} to every Vector3 element of this {@link BufferAttribute}. + * @param m + */ + applyMatrix3(m: Matrix3): this; + + /** + * Applies matrix {@link Matrix4 | m} to every Vector3 element of this {@link BufferAttribute}. + * @param m + */ + applyMatrix4(m: Matrix4): this; + + /** + * Applies normal matrix {@link Matrix3 | m} to every Vector3 element of this {@link BufferAttribute}. + * @param m + */ + applyNormalMatrix(m: Matrix3): this; + + /** + * Applies matrix {@link Matrix4 | m} to every Vector3 element of this {@link BufferAttribute}, interpreting the elements as a direction vectors. + * @param m + */ + transformDirection(m: Matrix4): this; + + /** + * Calls {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set | TypedArray.set}( {@link value}, {@link offset} ) + * on the {@link BufferAttribute.array | array}. + * @param value {@link Array | Array} or `TypedArray` from which to copy values. + * @param offset index of the {@link BufferAttribute.array | array} at which to start copying. Expects a `Integer`. Default `0`. + * @throws `RangeError` When {@link offset} is negative or is too large. + */ + set(value: ArrayLike | ArrayBufferView, offset?: number): this; + + /** + * Returns the given component of the vector at the given index. + */ + getComponent(index: number, component: number): number; + + /** + * Sets the given component of the vector at the given index. + */ + setComponent(index: number, component: number, value: number): void; + + /** + * Returns the x component of the vector at the given index. + * @param index Expects a `Integer` + */ + getX(index: number): number; + + /** + * Sets the x component of the vector at the given index. + * @param index Expects a `Integer` + * @param x + */ + setX(index: number, x: number): this; + + /** + * Returns the y component of the vector at the given index. + * @param index Expects a `Integer` + */ + getY(index: number): number; + + /** + * Sets the y component of the vector at the given index. + * @param index Expects a `Integer` + * @param y + */ + setY(index: number, y: number): this; + + /** + * Returns the z component of the vector at the given index. + * @param index Expects a `Integer` + */ + getZ(index: number): number; + + /** + * Sets the z component of the vector at the given index. + * @param index Expects a `Integer` + * @param z + */ + setZ(index: number, z: number): this; + + /** + * Returns the w component of the vector at the given index. + * @param index Expects a `Integer` + */ + getW(index: number): number; + + /** + * Sets the w component of the vector at the given index. + * @param index Expects a `Integer` + * @param w + */ + setW(index: number, z: number): this; + + /** + * Sets the x and y components of the vector at the given index. + * @param index Expects a `Integer` + * @param x + * @param y + */ + setXY(index: number, x: number, y: number): this; + + /** + * Sets the x, y and z components of the vector at the given index. + * @param index Expects a `Integer` + * @param x + * @param y + * @param z + */ + setXYZ(index: number, x: number, y: number, z: number): this; + + /** + * Sets the x, y, z and w components of the vector at the given index. + * @param index Expects a `Integer` + * @param x + * @param y + * @param z + * @param w + */ + setXYZW(index: number, x: number, y: number, z: number, w: number): this; + + /** + * Convert this object to three.js to the `data.attributes` part of {@link https://github.com/mrdoob/three.js/wiki/JSON-Geometry-format-4 | JSON Geometry format v4}, + */ + toJSON(): BufferAttributeJSON; +} + +/** + * A {@link THREE.BufferAttribute | BufferAttribute} for {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Int8Array: Int8Array} + * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray#typedarray_objects | TypedArray} + * @see {@link THREE.BufferAttribute | BufferAttribute} for details and for inherited methods and properties. + * @see {@link https://threejs.org/docs/index.html#api/en/core/bufferAttributeTypes/BufferAttributeTypes | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/BufferAttribute.js | Source} + */ +export class Int8BufferAttribute extends BufferAttribute { + /** + * This creates a new {@link THREE.Int8BufferAttribute | Int8BufferAttribute} object. + * @param array This can be a typed or untyped (normal) array or an integer length. An array value will be converted to `Int8Array`. + * If a length is given a new `TypedArray` will created, initialized with all elements set to zero. + * @param itemSize the number of values of the {@link array} that should be associated with a particular vertex. + * For instance, if this attribute is storing a 3-component vector (such as a _position_, _normal_, or _color_), + * then itemSize should be `3`. + * @param normalized Applies to integer data only. + * Indicates how the underlying data in the buffer maps to the values in the GLSL code. + * For instance, if {@link array} is an instance of `UInt16Array`, and {@link normalized} is true, + * the values `0` - `+65535` in the array data will be mapped to `0.0f` - `+1.0f` in the GLSL attribute. + * An `Int16Array` (signed) would map from `-32768` - `+32767` to `-1.0f` - `+1.0f`. + * If normalized is false, the values will be converted to floats unmodified, + * i.e. `32767` becomes `32767.0f`. + * Default `false`. + */ + constructor( + array: Iterable | ArrayLike | ArrayBuffer | number, + itemSize: number, + normalized?: boolean, + ); +} + +/** + * A {@link THREE.BufferAttribute | BufferAttribute} for {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array: Uint8Array} + * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray#typedarray_objects | TypedArray} + * @see {@link THREE.BufferAttribute | BufferAttribute} for details and for inherited methods and properties. + * @see {@link https://threejs.org/docs/index.html#api/en/core/bufferAttributeTypes/BufferAttributeTypes | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/BufferAttribute.js | Source} + */ +export class Uint8BufferAttribute extends BufferAttribute { + /** + * This creates a new {@link THREE.Uint8BufferAttribute | Uint8BufferAttribute} object. + * @param array This can be a typed or untyped (normal) array or an integer length. An array value will be converted to `Uint8Array`. + * If a length is given a new `TypedArray` will created, initialized with all elements set to zero. + * @param itemSize the number of values of the {@link array} that should be associated with a particular vertex. + * For instance, if this attribute is storing a 3-component vector (such as a _position_, _normal_, or _color_), + * then itemSize should be `3`. + * @param normalized Applies to integer data only. + * Indicates how the underlying data in the buffer maps to the values in the GLSL code. + * For instance, if {@link array} is an instance of `UInt16Array`, and {@link normalized} is true, + * the values `0` - `+65535` in the array data will be mapped to `0.0f` - `+1.0f` in the GLSL attribute. + * An `Int16Array` (signed) would map from `-32768` - `+32767` to `-1.0f` - `+1.0f`. + * If normalized is false, the values will be converted to floats unmodified, + * i.e. `32767` becomes `32767.0f`. + * Default `false`. + * @see {@link THREE.BufferAttribute | BufferAttribute} + */ + constructor( + array: Iterable | ArrayLike | ArrayBuffer | number, + itemSize: number, + normalized?: boolean, + ); +} + +/** + * A {@link THREE.BufferAttribute | BufferAttribute} for {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8ClampedArray: Uint8ClampedArray} + * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray#typedarray_objects | TypedArray} + * @see {@link THREE.BufferAttribute | BufferAttribute} for details and for inherited methods and properties. + * @see {@link https://threejs.org/docs/index.html#api/en/core/bufferAttributeTypes/BufferAttributeTypes | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/BufferAttribute.js | Source} + */ +export class Uint8ClampedBufferAttribute extends BufferAttribute { + /** + * This creates a new {@link THREE.Uint8ClampedBufferAttribute | Uint8ClampedBufferAttribute} object. + * @param array This can be a typed or untyped (normal) array or an integer length. An array value will be converted to `Uint8ClampedArray`. + * If a length is given a new `TypedArray` will created, initialized with all elements set to zero. + * @param itemSize the number of values of the {@link array} that should be associated with a particular vertex. + * For instance, if this attribute is storing a 3-component vector (such as a _position_, _normal_, or _color_), + * then itemSize should be `3`. + * @param normalized Applies to integer data only. + * Indicates how the underlying data in the buffer maps to the values in the GLSL code. + * For instance, if {@link array} is an instance of `UInt16Array`, and {@link normalized} is true, + * the values `0` - `+65535` in the array data will be mapped to `0.0f` - `+1.0f` in the GLSL attribute. + * An `Int16Array` (signed) would map from `-32768` - `+32767` to `-1.0f` - `+1.0f`. + * If normalized is false, the values will be converted to floats unmodified, + * i.e. `32767` becomes `32767.0f`. + * Default `false`. + * @see {@link THREE.BufferAttribute | BufferAttribute} + */ + constructor( + array: Iterable | ArrayLike | ArrayBuffer | number, + itemSize: number, + normalized?: boolean, + ); +} + +/** + * A {@link THREE.BufferAttribute | BufferAttribute} for {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Int16Array: Int16Array} + * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray#typedarray_objects | TypedArray} + * @see {@link THREE.BufferAttribute | BufferAttribute} for details and for inherited methods and properties. + * @see {@link https://threejs.org/docs/index.html#api/en/core/bufferAttributeTypes/BufferAttributeTypes | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/BufferAttribute.js | Source} + */ +export class Int16BufferAttribute extends BufferAttribute { + /** + * This creates a new {@link THREE.Int16BufferAttribute | Int16BufferAttribute} object. + * @param array This can be a typed or untyped (normal) array or an integer length. An array value will be converted to `Int16Array`. + * If a length is given a new `TypedArray` will created, initialized with all elements set to zero. + * @param itemSize the number of values of the {@link array} that should be associated with a particular vertex. + * For instance, if this attribute is storing a 3-component vector (such as a _position_, _normal_, or _color_), + * then itemSize should be `3`. + * @param normalized Applies to integer data only. + * Indicates how the underlying data in the buffer maps to the values in the GLSL code. + * For instance, if {@link array} is an instance of `UInt16Array`, and {@link normalized} is true, + * the values `0` - `+65535` in the array data will be mapped to `0.0f` - `+1.0f` in the GLSL attribute. + * An `Int16Array` (signed) would map from `-32768` - `+32767` to `-1.0f` - `+1.0f`. + * If normalized is false, the values will be converted to floats unmodified, + * i.e. `32767` becomes `32767.0f`. + * Default `false`. + * @see {@link THREE.BufferAttribute | BufferAttribute} + */ + constructor( + array: Iterable | ArrayLike | ArrayBuffer | number, + itemSize: number, + normalized?: boolean, + ); +} + +/** + * A {@link THREE.BufferAttribute | BufferAttribute} for {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint16Array: Uint16Array} + * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray#typedarray_objects | TypedArray} + * @see {@link THREE.BufferAttribute | BufferAttribute} for details and for inherited methods and properties. + * @see {@link https://threejs.org/docs/index.html#api/en/core/bufferAttributeTypes/BufferAttributeTypes | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/BufferAttribute.js | Source} + */ +export class Uint16BufferAttribute extends BufferAttribute { + /** + * This creates a new {@link THREE.Uint16BufferAttribute | Uint16BufferAttribute} object. + * @param array This can be a typed or untyped (normal) array or an integer length. An array value will be converted to `Uint16Array`. + * If a length is given a new `TypedArray` will created, initialized with all elements set to zero. + * @param itemSize the number of values of the {@link array} that should be associated with a particular vertex. + * For instance, if this attribute is storing a 3-component vector (such as a _position_, _normal_, or _color_), + * then itemSize should be `3`. + * @param normalized Applies to integer data only. + * Indicates how the underlying data in the buffer maps to the values in the GLSL code. + * For instance, if {@link array} is an instance of `UInt16Array`, and {@link normalized} is true, + * the values `0` - `+65535` in the array data will be mapped to `0.0f` - `+1.0f` in the GLSL attribute. + * An `Int16Array` (signed) would map from `-32768` - `+32767` to `-1.0f` - `+1.0f`. + * If normalized is false, the values will be converted to floats unmodified, + * i.e. `32767` becomes `32767.0f`. + * Default `false`. + * @see {@link THREE.BufferAttribute | BufferAttribute} + */ + constructor( + array: Iterable | ArrayLike | ArrayBuffer | number, + itemSize: number, + normalized?: boolean, + ); +} + +/** + * A {@link THREE.BufferAttribute | BufferAttribute} for {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Int32Array: Int32Array} + * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray#typedarray_objects | TypedArray} + * @see {@link THREE.BufferAttribute | BufferAttribute} for details and for inherited methods and properties. + * @see {@link https://threejs.org/docs/index.html#api/en/core/bufferAttributeTypes/BufferAttributeTypes | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/BufferAttribute.js | Source} + */ +export class Int32BufferAttribute extends BufferAttribute { + /** + * This creates a new {@link THREE.Int32BufferAttribute | Int32BufferAttribute} object. + * @param array This can be a typed or untyped (normal) array or an integer length. An array value will be converted to `Int32Array`. + * If a length is given a new `TypedArray` will created, initialized with all elements set to zero. + * @param itemSize the number of values of the {@link array} that should be associated with a particular vertex. + * For instance, if this attribute is storing a 3-component vector (such as a _position_, _normal_, or _color_), + * then itemSize should be `3`. + * @param normalized Applies to integer data only. + * Indicates how the underlying data in the buffer maps to the values in the GLSL code. + * For instance, if {@link array} is an instance of `UInt16Array`, and {@link normalized} is true, + * the values `0` - `+65535` in the array data will be mapped to `0.0f` - `+1.0f` in the GLSL attribute. + * An `Int16Array` (signed) would map from `-32768` - `+32767` to `-1.0f` - `+1.0f`. + * If normalized is false, the values will be converted to floats unmodified, + * i.e. `32767` becomes `32767.0f`. + * Default `false`. + * @see {@link THREE.BufferAttribute | BufferAttribute} + */ + constructor( + array: Iterable | ArrayLike | ArrayBuffer | number, + itemSize: number, + normalized?: boolean, + ); +} + +/** + * A {@link THREE.BufferAttribute | BufferAttribute} for {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint32Array: Uint32Array} + * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray#typedarray_objects | TypedArray} + * @see {@link THREE.BufferAttribute | BufferAttribute} for details and for inherited methods and properties. + * @see {@link https://threejs.org/docs/index.html#api/en/core/bufferAttributeTypes/BufferAttributeTypes | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/BufferAttribute.js | Source} + */ +export class Uint32BufferAttribute extends BufferAttribute { + /** + * This creates a new {@link THREE.Uint32BufferAttribute | Uint32BufferAttribute} object. + * @param array This can be a typed or untyped (normal) array or an integer length. An array value will be converted to `Uint32Array`. + * If a length is given a new `TypedArray` will created, initialized with all elements set to zero. + * @param itemSize the number of values of the {@link array} that should be associated with a particular vertex. + * For instance, if this attribute is storing a 3-component vector (such as a _position_, _normal_, or _color_), + * then itemSize should be `3`. + * @param normalized Applies to integer data only. + * Indicates how the underlying data in the buffer maps to the values in the GLSL code. + * For instance, if {@link array} is an instance of `UInt16Array`, and {@link normalized} is true, + * the values `0` - `+65535` in the array data will be mapped to `0.0f` - `+1.0f` in the GLSL attribute. + * An `Int16Array` (signed) would map from `-32768` - `+32767` to `-1.0f` - `+1.0f`. + * If normalized is false, the values will be converted to floats unmodified, + * i.e. `32767` becomes `32767.0f`. + * Default `false`. + * @see {@link THREE.BufferAttribute | BufferAttribute} + */ + constructor( + array: Iterable | ArrayLike | ArrayBuffer | number, + itemSize: number, + normalized?: boolean, + ); +} + +/** + * A {@link THREE.BufferAttribute | BufferAttribute} for {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint16Array: Uint16Array} + * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray#typedarray_objects | TypedArray} + * @see {@link THREE.BufferAttribute | BufferAttribute} for details and for inherited methods and properties. + * @see {@link https://threejs.org/docs/index.html#api/en/core/bufferAttributeTypes/BufferAttributeTypes | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/BufferAttribute.js | Source} + */ +export class Float16BufferAttribute extends BufferAttribute { + /** + * This creates a new {@link THREE.Float16BufferAttribute | Float16BufferAttribute} object. + * @param array This can be a typed or untyped (normal) array or an integer length. An array value will be converted to `Uint16Array`. + * If a length is given a new `TypedArray` will created, initialized with all elements set to zero. + * @param itemSize the number of values of the {@link array} that should be associated with a particular vertex. + * For instance, if this attribute is storing a 3-component vector (such as a _position_, _normal_, or _color_), + * then itemSize should be `3`. + * @param normalized Applies to integer data only. + * Indicates how the underlying data in the buffer maps to the values in the GLSL code. + * For instance, if {@link array} is an instance of `UInt16Array`, and {@link normalized} is true, + * the values `0` - `+65535` in the array data will be mapped to `0.0f` - `+1.0f` in the GLSL attribute. + * An `Int16Array` (signed) would map from `-32768` - `+32767` to `-1.0f` - `+1.0f`. + * If normalized is false, the values will be converted to floats unmodified, + * i.e. `32767` becomes `32767.0f`. + * Default `false`. + * @see {@link THREE.BufferAttribute | BufferAttribute} + */ + constructor( + array: Iterable | ArrayLike | ArrayBuffer | number, + itemSize: number, + normalized?: boolean, + ); +} + +/** + * A {@link THREE.BufferAttribute | BufferAttribute} for {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float32Array: Float32Array} + * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray#typedarray_objects | TypedArray} + * @see {@link THREE.BufferAttribute | BufferAttribute} for details and for inherited methods and properties. + * @see {@link https://threejs.org/docs/index.html#api/en/core/bufferAttributeTypes/BufferAttributeTypes | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/BufferAttribute.js | Source} + */ +export class Float32BufferAttribute extends BufferAttribute { + /** + * This creates a new {@link THREE.Float32BufferAttribute | Float32BufferAttribute} object. + * @param array This can be a typed or untyped (normal) array or an integer length. An array value will be converted to `Float32Array`. + * If a length is given a new `TypedArray` will created, initialized with all elements set to zero. + * @param itemSize the number of values of the {@link array} that should be associated with a particular vertex. + * For instance, if this attribute is storing a 3-component vector (such as a _position_, _normal_, or _color_), + * then itemSize should be `3`. + * @param normalized Applies to integer data only. + * Indicates how the underlying data in the buffer maps to the values in the GLSL code. + * For instance, if {@link array} is an instance of `UInt16Array`, and {@link normalized} is true, + * the values `0` - `+65535` in the array data will be mapped to `0.0f` - `+1.0f` in the GLSL attribute. + * An `Int16Array` (signed) would map from `-32768` - `+32767` to `-1.0f` - `+1.0f`. + * If normalized is false, the values will be converted to floats unmodified, + * i.e. `32767` becomes `32767.0f`. + * Default `false`. + * @see {@link THREE.BufferAttribute | BufferAttribute} + */ + constructor( + array: Iterable | ArrayLike | ArrayBuffer | number, + itemSize: number, + normalized?: boolean, + ); +} diff --git a/src-testing/src/core/BufferGeometry.d.ts b/src-testing/src/core/BufferGeometry.d.ts new file mode 100644 index 000000000..516d5f765 --- /dev/null +++ b/src-testing/src/core/BufferGeometry.d.ts @@ -0,0 +1,433 @@ +import { Box3 } from "../math/Box3.js"; +import { Matrix4 } from "../math/Matrix4.js"; +import { Quaternion } from "../math/Quaternion.js"; +import { Sphere } from "../math/Sphere.js"; +import { Vector2 } from "../math/Vector2.js"; +import { Vector3, Vector3Tuple } from "../math/Vector3.js"; +import IndirectStorageBufferAttribute from "../renderers/common/IndirectStorageBufferAttribute.js"; +import { BufferAttribute, BufferAttributeJSON } from "./BufferAttribute.js"; +import { EventDispatcher } from "./EventDispatcher.js"; +import { GLBufferAttribute } from "./GLBufferAttribute.js"; +import { InterleavedBufferAttribute } from "./InterleavedBufferAttribute.js"; + +export type NormalBufferAttributes = Record; +export type NormalOrGLBufferAttributes = Record< + string, + BufferAttribute | InterleavedBufferAttribute | GLBufferAttribute +>; + +export interface BufferGeometryJSON { + metadata?: { version: number; type: string; generator: string }; + + uuid: string; + type: string; + + name?: string; + userData?: Record; + + data?: { + attributes: Record; + + index?: { type: string; array: number[] }; + + morphAttributes?: Record; + morphTargetsRelative?: boolean; + + groups?: GeometryGroup[]; + + boundingSphere?: { center: Vector3Tuple; radius: number }; + }; +} + +export interface GeometryGroup { + /** + * Specifies the first element in this draw call – the first vertex for non-indexed geometry, otherwise the first triangle index. + * @remarks Expects a `Integer` + */ + start: number; + /** + * Specifies how many vertices (or indices) are included. + * @remarks Expects a `Integer` + */ + count: number; + /** + * Specifies the material array index to use. + * @remarks Expects a `Integer` + */ + materialIndex?: number | undefined; +} + +/** + * A representation of mesh, line, or point geometry + * Includes vertex positions, face indices, normals, colors, UVs, and custom attributes within buffers, reducing the cost of passing all this data to the GPU. + * @remarks + * To read and edit data in BufferGeometry attributes, see {@link THREE.BufferAttribute | BufferAttribute} documentation. + * @example + * ```typescript + * const geometry = new THREE.BufferGeometry(); + * + * // create a simple square shape. We duplicate the top left and bottom right + * // vertices because each vertex needs to appear once per triangle. + * const vertices = new Float32Array( [ + * -1.0, -1.0, 1.0, // v0 + * 1.0, -1.0, 1.0, // v1 + * 1.0, 1.0, 1.0, // v2 + * + * 1.0, 1.0, 1.0, // v3 + * -1.0, 1.0, 1.0, // v4 + * -1.0, -1.0, 1.0 // v5 + * ] ); + * + * // itemSize = 3 because there are 3 values (components) per vertex + * geometry.setAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) ); + * const material = new THREE.MeshBasicMaterial( { color: 0xff0000 } ); + * const mesh = new THREE.Mesh( geometry, material ); + * ``` + * @example + * ```typescript + * const geometry = new THREE.BufferGeometry(); + * + * const vertices = new Float32Array( [ + * -1.0, -1.0, 1.0, // v0 + * 1.0, -1.0, 1.0, // v1 + * 1.0, 1.0, 1.0, // v2 + * -1.0, 1.0, 1.0, // v3 + * ] ); + * geometry.setAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) ); + * + * const indices = [ + * 0, 1, 2, + * 2, 3, 0, + * ]; + * + * geometry.setIndex( indices ); + * geometry.setAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) ); + * + * const material = new THREE.MeshBasicMaterial( { color: 0xff0000 } ); + * const mesh = new THREE.Mesh( geometry, material ); + * ``` + * @see Example: {@link https://threejs.org/examples/#webgl_buffergeometry | Mesh with non-indexed faces} + * @see Example: {@link https://threejs.org/examples/#webgl_buffergeometry_indexed | Mesh with indexed faces} + * @see Example: {@link https://threejs.org/examples/#webgl_buffergeometry_lines | Lines} + * @see Example: {@link https://threejs.org/examples/#webgl_buffergeometry_lines_indexed | Indexed Lines} + * @see Example: {@link https://threejs.org/examples/#webgl_buffergeometry_custom_attributes_particles | Particles} + * @see Example: {@link https://threejs.org/examples/#webgl_buffergeometry_rawshader | Raw Shaders} + * @see {@link https://threejs.org/docs/index.html#api/en/core/BufferGeometry | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/BufferGeometry.js | Source} + */ +export class BufferGeometry< + Attributes extends NormalOrGLBufferAttributes = NormalBufferAttributes, +> extends EventDispatcher<{ dispose: {} }> { + /** + * This creates a new {@link THREE.BufferGeometry | BufferGeometry} object. + */ + constructor(); + + /** + * Unique number for this {@link THREE.BufferGeometry | BufferGeometry} instance. + * @remarks Expects a `Integer` + */ + id: number; + + /** + * {@link http://en.wikipedia.org/wiki/Universally_unique_identifier | UUID} of this object instance. + * @remarks This gets automatically assigned and shouldn't be edited. + */ + uuid: string; + + /** + * Optional name for this {@link THREE.BufferGeometry | BufferGeometry} instance. + * @defaultValue `''` + */ + name: string; + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `BufferGeometry` + */ + readonly type: string | "BufferGeometry"; + + /** + * Allows for vertices to be re-used across multiple triangles; this is called using "indexed triangles". + * Each triangle is associated with the indices of three vertices. This attribute therefore stores the index of each vertex for each triangular face. + * If this attribute is not set, the {@link THREE.WebGLRenderer | renderer} assumes that each three contiguous positions represent a single triangle. + * @defaultValue `null` + */ + index: BufferAttribute | null; + + indirect: IndirectStorageBufferAttribute | null; + + /** + * This hashmap has as id the name of the attribute to be set and as value the {@link THREE.BufferAttribute | buffer} to set it to. Rather than accessing this property directly, + * use {@link setAttribute | .setAttribute} and {@link getAttribute | .getAttribute} to access attributes of this geometry. + * @defaultValue `{}` + */ + attributes: Attributes; + + /** + * Hashmap of {@link THREE.BufferAttribute | BufferAttributes} holding details of the geometry's morph targets. + * @remarks + * Once the geometry has been rendered, the morph attribute data cannot be changed. + * You will have to call {@link dispose | .dispose}(), and create a new instance of {@link THREE.BufferGeometry | BufferGeometry}. + * @defaultValue `{}` + */ + morphAttributes: { + [name: string]: Array; // TODO Replace for 'Record<>' + }; + + /** + * Used to control the morph target behavior; when set to true, the morph target data is treated as relative offsets, rather than as absolute positions/normals. + * @defaultValue `false` + */ + morphTargetsRelative: boolean; + + /** + * Split the geometry into groups, each of which will be rendered in a separate WebGL draw call. This allows an array of materials to be used with the geometry. + * @remarks Every vertex and index must belong to exactly one group — groups must not share vertices or indices, and must not leave vertices or indices unused. + * @remarks Use {@link addGroup | .addGroup} to add groups, rather than modifying this array directly. + * @defaultValue `[]` + */ + groups: GeometryGroup[]; + + /** + * Bounding box for the {@link THREE.BufferGeometry | BufferGeometry}, which can be calculated with {@link computeBoundingBox | .computeBoundingBox()}. + * @remarks Bounding boxes aren't computed by default. They need to be explicitly computed, otherwise they are `null`. + * @defaultValue `null` + */ + boundingBox: Box3 | null; + + /** + * Bounding sphere for the {@link THREE.BufferGeometry | BufferGeometry}, which can be calculated with {@link computeBoundingSphere | .computeBoundingSphere()}. + * @remarks bounding spheres aren't computed by default. They need to be explicitly computed, otherwise they are `null`. + * @defaultValue `null` + */ + boundingSphere: Sphere | null; + + /** + * Determines the part of the geometry to render. This should not be set directly, instead use {@link setDrawRange | .setDrawRange(...)}. + * @remarks For non-indexed {@link THREE.BufferGeometry | BufferGeometry}, count is the number of vertices to render. + * @remarks For indexed {@link THREE.BufferGeometry | BufferGeometry}, count is the number of indices to render. + * @defaultValue `{ start: 0, count: Infinity }` + */ + drawRange: { start: number; count: number }; + + /** + * An object that can be used to store custom data about the BufferGeometry. It should not hold references to functions as these will not be cloned. + * @defaultValue `{}` + */ + userData: Record; + + /** + * Read-only flag to check if a given object is of type {@link BufferGeometry}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isBufferGeometry: true; + + /** + * Return the {@link index | .index} buffer. + */ + getIndex(): BufferAttribute | null; + + /** + * Set the {@link THREE.BufferGeometry.index | .index} buffer. + * @param index + */ + setIndex(index: BufferAttribute | number[] | null): this; + + setIndirect(indirect: IndirectStorageBufferAttribute | null): this; + + getIndirect(): IndirectStorageBufferAttribute | null; + + /** + * Sets an {@link attributes | attribute} to this geometry with the specified name. + * @remarks + * Use this rather than the attributes property, because an internal hashmap of {@link attributes | .attributes} is maintained to speed up iterating over attributes. + * @param name + * @param attribute + */ + setAttribute(name: K, attribute: Attributes[K]): this; + + /** + * Returns the {@link attributes | attribute} with the specified name. + * @param name + */ + getAttribute(name: K): Attributes[K]; + + /** + * Deletes the {@link attributes | attribute} with the specified name. + * @param name + */ + deleteAttribute(name: keyof Attributes): this; + + /** + * Returns true if the {@link attributes | attribute} with the specified name exists. + * @param name + */ + hasAttribute(name: keyof Attributes): boolean; + + /** + * Adds a group to this geometry + * @see the {@link BufferGeometry.groups | groups} property for details. + * @param start + * @param count + * @param materialIndex + */ + addGroup(start: number, count: number, materialIndex?: number): void; + + /** + * Clears all groups. + */ + clearGroups(): void; + + /** + * Set the {@link drawRange | .drawRange} property + * @remarks For non-indexed BufferGeometry, count is the number of vertices to render + * @remarks For indexed BufferGeometry, count is the number of indices to render. + * @param start + * @param count is the number of vertices or indices to render. Expects a `Integer` + */ + setDrawRange(start: number, count: number): void; + + /** + * Applies the matrix transform to the geometry. + * @param matrix + */ + applyMatrix4(matrix: Matrix4): this; + + /** + * Applies the rotation represented by the quaternion to the geometry. + * @param quaternion + */ + applyQuaternion(quaternion: Quaternion): this; + + /** + * Rotate the geometry about the X axis. This is typically done as a one time operation, and not during a loop. + * @remarks Use {@link THREE.Object3D.rotation | Object3D.rotation} for typical real-time mesh rotation. + * @param angle radians. Expects a `Float` + */ + rotateX(angle: number): this; + + /** + * Rotate the geometry about the Y axis. + * @remarks This is typically done as a one time operation, and not during a loop. + * @remarks Use {@link THREE.Object3D.rotation | Object3D.rotation} for typical real-time mesh rotation. + * @param angle radians. Expects a `Float` + */ + rotateY(angle: number): this; + + /** + * Rotate the geometry about the Z axis. + * @remarks This is typically done as a one time operation, and not during a loop. + * @remarks Use {@link THREE.Object3D.rotation | Object3D.rotation} for typical real-time mesh rotation. + * @param angle radians. Expects a `Float` + */ + rotateZ(angle: number): this; + + /** + * Translate the geometry. + * @remarks This is typically done as a one time operation, and not during a loop. + * @remarks Use {@link THREE.Object3D.position | Object3D.position} for typical real-time mesh rotation. + * @param x Expects a `Float` + * @param y Expects a `Float` + * @param z Expects a `Float` + */ + translate(x: number, y: number, z: number): this; + + /** + * Scale the geometry data. + * @remarks This is typically done as a one time operation, and not during a loop. + * @remarks Use {@link THREE.Object3D.scale | Object3D.scale} for typical real-time mesh scaling. + * @param x Expects a `Float` + * @param y Expects a `Float` + * @param z Expects a `Float` + */ + scale(x: number, y: number, z: number): this; + + /** + * Rotates the geometry to face a point in space. + * @remarks This is typically done as a one time operation, and not during a loop. + * @remarks Use {@link THREE.Object3D.lookAt | Object3D.lookAt} for typical real-time mesh usage. + * @param vector A world vector to look at. + */ + lookAt(vector: Vector3): this; + + /** + * Center the geometry based on the bounding box. + */ + center(): this; + + /** + * Defines a geometry by creating a `position` attribute based on the given array of points. The array can hold + * instances of {@link Vector2} or {@link Vector3}. When using two-dimensional data, the `z` coordinate for all + * vertices is set to `0`. + * + * If the method is used with an existing `position` attribute, the vertex data are overwritten with the data from + * the array. The length of the array must match the vertex count. + */ + setFromPoints(points: Vector3[] | Vector2[]): this; + + /** + * Computes the bounding box of the geometry, and updates the {@link .boundingBox} attribute. The bounding box is + * not computed by the engine; it must be computed by your app. You may need to recompute the bounding box if the + * geometry vertices are modified. + */ + computeBoundingBox(): void; + + /** + * Computes the bounding sphere of the geometry, and updates the {@link .boundingSphere} attribute. The engine + * automatically computes the bounding sphere when it is needed, e.g., for ray casting or view frustum culling. You + * may need to recompute the bounding sphere if the geometry vertices are modified. + */ + computeBoundingSphere(): void; + + /** + * Calculates and adds a tangent attribute to this geometry. + * The computation is only supported for indexed geometries and if position, normal, and uv attributes are defined + * @remarks + * When using a tangent space normal map, prefer the MikkTSpace algorithm provided by + * {@link BufferGeometryUtils.computeMikkTSpaceTangents} instead. + */ + computeTangents(): void; + + /** + * Computes vertex normals for the given vertex data. For indexed geometries, the method sets each vertex normal to + * be the average of the face normals of the faces that share that vertex. For non-indexed geometries, vertices are + * not shared, and the method sets each vertex normal to be the same as the face normal. + */ + computeVertexNormals(): void; + + /** + * Every normal vector in a geometry will have a magnitude of 1 + * @remarks This will correct lighting on the geometry surfaces. + */ + normalizeNormals(): void; + + /** + * Return a non-index version of an indexed BufferGeometry. + */ + toNonIndexed(): BufferGeometry; + + /** + * Convert the buffer geometry to three.js {@link https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 | JSON Object/Scene format}. + */ + toJSON(): BufferGeometryJSON; + + /** + * Creates a clone of this BufferGeometry + */ + clone(): this; + + /** + * Copies another BufferGeometry to this BufferGeometry. + * @param source + */ + copy(source: BufferGeometry): this; + + /** + * Frees the GPU-related resources allocated by this instance. + * @remarks Call this method whenever this instance is no longer used in your app. + */ + dispose(): void; +} diff --git a/src-testing/src/core/Clock.d.ts b/src-testing/src/core/Clock.d.ts new file mode 100644 index 000000000..05307083c --- /dev/null +++ b/src-testing/src/core/Clock.d.ts @@ -0,0 +1,72 @@ +/** + * Object for keeping track of time + * @remarks + * This uses {@link https://developer.mozilla.org/en-US/docs/Web/API/Performance/now | performance.now} if it is available, + * otherwise it reverts to the less accurate {@link https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Date/now | Date.now}. + * @see {@link https://threejs.org/docs/index.html#api/en/core/Clock | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/Clock.js | Source} + */ +export class Clock { + /** + * Create a new instance of {@link THREE.Clock | Clock} + * @param autoStart - Whether to automatically start the clock when {@link getDelta | .getDelta()} is called for the first time. Default `true` + */ + constructor(autoStart?: boolean); + + /** + * If set, starts the clock automatically when {@link getDelta | .getDelta()} is called for the first time. + * @defaultValue `true` + */ + autoStart: boolean; + + /** + * Holds the time at which the clock's {@link start | .start()} method was last called. + * @defaultValue `0` + */ + startTime: number; + + /** + * Holds the time at which the clock's {@link start | .start()}, {@link getElapsedTime | .getElapsedTime()} or {@link getDelta | .getDelta()} methods were last called. + * @defaultValue `0` + */ + oldTime: number; + + /** + * Keeps track of the total time that the clock has been running. + * @defaultValue `0` + */ + elapsedTime: number; + + /** + * Whether the clock is running or not. + * @defaultValue `false` + */ + running: boolean; + + /** + * Starts clock. + * @remarks + * Also sets the {@link startTime | .startTime} and {@link oldTime | .oldTime} to the current time, + * sets {@link elapsedTime | .elapsedTime} to `0` and {@link running | .running} to `true`. + */ + start(): void; + + /** + * Stops clock and sets {@link oldTime | oldTime} to the current time. + */ + stop(): void; + + /** + * Get the seconds passed since the clock started and sets {@link oldTime | .oldTime} to the current time. + * @remarks + * If {@link autoStart | .autoStart} is `true` and the clock is not running, also starts the clock. + */ + getElapsedTime(): number; + + /** + * Get the seconds passed since the time {@link oldTime | .oldTime} was set and sets {@link oldTime | .oldTime} to the current time. + * @remarks + * If {@link autoStart | .autoStart} is `true` and the clock is not running, also starts the clock. + */ + getDelta(): number; +} diff --git a/src-testing/src/core/EventDispatcher.d.ts b/src-testing/src/core/EventDispatcher.d.ts new file mode 100644 index 000000000..403dd1c2e --- /dev/null +++ b/src-testing/src/core/EventDispatcher.d.ts @@ -0,0 +1,82 @@ +/** + * The minimal basic Event that can be dispatched by a {@link EventDispatcher<>}. + */ +export interface BaseEvent { + readonly type: TEventType; +} + +/** + * The minimal expected contract of a fired Event that was dispatched by a {@link EventDispatcher<>}. + */ +export interface Event { + readonly type: TEventType; + readonly target: TTarget; +} + +export type EventListener = ( + event: TEventData & Event, +) => void; + +/** + * JavaScript events for custom objects + * @example + * ```typescript + * // Adding events to a custom object + * class Car extends EventDispatcher { + * start() { + * this.dispatchEvent( { type: 'start', message: 'vroom vroom!' } ); + * } + * }; + * // Using events with the custom object + * const car = new Car(); + * car.addEventListener( 'start', ( event ) => { + * alert( event.message ); + * } ); + * car.start(); + * ``` + * @see {@link https://github.com/mrdoob/eventdispatcher.js | mrdoob EventDispatcher on GitHub} + * @see {@link https://threejs.org/docs/index.html#api/en/core/EventDispatcher | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/EventDispatcher.js | Source} + */ +export class EventDispatcher { + /** + * Creates {@link THREE.EventDispatcher | EventDispatcher} object. + */ + constructor(); + + /** + * Adds a listener to an event type. + * @param type The type of event to listen to. + * @param listener The function that gets called when the event is fired. + */ + addEventListener>( + type: T, + listener: EventListener, + ): void; + + /** + * Checks if listener is added to an event type. + * @param type The type of event to listen to. + * @param listener The function that gets called when the event is fired. + */ + hasEventListener>( + type: T, + listener: EventListener, + ): boolean; + + /** + * Removes a listener from an event type. + * @param type The type of the listener that gets removed. + * @param listener The listener function that gets removed. + */ + removeEventListener>( + type: T, + listener: EventListener, + ): void; + + /** + * Fire an event type. + * @param event The event that gets fired. + */ + dispatchEvent>(event: BaseEvent & TEventMap[T]): void; +} diff --git a/src-testing/src/core/GLBufferAttribute.d.ts b/src-testing/src/core/GLBufferAttribute.d.ts new file mode 100644 index 000000000..c549518dd --- /dev/null +++ b/src-testing/src/core/GLBufferAttribute.d.ts @@ -0,0 +1,121 @@ +/** + * This buffer attribute class does not construct a VBO. + * Instead, it uses whatever VBO is passed in constructor and can later be altered via the {@link buffer | .buffer} property. + * @remarks + * It is required to pass additional params alongside the VBO + * Those are: the GL context, the GL data type, the number of components per vertex, the number of bytes per component, and the number of vertices. + * @remarks + * The most common use case for this class is when some kind of GPGPU calculation interferes or even produces the VBOs in question. + * @see Example: {@link https://threejs.org/examples/#webgl_buffergeometry_glbufferattribute | WebGL / buffergeometry / glbufferattribute} + * @see {@link https://threejs.org/docs/index.html#api/en/core/GLBufferAttribute | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/GLBufferAttribute.js | Source} + */ +export class GLBufferAttribute { + /** + * This creates a new GLBufferAttribute object. + * @param buffer Must be a {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGLBuffer | WebGLBuffer}. See {@link GLBufferAttribute.buffer | .buffer} + * @param type One of {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Constants#Data_types | WebGL Data Types}. See {@link GLBufferAttribute.type | .type} + * @param itemSize How many values make up each item (vertex). See {@link GLBufferAttribute.itemSize | .itemSize} + * @param elementSize `1`, `2` or `4`. The corresponding size (in bytes) for the given {@link type} param. See {@link GLBufferAttribute.elementSize | .elementSize} + * @param count The expected number of vertices in VBO. See {@link GLBufferAttribute.count | .count} + */ + constructor(buffer: WebGLBuffer, type: GLenum, itemSize: number, elementSize: 1 | 2 | 4, count: number); + + /** + * Read-only flag to check if a given object is of type {@link GLBufferAttribute}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isGLBufferAttribute: true; + + /** + * Optional name for this attribute instance. + * @defaultValue `""` + */ + name: string; + + /** + * The current {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGLBuffer | WebGLBuffer} instance. + */ + buffer: WebGLBuffer; + + /** + * A {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Constants#Data_types | WebGL Data Type} describing the underlying VBO contents. + * + * #### WebGL Data Type (`GLenum`) + * - gl.BYTE: 0x1400 + * - gl.UNSIGNED_BYTE: 0x1401 + * - gl.SHORT: 0x1402 + * - gl.UNSIGNED_SHORT: 0x1403 + * - gl.INT: 0x1404 + * - gl.UNSIGNED_INT: 0x1405 + * - gl.FLOAT: 0x1406 + * @remarks Set this property together with {@link elementSize | .elementSize}. The recommended way is using the {@link setType | .setType()} method. + * @remarks Expects a `DataType` `GLenum` _possible values:_ `0x1400` `0x1401` `0x1402` `0x1403` `0x1404` `0x1405` `0x1406` + */ + type: GLenum; + + /** + * How many values make up each item (vertex). + * @remarks The number of values of the array that should be associated with a particular vertex. + * For instance, if this attribute is storing a 3-component vector (such as a position, normal, or color), then itemSize should be 3. + * @remarks Expects a `Integer` + */ + itemSize: number; + + /** + * Stores the corresponding size in bytes for the current {@link type | .type} property value. + * + * The corresponding size (_in bytes_) for the given "type" param. + * #### WebGL Data Type (`GLenum`) + * - gl.BYTE: 1 + * - gl.UNSIGNED_BYTE: 1 + * - gl.SHORT: 2 + * - gl.UNSIGNED_SHORT: 2 + * - gl.INT: 4 + * - gl.UNSIGNED_INT: 4 + * - gl.FLOAT: 4 + * @remarks Set this property together with {@link type | .type}. The recommended way is using the {@link setType | .setType} method. + * @see `constructor`` for a list of known type sizes. + * @remarks Expects a `1`, `2` or `4` + */ + elementSize: 1 | 2 | 4; + + /** + * The expected number of vertices in VBO. + * @remarks Expects a `Integer` + */ + count: number; + + /** + * A version number, incremented every time the needsUpdate property is set to true. + * @remarks Expects a `Integer` + */ + version: number; + + /** + * Setting this to true increments {@link version | .version}. + * @remarks _set-only property_. + */ + set needsUpdate(value: boolean); + + /** + * Sets the {@link buffer | .buffer} property. + */ + setBuffer(buffer: WebGLBuffer): this; + + /** + * Sets the both {@link GLBufferAttribute.type | type} and {@link GLBufferAttribute.elementSize | elementSize} properties. + */ + setType(type: GLenum, elementSize: 1 | 2 | 4): this; + + /** + * Sets the {@link GLBufferAttribute.itemSize | itemSize} property. + */ + setItemSize(itemSize: number): this; + + /** + * Sets the {@link GLBufferAttribute.count | count} property. + */ + setCount(count: number): this; +} diff --git a/src-testing/src/core/InstancedBufferAttribute.d.ts b/src-testing/src/core/InstancedBufferAttribute.d.ts new file mode 100644 index 000000000..fde083b81 --- /dev/null +++ b/src-testing/src/core/InstancedBufferAttribute.d.ts @@ -0,0 +1,32 @@ +import { BufferAttribute, TypedArray } from "./BufferAttribute.js"; + +/** + * An instanced version of {@link THREE.BufferAttribute | BufferAttribute}. + * @see {@link https://threejs.org/docs/index.html#api/en/core/InstancedBufferAttribute | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/InstancedBufferAttribute.js | Source} + */ +export class InstancedBufferAttribute extends BufferAttribute { + /** + * Create a new instance of {@link THREE.InstancedBufferAttribute | InstancedBufferAttribute} + * @param array + * @param itemSize + * @param normalized + * @param meshPerAttribute + */ + constructor(array: TypedArray, itemSize: number, normalized?: boolean, meshPerAttribute?: number); + + /** + * Defines how often a value of this buffer attribute should be repeated. + * A value of one means that each value of the instanced attribute is used for a single instance. + * A value of two means that each value is used for two consecutive instances (and so on). + * @defaultValue `1` + */ + meshPerAttribute: number; + + /** + * Read-only flag to check if a given object is of type {@link InstancedBufferAttribute}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isInstancedBufferAttribute: true; +} diff --git a/src-testing/src/core/InstancedBufferGeometry.d.ts b/src-testing/src/core/InstancedBufferGeometry.d.ts new file mode 100644 index 000000000..421294c49 --- /dev/null +++ b/src-testing/src/core/InstancedBufferGeometry.d.ts @@ -0,0 +1,37 @@ +import { BufferGeometry } from "./BufferGeometry.js"; + +/** + * An instanced version of {@link THREE.BufferGeometry | BufferGeometry}. + * @see {@link https://threejs.org/docs/index.html#api/en/core/InstancedBufferGeometry | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/InstancedBufferGeometry.js | Source} + */ +export class InstancedBufferGeometry extends BufferGeometry { + /** + * Create a new instance of {@link InstancedBufferGeometry} + */ + constructor(); + + /** + * @defaultValue `InstancedBufferGeometry` + */ + type: string; + + /** + * Read-only flag to check if a given object is of type {@link InstancedBufferGeometry}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isInstancedBufferGeometry: true; + + /** + * @defaultValue `Infinity` + */ + instanceCount: number; + + /** + * Copies the given {@link InstancedBufferGeometry} to this instance. + * @param source + * @override + */ + copy(source: InstancedBufferGeometry): this; +} diff --git a/src-testing/src/core/InstancedInterleavedBuffer.d.ts b/src-testing/src/core/InstancedInterleavedBuffer.d.ts new file mode 100644 index 000000000..3c78beae4 --- /dev/null +++ b/src-testing/src/core/InstancedInterleavedBuffer.d.ts @@ -0,0 +1,22 @@ +import { TypedArray } from "./BufferAttribute.js"; +import { InterleavedBuffer } from "./InterleavedBuffer.js"; + +/** + * An instanced version of {@link THREE.InterleavedBuffer | InterleavedBuffer}. + * @see {@link https://threejs.org/docs/index.html#api/en/core/InstancedInterleavedBuffer | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/InstancedInterleavedBuffer.js | Source} + */ +export class InstancedInterleavedBuffer extends InterleavedBuffer { + /** + * Create a new instance of {@link InstancedInterleavedBuffer} + * @param array + * @param itemSize + * @param meshPerAttribute + */ + constructor(array: TypedArray, stride: number, meshPerAttribute?: number); + + /** + * @defaultValue `1` + */ + meshPerAttribute: number; +} diff --git a/src-testing/src/core/InterleavedBuffer.d.ts b/src-testing/src/core/InterleavedBuffer.d.ts new file mode 100644 index 000000000..89819f6c2 --- /dev/null +++ b/src-testing/src/core/InterleavedBuffer.d.ts @@ -0,0 +1,150 @@ +import { Usage } from "../constants.js"; +import { TypedArray } from "./BufferAttribute.js"; +import { InterleavedBufferAttribute } from "./InterleavedBufferAttribute.js"; + +/** + * **"Interleaved"** means that multiple attributes, possibly of different types, (e.g., _position, normal, uv, color_) are packed into a single array buffer. + * An introduction into interleaved arrays can be found here: {@link https://blog.tojicode.com/2011/05/interleaved-array-basics.html | Interleaved array basics} + * @see Example: {@link https://threejs.org/examples/#webgl_buffergeometry_points_interleaved | webgl / buffergeometry / points / interleaved} + * @see {@link https://threejs.org/docs/index.html#api/en/core/InterleavedBuffer | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/InterleavedBuffer.js | Source} + */ +export class InterleavedBuffer { + readonly isInterleavedBuffer: true; + + /** + * Create a new instance of {@link InterleavedBuffer} + * @param array A {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray | TypedArray} with a shared buffer. Stores the geometry data. + * @param stride The number of typed-array elements per vertex. Expects a `Integer` + */ + constructor(array: TypedArray, stride: number); + + /** + * A {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray | TypedArray} with a shared buffer. Stores the geometry data. + */ + array: TypedArray; + + /** + * The number of {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray | TypedArray} elements per vertex. + * @remarks Expects a `Integer` + */ + stride: number; + + /** + * Defines the intended usage pattern of the data store for optimization purposes. + * Corresponds to the {@link BufferAttribute.usage | usage} parameter of + * {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/bufferData | WebGLRenderingContext.bufferData}. + * @remarks + * After the initial use of a buffer, its usage cannot be changed. Instead, instantiate a new one and set the desired usage before the next render. + * @see {@link https://threejs.org/docs/index.html#api/en/constants/BufferAttributeUsage | Buffer Attribute Usage Constants} for all possible values. + * @see {@link BufferAttribute.setUsage | setUsage} + * @defaultValue {@link THREE.StaticDrawUsage | THREE.StaticDrawUsage}. + */ + usage: Usage; + + /** + * This can be used to only update some components of stored data. Use the {@link .addUpdateRange} function to add + * ranges to this array. + */ + updateRanges: Array<{ + /** + * Position at which to start update. + */ + start: number; + /** + * The number of components to update. + */ + count: number; + }>; + + /** + * A version number, incremented every time the {@link BufferAttribute.needsUpdate | needsUpdate} property is set to true. + * @remarks Expects a `Integer` + * @defaultValue `0` + */ + version: number; + + /** + * Gives the total number of elements in the array. + * @remarks Expects a `Integer` + * @defaultValue 0 + */ + count: number; + + /** + * Flag to indicate that this attribute has changed and should be re-sent to the GPU. + * Set this to true when you modify the value of the array. + * @remarks Setting this to true also increments the {@link BufferAttribute.version | version}. + * @remarks _set-only property_. + */ + set needsUpdate(value: boolean); + + /** + * {@link http://en.wikipedia.org/wiki/Universally_unique_identifier | UUID} of this object instance. + * @remarks This gets automatically assigned and shouldn't be edited. + */ + uuid: string; + + /** + * Calls {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set | TypedArray.set}( {@link value}, {@link offset} ) + * on the {@link BufferAttribute.array | array}. + * @param value The source `TypedArray`. + * @param offset index of the {@link BufferAttribute.array | array} at which to start copying. Expects a `Integer`. Default `0`. + * @throws `RangeError` When {@link offset} is negative or is too large. + */ + set(value: ArrayLike, offset: number): this; + + /** + * Set {@link BufferAttribute.usage | usage} + * @remarks + * After the initial use of a buffer, its usage cannot be changed. Instead, instantiate a new one and set the desired usage before the next render. + * @see {@link https://threejs.org/docs/index.html#api/en/constants/BufferAttributeUsage | Buffer Attribute Usage Constants} for all possible values. + * @see {@link BufferAttribute.usage | usage} + * @param value Corresponds to the {@link BufferAttribute.usage | usage} parameter of + * {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/bufferData | WebGLRenderingContext.bufferData}. + */ + setUsage(value: Usage): this; + + /** + * Adds a range of data in the data array to be updated on the GPU. Adds an object describing the range to the + * {@link .updateRanges} array. + */ + addUpdateRange(start: number, count: number): void; + + /** + * Clears the {@link .updateRanges} array. + */ + clearUpdateRanges(): void; + + /** + * Copies another {@link InterleavedBuffer} to this {@link InterleavedBuffer} instance. + * @param source + */ + copy(source: InterleavedBuffer): this; + + /** + * Copies data from {@link attribute}[{@link index2}] to {@link InterleavedBuffer.array | array}[{@link index1}]. + * @param index1 Expects a `Integer` + * @param attribute + * @param index2 Expects a `Integer` + */ + copyAt(index1: number, attribute: InterleavedBufferAttribute, index2: number): this; + + /** + * Creates a clone of this {@link InterleavedBuffer}. + * @param data This object holds shared array buffers required for properly cloning geometries with interleaved attributes. + */ + clone(data: {}): InterleavedBuffer; + + /** + * Serializes this {@link InterleavedBuffer}. + * Converting to {@link https://github.com/mrdoob/three.js/wiki/JSON-Geometry-format-4 | JSON Geometry format v4}, + * @param data This object holds shared array buffers required for properly serializing geometries with interleaved attributes. + */ + toJSON(data: {}): { + uuid: string; + buffer: string; + type: string; + stride: number; + }; +} diff --git a/src-testing/src/core/InterleavedBufferAttribute.d.ts b/src-testing/src/core/InterleavedBufferAttribute.d.ts new file mode 100644 index 000000000..955049938 --- /dev/null +++ b/src-testing/src/core/InterleavedBufferAttribute.d.ts @@ -0,0 +1,201 @@ +import { Matrix3 } from "../math/Matrix3.js"; +import { Matrix4 } from "../math/Matrix4.js"; +import { BufferAttribute, TypedArray } from "./BufferAttribute.js"; +import { InterleavedBuffer } from "./InterleavedBuffer.js"; + +/** + * @see {@link https://threejs.org/docs/index.html#api/en/core/InterleavedBufferAttribute | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/InterleavedBufferAttribute.js | Source} + */ +export class InterleavedBufferAttribute { + /** + * Create a new instance of {@link THREE.InterleavedBufferAttribute | InterleavedBufferAttribute}. + * @param interleavedBuffer + * @param itemSize + * @param offset + * @param normalized Default `false`. + */ + constructor(interleavedBuffer: InterleavedBuffer, itemSize: number, offset: number, normalized?: boolean); + + /** + * Optional name for this attribute instance. + * @defaultValue `''` + */ + name: string; + + /** + * The {@link InterleavedBuffer | InterleavedBuffer} instance passed in the constructor. + */ + data: InterleavedBuffer; + + /** + * How many values make up each item. + * @remarks Expects a `Integer` + */ + itemSize: number; + + /** + * The offset in the underlying array buffer where an item starts. + * @remarks Expects a `Integer` + */ + offset: number; + + /** + * @defaultValue `false` + */ + normalized: boolean; + + /** + * The value of {@link data | .data}.{@link InterleavedBuffer.count | count}. + * If the buffer is storing a 3-component item (such as a _position, normal, or color_), then this will count the number of such items stored. + * @remarks _get-only property_. + * @remarks Expects a `Integer` + */ + get count(): number; + + /** + * The value of {@link InterleavedBufferAttribute.data | data}.{@link InterleavedBuffer.array | array}. + * @remarks _get-only property_. + */ + get array(): TypedArray; + + /** + * Flag to indicate that the {@link data | .data} ({@link InterleavedBuffer}) attribute has changed and should be re-sent to the GPU. + * @remarks Setting this to have the same result of setting true also increments the {@link InterleavedBuffer.needsUpdate | InterleavedBuffer.needsUpdate} of {@link data | .data}. + * @remarks Setting this to true also increments the {@link InterleavedBuffer.version | InterleavedBuffer.version}. + * @remarks _set-only property_. + */ + set needsUpdate(value: boolean); + + /** + * Read-only flag to check if a given object is of type {@link InterleavedBufferAttribute}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isInterleavedBufferAttribute: true; + + /** + * Applies matrix {@link Matrix4 | m} to every Vector3 element of this InterleavedBufferAttribute. + * @param m + */ + applyMatrix4(m: Matrix4): this; + + /** + * Applies normal matrix {@link Matrix3 | m} to every Vector3 element of this InterleavedBufferAttribute. + * @param m + */ + applyNormalMatrix(m: Matrix3): this; + + /** + * Applies matrix {@link Matrix4 | m} to every Vector3 element of this InterleavedBufferAttribute, interpreting the elements as a direction vectors. + * @param m + */ + transformDirection(m: Matrix4): this; + + /** + * Returns the given component of the vector at the given index. + */ + getComponent(index: number, component: number): number; + + /** + * Sets the given component of the vector at the given index. + */ + setComponent(index: number, component: number, value: number): this; + + /** + * Returns the x component of the item at the given index. + * @param index Expects a `Integer` + */ + getX(index: number): number; + + /** + * Sets the x component of the item at the given index. + * @param index Expects a `Integer` + * @param x Expects a `Float` + */ + setX(index: number, x: number): this; + + /** + * Returns the y component of the item at the given index. + * @param index Expects a `Integer` + */ + getY(index: number): number; + + /** + * Sets the y component of the item at the given index. + * @param index Expects a `Integer` + * @param y Expects a `Float` + */ + setY(index: number, y: number): this; + + /** + * Returns the z component of the item at the given index. + * @param index Expects a `Integer` + */ + getZ(index: number): number; + + /** + * Sets the z component of the item at the given index. + * @param index Expects a `Integer` + * @param z Expects a `Float` + */ + setZ(index: number, z: number): this; + + /** + * Returns the w component of the item at the given index. + * @param index Expects a `Integer` + */ + getW(index: number): number; + + /** + * Sets the w component of the item at the given index. + * @param index Expects a `Integer` + * @param w Expects a `Float` + */ + setW(index: number, z: number): this; + + /** + * Sets the x and y components of the item at the given index. + * @param index Expects a `Integer` + * @param x Expects a `Float` + * @param y Expects a `Float` + */ + setXY(index: number, x: number, y: number): this; + /** + * Sets the x, y and z components of the item at the given index. + * @param index Expects a `Integer` + * @param x Expects a `Float` + * @param y Expects a `Float` + * @param z Expects a `Float` + */ + setXYZ(index: number, x: number, y: number, z: number): this; + + /** + * Sets the x, y, z and w components of the item at the given index. + * @param index Expects a `Integer` + * @param x Expects a `Float` + * @param y Expects a `Float` + * @param z Expects a `Float` + * @param w Expects a `Float` + */ + setXYZW(index: number, x: number, y: number, z: number, w: number): this; + + /** + * Creates a clone of this {@link InterleavedBufferAttribute}. + * @param data This object holds shared array buffers required for properly cloning geometries with interleaved attributes. + */ + clone(data?: {}): BufferAttribute; + + /** + * Serializes this {@link InterleavedBufferAttribute}. + * Converting to {@link https://github.com/mrdoob/three.js/wiki/JSON-Geometry-format-4 | JSON Geometry format v4}, + * @param data This object holds shared array buffers required for properly serializing geometries with interleaved attributes. + */ + toJSON(data?: {}): { + isInterleavedBufferAttribute: true; + itemSize: number; + data: string; + offset: number; + normalized: boolean; + }; +} diff --git a/src-testing/src/core/Layers.d.ts b/src-testing/src/core/Layers.d.ts new file mode 100644 index 000000000..ad95f892d --- /dev/null +++ b/src-testing/src/core/Layers.d.ts @@ -0,0 +1,72 @@ +/** + * A {@link THREE.Layers | Layers} object assigns an {@link THREE.Object3D | Object3D} to 1 or more of 32 layers numbered `0` to `31` - internally the + * layers are stored as a {@link https://en.wikipedia.org/wiki/Mask_(computing) | bit mask}, and + * by default all Object3Ds are a member of layer `0`. + * @remarks + * This can be used to control visibility - an object must share a layer with a {@link Camera | camera} to be visible when that camera's view is rendered. + * @remarks + * All classes that inherit from {@link THREE.Object3D | Object3D} have an {@link THREE.Object3D.layers | Object3D.layers} property which is an instance of this class. + * @see Example: {@link https://threejs.org/examples/#webgl_layers | WebGL / layers} + * @see Example: {@link https://threejs.org/examples/#webxr_vr_layers | Webxr / vr / layers} + * @see {@link https://threejs.org/docs/index.html#api/en/core/Layers | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/Layers.js | Source} + */ +export class Layers { + /** + * Create a new Layers object, with membership initially set to layer 0. + */ + constructor(); + + /** + * A bit mask storing which of the 32 layers this layers object is currently a member of. + * @defaultValue `1 | 0` + * @remarks Expects a `Integer` + */ + mask: number; + + /** + * Set membership to `layer`, and remove membership all other layers. + * @param layer An integer from 0 to 31. + */ + set(layer: number): void; + + /** + * Add membership of this `layer`. + * @param layer An integer from 0 to 31. + */ + enable(layer: number): void; + + /** + * Add membership to all layers. + */ + enableAll(): void; + + /** + * Toggle membership of `layer`. + * @param layer An integer from 0 to 31. + */ + toggle(layer: number): void; + + /** + * Remove membership of this `layer`. + * @param layer An integer from 0 to 31. + */ + disable(layer: number): void; + + /** + * Remove membership from all layers. + */ + disableAll(): void; + + /** + * Returns true if this and the passed `layers` object have at least one layer in common. + * @param layers A Layers object + */ + test(layers: Layers): boolean; + + /** + * Returns true if the given layer is enabled. + * @param layer An integer from 0 to 31. + */ + isEnabled(layer: number): boolean; +} diff --git a/src-testing/src/core/Object3D.d.ts b/src-testing/src/core/Object3D.d.ts new file mode 100644 index 000000000..20bba57ce --- /dev/null +++ b/src-testing/src/core/Object3D.d.ts @@ -0,0 +1,674 @@ +import { AnimationClip, AnimationClipJSON } from "../animation/AnimationClip.js"; +import { Camera } from "../cameras/Camera.js"; +import { ShapeJSON } from "../extras/core/Shape.js"; +import { Material, MaterialJSON } from "../materials/Material.js"; +import { Euler } from "../math/Euler.js"; +import { Matrix3 } from "../math/Matrix3.js"; +import { Matrix4, Matrix4Tuple } from "../math/Matrix4.js"; +import { Quaternion } from "../math/Quaternion.js"; +import { Vector3, Vector3Tuple } from "../math/Vector3.js"; +import { Group } from "../objects/Group.js"; +import { SkeletonJSON } from "../objects/Skeleton.js"; +import { WebGLRenderer } from "../renderers/WebGLRenderer.js"; +import { Scene } from "../scenes/Scene.js"; +import { SourceJSON } from "../textures/Source.js"; +import { TextureJSON } from "../textures/Texture.js"; +import { BufferGeometry, BufferGeometryJSON } from "./BufferGeometry.js"; +import { EventDispatcher } from "./EventDispatcher.js"; +import { Layers } from "./Layers.js"; +import { Intersection, Raycaster } from "./Raycaster.js"; + +export interface Object3DJSONObject { + uuid: string; + type: string; + + name?: string; + castShadow?: boolean; + receiveShadow?: boolean; + visible?: boolean; + frustumCulled?: boolean; + renderOrder?: number; + userData?: Record; + + layers: number; + matrix: Matrix4Tuple; + up: Vector3Tuple; + + matrixAutoUpdate?: boolean; + + material?: string | string[]; + + children?: string[]; + + animations?: string[]; +} + +export interface Object3DJSON { + metadata?: { version: number; type: string; generator: string }; + object: Object3DJSONObject; +} + +export interface JSONMeta { + geometries: Record; + materials: Record; + textures: Record; + images: Record; + shapes: Record; + skeletons: Record; + animations: Record; + nodes: Record; +} + +export interface Object3DEventMap { + /** + * Fires when the object has been added to its parent object. + */ + added: {}; + + /** + * Fires when the object has been removed from its parent object. + */ + removed: {}; + + /** + * Fires when a new child object has been added. + */ + childadded: { child: Object3D }; + + /** + * Fires when a new child object has been removed. + */ + childremoved: { child: Object3D }; +} + +/** + * This is the base class for most objects in three.js and provides a set of properties and methods for manipulating objects in 3D space. + * @remarks Note that this can be used for grouping objects via the {@link THREE.Object3D.add | .add()} method which adds the object as a child, + * however it is better to use {@link THREE.Group | Group} for this. + * @see {@link https://threejs.org/docs/index.html#api/en/core/Object3D | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/Object3D.js | Source} + */ +export class Object3D extends EventDispatcher { + /** + * This creates a new {@link Object3D} object. + */ + constructor(); + + /** + * Flag to check if a given object is of type {@link Object3D}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isObject3D: true; + + /** + * Unique number for this {@link Object3D} instance. + * @remarks Note that ids are assigned in chronological order: 1, 2, 3, ..., incrementing by one for each new object. + * Expects a `Integer` + */ + readonly id: number; + + /** + * {@link http://en.wikipedia.org/wiki/Universally_unique_identifier | UUID} of this object instance. + * @remarks This gets automatically assigned and shouldn't be edited. + */ + uuid: string; + + /** + * Optional name of the object + * @remarks _(doesn't need to be unique)_. + * @defaultValue `""` + */ + name: string; + + /** + * A Read-only _string_ to check `this` object type. + * @remarks This can be used to find a specific type of Object3D in a scene. + * Sub-classes will update this value. + * @defaultValue `Object3D` + */ + readonly type: string; + + /** + * Object's parent in the {@link https://en.wikipedia.org/wiki/Scene_graph | scene graph}. + * @remarks An object can have at most one parent. + * @defaultValue `null` + */ + parent: Object3D | null; + + /** + * Array with object's children. + * @see {@link THREE.Object3DGroup | Group} for info on manually grouping objects. + * @defaultValue `[]` + */ + + children: Object3D[]; + + /** + * This is used by the {@link lookAt | lookAt} method, for example, to determine the orientation of the result. + * @defaultValue {@link DEFAULT_UP | Object3D.DEFAULT_UP} - that is `(0, 1, 0)`. + */ + up: Vector3; + + /** + * Object's local position. + * @defaultValue `new THREE.Vector3()` - that is `(0, 0, 0)`. + */ + readonly position: Vector3; + + /** + * Object's local rotation ({@link https://en.wikipedia.org/wiki/Euler_angles | Euler angles}), in radians. + * @defaultValue `new THREE.Euler()` - that is `(0, 0, 0, Euler.DEFAULT_ORDER)`. + */ + readonly rotation: Euler; + + /** + * Object's local rotation as a {@link THREE.Quaternion | Quaternion}. + * @defaultValue `new THREE.Quaternion()` - that is `(0, 0, 0, 1)`. + */ + readonly quaternion: Quaternion; + + /** + * The object's local scale. + * @defaultValue `new THREE.Vector3( 1, 1, 1 )` + */ + readonly scale: Vector3; + + /** + * @defaultValue `new THREE.Matrix4()` + */ + readonly modelViewMatrix: Matrix4; + + /** + * @defaultValue `new THREE.Matrix3()` + */ + readonly normalMatrix: Matrix3; + + /** + * The local transform matrix. + * @defaultValue `new THREE.Matrix4()` + */ + matrix: Matrix4; + + /** + * The global transform of the object. + * @remarks If the {@link Object3D} has no parent, then it's identical to the local transform {@link THREE.Object3D.matrix | .matrix}. + * @defaultValue `new THREE.Matrix4()` + */ + matrixWorld: Matrix4; + + /** + * When this is set, it calculates the matrix of position, (rotation or quaternion) and + * scale every frame and also recalculates the matrixWorld property. + * @defaultValue {@link DEFAULT_MATRIX_AUTO_UPDATE} - that is `(true)`. + */ + matrixAutoUpdate: boolean; + + /** + * If set, then the renderer checks every frame if the object and its children need matrix updates. + * When it isn't, then you have to maintain all matrices in the object and its children yourself. + * @defaultValue {@link DEFAULT_MATRIX_WORLD_AUTO_UPDATE} - that is `(true)`. + */ + matrixWorldAutoUpdate: boolean; + + /** + * When this is set, it calculates the matrixWorld in that frame and resets this property to false. + * @defaultValue `false` + */ + matrixWorldNeedsUpdate: boolean; + + /** + * The layer membership of the object. + * @remarks The object is only visible if it has at least one layer in common with the {@link THREE.Object3DCamera | Camera} in use. + * This property can also be used to filter out unwanted objects in ray-intersection tests when using {@link THREE.Raycaster | Raycaster}. + * @defaultValue `new THREE.Layers()` + */ + layers: Layers; + + /** + * Object gets rendered if `true`. + * @defaultValue `true` + */ + visible: boolean; + + /** + * Whether the object gets rendered into shadow map. + * @defaultValue `false` + */ + castShadow: boolean; + + /** + * Whether the material receives shadows. + * @defaultValue `false` + */ + receiveShadow: boolean; + + /** + * When this is set, it checks every frame if the object is in the frustum of the camera before rendering the object. + * If set to `false` the object gets rendered every frame even if it is not in the frustum of the camera. + * @defaultValue `true` + */ + frustumCulled: boolean; + + /** + * This value allows the default rendering order of {@link https://en.wikipedia.org/wiki/Scene_graph | scene graph} + * objects to be overridden although opaque and transparent objects remain sorted independently. + * @remarks When this property is set for an instance of {@link Group | Group}, all descendants objects will be sorted and rendered together. + * Sorting is from lowest to highest renderOrder. + * @defaultValue `0` + */ + renderOrder: number; + + /** + * Array with object's animation clips. + * @defaultValue `[]` + */ + animations: AnimationClip[]; + + /** + * An object that can be used to store custom data about the {@link Object3D}. + * @remarks It should not hold references to _functions_ as these **will not** be cloned. + * @default `{}` + */ + userData: Record; + + /** + * Custom depth material to be used when rendering to the depth map. + * @remarks Can only be used in context of meshes. + * When shadow-casting with a {@link THREE.DirectionalLight | DirectionalLight} or {@link THREE.SpotLight | SpotLight}, + * if you are modifying vertex positions in the vertex shader you must specify a customDepthMaterial for proper shadows. + * @defaultValue `undefined` + */ + customDepthMaterial?: Material | undefined; + + /** + * Same as {@link customDepthMaterial}, but used with {@link THREE.Object3DPointLight | PointLight}. + * @defaultValue `undefined` + */ + customDistanceMaterial?: Material | undefined; + + /** + * An optional callback that is executed immediately before a 3D object is rendered to a shadow map. + * @remarks This function is called with the following parameters: renderer, scene, camera, shadowCamera, geometry, + * depthMaterial, group. + * Please notice that this callback is only executed for `renderable` 3D objects. Meaning 3D objects which + * define their visual appearance with geometries and materials like instances of {@link Mesh}, {@link Line}, + * {@link Points} or {@link Sprite}. Instances of {@link Object3D}, {@link Group} or {@link Bone} are not renderable + * and thus this callback is not executed for such objects. + */ + onBeforeShadow( + renderer: WebGLRenderer, + scene: Scene, + camera: Camera, + shadowCamera: Camera, + geometry: BufferGeometry, + depthMaterial: Material, + group: Group, + ): void; + + /** + * An optional callback that is executed immediately after a 3D object is rendered to a shadow map. + * @remarks This function is called with the following parameters: renderer, scene, camera, shadowCamera, geometry, + * depthMaterial, group. + * Please notice that this callback is only executed for `renderable` 3D objects. Meaning 3D objects which + * define their visual appearance with geometries and materials like instances of {@link Mesh}, {@link Line}, + * {@link Points} or {@link Sprite}. Instances of {@link Object3D}, {@link Group} or {@link Bone} are not renderable + * and thus this callback is not executed for such objects. + */ + onAfterShadow( + renderer: WebGLRenderer, + scene: Scene, + camera: Camera, + shadowCamera: Camera, + geometry: BufferGeometry, + depthMaterial: Material, + group: Group, + ): void; + + /** + * An optional callback that is executed immediately before a 3D object is rendered. + * @remarks This function is called with the following parameters: renderer, scene, camera, geometry, material, group. + * Please notice that this callback is only executed for `renderable` 3D objects. Meaning 3D objects which + * define their visual appearance with geometries and materials like instances of {@link Mesh}, {@link Line}, + * {@link Points} or {@link Sprite}. Instances of {@link Object3D}, {@link Group} or {@link Bone} are not renderable + * and thus this callback is not executed for such objects. + */ + onBeforeRender( + renderer: WebGLRenderer, + scene: Scene, + camera: Camera, + geometry: BufferGeometry, + material: Material, + group: Group, + ): void; + + /** + * An optional callback that is executed immediately after a 3D object is rendered. + * @remarks This function is called with the following parameters: renderer, scene, camera, geometry, material, group. + * Please notice that this callback is only executed for `renderable` 3D objects. Meaning 3D objects which + * define their visual appearance with geometries and materials like instances of {@link Mesh}, {@link Line}, + * {@link Points} or {@link Sprite}. Instances of {@link Object3D}, {@link Group} or {@link Bone} are not renderable + * and thus this callback is not executed for such objects. + */ + onAfterRender( + renderer: WebGLRenderer, + scene: Scene, + camera: Camera, + geometry: BufferGeometry, + material: Material, + group: Group, + ): void; + + /** + * The default {@link up} direction for objects, also used as the default position for {@link THREE.DirectionalLight | DirectionalLight}, + * {@link THREE.HemisphereLight | HemisphereLight} and {@link THREE.Spotlight | Spotlight} (which creates lights shining from the top down). + * @defaultValue `new THREE.Vector3( 0, 1, 0)` + */ + static DEFAULT_UP: Vector3; + + /** + * The default setting for {@link matrixAutoUpdate} for newly created Object3Ds. + * @defaultValue `true` + */ + static DEFAULT_MATRIX_AUTO_UPDATE: boolean; + + /** + * The default setting for {@link matrixWorldAutoUpdate} for newly created Object3Ds. + * @defaultValue `true` + */ + static DEFAULT_MATRIX_WORLD_AUTO_UPDATE: boolean; + + /** + * Applies the matrix transform to the object and updates the object's position, rotation and scale. + * @param matrix + */ + applyMatrix4(matrix: Matrix4): void; + + /** + * Applies the rotation represented by the quaternion to the object. + * @param quaternion + */ + applyQuaternion(quaternion: Quaternion): this; + + /** + * Calls {@link THREE.Quaternion.setFromAxisAngle | setFromAxisAngle}({@link axis}, {@link angle}) on the {@link quaternion | .quaternion}. + * @param axis A normalized vector in object space. + * @param angle Angle in radians. Expects a `Float` + */ + setRotationFromAxisAngle(axis: Vector3, angle: number): void; + + /** + * Calls {@link THREE.Quaternion.setFromEuler | setFromEuler}({@link euler}) on the {@link quaternion | .quaternion}. + * @param euler Euler angle specifying rotation amount. + */ + setRotationFromEuler(euler: Euler): void; + + /** + * Calls {@link THREE.Quaternion.setFromRotationMatrix | setFromRotationMatrix}({@link m}) on the {@link quaternion | .quaternion}. + * @remarks Note that this assumes that the upper 3x3 of m is a pure rotation matrix (i.e, unscaled). + * @param m Rotate the quaternion by the rotation component of the matrix. + */ + setRotationFromMatrix(m: Matrix4): void; + + /** + * Copy the given {@link THREE.Quaternion | Quaternion} into {@link quaternion | .quaternion}. + * @param q Normalized Quaternion. + */ + setRotationFromQuaternion(q: Quaternion): void; + + /** + * Rotate an object along an axis in object space. + * @remarks The axis is assumed to be normalized. + * @param axis A normalized vector in object space. + * @param angle The angle in radians. Expects a `Float` + */ + rotateOnAxis(axis: Vector3, angle: number): this; + + /** + * Rotate an object along an axis in world space. + * @remarks The axis is assumed to be normalized + * Method Assumes no rotated parent. + * @param axis A normalized vector in world space. + * @param angle The angle in radians. Expects a `Float` + */ + rotateOnWorldAxis(axis: Vector3, angle: number): this; + + /** + * Rotates the object around _x_ axis in local space. + * @param rad The angle to rotate in radians. Expects a `Float` + */ + rotateX(angle: number): this; + + /** + * Rotates the object around _y_ axis in local space. + * @param rad The angle to rotate in radians. Expects a `Float` + */ + rotateY(angle: number): this; + + /** + * Rotates the object around _z_ axis in local space. + * @param rad The angle to rotate in radians. Expects a `Float` + */ + rotateZ(angle: number): this; + + /** + * Translate an object by distance along an axis in object space + * @remarks The axis is assumed to be normalized. + * @param axis A normalized vector in object space. + * @param distance The distance to translate. Expects a `Float` + */ + translateOnAxis(axis: Vector3, distance: number): this; + + /** + * Translates object along x axis in object space by {@link distance} units. + * @param distance Expects a `Float` + */ + translateX(distance: number): this; + + /** + * Translates object along _y_ axis in object space by {@link distance} units. + * @param distance Expects a `Float` + */ + translateY(distance: number): this; + + /** + * Translates object along _z_ axis in object space by {@link distance} units. + * @param distance Expects a `Float` + */ + translateZ(distance: number): this; + + /** + * Converts the vector from this object's local space to world space. + * @param vector A vector representing a position in this object's local space. + */ + localToWorld(vector: Vector3): Vector3; + + /** + * Converts the vector from world space to this object's local space. + * @param vector A vector representing a position in world space. + */ + worldToLocal(vector: Vector3): Vector3; + + /** + * Rotates the object to face a point in world space. + * @remarks This method does not support objects having non-uniformly-scaled parent(s). + * @param vector A vector representing a position in world space to look at. + */ + lookAt(vector: Vector3): void; + /** + * Rotates the object to face a point in world space. + * @remarks This method does not support objects having non-uniformly-scaled parent(s). + * @param x Expects a `Float` + * @param y Expects a `Float` + * @param z Expects a `Float` + */ + lookAt(x: number, y: number, z: number): void; + + /** + * Adds another {@link Object3D} as child of this {@link Object3D}. + * @remarks An arbitrary number of objects may be added + * Any current parent on an {@link object} passed in here will be removed, since an {@link Object3D} can have at most one parent. + * @see {@link attach} + * @see {@link THREE.Group | Group} for info on manually grouping objects. + * @param object + */ + add(...object: Object3D[]): this; + + /** + * Removes a {@link Object3D} as child of this {@link Object3D}. + * @remarks An arbitrary number of objects may be removed. + * @see {@link THREE.Group | Group} for info on manually grouping objects. + * @param object + */ + remove(...object: Object3D[]): this; + + /** + * Removes this object from its current parent. + */ + removeFromParent(): this; + + /** + * Removes all child objects. + */ + clear(): this; + + /** + * Adds a {@link Object3D} as a child of this, while maintaining the object's world transform. + * @remarks Note: This method does not support scene graphs having non-uniformly-scaled nodes(s). + * @see {@link add} + * @param object + */ + attach(object: Object3D): this; + + /** + * Searches through an object and its children, starting with the object itself, and returns the first with a matching id. + * @remarks Note that ids are assigned in chronological order: 1, 2, 3, ..., incrementing by one for each new object. + * @see {@link id} + * @param id Unique number of the object instance. Expects a `Integer` + */ + getObjectById(id: number): Object3D | undefined; + + /** + * Searches through an object and its children, starting with the object itself, and returns the first with a matching name. + * @remarks Note that for most objects the name is an empty string by default + * You will have to set it manually to make use of this method. + * @param name String to match to the children's Object3D.name property. + */ + getObjectByName(name: string): Object3D | undefined; + + /** + * Searches through an object and its children, starting with the object itself, + * and returns the first with a property that matches the value given. + * + * @param name - the property name to search for. + * @param value - value of the given property. + */ + getObjectByProperty(name: string, value: any): Object3D | undefined; + + /** + * Searches through an object and its children, starting with the object itself, + * and returns the first with a property that matches the value given. + * @param name The property name to search for. + * @param value Value of the given property. + * @param optionalTarget target to set the result. Otherwise a new Array is instantiated. If set, you must clear + * this array prior to each call (i.e., array.length = 0;). + */ + getObjectsByProperty(name: string, value: any, optionalTarget?: Object3D[]): Object3D[]; + + /** + * Returns a vector representing the position of the object in world space. + * @param target The result will be copied into this Vector3. + */ + getWorldPosition(target: Vector3): Vector3; + + /** + * Returns a quaternion representing the rotation of the object in world space. + * @param target The result will be copied into this Quaternion. + */ + getWorldQuaternion(target: Quaternion): Quaternion; + + /** + * Returns a vector of the scaling factors applied to the object for each axis in world space. + * @param target The result will be copied into this Vector3. + */ + getWorldScale(target: Vector3): Vector3; + + /** + * Returns a vector representing the direction of object's positive z-axis in world space. + * @param target The result will be copied into this Vector3. + */ + getWorldDirection(target: Vector3): Vector3; + + /** + * Abstract (empty) method to get intersections between a casted ray and this object + * @remarks Subclasses such as {@link THREE.Mesh | Mesh}, {@link THREE.Line | Line}, and {@link THREE.Points | Points} implement this method in order to use raycasting. + * @see {@link THREE.Raycaster | Raycaster} + * @param raycaster + * @param intersects + * @defaultValue `() => {}` + */ + raycast(raycaster: Raycaster, intersects: Intersection[]): void; + + /** + * Executes the callback on this object and all descendants. + * @remarks Note: Modifying the scene graph inside the callback is discouraged. + * @param callback A function with as first argument an {@link Object3D} object. + */ + traverse(callback: (object: Object3D) => any): void; + + /** + * Like traverse, but the callback will only be executed for visible objects + * @remarks Descendants of invisible objects are not traversed. + * Note: Modifying the scene graph inside the callback is discouraged. + * @param callback A function with as first argument an {@link Object3D} object. + */ + traverseVisible(callback: (object: Object3D) => any): void; + + /** + * Executes the callback on all ancestors. + * @remarks Note: Modifying the scene graph inside the callback is discouraged. + * @param callback A function with as first argument an {@link Object3D} object. + */ + traverseAncestors(callback: (object: Object3D) => any): void; + + /** + * Updates local transform. + */ + updateMatrix(): void; + + /** + * Updates the global transform of the object. + * And will update the object descendants if {@link matrixWorldNeedsUpdate | .matrixWorldNeedsUpdate} is set to true or if the {@link force} parameter is set to `true`. + * @param force A boolean that can be used to bypass {@link matrixWorldAutoUpdate | .matrixWorldAutoUpdate}, to recalculate the world matrix of the object and descendants on the current frame. + * Useful if you cannot wait for the renderer to update it on the next frame, assuming {@link matrixWorldAutoUpdate | .matrixWorldAutoUpdate} set to `true`. + */ + updateMatrixWorld(force?: boolean): void; + + /** + * Updates the global transform of the object. + * @param updateParents Recursively updates global transform of ancestors. + * @param updateChildren Recursively updates global transform of descendants. + */ + updateWorldMatrix(updateParents: boolean, updateChildren: boolean): void; + + /** + * Convert the object to three.js {@link https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 | JSON Object/Scene format}. + * @param meta Object containing metadata such as materials, textures or images for the object. + */ + toJSON(meta?: JSONMeta): Object3DJSON; + + /** + * Returns a clone of `this` object and optionally all descendants. + * @param recursive If true, descendants of the object are also cloned. Default `true` + */ + clone(recursive?: boolean): this; + + /** + * Copies the given object into this object. + * @remarks Event listeners and user-defined callbacks ({@link .onAfterRender} and {@link .onBeforeRender}) are not copied. + * @param object + * @param recursive If set to `true`, descendants of the object are copied next to the existing ones. If set to + * `false`, descendants are left unchanged. Default is `true`. + */ + copy(object: Object3D, recursive?: boolean): this; +} diff --git a/src-testing/src/core/Raycaster.d.ts b/src-testing/src/core/Raycaster.d.ts new file mode 100644 index 000000000..4b6d3746e --- /dev/null +++ b/src-testing/src/core/Raycaster.d.ts @@ -0,0 +1,208 @@ +import { Camera } from "../cameras/Camera.js"; +import { Ray } from "../math/Ray.js"; +import { Vector2 } from "../math/Vector2.js"; +import { Vector3 } from "../math/Vector3.js"; +import { XRTargetRaySpace } from "../renderers/webxr/WebXRController.js"; +import { Layers } from "./Layers.js"; +import { Object3D } from "./Object3D.js"; + +export interface Face { + a: number; + b: number; + c: number; + normal: Vector3; + materialIndex: number; +} + +export interface Intersection { + /** Distance between the origin of the ray and the intersection */ + distance: number; + distanceToRay?: number | undefined; + /** Point of intersection, in world coordinates */ + point: Vector3; + index?: number | undefined; + /** Intersected face */ + face?: Face | null | undefined; + /** Index of the intersected face */ + faceIndex?: number | null | undefined; + barycoord?: Vector3 | null; + /** The intersected object */ + object: TIntersected; + uv?: Vector2 | undefined; + uv1?: Vector2 | undefined; + normal?: Vector3; + /** The index number of the instance where the ray intersects the {@link THREE.InstancedMesh | InstancedMesh } */ + instanceId?: number | undefined; + pointOnLine?: Vector3; + batchId?: number; +} + +export interface RaycasterParameters { + Mesh: any; + Line: { threshold: number }; + Line2?: { threshold: number }; + LOD: any; + Points: { threshold: number }; + Sprite: any; +} + +/** + * This class is designed to assist with {@link https://en.wikipedia.org/wiki/Ray_casting | raycasting} + * @remarks + * Raycasting is used for mouse picking (working out what objects in the 3d space the mouse is over) amongst other things. + * @example + * ```typescript + * const raycaster = new THREE.Raycaster(); + * const pointer = new THREE.Vector2(); + * + * function onPointerMove(event) { + * // calculate pointer position in normalized device coordinates (-1 to +1) for both components + * pointer.x = (event.clientX / window.innerWidth) * 2 - 1; + * pointer.y = -(event.clientY / window.innerHeight) * 2 + 1; + * } + * + * function render() { + * // update the picking ray with the camera and pointer position + * raycaster.setFromCamera(pointer, camera); + * // calculate objects intersecting the picking ray + * const intersects = raycaster.intersectObjects(scene.children); + * for (let i = 0; i & lt; intersects.length; i++) { + * intersects[i].object.material.color.set(0xff0000); + * } + * renderer.render(scene, camera); + * } + * window.addEventListener('pointermove', onPointerMove); + * window.requestAnimationFrame(render); + * ``` + * @see Example: {@link https://threejs.org/examples/#webgl_interactive_cubes | Raycasting to a Mesh} + * @see Example: {@link https://threejs.org/examples/#webgl_interactive_cubes_ortho | Raycasting to a Mesh in using an OrthographicCamera} + * @see Example: {@link https://threejs.org/examples/#webgl_interactive_buffergeometry | Raycasting to a Mesh with BufferGeometry} + * @see Example: {@link https://threejs.org/examples/#webgl_instancing_raycast | Raycasting to a InstancedMesh} + * @see Example: {@link https://threejs.org/examples/#webgl_interactive_lines | Raycasting to a Line} + * @see Example: {@link https://threejs.org/examples/#webgl_interactive_raycasting_points | Raycasting to Points} + * @see Example: {@link https://threejs.org/examples/#webgl_geometry_terrain_raycast | Terrain raycasting} + * @see Example: {@link https://threejs.org/examples/#webgl_interactive_voxelpainter | Raycasting to paint voxels} + * @see Example: {@link https://threejs.org/examples/#webgl_raycaster_texture | Raycast to a Texture} + * @see {@link https://threejs.org/docs/index.html#api/en/core/Raycaster | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/Raycaster.js | Source} + */ +export class Raycaster { + /** + * This creates a new {@link Raycaster} object. + * @param origin The origin vector where the ray casts from. Default `new Vector3()` + * @param direction The direction vector that gives direction to the ray. Should be normalized. Default `new Vector3(0, 0, -1)` + * @param near All results returned are further away than near. Near can't be negative. Expects a `Float`. Default `0` + * @param far All results returned are closer than far. Far can't be lower than near. Expects a `Float`. Default `Infinity` + */ + constructor(origin?: Vector3, direction?: Vector3, near?: number, far?: number); + + /** + * The {@link THREE.RaycasterRay | Ray} used for the raycasting. + */ + ray: Ray; + + /** + * The near factor of the raycaster. This value indicates which objects can be discarded based on the distance. + * This value shouldn't be negative and should be smaller than the far property. + * @remarks Expects a `Float` + * @defaultValue `0` + */ + near: number; + + /** + * The far factor of the raycaster. This value indicates which objects can be discarded based on the distance. + * This value shouldn't be negative and should be larger than the near property. + * @remarks Expects a `Float` + * @defaultValue `Infinity` + */ + far: number; + + /** + * The camera to use when raycasting against view-dependent objects such as billboarded objects like {@link THREE.Sprites | Sprites}. + * This field can be set manually or is set when calling {@link setFromCamera}. + * @defaultValue `null` + */ + camera: Camera; + + /** + * Used by {@link Raycaster} to selectively ignore 3D objects when performing intersection tests. + * The following code example ensures that only 3D objects on layer `1` will be honored by the instance of Raycaster. + * ``` + * raycaster.layers.set( 1 ); + * object.layers.enable( 1 ); + * ``` + * @defaultValue `new THREE.Layers()` - See {@link THREE.Layers | Layers}. + */ + layers: Layers; + + /** + * An data object where threshold is the precision of the {@link Raycaster} when intersecting objects, in world units. + * @defaultValue `{ Mesh: {}, Line: { threshold: 1 }, LOD: {}, Points: { threshold: 1 }, Sprite: {} }` + */ + params: RaycasterParameters; + + /** + * Updates the ray with a new origin and direction + * @remarks + * Please note that this method only copies the values from the arguments. + * @param origin The origin vector where the ray casts from. + * @param direction The normalized direction vector that gives direction to the ray. + */ + set(origin: Vector3, direction: Vector3): void; + + /** + * Updates the ray with a new origin and direction. + * @param coords 2D coordinates of the mouse, in normalized device coordinates (NDC)---X and Y components should be between -1 and 1. + * @param camera camera from which the ray should originate + */ + setFromCamera(coords: Vector2, camera: Camera): void; + + /** + * Updates the ray with a new origin and direction. + * @param controller The controller to copy the position and direction from. + */ + setFromXRController(controller: XRTargetRaySpace): this; + + /** + * Checks all intersection between the ray and the object with or without the descendants + * @remarks Intersections are returned sorted by distance, closest first + * @remarks {@link Raycaster} delegates to the {@link Object3D.raycast | raycast} method of the passed object, when evaluating whether the ray intersects the object or not + * This allows {@link THREE.Mesh | meshes} to respond differently to ray casting than {@link THREE.Line | lines} and {@link THREE.Points | pointclouds}. + * **Note** that for meshes, faces must be pointed towards the origin of the {@link Raycaster.ray | ray} in order to be detected; + * intersections of the ray passing through the back of a face will not be detected + * To raycast against both faces of an object, you'll want to set the {@link Mesh.material | material}'s {@link Material.side | side} property to `THREE.DoubleSide`. + * @see {@link intersectObjects | .intersectObjects()}. + * @param object The object to check for intersection with the ray. + * @param recursive If true, it also checks all descendants. Otherwise it only checks intersection with the object. Default `true` + * @param optionalTarget Target to set the result. Otherwise a new {@link Array | Array} is instantiated. + * If set, you must clear this array prior to each call (i.e., array.length = 0;). Default `[]` + * @returns An array of intersections is returned. + */ + intersectObject( + object: Object3D, + recursive?: boolean, + optionalTarget?: Array>, + ): Array>; + + /** + * Checks all intersection between the ray and the objects with or without the descendants + * @remarks Intersections are returned sorted by distance, closest first + * @remarks Intersections are of the same form as those returned by {@link intersectObject | .intersectObject()}. + * @remarks {@link Raycaster} delegates to the {@link Object3D.raycast | raycast} method of the passed object, when evaluating whether the ray intersects the object or not + * This allows {@link THREE.Mesh | meshes} to respond differently to ray casting than {@link THREE.Line | lines} and {@link THREE.Points | pointclouds}. + * **Note** that for meshes, faces must be pointed towards the origin of the {@link Raycaster.ray | ray} in order to be detected; + * intersections of the ray passing through the back of a face will not be detected + * To raycast against both faces of an object, you'll want to set the {@link Mesh.material | material}'s {@link Material.side | side} property to `THREE.DoubleSide`. + * @see {@link intersectObject | .intersectObject()}. + * @param objects The objects to check for intersection with the ray. + * @param recursive If true, it also checks all descendants of the objects. Otherwise it only checks intersection with the objects. Default `true` + * @param optionalTarget Target to set the result. Otherwise a new {@link Array | Array} is instantiated. + * If set, you must clear this array prior to each call (i.e., array.length = 0;). Default `[]` + * @returns An array of intersections is returned. + */ + intersectObjects( + objects: Object3D[], + recursive?: boolean, + optionalTarget?: Array>, + ): Array>; +} diff --git a/src-testing/src/core/RenderTarget.d.ts b/src-testing/src/core/RenderTarget.d.ts new file mode 100644 index 000000000..2f20cabb5 --- /dev/null +++ b/src-testing/src/core/RenderTarget.d.ts @@ -0,0 +1,95 @@ +import { + MagnificationTextureFilter, + MinificationTextureFilter, + PixelFormatGPU, + TextureDataType, + Wrapping, +} from "../constants.js"; +import { Vector4 } from "../math/Vector4.js"; +import { DepthTexture } from "../textures/DepthTexture.js"; +import { Texture } from "../textures/Texture.js"; +import { EventDispatcher } from "./EventDispatcher.js"; + +export interface RenderTargetOptions { + wrapS?: Wrapping | undefined; + wrapT?: Wrapping | undefined; + magFilter?: MagnificationTextureFilter | undefined; + minFilter?: MinificationTextureFilter | undefined; + generateMipmaps?: boolean | undefined; // true + format?: number | undefined; // RGBAFormat + type?: TextureDataType | undefined; // UnsignedByteType + anisotropy?: number | undefined; // 1 + colorSpace?: string | undefined; + internalFormat?: PixelFormatGPU | null | undefined; // null + depthBuffer?: boolean | undefined; // true + stencilBuffer?: boolean | undefined; // false + resolveDepthBuffer?: boolean | undefined; // true + resolveStencilBuffer?: boolean | undefined; // true + depthTexture?: DepthTexture | null | undefined; // null + /** + * Defines the count of MSAA samples. Can only be used with WebGL 2. Default is **0**. + * @default 0 + */ + samples?: number | undefined; + count?: number | undefined; +} + +export class RenderTarget extends EventDispatcher<{ dispose: {} }> { + readonly isRenderTarget: true; + + width: number; + height: number; + depth: number; + + scissor: Vector4; + /** + * @default false + */ + scissorTest: boolean; + viewport: Vector4; + textures: TTexture[]; + + /** + * @default true + */ + depthBuffer: boolean; + + /** + * @default false + */ + stencilBuffer: boolean; + + /** + * Defines whether the depth buffer should be resolved when rendering into a multisampled render target. + * @default true + */ + resolveDepthBuffer: boolean; + + /** + * Defines whether the stencil buffer should be resolved when rendering into a multisampled render target. + * This property has no effect when {@link .resolveDepthBuffer} is set to `false`. + * @default true + */ + resolveStencilBuffer: boolean; + + /** + * @default null + */ + depthTexture: DepthTexture | null; + + /** + * Defines the count of MSAA samples. Can only be used with WebGL 2. Default is **0**. + * @default 0 + */ + samples: number; + + constructor(width?: number, height?: number, options?: RenderTargetOptions); + + get texture(): TTexture; + set texture(value: TTexture); + + setSize(width: number, height: number, depth?: number): void; + clone(): this; + copy(source: RenderTarget): this; + dispose(): void; +} diff --git a/src-testing/src/core/Uniform.d.ts b/src-testing/src/core/Uniform.d.ts new file mode 100644 index 000000000..851ae2bf9 --- /dev/null +++ b/src-testing/src/core/Uniform.d.ts @@ -0,0 +1,38 @@ +/** + * Uniforms are global GLSL variables. + * They are passed to shader programs. + * @example + * When declaring a uniform of a {@link THREE.ShaderMaterial | ShaderMaterial}, it is declared by value or by object. + * ```typescript + * uniforms: { + * time: { + * value: 1.0 + * }, + * resolution: new Uniform(new Vector2()) + * }; + * ``` + * @see Example: {@link https://threejs.org/examples/#webgl_nodes_materials_instance_uniform | WebGL2 / nodes / materials / instance / uniform} + * @see Example: {@link https://threejs.org/examples/#webgpu_instance_uniform| WebGPU / instance / uniform} + * @see {@link https://threejs.org/docs/index.html#api/en/core/Uniform | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/Uniform.js | Source} + */ +export class Uniform { + /** + * Create a new instance of {@link THREE.Uniform | Uniform} + * @param value An object containing the value to set up the uniform. It's type must be one of the Uniform Types described above. + */ + constructor(value: T); + + /** + * Current value of the uniform. + */ + value: T; + + /** + * Returns a clone of this uniform. + * @remarks + * If the uniform's {@link value} property is an {@link Object | Object} with a `clone()` method, this is used, + * otherwise the value is copied by assignment Array values are **shared** between cloned {@link THREE.UniformUniform | Uniform}s. + */ + clone(): Uniform; +} diff --git a/src-testing/src/core/UniformsGroup.d.ts b/src-testing/src/core/UniformsGroup.d.ts new file mode 100644 index 000000000..4fb30b2c1 --- /dev/null +++ b/src-testing/src/core/UniformsGroup.d.ts @@ -0,0 +1,33 @@ +import { Usage } from "../constants.js"; +import { EventDispatcher } from "./EventDispatcher.js"; +import { Uniform } from "./Uniform.js"; + +/** + * @see Example: {@link https://threejs.org/examples/#webgl2_ubo | WebGL2 / UBO} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/UniformsGroup.js | Source} + */ +export class UniformsGroup extends EventDispatcher<{ dispose: {} }> { + constructor(); + + readonly isUniformsGroup: true; + + id: number; + + usage: Usage; + + uniforms: Array; + + add(uniform: Uniform | Uniform[]): this; + + remove(uniform: Uniform | Uniform[]): this; + + setName(name: string): this; + + setUsage(value: Usage): this; + + dispose(): this; + + copy(source: UniformsGroup): this; + + clone(): UniformsGroup; +} diff --git a/src-testing/src/extras/Controls.d.ts b/src-testing/src/extras/Controls.d.ts new file mode 100644 index 000000000..6202a5c0c --- /dev/null +++ b/src-testing/src/extras/Controls.d.ts @@ -0,0 +1,54 @@ +import { EventDispatcher } from "../core/EventDispatcher.js"; +import { Object3D } from "../core/Object3D.js"; + +/** + * Abstract base class for controls. + */ +declare abstract class Controls extends EventDispatcher { + /** + * The 3D object that is managed by the controls. + */ + object: Object3D; + + /** + * The HTML element used for event listeners. If not provided via the constructor, {@link .connect} must be called + * after `domElement` has been set. + */ + domElement: HTMLElement | null; + + /** + * When set to `false`, the controls will not respond to user input. Default is `true`. + */ + enabled: boolean; + + /** + * Creates a new instance of {@link Controls}. + * @param object The object the controls should manage (usually the camera). + * @param domElement The HTML element used for event listeners. (optional) + */ + constructor(object: Object3D, domElement?: HTMLElement | null); + + /** + * Connects the controls to the DOM. This method has so called "side effects" since it adds the module's event + * listeners to the DOM. + */ + connect(): void; + + /** + * Disconnects the controls from the DOM. + */ + disconnect(): void; + + /** + * Call this method if you no longer want use to the controls. It frees all internal resources and removes all event + * listeners. + */ + dispose(): void; + + /** + * Controls should implement this method if they have to update their internal state per simulation step. + */ + update(delta: number): void; +} + +export { Controls }; diff --git a/src-testing/src/extras/DataUtils.d.ts b/src-testing/src/extras/DataUtils.d.ts new file mode 100644 index 000000000..fd678dbf4 --- /dev/null +++ b/src-testing/src/extras/DataUtils.d.ts @@ -0,0 +1,22 @@ +/** + * Returns a half precision floating point value from the given single precision floating point value. + * @param val A single precision floating point value. + * @see {@link https://threejs.org/docs/index.html#api/en/extras/DataUtils | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/DataUtils.js | Source} + */ +declare function toHalfFloat(val: number): number; + +/** + * Returns a single precision floating point value from the given half precision floating point value. + * @param val A half precision floating point value. + * @see {@link https://threejs.org/docs/index.html#api/en/extras/DataUtils | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/DataUtils.js | Source} + */ +declare function fromHalfFloat(val: number): number; + +declare const DataUtils: { + toHalfFloat: typeof toHalfFloat; + fromHalfFloat: typeof fromHalfFloat; +}; + +export { DataUtils, fromHalfFloat, toHalfFloat }; diff --git a/src-testing/src/extras/Earcut.d.ts b/src-testing/src/extras/Earcut.d.ts new file mode 100644 index 000000000..623b8ee82 --- /dev/null +++ b/src-testing/src/extras/Earcut.d.ts @@ -0,0 +1,15 @@ +/** + * An implementation of the {@link Earcut} polygon triangulation algorithm + * @remarks + * The code is a port of {@link https://github.com/mapbox/earcut | mapbox/earcut}. + * @see {@link https://threejs.org/docs/index.html#api/en/extras/Earcut | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/Earcut.js | Source} + */ +export const Earcut: { + /** + * Triangulates the given shape definition by returning an array of triangles + * @remarks + * A triangle is defined by three consecutive integers representing vertex indices. + */ + triangulate(data: number[], holeIndices?: number[], dim?: number): number[]; +}; diff --git a/src-testing/src/extras/ImageUtils.d.ts b/src-testing/src/extras/ImageUtils.d.ts new file mode 100644 index 000000000..798fc3e90 --- /dev/null +++ b/src-testing/src/extras/ImageUtils.d.ts @@ -0,0 +1,32 @@ +/** + * A class containing utility functions for images. + * @see {@link https://threejs.org/docs/index.html#api/en/extras/ImageUtils | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/ImageUtils.js | Source} + */ +declare class ImageUtils { + /** + * Returns a data URI containing a representation of the given image. + * @param image The image object. + */ + static getDataURL( + image: HTMLImageElement | HTMLCanvasElement | CanvasImageSource | ImageBitmap | ImageData, + ): string; + + /** + * Converts the given sRGB image data to linear color space. + * @param image + */ + static sRGBToLinear(image: HTMLImageElement | HTMLCanvasElement | ImageBitmap): HTMLCanvasElement; + + /** + * Converts the given sRGB image data to linear color space. + * @param image + */ + static sRGBToLinear(image: ImageData): { + data: ImageData["data"]; + width: ImageData["width"]; + height: ImageData["height"]; + }; +} + +export { ImageUtils }; diff --git a/src-testing/src/extras/PMREMGenerator.d.ts b/src-testing/src/extras/PMREMGenerator.d.ts new file mode 100644 index 000000000..3eb4a15e1 --- /dev/null +++ b/src-testing/src/extras/PMREMGenerator.d.ts @@ -0,0 +1,82 @@ +import { WebGLRenderer } from "../renderers/WebGLRenderer.js"; +import { WebGLRenderTarget } from "../renderers/WebGLRenderTarget.js"; +import { Scene } from "../scenes/Scene.js"; +import { CubeTexture } from "../textures/CubeTexture.js"; +import { Texture } from "../textures/Texture.js"; + +/** + * This class generates a Prefiltered, Mipmapped Radiance Environment Map (PMREM) from a cubeMap environment texture. + * @remarks + * This allows different levels of blur to be quickly accessed based on material roughness + * Unlike a traditional mipmap chain, it only goes down to the LOD_MIN level (above), and then creates extra even more filtered 'mips' at the same LOD_MIN resolution, + * associated with higher roughness levels + * In this way we maintain resolution to smoothly interpolate diffuse lighting while limiting sampling computation. + * @remarks + * Note: The minimum {@link THREE.MeshStandardMaterial | MeshStandardMaterial}'s roughness depends on the size of the provided texture + * If your render has small dimensions or the shiny parts have a lot of curvature, you may still be able to get away with a smaller texture size. + * + * | texture size | minimum roughness | + * |--------------|--------------------| + * | 16 | 0.21 | + * | 32 | 0.15 | + * | 64 | 0.11 | + * | 128 | 0.076 | + * | 256 | 0.054 | + * | 512 | 0.038 | + * | 1024 | 0.027 | + * + * @see {@link https://threejs.org/docs/index.html#api/en/extras/PMREMGenerator | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/PMREMGenerator.js | Source} + */ +export class PMREMGenerator { + /** + * This constructor creates a new PMREMGenerator. + * @param renderer + */ + constructor(renderer: WebGLRenderer); + + /** + * Generates a PMREM from a supplied Scene, which can be faster than using an image if networking bandwidth is low + * @remarks + * Optional near and far planes ensure the scene is rendered in its entirety (the cubeCamera is placed at the origin). + * @param scene The given scene. + * @param sigma Specifies a blur radius in radians to be applied to the scene before PMREM generation. Default `0`. + * @param near The near plane value. Default `0.1`. + * @param far The far plane value. Default `100`. + */ + fromScene(scene: Scene, sigma?: number, near?: number, far?: number): WebGLRenderTarget; + + /** + * Generates a PMREM from an equirectangular texture, which can be either LDR or HDR. The ideal input image size is + * 1k (1024 x 512), as this matches best with the 256 x 256 cubemap output. The smallest supported equirectangular + * image size is 64 x 32. + */ + fromEquirectangular(equirectangular: Texture, renderTarget?: WebGLRenderTarget | null): WebGLRenderTarget; + + /** + * Generates a PMREM from an cubemap texture, which can be either LDR or HDR. The ideal input cube size is + * 256 x 256, as this matches best with the 256 x 256 cubemap output. The smallest supported cube size is 16 x 16. + */ + fromCubemap(cubemap: CubeTexture, renderTarget?: WebGLRenderTarget | null): WebGLRenderTarget; + + /** + * Pre-compiles the cubemap shader + * @remarks + * You can get faster start-up by invoking this method during your texture's network fetch for increased concurrency. + */ + compileCubemapShader(): void; + + /** + * Pre-compiles the equirectangular shader + * @remarks + * You can get faster start-up by invoking this method during your texture's network fetch for increased concurrency. + */ + compileEquirectangularShader(): void; + + /** + * Frees the GPU-related resources allocated by this instance + * @remarks + * Call this method whenever this instance is no longer used in your app. + */ + dispose(): void; +} diff --git a/src-testing/src/extras/ShapeUtils.d.ts b/src-testing/src/extras/ShapeUtils.d.ts new file mode 100644 index 000000000..60fe8aaf9 --- /dev/null +++ b/src-testing/src/extras/ShapeUtils.d.ts @@ -0,0 +1,25 @@ +import { Vector2Like } from "../math/Vector2.js"; + +/** + * A class containing utility functions for shapes. + * @remarks Note that these are all linear functions so it is necessary to calculate separately for x, y (and z, w if present) components of a vector. + * @see {@link https://threejs.org/docs/index.html#api/en/extras/ShapeUtils | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/ShapeUtils.js | Source} + */ +export class ShapeUtils { + /** + * Calculate area of a ( 2D ) contour polygon. + */ + static area(contour: readonly Vector2Like[]): number; + + /** + * Note that this is a linear function so it is necessary to calculate separately for x, y components of a polygon. + * @remarks Used internally by {@link THREE.Path | Path}, {@link THREE.ExtrudeGeometry | ExtrudeGeometry} and {@link THREE.ShapeGeometry | ShapeGeometry}. + */ + static isClockWise(pts: readonly Vector2Like[]): boolean; + + /** + * Used internally by {@link THREE.ExtrudeGeometry | ExtrudeGeometry} and {@link THREE.ShapeGeometry | ShapeGeometry} to calculate faces in shapes with holes. + */ + static triangulateShape(contour: Vector2Like[], holes: Vector2Like[][]): number[][]; +} diff --git a/src-testing/src/extras/TextureUtils.d.ts b/src-testing/src/extras/TextureUtils.d.ts new file mode 100644 index 000000000..254458b43 --- /dev/null +++ b/src-testing/src/extras/TextureUtils.d.ts @@ -0,0 +1,42 @@ +import { CompressedPixelFormat, PixelFormat, TextureDataType } from "../constants.js"; +import { Texture } from "../textures/Texture.js"; + +/** + * Scales the texture as large as possible within its surface without cropping or stretching the texture. The method + * preserves the original aspect ratio of the texture. Akin to CSS `object-fit: contain`. + */ +declare function contain(texture: Texture, aspect: number): Texture; + +/** + * Scales the texture to the smallest possible size to fill the surface, leaving no empty space. The method preserves + * the original aspect ratio of the texture. Akin to CSS `object-fit: cover`. + */ +declare function cover(texture: Texture, aspect: number): Texture; + +/** + * Configures the texture to the default transformation. Akin to CSS `object-fit: fill`. + */ +declare function fill(texture: Texture): Texture; + +/** + * Given the width, height, format, and type of a texture. Determines how many bytes must be used to represent the + * texture. + */ +declare function getByteLength( + width: number, + height: number, + format: PixelFormat | CompressedPixelFormat, + type: TextureDataType, +): number; + +/** + * A class containing utility functions for textures. + */ +declare const TextureUtils: { + contain: typeof contain; + cover: typeof cover; + fill: typeof fill; + getByteLength: typeof getByteLength; +}; + +export { contain, cover, fill, getByteLength, TextureUtils }; diff --git a/src-testing/src/extras/core/Curve.d.ts b/src-testing/src/extras/core/Curve.d.ts new file mode 100644 index 000000000..9e3610903 --- /dev/null +++ b/src-testing/src/extras/core/Curve.d.ts @@ -0,0 +1,162 @@ +import { Vector2 } from "../../math/Vector2.js"; +import { Vector3 } from "../../math/Vector3.js"; + +export interface CurveJSON { + metadata: { version: number; type: string; generator: string }; + arcLengthDivisions: number; + type: string; +} + +/** + * An abstract base class for creating a {@link Curve} object that contains methods for interpolation + * @remarks + * For an array of Curves see {@link THREE.CurvePath | CurvePath}. + * @remarks + * This following curves inherit from THREE.Curve: + * + * **2D curves** + * - {@link THREE.ArcCurve} + * - {@link THREE.CubicBezierCurve} + * - {@link THREE.EllipseCurve} + * - {@link THREE.LineCurve} + * - {@link THREE.QuadraticBezierCurve} + * - {@link THREE.SplineCurve} + * + * **3D curves** + * - {@link THREE.CatmullRomCurve3} + * - {@link THREE.CubicBezierCurve3} + * - {@link THREE.LineCurve3} + * - {@link THREE.QuadraticBezierCurve3} + * + * @see {@link https://threejs.org/docs/index.html#api/en/extras/core/Curve | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/core/Curve.js | Source} + */ +export abstract class Curve { + protected constructor(); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `Curve` + */ + readonly type: string | "Curve"; + + /** + * This value determines the amount of divisions when calculating the cumulative segment lengths of a {@link Curve} + * via {@link .getLengths}. + * To ensure precision when using methods like {@link .getSpacedPoints}, it is recommended to increase {@link .arcLengthDivisions} if the {@link Curve} is very large. + * @defaultValue `200` + * @remarks Expects a `Integer` + */ + arcLengthDivisions: number; + + /** + * Returns a vector for a given position on the curve. + * @param t A position on the curve. Must be in the range `[ 0, 1 ]`. Expects a `Float` + * @param optionalTarget If specified, the result will be copied into this Vector, otherwise a new Vector will be created. Default `new T`. + */ + getPoint(t: number, optionalTarget?: TVector): TVector; + + /** + * Returns a vector for a given position on the {@link Curve} according to the arc length. + * @param u A position on the {@link Curve} according to the arc length. Must be in the range `[ 0, 1 ]`. Expects a `Float` + * @param optionalTarget If specified, the result will be copied into this Vector, otherwise a new Vector will be created. Default `new T`. + */ + getPointAt(u: number, optionalTarget?: TVector): TVector; + + /** + * Returns a set of divisions `+1` points using {@link .getPoint | getPoint(t)}. + * @param divisions Number of pieces to divide the {@link Curve} into. Expects a `Integer`. Default `5` + */ + getPoints(divisions?: number): TVector[]; + + /** + * Returns a set of divisions `+1` equi-spaced points using {@link .getPointAt | getPointAt(u)}. + * @param divisions Number of pieces to divide the {@link Curve} into. Expects a `Integer`. Default `5` + */ + getSpacedPoints(divisions?: number): TVector[]; + + /** + * Get total {@link Curve} arc length. + */ + getLength(): number; + + /** + * Get list of cumulative segment lengths. + * @param divisions Expects a `Integer` + */ + getLengths(divisions?: number): number[]; + + /** + * Update the cumulative segment distance cache + * @remarks + * The method must be called every time {@link Curve} parameters are changed + * If an updated {@link Curve} is part of a composed {@link Curve} like {@link THREE.CurvePath | CurvePath}, + * {@link .updateArcLengths}() must be called on the composed curve, too. + */ + updateArcLengths(): void; + + /** + * Given u in the range `[ 0, 1 ]`, + * @remarks + * `u` and `t` can then be used to give you points which are equidistant from the ends of the curve, using {@link .getPoint}. + * @param u Expects a `Float` + * @param distance Expects a `Float` + * @returns `t` also in the range `[ 0, 1 ]`. Expects a `Float`. + */ + getUtoTmapping(u: number, distance: number): number; + + /** + * Returns a unit vector tangent at t + * @remarks + * If the derived {@link Curve} does not implement its tangent derivation, two points a small delta apart will be used to find its gradient which seems to give a reasonable approximation. + * @param t A position on the curve. Must be in the range `[ 0, 1 ]`. Expects a `Float` + * @param optionalTarget If specified, the result will be copied into this Vector, otherwise a new Vector will be created. + */ + getTangent(t: number, optionalTarget?: TVector): TVector; + + /** + * Returns tangent at a point which is equidistant to the ends of the {@link Curve} from the point given in {@link .getTangent}. + * @param u A position on the {@link Curve} according to the arc length. Must be in the range `[ 0, 1 ]`. Expects a `Float` + * @param optionalTarget If specified, the result will be copied into this Vector, otherwise a new Vector will be created. + */ + getTangentAt(u: number, optionalTarget?: TVector): TVector; + + /** + * Generates the Frenet Frames + * @remarks + * Requires a {@link Curve} definition in 3D space + * Used in geometries like {@link THREE.TubeGeometry | TubeGeometry} or {@link THREE.ExtrudeGeometry | ExtrudeGeometry}. + * @param segments Expects a `Integer` + * @param closed + */ + computeFrenetFrames( + segments: number, + closed?: boolean, + ): { + tangents: Vector3[]; + normals: Vector3[]; + binormals: Vector3[]; + }; + + /** + * Creates a clone of this instance. + */ + clone(): this; + /** + * Copies another {@link Curve} object to this instance. + * @param source + */ + copy(source: Curve): this; + + /** + * Returns a JSON object representation of this instance. + */ + toJSON(): CurveJSON; + + /** + * Copies the data from the given JSON object to this instance. + * @param json + */ + fromJSON(json: CurveJSON): this; +} diff --git a/src-testing/src/extras/core/CurvePath.d.ts b/src-testing/src/extras/core/CurvePath.d.ts new file mode 100644 index 000000000..3a8577fd1 --- /dev/null +++ b/src-testing/src/extras/core/CurvePath.d.ts @@ -0,0 +1,77 @@ +import { Vector2 } from "../../math/Vector2.js"; +import { Vector3 } from "../../math/Vector3.js"; +import { Curve, CurveJSON } from "./Curve.js"; + +export interface CurvePathJSON extends CurveJSON { + autoClose: boolean; + curves: CurveJSON[]; +} + +/** + * Curved Path - a curve path is simply a array of connected curves, but retains the api of a curve. + * @remarks + * A {@link CurvePath} is simply an array of connected curves, but retains the api of a curve. + * @see {@link https://threejs.org/docs/index.html#api/en/extras/core/CurvePath | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/core/CurvePath.js | Source} + */ +export class CurvePath extends Curve { + /** + * The constructor take no parameters. + */ + constructor(); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `CurvePath` + */ + override readonly type: string | "CurvePath"; + + /** + * The array of {@link Curve | Curves}. + * @defaultValue `[]` + */ + curves: Array>; + + /** + * Whether or not to automatically close the path. + * @defaultValue false + */ + autoClose: boolean; + + /** + * Add a curve to the {@link .curves} array. + * @param curve + */ + add(curve: Curve): void; + /** + * Adds a {@link LineCurve | lineCurve} to close the path. + */ + closePath(): this; + + getPoint(t: number, optionalTarget?: TVector): TVector; + + /** + * Get list of cumulative curve lengths of the curves in the {@link .curves} array. + */ + getCurveLengths(): number[]; + + /** + * Returns an array of points representing a sequence of curves + * @remarks + * The `division` parameter defines the number of pieces each curve is divided into + * However, for optimization and quality purposes, the actual sampling resolution for each curve depends on its type + * For example, for a {@link THREE.LineCurve | LineCurve}, the returned number of points is always just 2. + * @param divisions Number of pieces to divide the curve into. Expects a `Integer`. Default `12` + */ + override getPoints(divisions?: number): TVector[]; + + /** + * Returns a set of divisions `+1` equi-spaced points using {@link .getPointAt | getPointAt(u)}. + * @param divisions Number of pieces to divide the curve into. Expects a `Integer`. Default `40` + */ + override getSpacedPoints(divisions?: number): TVector[]; + + toJSON(): CurvePathJSON; + fromJSON(json: CurvePathJSON): this; +} diff --git a/src-testing/src/extras/core/Interpolations.d.ts b/src-testing/src/extras/core/Interpolations.d.ts new file mode 100644 index 000000000..9f5ed3784 --- /dev/null +++ b/src-testing/src/extras/core/Interpolations.d.ts @@ -0,0 +1,36 @@ +/** + * Used internally by {@link THREE.SplineCurve | SplineCurve}. + * @param t Interpolation weight. Expects a `Float` + * @param p0 Expects a `Float` + * @param p1 Expects a `Float` + * @param p2 Expects a `Float` + * @param p3 P0, p1, p2, the points defining the spline curve. Expects a `Float` + * @see {@link https://threejs.org/docs/index.html#api/en/extras/core/Interpolations | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/core/Interpolations.js | Source} + */ +declare function CatmullRom(t: number, p0: number, p1: number, p2: number, p3: number): number; + +/** + * Used internally by {@link THREE.QuadraticBezierCurve3 | QuadraticBezierCurve3} and {@link THREE.QuadraticBezierCurve | QuadraticBezierCurve}. + * @param t Interpolation weight. Expects a `Float` + * @param p0 Expects a `Float` + * @param p1 Expects a `Float` + * @param p2 P0, p1, the starting, control and end points defining the curve. Expects a `Float` + * @see {@link https://threejs.org/docs/index.html#api/en/extras/core/Interpolations | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/core/Interpolations.js | Source} + */ +declare function QuadraticBezier(t: number, p0: number, p1: number, p2: number): number; + +/** + * Used internally by {@link THREE.CubicBezierCurve3 | CubicBezierCurve3} and {@link THREE.CubicBezierCurve | CubicBezierCurve}. + * @param t Interpolation weight. Expects a `Float` + * @param p0 Expects a `Float` + * @param p1 Expects a `Float` + * @param p2 Expects a `Float` + * @param p3 P0, p1, p2, the starting, control(twice) and end points defining the curve. Expects a `Float` + * @see {@link https://threejs.org/docs/index.html#api/en/extras/core/Interpolations | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/core/Interpolations.js | Source} + */ +declare function CubicBezier(t: number, p0: number, p1: number, p2: number, p3: number): number; + +export { CatmullRom, CubicBezier, QuadraticBezier }; diff --git a/src-testing/src/extras/core/Path.d.ts b/src-testing/src/extras/core/Path.d.ts new file mode 100644 index 000000000..28be15b9c --- /dev/null +++ b/src-testing/src/extras/core/Path.d.ts @@ -0,0 +1,166 @@ +import { Vector2, Vector2Tuple } from "../../math/Vector2.js"; +import { CurvePath, CurvePathJSON } from "./CurvePath.js"; + +export interface PathJSON extends CurvePathJSON { + currentPoint: Vector2Tuple; +} + +/** + * A 2D {@link Path} representation. + * @remarks + * The class provides methods for creating paths and contours of 2D shapes similar to the 2D Canvas API. + * @example + * ```typescript + * const {@link Path} = new THREE.Path(); + * path.lineTo(0, 0.8); + * path.quadraticCurveTo(0, 1, 0.2, 1); + * path.lineTo(1, 1); + * const points = path.getPoints(); + * const geometry = new THREE.BufferGeometry().setFromPoints(points); + * const material = new THREE.LineBasicMaterial({ + * color: 0xffffff + * }); + * const line = new THREE.Line(geometry, material); + * scene.add(line); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/extras/core/Path | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/core/Path.js | Source} + */ +export class Path extends CurvePath { + /** + * Creates a {@link Path} from the points + * @remarks + * The first point defines the offset, then successive points are added to the {@link CurvePath.curves | curves} array as {@link LineCurve | LineCurves}. + * If no points are specified, an empty {@link Path} is created and the {@link .currentPoint} is set to the origin. + * @param points Array of {@link Vector2 | Vector2s}. + */ + constructor(points?: Vector2[]); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `Path` + */ + override readonly type: string | "Path"; + + /** + * The current offset of the path. Any new {@link THREE.Curve | Curve} added will start here. + * @defaultValue `new THREE.Vector2()` + */ + currentPoint: Vector2; + + /** + * Adds an absolutely positioned {@link THREE.EllipseCurve | EllipseCurve} to the path. + * @param x Expects a `Float` + * @param y X, The absolute center of the arc. Expects a `Float` + * @param radius The radius of the arc. Expects a `Float` + * @param startAngle The start angle in radians. Expects a `Float` + * @param endAngle The end angle in radians. Expects a `Float` + * @param clockwise Sweep the arc clockwise. Default `false` + */ + absarc(aX: number, aY: number, aRadius: number, aStartAngle: number, aEndAngle: number, aClockwise?: boolean): this; + + /** + * Adds an absolutely positioned {@link THREE.EllipseCurve | EllipseCurve} to the path. + * @param x Expects a `Float` + * @param y X, The absolute center of the ellipse. Expects a `Float` + * @param xRadius The radius of the ellipse in the x axis. Expects a `Float` + * @param yRadius The radius of the ellipse in the y axis. Expects a `Float` + * @param startAngle The start angle in radians. Expects a `Float` + * @param endAngle The end angle in radians. Expects a `Float` + * @param clockwise Sweep the ellipse clockwise. Default `false` + * @param rotation The rotation angle of the ellipse in radians, counterclockwise from the positive X axis. Optional, Expects a `Float`. Default `0` + */ + absellipse( + aX: number, + aY: number, + xRadius: number, + yRadius: number, + aStartAngle: number, + aEndAngle: number, + aClockwise?: boolean, + aRotation?: number, + ): this; + + /** + * Adds an {@link THREE.EllipseCurve | EllipseCurve} to the path, positioned relative to {@link .currentPoint}. + * @param x Expects a `Float` + * @param y X, The center of the arc offset from the last call. Expects a `Float` + * @param radius The radius of the arc. Expects a `Float` + * @param startAngle The start angle in radians. Expects a `Float` + * @param endAngle The end angle in radians. Expects a `Float` + * @param clockwise Sweep the arc clockwise. Default `false` + */ + arc(aX: number, aY: number, aRadius: number, aStartAngle: number, aEndAngle: number, aClockwise?: boolean): this; + + /** + * This creates a bezier curve from {@link .currentPoint} with (cp1X, cp1Y) and (cp2X, cp2Y) as control points and updates {@link .currentPoint} to x and y. + * @param cp1X Expects a `Float` + * @param cp1Y Expects a `Float` + * @param cp2X Expects a `Float` + * @param cp2Y Expects a `Float` + * @param x Expects a `Float` + * @param y Expects a `Float` + */ + bezierCurveTo(aCP1x: number, aCP1y: number, aCP2x: number, aCP2y: number, aX: number, aY: number): this; + + /** + * Adds an {@link THREE.EllipseCurve | EllipseCurve} to the path, positioned relative to {@link .currentPoint}. + * @param x Expects a `Float` + * @param y X, The center of the ellipse offset from the last call. Expects a `Float` + * @param xRadius The radius of the ellipse in the x axis. Expects a `Float` + * @param yRadius The radius of the ellipse in the y axis. Expects a `Float` + * @param startAngle The start angle in radians. Expects a `Float` + * @param endAngle The end angle in radians. Expects a `Float` + * @param clockwise Sweep the ellipse clockwise. Default `false` + * @param rotation The rotation angle of the ellipse in radians, counterclockwise from the positive X axis. Optional, Expects a `Float`. Default `0` + */ + ellipse( + aX: number, + aY: number, + xRadius: number, + yRadius: number, + aStartAngle: number, + aEndAngle: number, + aClockwise?: boolean, + aRotation?: number, + ): this; + + /** + * Connects a {@link THREE.LineCurve | LineCurve} from {@link .currentPoint} to x, y onto the path. + * @param x Expects a `Float` + * @param y Expects a `Float` + */ + lineTo(x: number, y: number): this; + + /** + * Move the {@link .currentPoint} to x, y. + * @param x Expects a `Float` + * @param y Expects a `Float` + */ + moveTo(x: number, y: number): this; + + /** + * Creates a quadratic curve from {@link .currentPoint} with cpX and cpY as control point and updates {@link .currentPoint} to x and y. + * @param cpX Expects a `Float` + * @param cpY Expects a `Float` + * @param x Expects a `Float` + * @param y Expects a `Float` + */ + quadraticCurveTo(aCPx: number, aCPy: number, aX: number, aY: number): this; + + /** + * Points are added to the {@link CurvePath.curves | curves} array as {@link THREE.LineCurve | LineCurves}. + * @param vector2s + */ + setFromPoints(vectors: Vector2[]): this; + + /** + * Connects a new {@link THREE.SplineCurve | SplineCurve} onto the path. + * @param points An array of {@link Vector2 | Vector2's} + */ + splineThru(pts: Vector2[]): this; + + toJSON(): PathJSON; + fromJSON(json: PathJSON): this; +} diff --git a/src-testing/src/extras/core/Shape.d.ts b/src-testing/src/extras/core/Shape.d.ts new file mode 100644 index 000000000..84e5ff37f --- /dev/null +++ b/src-testing/src/extras/core/Shape.d.ts @@ -0,0 +1,86 @@ +import { Vector2 } from "../../math/Vector2.js"; +import { Path, PathJSON } from "./Path.js"; + +export interface ShapeJSON extends PathJSON { + uuid: string; + holes: PathJSON[]; +} + +/** + * Defines an arbitrary 2d {@link Shape} plane using paths with optional holes + * @remarks + * It can be used with {@link THREE.ExtrudeGeometry | ExtrudeGeometry}, {@link THREE.ShapeGeometry | ShapeGeometry}, to get points, or to get triangulated faces. + * @example + * ```typescript + * const heartShape = new THREE.Shape(); + * heartShape.moveTo(25, 25); + * heartShape.bezierCurveTo(25, 25, 20, 0, 0, 0); + * heartShape.bezierCurveTo(-30, 0, -30, 35, -30, 35); + * heartShape.bezierCurveTo(-30, 55, -10, 77, 25, 95); + * heartShape.bezierCurveTo(60, 77, 80, 55, 80, 35); + * heartShape.bezierCurveTo(80, 35, 80, 0, 50, 0); + * heartShape.bezierCurveTo(35, 0, 25, 25, 25, 25); + * const extrudeSettings = { + * depth: 8, + * bevelEnabled: true, + * bevelSegments: 2, + * steps: 2, + * bevelSize: 1, + * bevelThickness: 1 + * }; + * const geometry = new THREE.ExtrudeGeometry(heartShape, extrudeSettings); + * const mesh = new THREE.Mesh(geometry, new THREE.MeshPhongMaterial()); + * ``` + * @see Example: {@link https://threejs.org/examples/#webgl_geometry_shapes | geometry / shapes } + * @see Example: {@link https://threejs.org/examples/#webgl_geometry_extrude_shapes | geometry / extrude / shapes } + * @see Example: {@link https://threejs.org/examples/#webgl_geometry_extrude_shapes2 | geometry / extrude / shapes2 } + * @see {@link https://threejs.org/docs/index.html#api/en/extras/core/Shape | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/core/Shape.js | Source} + */ +export class Shape extends Path { + /** + * Creates a {@link Shape} from the points + * @remarks + * The first point defines the offset, then successive points are added to the {@link CurvePath.curves | curves} array as {@link THREE.LineCurve | LineCurves}. + * If no points are specified, an empty {@link Shape} is created and the {@link .currentPoint} is set to the origin. + * @param points Array of {@link Vector2 | Vector2s}. + */ + constructor(points?: Vector2[]); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `Shape` + */ + override readonly type: string | "Shape"; + + /** + * {@link http://en.wikipedia.org/wiki/Universally_unique_identifier | UUID} of this object instance. + * @remarks This gets automatically assigned and shouldn't be edited. + */ + uuid: string; + + /** + * An array of {@link Path | paths} that define the holes in the shape. + * @defaultValue `[]` + */ + holes: Path[]; + + /** + * Call {@link THREE.Curve.getPoints | getPoints} on the {@link Shape} and the {@link holes} array + * @param divisions The fineness of the result. Expects a `Integer` + */ + extractPoints(divisions: number): { + shape: Vector2[]; + holes: Vector2[][]; + }; + + /** + * Get an array of {@link Vector2 | Vector2's} that represent the holes in the shape. + * @param divisions The fineness of the result. Expects a `Integer` + */ + getPointsHoles(divisions: number): Vector2[][]; + + toJSON(): ShapeJSON; + fromJSON(json: ShapeJSON): this; +} diff --git a/src-testing/src/extras/core/ShapePath.d.ts b/src-testing/src/extras/core/ShapePath.d.ts new file mode 100644 index 000000000..0fcd88312 --- /dev/null +++ b/src-testing/src/extras/core/ShapePath.d.ts @@ -0,0 +1,98 @@ +import { Color } from "../../math/Color.js"; +import { Vector2 } from "../../math/Vector2.js"; +import { Path } from "./Path.js"; +import { Shape } from "./Shape.js"; + +/** + * This class is used to convert a series of shapes to an array of {@link THREE.Path | Path's}, + * for example an SVG shape to a path. + * @see {@link https://threejs.org/docs/index.html#api/en/extras/core/ShapePath | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/core/ShapePath.js | Source} + */ +export class ShapePath { + /** + * Creates a new {@link ShapePath} + * @remarks + * Unlike a {@link THREE.Path | Path}, no points are passed in as the {@link ShapePath} is designed to be generated after creation. + */ + constructor(); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `ShapePath` + */ + readonly type: "ShapePath"; + + /** + * Array of {@link THREE.Path | Path's}s. + * @defaultValue `[]` + */ + subPaths: Path[]; + + /** + * The current {@link THREE.Path | Path} that is being generated. + * @defaultValue `null` + */ + readonly currentPath: Path | null; + + /** + * {@link THREE.Color | Color} of the shape, by default set to white _(0xffffff)_. + * @defaultValue `new THREE.Color()` + */ + color: Color; + + /** + * Starts a new {@link THREE.Path | Path} and calls {@link THREE.Path.moveTo | Path.moveTo}( x, y ) on that {@link THREE.Path | Path} + * @remarks + * Also points {@link ShapePath.currentPath | currentPath} to that {@link THREE.Path | Path}. + * @param x Expects a `Float` + * @param y Expects a `Float` + */ + moveTo(x: number, y: number): this; + + /** + * This creates a line from the {@link ShapePath.currentPath | currentPath}'s offset to X and Y and updates the offset to X and Y. + * @param x Expects a `Float` + * @param y Expects a `Float` + */ + lineTo(x: number, y: number): this; + + /** + * This creates a quadratic curve from the {@link ShapePath.currentPath | currentPath}'s + * offset to _x_ and _y_ with _cpX_ and _cpY_ as control point and updates the {@link ShapePath.currentPath | currentPath}'s offset to _x_ and _y_. + * @param cpX Expects a `Float` + * @param cpY Expects a `Float` + * @param x Expects a `Float` + * @param y Expects a `Float` + */ + quadraticCurveTo(aCPx: number, aCPy: number, aX: number, aY: number): this; + + /** + * This creates a bezier curve from the {@link ShapePath.currentPath | currentPath}'s + * offset to _x_ and _y_ with _cp1X_, _cp1Y_ and _cp2X_, _cp2Y_ as control points and + * updates the {@link ShapePath.currentPath | currentPath}'s offset to _x_ and _y_. + * @param cp1X Expects a `Float` + * @param cp1Y Expects a `Float` + * @param cp2X Expects a `Float` + * @param cp2Y Expects a `Float` + * @param x Expects a `Float` + * @param y Expects a `Float` + */ + bezierCurveTo(aCP1x: number, aCP1y: number, aCP2x: number, aCP2y: number, aX: number, aY: number): this; + + /** + * Connects a new {@link THREE.SplineCurve | SplineCurve} onto the {@link ShapePath.currentPath | currentPath}. + * @param points An array of {@link THREE.Vector2 | Vector2}s + */ + splineThru(pts: Vector2[]): this; + + /** + * Converts the {@link ShapePath.subPaths | subPaths} array into an array of Shapes + * @remarks + * By default solid shapes are defined clockwise (CW) and holes are defined counterclockwise (CCW) + * If isCCW is set to true, then those are flipped. + * @param isCCW Changes how solids and holes are generated + */ + toShapes(isCCW: boolean): Shape[]; +} diff --git a/src-testing/src/extras/curves/ArcCurve.d.ts b/src-testing/src/extras/curves/ArcCurve.d.ts new file mode 100644 index 000000000..0932f7ffb --- /dev/null +++ b/src-testing/src/extras/curves/ArcCurve.d.ts @@ -0,0 +1,41 @@ +import { EllipseCurve } from "./EllipseCurve.js"; + +/** + * Alias for {@link THREE.EllipseCurve | EllipseCurve}. + * @see {@link https://threejs.org/docs/index.html#api/en/extras/curves/ArcCurve | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/curves/ArcCurve.js | Source} + */ +export class ArcCurve extends EllipseCurve { + /** + * This constructor creates a new {@link ArcCurve}. + * @param aX The X center of the ellipse. Expects a `Float`. Default is `0`. + * @param aY The Y center of the ellipse. Expects a `Float`. Default is `0`. + * @param xRadius The radius of the ellipse in the x direction. Expects a `Float`. Default is `1`. + * @param yRadius The radius of the ellipse in the y direction. Expects a `Float`. Default is `1`. + * @param aStartAngle The start angle of the curve in radians starting from the positive X axis. Default is `0`. + * @param aEndAngle The end angle of the curve in radians starting from the positive X axis. Default is `2 x Math.PI`. + * @param aClockwise Whether the ellipse is drawn clockwise. Default is `false`. + */ + constructor( + aX?: number, + aY?: number, + aRadius?: number, + aStartAngle?: number, + aEndAngle?: number, + aClockwise?: boolean, + ); + + /** + * Read-only flag to check if a given object is of type {@link ArcCurve}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isArcCurve = true; + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `ArcCurve` + */ + override readonly type: string | "ArcCurve"; +} diff --git a/src-testing/src/extras/curves/CatmullRomCurve3.d.ts b/src-testing/src/extras/curves/CatmullRomCurve3.d.ts new file mode 100644 index 000000000..55088e412 --- /dev/null +++ b/src-testing/src/extras/curves/CatmullRomCurve3.d.ts @@ -0,0 +1,77 @@ +import { Vector3 } from "../../math/Vector3.js"; +import { Curve } from "../core/Curve.js"; + +export type CurveType = "centripetal" | "chordal" | "catmullrom"; + +/** + * Create a smooth **3D** spline curve from a series of points using the {@link https://en.wikipedia.org/wiki/Centripetal_Catmull-Rom_spline | Catmull-Rom} algorithm. + * @example + * ```typescript + * //Create a closed wavey loop + * const curve = new THREE.CatmullRomCurve3([ + * new THREE.Vector3(-10, 0, 10), + * new THREE.Vector3(-5, 5, 5), + * new THREE.Vector3(0, 0, 0), + * new THREE.Vector3(5, -5, 5), + * new THREE.Vector3(10, 0, 10)]); + * const points = curve.getPoints(50); + * const geometry = new THREE.BufferGeometry().setFromPoints(points); + * const material = new THREE.LineBasicMaterial({ + * color: 0xff0000 + * }); + * // Create the final object to add to the scene + * const curveObject = new THREE.Line(geometry, material); + * ``` + * @see Example: {@link https://threejs.org/examples/#webgl_geometry_extrude_splines | WebGL / geometry / extrude / splines} + * @see {@link https://threejs.org/docs/index.html#api/en/extras/curves/CatmullRomCurve3 | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/curves/CatmullRomCurve3.js | Source} + */ +export class CatmullRomCurve3 extends Curve { + /** + * This constructor creates a new {@link CatmullRomCurve3}. + * @param points An array of {@link THREE.Vector3 | Vector3} points + * @param closed Whether the curve is closed. Default `false` + * @param curveType Type of the curve. Default `centripetal` + * @param tension Tension of the curve. Expects a `Float`. Default `0.5` + */ + constructor(points?: Vector3[], closed?: boolean, curveType?: CurveType, tension?: number); + + /** + * Read-only flag to check if a given object is of type {@link CatmullRomCurve3}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isCatmullRomCurve3 = true; + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `CatmullRomCurve3` + */ + override readonly type: string | "CatmullRomCurve3"; + + /** + * The curve will loop back onto itself when this is true. + * @defaultValue `false` + */ + closed: boolean; + + /** + * The array of {@link THREE.Vector3 | Vector3} points that define the curve. + * @remarks It needs at least two entries. + * @defaultValue `[]` + */ + points: Vector3[]; + + /** + * Possible values are `centripetal`, `chordal` and `catmullrom`. + * @defaultValue `centripetal` + */ + curveType: CurveType; + + /** + * When {@link .curveType} is `catmullrom`, defines catmullrom's tension. + * @remarks Expects a `Float` + */ + tension: number; +} diff --git a/src-testing/src/extras/curves/CubicBezierCurve.d.ts b/src-testing/src/extras/curves/CubicBezierCurve.d.ts new file mode 100644 index 000000000..ae4518312 --- /dev/null +++ b/src-testing/src/extras/curves/CubicBezierCurve.d.ts @@ -0,0 +1,72 @@ +import { Vector2 } from "../../math/Vector2.js"; +import { Curve } from "../core/Curve.js"; + +/** + * Create a smooth **2D** {@link http://en.wikipedia.org/wiki/B%C3%A9zier_curve#mediaviewer/File:Bezier_curve.svg | cubic bezier curve}, + * defined by a start point, endpoint and two control points. + * @example + * ```typescript + * const curve = new THREE.CubicBezierCurve( + * new THREE.Vector2(-10, 0), + * new THREE.Vector2(-5, 15), + * new THREE.Vector2(20, 15), + * new THREE.Vector2(10, 0)); + * const points = curve.getPoints(50); + * const geometry = new THREE.BufferGeometry().setFromPoints(points); + * const material = new THREE.LineBasicMaterial({ + * color: 0xff0000 + * }); + * // Create the final object to add to the scene + * const curveObject = new THREE.Line(geometry, material); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/extras/curves/CubicBezierCurve | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/curves/CubicBezierCurve.js | Source} + */ +export class CubicBezierCurve extends Curve { + /** + * This constructor creates a new {@link CubicBezierCurve}. + * @param v0 The starting point. Default is `new THREE.Vector2()`. + * @param v1 The first control point. Default is `new THREE.Vector2()`. + * @param v2 The second control point. Default is `new THREE.Vector2()`. + * @param v3 The ending point. Default is `new THREE.Vector2()`. + */ + constructor(v0?: Vector2, v1?: Vector2, v2?: Vector2, v3?: Vector2); + + /** + * Read-only flag to check if a given object is of type {@link CubicBezierCurve}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isCubicBezierCurve = true; + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `CubicBezierCurve` + */ + override readonly type: string | "CubicBezierCurve"; + + /** + * The starting point. + * @defaultValue `new THREE.Vector2()` + */ + v0: Vector2; + + /** + * The first control point. + * @defaultValue `new THREE.Vector2()` + */ + v1: Vector2; + + /** + * The second control point. + * @defaultValue `new THREE.Vector2()` + */ + v2: Vector2; + + /** + * The ending point. + * @defaultValue `new THREE.Vector2()` + */ + v3: Vector2; +} diff --git a/src-testing/src/extras/curves/CubicBezierCurve3.d.ts b/src-testing/src/extras/curves/CubicBezierCurve3.d.ts new file mode 100644 index 000000000..ad8edb356 --- /dev/null +++ b/src-testing/src/extras/curves/CubicBezierCurve3.d.ts @@ -0,0 +1,72 @@ +import { Vector3 } from "../../math/Vector3.js"; +import { Curve } from "../core/Curve.js"; + +/** + * Create a smooth **3D** {@link http://en.wikipedia.org/wiki/B%C3%A9zier_curve#mediaviewer/File:Bezier_curve.svg | cubic bezier curve}, + * defined by a start point, endpoint and two control points. + * @example + * ```typescript + * const curve = new THREE.CubicBezierCurve( + * new THREE.Vector2(-10, 0), + * new THREE.Vector2(-5, 15), + * new THREE.Vector2(20, 15), + * new THREE.Vector2(10, 0)); + * const points = curve.getPoints(50); + * const geometry = new THREE.BufferGeometry().setFromPoints(points); + * const material = new THREE.LineBasicMaterial({ + * color: 0xff0000 + * }); + * // Create the final object to add to the scene + * const curveObject = new THREE.Line(geometry, material); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/extras/curves/CubicBezierCurve | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/curves/CubicBezierCurve.js | Source} + */ +export class CubicBezierCurve3 extends Curve { + /** + * This constructor creates a new {@link CubicBezierCurve3}. + * @param v0 The starting point. Default is `new THREE.Vector3()`. + * @param v1 The first control point. Default is `new THREE.Vector3()`. + * @param v2 The second control point. Default is `new THREE.Vector3()`. + * @param v3 The ending point. Default is `new THREE.Vector3()`. + */ + constructor(v0?: Vector3, v1?: Vector3, v2?: Vector3, v3?: Vector3); + + /** + * Read-only flag to check if a given object is of type {@link CubicBezierCurve3}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isCubicBezierCurve3 = true; + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `CubicBezierCurve3` + */ + override readonly type: string | "CubicBezierCurve3"; + + /** + * The starting point. + * @defaultValue `new THREE.Vector3()`. + */ + v0: Vector3; + + /** + * The first control point. + * @defaultValue `new THREE.Vector3()`. + */ + v1: Vector3; + + /** + * The second control point. + * @defaultValue `new THREE.Vector3()`. + */ + v2: Vector3; + + /** + * The ending point. + * @defaultValue `new THREE.Vector3()`. + */ + v3: Vector3; +} diff --git a/src-testing/src/extras/curves/Curves.d.ts b/src-testing/src/extras/curves/Curves.d.ts new file mode 100644 index 000000000..996021d72 --- /dev/null +++ b/src-testing/src/extras/curves/Curves.d.ts @@ -0,0 +1,10 @@ +export * from "./ArcCurve.js"; +export * from "./CatmullRomCurve3.js"; +export * from "./CubicBezierCurve.js"; +export * from "./CubicBezierCurve3.js"; +export * from "./EllipseCurve.js"; +export * from "./LineCurve.js"; +export * from "./LineCurve3.js"; +export * from "./QuadraticBezierCurve.js"; +export * from "./QuadraticBezierCurve3.js"; +export * from "./SplineCurve.js"; diff --git a/src-testing/src/extras/curves/EllipseCurve.d.ts b/src-testing/src/extras/curves/EllipseCurve.d.ts new file mode 100644 index 000000000..4d15ca8c2 --- /dev/null +++ b/src-testing/src/extras/curves/EllipseCurve.d.ts @@ -0,0 +1,115 @@ +import { Vector2 } from "../../math/Vector2.js"; +import { Curve } from "../core/Curve.js"; + +/** + * Creates a 2d curve in the shape of an ellipse + * @remarks + * Setting the {@link xRadius} equal to the {@link yRadius} will result in a circle. + * @example + * ```typescript + * const curve = new THREE.EllipseCurve( + * 0, 0, // ax, aY + * 10, 10, // xRadius, yRadius + * 0, 2 * Math.PI, // aStartAngle, aEndAngle + * false, // aClockwise + * 0 // aRotation + * ); + * const points = curve.getPoints(50); + * const geometry = new THREE.BufferGeometry().setFromPoints(points); + * const material = new THREE.LineBasicMaterial({ color: 0xff0000 }); + * // Create the final object to add to the scene + * const ellipse = new THREE.Line(geometry, material); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/extras/curves/EllipseCurve | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/curves/EllipseCurve.js | Source} + */ +export class EllipseCurve extends Curve { + /** + * This constructor creates a new {@link EllipseCurve}. + * @param aX The X center of the ellipse. Expects a `Float`. Default is `0`. + * @param aY The Y center of the ellipse. Expects a `Float`. Default is `0`. + * @param xRadius The radius of the ellipse in the x direction. Expects a `Float`. Default is `1`. + * @param yRadius The radius of the ellipse in the y direction. Expects a `Float`. Default is `1`. + * @param aStartAngle The start angle of the curve in radians starting from the positive X axis. Default is `0`. + * @param aEndAngle The end angle of the curve in radians starting from the positive X axis. Default is `2 x Math.PI`. + * @param aClockwise Whether the ellipse is drawn clockwise. Default is `false`. + * @param aRotation The rotation angle of the ellipse in radians, counterclockwise from the positive X axis. Default is `0`. + */ + constructor( + aX?: number, + aY?: number, + xRadius?: number, + yRadius?: number, + aStartAngle?: number, + aEndAngle?: number, + aClockwise?: boolean, + aRotation?: number, + ); + + /** + * Read-only flag to check if a given object is of type {@link EllipseCurve}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isEllipseCurve = true; + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `EllipseCurve` + */ + override readonly type: string | "EllipseCurve"; + + /** + * The X center of the ellipse. + * @remarks Expects a `Float` + * @defaultValue `0` + */ + aX: number; + + /** + * The Y center of the ellipse. + * @remarks Expects a `Float` + * @defaultValue `0` + */ + aY: number; + + /** + * The radius of the ellipse in the x direction. + * @defaultValue `1` + */ + xRadius: number; + + /** + * The radius of the ellipse in the y direction. + * @defaultValue `1` + */ + yRadius: number; + + /** + * The start angle of the curve in radians starting from the middle right side. + * @remarks Expects a `Float` + * @defaultValue `0` + */ + aStartAngle: number; + + /** + * The end angle of the curve in radians starting from the middle right side. + * @remarks Expects a `Float` + * @defaultValue `2 * Math.PI` + */ + aEndAngle: number; + + /** + * Whether the ellipse is drawn clockwise. + * @defaultValue `false`` + */ + aClockwise: boolean; + + /** + * The rotation angle of the ellipse in radians, counterclockwise from the positive X axis (optional). + * @remarks Expects a `Float` + * @defaultValue `0` + */ + aRotation: number; +} diff --git a/src-testing/src/extras/curves/LineCurve.d.ts b/src-testing/src/extras/curves/LineCurve.d.ts new file mode 100644 index 000000000..3bcb000d3 --- /dev/null +++ b/src-testing/src/extras/curves/LineCurve.d.ts @@ -0,0 +1,42 @@ +import { Vector2 } from "../../math/Vector2.js"; +import { Curve } from "../core/Curve.js"; + +/** + * A curve representing a **2D** line segment. + * @see {@link https://threejs.org/docs/index.html#api/en/extras/curves/LineCurve | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/curves/LineCurve.js | Source} + */ +export class LineCurve extends Curve { + /** + * This constructor creates a new {@link LineCurve}. + * @param v1 The start point. Default is `new THREE.Vector2()`. + * @param v2 The end point. Default is `new THREE.Vector2()`. + */ + constructor(v1?: Vector2, v2?: Vector2); + + /** + * Read-only flag to check if a given object is of type {@link LineCurve}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isLineCurve = true; + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `LineCurve` + */ + override readonly type: string | "LineCurve"; + + /** + * The start point. + * @defaultValue `new THREE.Vector2()` + */ + v1: Vector2; + + /** + * The end point + * @defaultValue `new THREE.Vector2()` + */ + v2: Vector2; +} diff --git a/src-testing/src/extras/curves/LineCurve3.d.ts b/src-testing/src/extras/curves/LineCurve3.d.ts new file mode 100644 index 000000000..c7ae7c301 --- /dev/null +++ b/src-testing/src/extras/curves/LineCurve3.d.ts @@ -0,0 +1,42 @@ +import { Vector3 } from "../../math/Vector3.js"; +import { Curve } from "../core/Curve.js"; + +/** + * A curve representing a **3D** line segment. + * @see {@link https://threejs.org/docs/index.html#api/en/extras/curves/LineCurve3 | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/curves/LineCurve3.js | Source} + */ +export class LineCurve3 extends Curve { + /** + * This constructor creates a new {@link LineCurve3}. + * @param v1 The start point. Default is `new THREE.Vector3()`. + * @param v2 The end point. Default is `new THREE.Vector3()`. + */ + constructor(v1?: Vector3, v2?: Vector3); + + /** + * Read-only flag to check if a given object is of type {@link LineCurve3}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isLineCurve3 = true; + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `LineCurve3` + */ + override readonly type: string | "LineCurve3"; + + /** + * The start point. + * @defaultValue `new THREE.Vector3()`. + */ + v1: Vector3; + + /** + * The end point. + * @defaultValue `new THREE.Vector3()`. + */ + v2: Vector3; +} diff --git a/src-testing/src/extras/curves/QuadraticBezierCurve.d.ts b/src-testing/src/extras/curves/QuadraticBezierCurve.d.ts new file mode 100644 index 000000000..8ae4c3213 --- /dev/null +++ b/src-testing/src/extras/curves/QuadraticBezierCurve.d.ts @@ -0,0 +1,64 @@ +import { Vector2 } from "../../math/Vector2.js"; +import { Curve } from "../core/Curve.js"; + +/** + * Create a smooth **2D** {@link http://en.wikipedia.org/wiki/B%C3%A9zier_curve#mediaviewer/File:B%C3%A9zier_2_big.gif | quadratic bezier curve}, + * defined by a start point, end point and a single control point. + * @example + * ```typescript + * const curve = new THREE.QuadraticBezierCurve( + * new THREE.Vector2(-10, 0), + * new THREE.Vector2(20, 15), + * new THREE.Vector2(10, 0)); + * const points = curve.getPoints(50); + * const geometry = new THREE.BufferGeometry().setFromPoints(points); + * const material = new THREE.LineBasicMaterial({ + * color: 0xff0000 + * }); + * // Create the final object to add to the scene + * const curveObject = new THREE.Line(geometry, material); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/extras/curves/QuadraticBezierCurve | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/curves/QuadraticBezierCurve.js | Source} + */ +export class QuadraticBezierCurve extends Curve { + /** + * This constructor creates a new {@link QuadraticBezierCurve}. + * @param v0 The start point. Default is `new THREE.Vector2()`. + * @param v1 The control point. Default is `new THREE.Vector2()`. + * @param v2 The end point. Default is `new THREE.Vector2()`. + */ + constructor(v0?: Vector2, v1?: Vector2, v2?: Vector2); + + /** + * Read-only flag to check if a given object is of type {@link LineCurve3}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isQuadraticBezierCurve = true; + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `QuadraticBezierCurve` + */ + override readonly type: string | "QuadraticBezierCurve"; + + /** + * The start point. + * @defaultValue `new THREE.Vector2()` + */ + v0: Vector2; + + /** + * The control point. + * @defaultValue `new THREE.Vector2()` + */ + v1: Vector2; + + /** + * The end point. + * @defaultValue `new THREE.Vector2()` + */ + v2: Vector2; +} diff --git a/src-testing/src/extras/curves/QuadraticBezierCurve3.d.ts b/src-testing/src/extras/curves/QuadraticBezierCurve3.d.ts new file mode 100644 index 000000000..3964af820 --- /dev/null +++ b/src-testing/src/extras/curves/QuadraticBezierCurve3.d.ts @@ -0,0 +1,64 @@ +import { Vector3 } from "../../math/Vector3.js"; +import { Curve } from "../core/Curve.js"; + +/** + * Create a smooth **3D** {@link http://en.wikipedia.org/wiki/B%C3%A9zier_curve#mediaviewer/File:B%C3%A9zier_2_big.gif | quadratic bezier curve}, + * defined by a start point, end point and a single control point. + * @example + * ```typescript + * const curve = new THREE.QuadraticBezierCurve3( + * new THREE.Vector3(-10, 0, 0), + * new THREE.Vector3(20, 15, 0), + * new THREE.Vector3(10, 0, 0)); + * const points = curve.getPoints(50); + * const geometry = new THREE.BufferGeometry().setFromPoints(points); + * const material = new THREE.LineBasicMaterial({ + * color: 0xff0000 + * }); + * // Create the final object to add to the scene + * const curveObject = new THREE.Line(geometry, material); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/extras/curves/QuadraticBezierCurve3 | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/curves/QuadraticBezierCurve3.js | Source} + */ +export class QuadraticBezierCurve3 extends Curve { + /** + * This constructor creates a new {@link QuadraticBezierCurve}. + * @param v0 The start point. Default is `new THREE.Vector3()`. + * @param v1 The control point. Default is `new THREE.Vector3()`. + * @param v2 The end point. Default is `new THREE.Vector3()`. + */ + constructor(v0?: Vector3, v1?: Vector3, v2?: Vector3); + + /** + * Read-only flag to check if a given object is of type {@link QuadraticBezierCurve3}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isQuadraticBezierCurve3 = true; + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `QuadraticBezierCurve3` + */ + override readonly type: string | "QuadraticBezierCurve3"; + + /** + * The start point. + * @defaultValue `new THREE.Vector3()` + */ + v0: Vector3; + + /** + * The control point. + * @defaultValue `new THREE.Vector3()` + */ + v1: Vector3; + + /** + * The end point. + * @defaultValue `new THREE.Vector3()` + */ + v2: Vector3; +} diff --git a/src-testing/src/extras/curves/SplineCurve.d.ts b/src-testing/src/extras/curves/SplineCurve.d.ts new file mode 100644 index 000000000..c3c56210a --- /dev/null +++ b/src-testing/src/extras/curves/SplineCurve.d.ts @@ -0,0 +1,52 @@ +import { Vector2 } from "../../math/Vector2.js"; +import { Curve } from "../core/Curve.js"; + +/** + * Create a smooth **2D** spline curve from a series of points. + * @example + * ```typescript + * // Create a sine-like wave + * const curve = new THREE.SplineCurve([ + * new THREE.Vector2(-10, 0), + * new THREE.Vector2(-5, 5), + * new THREE.Vector2(0, 0), + * new THREE.Vector2(5, -5), + * new THREE.Vector2(10, 0)]); + * const points = curve.getPoints(50); + * const geometry = new THREE.BufferGeometry().setFromPoints(points); + * const material = new THREE.LineBasicMaterial({ + * color: 0xff0000 + * }); + * // Create the final object to add to the scene + * const splineObject = new THREE.Line(geometry, material); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/extras/curves/SplineCurve | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/curves/SplineCurve.js | Source} + */ +export class SplineCurve extends Curve { + /** + * This constructor creates a new {@link SplineCurve}. + * @param points An array of {@link THREE.Vector2 | Vector2} points that define the curve. Default `[]` + */ + constructor(points?: Vector2[]); + + /** + * Read-only flag to check if a given object is of type {@link SplineCurve}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isSplineCurve = true; + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `SplineCurve` + */ + override readonly type: string | "SplineCurve"; + + /** + * The array of {@link THREE.Vector2 | Vector2} points that define the curve. + * @defaultValue `[]` + */ + points: Vector2[]; +} diff --git a/src-testing/src/geometries/BoxGeometry.d.ts b/src-testing/src/geometries/BoxGeometry.d.ts new file mode 100644 index 000000000..7a756ae56 --- /dev/null +++ b/src-testing/src/geometries/BoxGeometry.d.ts @@ -0,0 +1,59 @@ +import { BufferGeometry } from "../core/BufferGeometry.js"; + +/** + * {@link BoxGeometry} is a geometry class for a rectangular cuboid with a given 'width', 'height', and 'depth' + * @remarks On creation, the cuboid is centred on the origin, with each edge parallel to one of the axes. + * @example + * ```typescript + * const geometry = new THREE.BoxGeometry(1, 1, 1); + * const material = new THREE.MeshBasicMaterial({ + * color: 0x00ff00 + * }); + * const cube = new THREE.Mesh(geometry, material); + * scene.add(cube); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/geometries/BoxGeometry | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/BoxGeometry.js | Source} + */ +export class BoxGeometry extends BufferGeometry { + /** + * Create a new instance of {@link BoxGeometry} + * @param width Width; that is, the length of the edges parallel to the X axis. Optional; Expects a `Float`. Default `1` + * @param height Height; that is, the length of the edges parallel to the Y axis. Optional; Expects a `Float`. Default `1` + * @param depth Depth; that is, the length of the edges parallel to the Z axis. Optional; Expects a `Float`. Default `1` + * @param widthSegments Number of segmented rectangular faces along the width of the sides. Optional; Expects a `Integer`. Default `1` + * @param heightSegments Number of segmented rectangular faces along the height of the sides. Optional; Expects a `Integer`. Default `1` + * @param depthSegments Number of segmented rectangular faces along the depth of the sides. Optional; Expects a `Integer`. Default `1` + */ + constructor( + width?: number, + height?: number, + depth?: number, + widthSegments?: number, + heightSegments?: number, + depthSegments?: number, + ); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `BoxGeometry` + */ + override readonly type: string | "BoxGeometry"; + + /** + * An object with a property for each of the constructor parameters. + * @remarks Any modification after instantiation does not change the geometry. + */ + readonly parameters: { + readonly width: number; + readonly height: number; + readonly depth: number; + readonly widthSegments: number; + readonly heightSegments: number; + readonly depthSegments: number; + }; + + /** @internal */ + static fromJSON(data: {}): BoxGeometry; +} diff --git a/src-testing/src/geometries/CapsuleGeometry.d.ts b/src-testing/src/geometries/CapsuleGeometry.d.ts new file mode 100644 index 000000000..b20616035 --- /dev/null +++ b/src-testing/src/geometries/CapsuleGeometry.d.ts @@ -0,0 +1,48 @@ +import { BufferGeometry } from "../core/BufferGeometry.js"; + +/** + * {@link CapsuleGeometry} is a geometry class for a capsule with given radii and height + * @remarks It is constructed using a lathe. + * @example + * ```typescript + * const geometry = new THREE.CapsuleGeometry(1, 1, 4, 8); + * const material = new THREE.MeshBasicMaterial({ + * color: 0x00ff00 + * }); + * const capsule = new THREE.Mesh(geometry, material); + * scene.add(capsule); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/geometries/CapsuleGeometry | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/CapsuleGeometry.js | Source} + */ +export class CapsuleGeometry extends BufferGeometry { + /** + * Create a new instance of {@link CapsuleGeometry} + * @param radius Radius of the capsule. Expects a `Float`. Default `1` + * @param length Length of the middle section. Expects a `Float`. Default `1` + * @param capSegments Number of curve segments used to build the caps. Expects a `Integer`. Default `4` + * @param radialSegments Number of segmented faces around the circumference of the capsule. Expects a `Integer`. Default `8` + */ + constructor(radius?: number, length?: number, capSegments?: number, radialSegments?: number); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `CapsuleGeometry` + */ + override readonly type: string | "CapsuleGeometry"; + + /** + * An object with a property for each of the constructor parameters. + * @remarks Any modification after instantiation does not change the geometry. + */ + readonly parameters: { + readonly radius: number; + readonly length: number; + readonly capSegments: number; + readonly radialSegments: number; + }; + + /** @internal */ + static fromJSON(data: {}): CapsuleGeometry; +} diff --git a/src-testing/src/geometries/CircleGeometry.d.ts b/src-testing/src/geometries/CircleGeometry.d.ts new file mode 100644 index 000000000..b512e4866 --- /dev/null +++ b/src-testing/src/geometries/CircleGeometry.d.ts @@ -0,0 +1,51 @@ +import { BufferGeometry } from "../core/BufferGeometry.js"; + +/** + * {@link CircleGeometry} is a simple shape of Euclidean geometry + * @remarks + * It is constructed from a number of triangular segments that are oriented around a central point and extend as far out as a given radius + * It is built counter-clockwise from a start angle and a given central angle + * It can also be used to create regular polygons, where the number of segments determines the number of sides. + * @example + * ```typescript + * const geometry = new THREE.CircleGeometry(5, 32); + * const material = new THREE.MeshBasicMaterial({ + * color: 0xffff00 + * }); + * const circle = new THREE.Mesh(geometry, material); + * scene.add(circle); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/geometries/CircleGeometry | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/CircleGeometry.js | Source} + */ +export class CircleGeometry extends BufferGeometry { + /** + * Create a new instance of {@link CircleGeometry} + * @param radius Radius of the circle. Expects a `Float`. Default `1` + * @param segments Number of segments (triangles). Expects a `Integer`. Minimum `3`. Default `32` + * @param thetaStart Start angle for first segment. Expects a `Float`. Default `0`, _(three o'clock position)_. + * @param thetaLength The central angle, often called theta, of the circular sector. Expects a `Float`. Default `Math.PI * 2`, _which makes for a complete circle_. + */ + constructor(radius?: number, segments?: number, thetaStart?: number, thetaLength?: number); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `CircleGeometry` + */ + override readonly type: string | "CircleGeometry"; + + /** + * An object with a property for each of the constructor parameters. + * @remarks Any modification after instantiation does not change the geometry. + */ + readonly parameters: { + readonly radius: number; + readonly segments: number; + readonly thetaStart: number; + readonly thetaLength: number; + }; + + /** @internal */ + static fromJSON(data: {}): CircleGeometry; +} diff --git a/src-testing/src/geometries/ConeGeometry.d.ts b/src-testing/src/geometries/ConeGeometry.d.ts new file mode 100644 index 000000000..683376429 --- /dev/null +++ b/src-testing/src/geometries/ConeGeometry.d.ts @@ -0,0 +1,64 @@ +import { CylinderGeometry } from "./CylinderGeometry.js"; + +/** + * A class for generating cone geometries. + * @example + * ```typescript + * const geometry = new THREE.ConeGeometry(5, 20, 32); + * const material = new THREE.MeshBasicMaterial({ + * color: 0xffff00 + * }); + * const cone = new THREE.Mesh(geometry, material); + * scene.add(cone); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/geometries/ConeGeometry | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/ConeGeometry.js | Source} + */ +export class ConeGeometry extends CylinderGeometry { + /** + * Create a new instance of {@link ConeGeometry} + * @param radius Radius of the cone base. Expects a `Float`. Default `1` + * @param height Height of the cone. Expects a `Float`. Default `1` + * @param radialSegments Number of segmented faces around the circumference of the cone. Expects a `Integer`. Default `32` + * @param heightSegments Number of rows of faces along the height of the cone. Expects a `Integer`. Default `1` + * @param openEnded A Boolean indicating whether the base of the cone is open or capped. Default `false`, _meaning capped_. + * @param thetaStart Start angle for first segment. Expects a `Float`. Default `0`, _(three o'clock position)_. + * @param thetaLength The central angle, often called theta, of the circular sector. Expects a `Float`. Default `Math.PI * 2`, _which makes for a complete cone_. + */ + constructor( + radius?: number, + height?: number, + radialSegments?: number, + heightSegments?: number, + openEnded?: boolean, + thetaStart?: number, + thetaLength?: number, + ); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `ConeGeometry` + */ + override readonly type: string | "ConeGeometry"; + + /** + * An object with a property for each of the constructor parameters. + * @remarks {@link radiusTop} and {@link radiusBottom} are from base {@link THREE.CylinderGeometry} class. + * @remarks Any modification after instantiation does not change the geometry. + */ + override readonly parameters: { + readonly radius: number; + readonly radiusTop: number; + readonly radiusBottom: number; + readonly height: number; + readonly radialSegments: number; + readonly heightSegments: number; + readonly openEnded: boolean; + readonly thetaStart: number; + readonly thetaLength: number; + }; + + /** @internal */ + static fromJSON(data: {}): ConeGeometry; +} diff --git a/src-testing/src/geometries/CylinderGeometry.d.ts b/src-testing/src/geometries/CylinderGeometry.d.ts new file mode 100644 index 000000000..90f1b06f3 --- /dev/null +++ b/src-testing/src/geometries/CylinderGeometry.d.ts @@ -0,0 +1,64 @@ +import { BufferGeometry } from "../core/BufferGeometry.js"; + +/** + * A class for generating cylinder geometries. + * @example + * ```typescript + * const geometry = new THREE.CylinderGeometry(5, 5, 20, 32); + * const material = new THREE.MeshBasicMaterial({ + * color: 0xffff00 + * }); + * const cylinder = new THREE.Mesh(geometry, material); + * scene.add(cylinder); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/geometries/CylinderGeometry | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/CylinderGeometry.js | Source} + */ +export class CylinderGeometry extends BufferGeometry { + /** + * Create a new instance of {@link CylinderGeometry} + * @param radiusTop Radius of the cylinder at the top. Default `1` + * @param radiusBottom Radius of the cylinder at the bottom. Default `1` + * @param height Height of the cylinder. Default `1` + * @param radialSegments Number of segmented faces around the circumference of the cylinder. Default `32` + * @param heightSegments Number of rows of faces along the height of the cylinder. Expects a `Integer`. Default `1` + * @param openEnded A Boolean indicating whether the ends of the cylinder are open or capped. Default `false`, _meaning capped_. + * @param thetaStart Start angle for first segment. Default `0`, _(three o'clock position)_. + * @param thetaLength The central angle, often called theta, of the circular sector. Default `Math.PI * 2`, _which makes for a complete cylinder. + */ + constructor( + radiusTop?: number, + radiusBottom?: number, + height?: number, + radialSegments?: number, + heightSegments?: number, + openEnded?: boolean, + thetaStart?: number, + thetaLength?: number, + ); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `CylinderGeometry` + */ + override readonly type: string | "CylinderGeometry"; + + /** + * An object with a property for each of the constructor parameters. + * @remarks Any modification after instantiation does not change the geometry. + */ + readonly parameters: { + readonly radiusTop: number; + readonly radiusBottom: number; + readonly height: number; + readonly radialSegments: number; + readonly heightSegments: number; + readonly openEnded: boolean; + readonly thetaStart: number; + readonly thetaLength: number; + }; + + /** @internal */ + static fromJSON(data: any): CylinderGeometry; +} diff --git a/src-testing/src/geometries/DodecahedronGeometry.d.ts b/src-testing/src/geometries/DodecahedronGeometry.d.ts new file mode 100644 index 000000000..e79e5a895 --- /dev/null +++ b/src-testing/src/geometries/DodecahedronGeometry.d.ts @@ -0,0 +1,25 @@ +import { PolyhedronGeometry } from "./PolyhedronGeometry.js"; + +/** + * A class for generating a dodecahedron geometries. + * @see {@link https://threejs.org/docs/index.html#api/en/geometries/DodecahedronGeometry | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/DodecahedronGeometry.js | Source} + */ +export class DodecahedronGeometry extends PolyhedronGeometry { + /** + * Create a new instance of {@link DodecahedronGeometry} + * @param radius Radius of the dodecahedron. Expects a `Float`. Default `1` + * @param detail Setting this to a value greater than 0 adds vertices making it no longer a dodecahedron. Expects a `Integer`. Default `0` + */ + constructor(radius?: number, detail?: number); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `DodecahedronGeometry` + */ + override readonly type: string | "DodecahedronGeometry"; + + /** @internal */ + static fromJSON(data: {}): DodecahedronGeometry; +} diff --git a/src-testing/src/geometries/EdgesGeometry.d.ts b/src-testing/src/geometries/EdgesGeometry.d.ts new file mode 100644 index 000000000..b901b10d7 --- /dev/null +++ b/src-testing/src/geometries/EdgesGeometry.d.ts @@ -0,0 +1,41 @@ +import { BufferGeometry } from "../core/BufferGeometry.js"; + +/** + * This can be used as a helper object to view the edges of a {@link THREE.BufferGeometry | geometry}. + * @example + * ```typescript + * const geometry = new THREE.BoxGeometry(100, 100, 100); + * const edges = new THREE.EdgesGeometry(geometry); + * const line = new THREE.LineSegments(edges, new THREE.LineBasicMaterial({ + * color: 0xffffff + * })); + * scene.add(line); + * ``` + * @see Example: {@link https://threejs.org/examples/#webgl_helpers | helpers} + * @see {@link https://threejs.org/docs/index.html#api/en/geometries/EdgesGeometry | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/EdgesGeometry.js | Source} + */ +export class EdgesGeometry extends BufferGeometry { + /** + * Create a new instance of {@link EdgesGeometry} + * @param geometry Any geometry object. Default `null`. + * @param thresholdAngle An edge is only rendered if the angle (in degrees) between the face normals of the adjoining faces exceeds this value. Expects a `Integer`. Default `1` _degree_. + */ + constructor(geometry?: TBufferGeometry | null, thresholdAngle?: number); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `EdgesGeometry` + */ + override readonly type: string | "EdgesGeometry"; + + /** + * An object with a property for each of the constructor parameters. + * @remarks Any modification after instantiation does not change the geometry. + */ + readonly parameters: { + readonly geometry: TBufferGeometry | null; + readonly thresholdAngle: number; + }; +} diff --git a/src-testing/src/geometries/ExtrudeGeometry.d.ts b/src-testing/src/geometries/ExtrudeGeometry.d.ts new file mode 100644 index 000000000..d872b7c21 --- /dev/null +++ b/src-testing/src/geometries/ExtrudeGeometry.d.ts @@ -0,0 +1,152 @@ +import { BufferGeometry } from "../core/BufferGeometry.js"; +import { Curve } from "../extras/core/Curve.js"; +import { Shape } from "../extras/core/Shape.js"; +import { Vector2 } from "../math/Vector2.js"; +import { Vector3 } from "../math/Vector3.js"; + +export interface ExtrudeGeometryOptions { + /** + * Number of points on the curves. + * Expects a `Integer`. + * @defaultValue `12` + */ + curveSegments?: number | undefined; + + /** + * Number of points used for subdividing segments along the depth of the extruded spline. + * @defaultValue `1` + */ + steps?: number | undefined; + + /** + * Depth to extrude the shape. + * @defaultValue `1` + */ + depth?: number | undefined; + + /** + * Turn on bevel. Applying beveling to the shape. + * @defaultValue `true` + */ + bevelEnabled?: boolean | undefined; + + /** + * How deep into the original shape the bevel goes. + * Expects a `Float`. + * @defaultValue `0.2` + */ + bevelThickness?: number | undefined; + + /** + * Distance from the shape outline that the bevel extends + * Expects a `Float`. + * @defaultValue `bevelThickness - 0.1` + */ + bevelSize?: number | undefined; + + /** + * Distance from the shape outline that the bevel starts. + * Expects a `Float`. + * @defaultValue `0` + */ + bevelOffset?: number | undefined; + + /** + * Number of bevel layers/segments. + * Expects a `Integer`. + * @defaultValue `3` + */ + bevelSegments?: number | undefined; + + /** + * A 3D spline path along which the shape should be extruded. + * @remarks Bevels not supported for path extrusion. + */ + extrudePath?: Curve | undefined; + + /** + * A object that provides UV generator functions. + */ + UVGenerator?: UVGenerator | undefined; +} + +export interface UVGenerator { + generateTopUV( + geometry: ExtrudeGeometry, + vertices: number[], + indexA: number, + indexB: number, + indexC: number, + ): Vector2[]; + generateSideWallUV( + geometry: ExtrudeGeometry, + vertices: number[], + indexA: number, + indexB: number, + indexC: number, + indexD: number, + ): Vector2[]; +} + +/** + * Creates extruded geometry from a path shape. + * @remarks This object extrudes a 2D shape to a 3D geometry. + * @remarks When creating a Mesh with this geometry, if you'd like to have a separate material used for its face and its extruded sides, you can use an array of materials + * @remarks The first material will be applied to the face; the second material will be applied to the sides. + * @example + * ```typescript + * const length = 12, width = 8; + * const shape = new THREE.Shape(); + * shape.moveTo(0, 0); + * shape.lineTo(0, width); + * shape.lineTo(length, width); + * shape.lineTo(length, 0); + * shape.lineTo(0, 0); + * const extrudeSettings = { + * steps: 2, + * depth: 16, + * bevelEnabled: true, + * bevelThickness: 1, + * bevelSize: 1, + * bevelOffset: 0, + * bevelSegments: 1 + * }; + * const geometry = new THREE.ExtrudeGeometry(shape, extrudeSettings); + * const material = new THREE.MeshBasicMaterial({ + * color: 0x00ff00 + * }); + * const mesh = new THREE.Mesh(geometry, material); + * scene.add(mesh); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/geometries/ExtrudeGeometry | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/ExtrudeGeometry.js | Source} + */ +export class ExtrudeGeometry extends BufferGeometry { + /** + * Create a new instance of {@link ExtrudeGeometry} + * @param shapes Shape or an array of shapes. Default `new Shape([new Vector2(0.5, 0.5), new Vector2(-0.5, 0.5), new Vector2(-0.5, -0.5), new Vector2(0.5, -0.5)])`. + * @param options Object that can contain the following parameters. @see {@link ExtrudeGeometryOptions} for defaults. + */ + constructor(shapes?: Shape | Shape[], options?: ExtrudeGeometryOptions); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `ExtrudeGeometry` + */ + override readonly type: string | "ExtrudeGeometry"; + + /** + * An object with a property for each of the constructor parameters. + * @remarks Any modification after instantiation does not change the geometry. + */ + readonly parameters: { + readonly shapes: Shape | Shape[]; + readonly options: ExtrudeGeometryOptions; + }; + + addShape(shape: Shape): void; + + /** @internal */ + static fromJSON(data: {}, shapes: unknown): ExtrudeGeometry; +} diff --git a/src-testing/src/geometries/Geometries.d.ts b/src-testing/src/geometries/Geometries.d.ts new file mode 100644 index 000000000..b1be46c46 --- /dev/null +++ b/src-testing/src/geometries/Geometries.d.ts @@ -0,0 +1,21 @@ +export * from "./BoxGeometry.js"; +export * from "./CapsuleGeometry.js"; +export * from "./CircleGeometry.js"; +export * from "./ConeGeometry.js"; +export * from "./CylinderGeometry.js"; +export * from "./DodecahedronGeometry.js"; +export * from "./EdgesGeometry.js"; +export * from "./ExtrudeGeometry.js"; +export * from "./IcosahedronGeometry.js"; +export * from "./LatheGeometry.js"; +export * from "./OctahedronGeometry.js"; +export * from "./PlaneGeometry.js"; +export * from "./PolyhedronGeometry.js"; +export * from "./RingGeometry.js"; +export * from "./ShapeGeometry.js"; +export * from "./SphereGeometry.js"; +export * from "./TetrahedronGeometry.js"; +export * from "./TorusGeometry.js"; +export * from "./TorusKnotGeometry.js"; +export * from "./TubeGeometry.js"; +export * from "./WireframeGeometry.js"; diff --git a/src-testing/src/geometries/IcosahedronGeometry.d.ts b/src-testing/src/geometries/IcosahedronGeometry.d.ts new file mode 100644 index 000000000..4c05b54de --- /dev/null +++ b/src-testing/src/geometries/IcosahedronGeometry.d.ts @@ -0,0 +1,26 @@ +import { PolyhedronGeometry } from "./PolyhedronGeometry.js"; + +/** + * A class for generating an icosahedron geometry. + * @see {@link https://threejs.org/docs/index.html#api/en/geometries/IcosahedronGeometry | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/IcosahedronGeometry.js | Source} + */ +export class IcosahedronGeometry extends PolyhedronGeometry { + /** + * Create a new instance of {@link IcosahedronGeometry} + * @param radius Expects a `Float`. Default `1` + * @param detail Setting this to a value greater than 0 adds more vertices making it no longer an icosahedron. + * When detail is greater than 1, it's effectively a sphere. Expects a `Integer`. Default `0` + */ + constructor(radius?: number, detail?: number); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `IcosahedronGeometry` + */ + override readonly type: string | "IcosahedronGeometry"; + + /** @internal */ + static fromJSON(data: {}): IcosahedronGeometry; +} diff --git a/src-testing/src/geometries/LatheGeometry.d.ts b/src-testing/src/geometries/LatheGeometry.d.ts new file mode 100644 index 000000000..f4194e514 --- /dev/null +++ b/src-testing/src/geometries/LatheGeometry.d.ts @@ -0,0 +1,55 @@ +import { BufferGeometry } from "../core/BufferGeometry.js"; +import { Vector2 } from "../math/Vector2.js"; + +/** + * Creates meshes with axial symmetry like vases + * @remarks + * The lathe rotates around the Y axis. + * @example + * ```typescript + * const points = []; + * for (let i = 0; i & lt; 10; i++) { + * points.push(new THREE.Vector2(Math.sin(i * 0.2) * 10 + 5, (i - 5) * 2)); + * } + * const geometry = new THREE.LatheGeometry(points); + * const material = new THREE.MeshBasicMaterial({ + * color: 0xffff00 + * }); + * const lathe = new THREE.Mesh(geometry, material); + * scene.add(lathe); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/geometries/LatheGeometry | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/LatheGeometry.js | Source} + */ +export class LatheGeometry extends BufferGeometry { + /** + * This creates a {@link LatheGeometry} based on the parameters. + * @param points Array of Vector2s. The x-coordinate of each point must be greater than zero. + * Default `[new Vector2(0, -0.5), new Vector2(0.5, 0), new Vector2(0, 0.5)]` _which creates a simple diamond shape_. + * @param segments The number of circumference segments to generate. Expects a `Integer`. Default `12`. + * @param phiStart The starting angle in radians. Expects a `Float`. Default `0`. + * @param phiLength The radian (0 to 2*PI) range of the lathed section 2*PI is a closed lathe, less than 2PI is a portion. Expects a `Float`. Default `Math.PI * 2`. + */ + constructor(points?: Vector2[], segments?: number, phiStart?: number, phiLength?: number); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `LatheGeometry` + */ + override readonly type: string | "LatheGeometry"; + + /** + * An object with a property for each of the constructor parameters. + * @remarks Any modification after instantiation does not change the geometry. + */ + readonly parameters: { + readonly points: Vector2[]; + readonly segments: number; + readonly phiStart: number; + readonly phiLength: number; + }; + + /** @internal */ + static fromJSON(data: {}): LatheGeometry; +} diff --git a/src-testing/src/geometries/OctahedronGeometry.d.ts b/src-testing/src/geometries/OctahedronGeometry.d.ts new file mode 100644 index 000000000..09ba0b1e7 --- /dev/null +++ b/src-testing/src/geometries/OctahedronGeometry.d.ts @@ -0,0 +1,25 @@ +import { PolyhedronGeometry } from "./PolyhedronGeometry.js"; + +/** + * A class for generating an octahedron geometry. + * @see {@link https://threejs.org/docs/index.html#api/en/geometries/OctahedronGeometry | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/OctahedronGeometry.js | Source} + */ +export class OctahedronGeometry extends PolyhedronGeometry { + /** + * Create a new instance of {@link OctahedronGeometry} + * @param radius Radius of the octahedron. Expects a `Float`. Default `1` + * @param detail Setting this to a value greater than zero add vertices making it no longer an octahedron. Expects a `Integer`. Default `0` + */ + constructor(radius?: number, detail?: number); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `OctahedronGeometry` + */ + override readonly type: string | "OctahedronGeometry"; + + /** @internal */ + static fromJSON(data: {}): OctahedronGeometry; +} diff --git a/src-testing/src/geometries/PlaneGeometry.d.ts b/src-testing/src/geometries/PlaneGeometry.d.ts new file mode 100644 index 000000000..fda5f4908 --- /dev/null +++ b/src-testing/src/geometries/PlaneGeometry.d.ts @@ -0,0 +1,48 @@ +import { BufferGeometry } from "../core/BufferGeometry.js"; + +/** + * A class for generating plane geometries. + * @example + * ```typescript + * const geometry = new THREE.PlaneGeometry(1, 1); + * const material = new THREE.MeshBasicMaterial({ + * color: 0xffff00, + * side: THREE.DoubleSide + * }); + * const plane = new THREE.Mesh(geometry, material); + * scene.add(plane); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/geometries/PlaneGeometry | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/PlaneGeometry.js | Source} + */ +export class PlaneGeometry extends BufferGeometry { + /** + * Create a new instance of {@link PlaneGeometry} + * @param width Width along the X axis. Expects a `Float`. Default `1` + * @param height Height along the Y axis. Expects a `Float`. Default `1` + * @param widthSegments Number of segmented faces along the width of the sides. Expects a `Integer`. Default `1` + * @param heightSegments Number of segmented faces along the height of the sides. Expects a `Integer`. Default `1` + */ + constructor(width?: number, height?: number, widthSegments?: number, heightSegments?: number); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `PlaneGeometry` + */ + override readonly type: string | "PlaneGeometry"; + + /** + * An object with a property for each of the constructor parameters. + * @remarks Any modification after instantiation does not change the geometry. + */ + readonly parameters: { + readonly width: number; + readonly height: number; + readonly widthSegments: number; + readonly heightSegments: number; + }; + + /** @internal */ + static fromJSON(data: {}): PlaneGeometry; +} diff --git a/src-testing/src/geometries/PolyhedronGeometry.d.ts b/src-testing/src/geometries/PolyhedronGeometry.d.ts new file mode 100644 index 000000000..f4c07772b --- /dev/null +++ b/src-testing/src/geometries/PolyhedronGeometry.d.ts @@ -0,0 +1,54 @@ +import { BufferGeometry } from "../core/BufferGeometry.js"; + +/** + * A polyhedron is a solid in three dimensions with flat faces + * @remarks + * This class will take an array of vertices, project them onto a sphere, and then divide them up to the desired level of detail + * This class is used by {@link THREE.DodecahedronGeometry | DodecahedronGeometry}, {@link THREE.IcosahedronGeometry | IcosahedronGeometry}, + * {@link THREE.OctahedronGeometry | OctahedronGeometry}, and {@link THREE.TetrahedronGeometry | TetrahedronGeometry} to generate their respective geometries. + * @example + * ```typescript + * const verticesOfCube = [-1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, ]; + * const indicesOfFaces = [ + * 2, 1, 0, 0, 3, 2, + * 0, 4, 7, 7, 3, 0, + * 0, 1, 5, 5, 4, 0, + * 1, 2, 6, 6, 5, 1, + * 2, 3, 7, 7, 6, 2, + * 4, 5, 6, 6, 7, 4]; + * const geometry = new THREE.PolyhedronGeometry(verticesOfCube, indicesOfFaces, 6, 2); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/geometries/PolyhedronGeometry | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/PolyhedronGeometry.js | Source} + */ +export class PolyhedronGeometry extends BufferGeometry { + /** + * Create a new instance of {@link PolyhedronGeometry} + * @param vertices Array of points of the form [1,1,1, -1,-1,-1, ... ]. Default `[]`. + * @param indices Array of indices that make up the faces of the form [0,1,2, 2,3,0, ... ]. Default `[]`. + * @param radius [page:The radius of the final shape Expects a `Float`. Default `1` + * @param detail [page:How many levels to subdivide the geometry. The more detail, the smoother the shape. Expects a `Integer`. Default `0` + */ + constructor(vertices?: number[], indices?: number[], radius?: number, detail?: number); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `PolyhedronGeometry` + */ + override readonly type: string | "PolyhedronGeometry"; + + /** + * An object with a property for each of the constructor parameters. + * @remarks Any modification after instantiation does not change the geometry. + */ + readonly parameters: { + readonly vertices: number[]; + readonly indices: number[]; + readonly radius: number; + readonly detail: number; + }; + + /** @internal */ + static fromJSON(data: {}): PolyhedronGeometry; +} diff --git a/src-testing/src/geometries/RingGeometry.d.ts b/src-testing/src/geometries/RingGeometry.d.ts new file mode 100644 index 000000000..2cbc63ef4 --- /dev/null +++ b/src-testing/src/geometries/RingGeometry.d.ts @@ -0,0 +1,59 @@ +import { BufferGeometry } from "../core/BufferGeometry.js"; + +/** + * A class for generating a two-dimensional ring geometry. + * @example + * ```typescript + * const geometry = new THREE.RingGeometry(1, 5, 32); + * const material = new THREE.MeshBasicMaterial({ + * color: 0xffff00, + * side: THREE.DoubleSide + * }); + * const mesh = new THREE.Mesh(geometry, material); + * scene.add(mesh); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/geometries/RingGeometry | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/RingGeometry.js | Source} + */ +export class RingGeometry extends BufferGeometry { + /** + * Create a new instance of {@link RingGeometry} + * @param innerRadius Expects a `Float`. Default `0.5`. + * @param outerRadius Expects a `Float`. Default `1`. + * @param thetaSegments Number of segments. A higher number means the ring will be more round. Minimum is 3. Expects a `Integer`. Default `32`. + * @param phiSegments Number of segments per ring segment. Minimum is `1`. Expects a `Integer`. Default `1`. + * @param thetaStart Starting angle. Expects a `Float`. Default `0`. + * @param thetaLength Central angle. Expects a `Float`. Default `Math.PI * 2`. + */ + constructor( + innerRadius?: number, + outerRadius?: number, + thetaSegments?: number, + phiSegments?: number, + thetaStart?: number, + thetaLength?: number, + ); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `RingGeometry` + */ + override readonly type: string | "RingGeometry"; + + /** + * An object with a property for each of the constructor parameters. + * @remarks Any modification after instantiation does not change the geometry. + */ + readonly parameters: { + readonly innerRadius: number; + readonly outerRadius: number; + readonly thetaSegments: number; + readonly phiSegments: number; + readonly thetaStart: number; + readonly thetaLength: number; + }; + + /** @internal */ + static fromJSON(data: {}): RingGeometry; +} diff --git a/src-testing/src/geometries/ShapeGeometry.d.ts b/src-testing/src/geometries/ShapeGeometry.d.ts new file mode 100644 index 000000000..a3089a645 --- /dev/null +++ b/src-testing/src/geometries/ShapeGeometry.d.ts @@ -0,0 +1,53 @@ +import { BufferGeometry } from "../core/BufferGeometry.js"; +import { Shape } from "../extras/core/Shape.js"; + +/** + * Creates an one-sided polygonal geometry from one or more path shapes. + * @example + * ```typescript + * const x = 0, y = 0; + * const heartShape = new THREE.Shape(); + * heartShape.moveTo(x + 5, y + 5); + * heartShape.bezierCurveTo(x + 5, y + 5, x + 4, y, x, y); + * heartShape.bezierCurveTo(x - 6, y, x - 6, y + 7, x - 6, y + 7); + * heartShape.bezierCurveTo(x - 6, y + 11, x - 3, y + 15.4, x + 5, y + 19); + * heartShape.bezierCurveTo(x + 12, y + 15.4, x + 16, y + 11, x + 16, y + 7); + * heartShape.bezierCurveTo(x + 16, y + 7, x + 16, y, x + 10, y); + * heartShape.bezierCurveTo(x + 7, y, x + 5, y + 5, x + 5, y + 5); + * const geometry = new THREE.ShapeGeometry(heartShape); + * const material = new THREE.MeshBasicMaterial({ + * color: 0x00ff00 + * }); + * const mesh = new THREE.Mesh(geometry, material); + * scene.add(mesh); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/geometries/ShapeGeometry | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/ShapeGeometry.js | Source} + */ +export class ShapeGeometry extends BufferGeometry { + /** + * Create a new instance of {@link ShapeGeometry} + * @param shapes Array of shapes or a single {@link THREE.Shape | Shape}. Default `new Shape([new Vector2(0, 0.5), new Vector2(-0.5, -0.5), new Vector2(0.5, -0.5)])`, _a single triangle shape_. + * @param curveSegments Number of segments per shape. Expects a `Integer`. Default `12` + */ + constructor(shapes?: Shape | Shape[], curveSegments?: number); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `ShapeGeometry` + */ + override readonly type: string | "ShapeGeometry"; + + /** + * An object with a property for each of the constructor parameters. + * @remarks Any modification after instantiation does not change the geometry. + */ + readonly parameters: { + readonly shapes: Shape | Shape[]; + readonly curveSegments: number; + }; + + /** @internal */ + static fromJSON(data: {}): ShapeGeometry; +} diff --git a/src-testing/src/geometries/SphereGeometry.d.ts b/src-testing/src/geometries/SphereGeometry.d.ts new file mode 100644 index 000000000..b597bb26c --- /dev/null +++ b/src-testing/src/geometries/SphereGeometry.d.ts @@ -0,0 +1,67 @@ +import { BufferGeometry } from "../core/BufferGeometry.js"; + +/** + * A class for generating sphere geometries. + * @example + * ```typescript + * const geometry = new THREE.SphereGeometry(15, 32, 16); + * const material = new THREE.MeshBasicMaterial({ + * color: 0xffff00 + * }); + * const sphere = new THREE.Mesh(geometry, material); + * scene.add(sphere); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/geometries/SphereGeometry | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/SphereGeometry.js | Source} + */ +export class SphereGeometry extends BufferGeometry { + /** + * Create a new instance of {@link SphereGeometry} + * @remarks + * The geometry is created by sweeping and calculating vertexes + * around the **Y** axis (horizontal sweep) and the **Z** axis (vertical sweep) + * Thus, incomplete spheres (akin to `'sphere slices'`) can be created + * through the use of different values of {@link phiStart}, {@link phiLength}, {@link thetaStart} and {@link thetaLength}, + * in order to define the points in which we start (or end) calculating those vertices. + * @param radius Sphere radius. Expects a `Float`. Default `1` + * @param widthSegments Number of horizontal segments. Minimum value is 3, and the Expects a `Integer`. Default `32` + * @param heightSegments Number of vertical segments. Minimum value is 2, and the Expects a `Integer`. Default `16` + * @param phiStart Specify horizontal starting angle. Expects a `Float`. Default `0` + * @param phiLength Specify horizontal sweep angle size. Expects a `Float`. Default `Math.PI * 2` + * @param thetaStart Specify vertical starting angle. Expects a `Float`. Default `0` + * @param thetaLength Specify vertical sweep angle size. Expects a `Float`. Default `Math.PI` + */ + constructor( + radius?: number, + widthSegments?: number, + heightSegments?: number, + phiStart?: number, + phiLength?: number, + thetaStart?: number, + thetaLength?: number, + ); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `SphereGeometry` + */ + override readonly type: string | "SphereGeometry"; + + /** + * An object with a property for each of the constructor parameters. + * @remarks Any modification after instantiation does not change the geometry. + */ + readonly parameters: { + readonly radius: number; + readonly widthSegments: number; + readonly heightSegments: number; + readonly phiStart: number; + readonly phiLength: number; + readonly thetaStart: number; + readonly thetaLength: number; + }; + + /** @internal */ + static fromJSON(data: {}): SphereGeometry; +} diff --git a/src-testing/src/geometries/TetrahedronGeometry.d.ts b/src-testing/src/geometries/TetrahedronGeometry.d.ts new file mode 100644 index 000000000..2dd0fe5b6 --- /dev/null +++ b/src-testing/src/geometries/TetrahedronGeometry.d.ts @@ -0,0 +1,25 @@ +import { PolyhedronGeometry } from "./PolyhedronGeometry.js"; + +/** + * A class for generating a tetrahedron geometries. + * @see {@link https://threejs.org/docs/index.html#api/en/geometries/TetrahedronGeometry | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/TetrahedronGeometry.js | Source} + */ +export class TetrahedronGeometry extends PolyhedronGeometry { + /** + * Create a new instance of {@link TetrahedronGeometry} + * @param radius Radius of the tetrahedron. Expects a `Float`. Default `1` + * @param detail Setting this to a value greater than 0 adds vertices making it no longer a tetrahedron. Expects a `Integer`. Default `0` + */ + constructor(radius?: number, detail?: number); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `TetrahedronGeometry` + */ + override readonly type: string | "TetrahedronGeometry"; + + /** @internal */ + static fromJSON(data: {}): TetrahedronGeometry; +} diff --git a/src-testing/src/geometries/TorusGeometry.d.ts b/src-testing/src/geometries/TorusGeometry.d.ts new file mode 100644 index 000000000..47a70ceea --- /dev/null +++ b/src-testing/src/geometries/TorusGeometry.d.ts @@ -0,0 +1,49 @@ +import { BufferGeometry } from "../core/BufferGeometry.js"; + +/** + * A class for generating torus geometries. + * @example + * ```typescript + * const geometry = new THREE.TorusGeometry(10, 3, 16, 100); + * const material = new THREE.MeshBasicMaterial({ + * color: 0xffff00 + * }); + * const torus = new THREE.Mesh(geometry, material); + * scene.add(torus); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/geometries/TorusGeometry | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/TorusGeometry.js | Source} + */ +export class TorusGeometry extends BufferGeometry { + /** + * Create a new instance of {@link TorusGeometry} + * @param radius Radius of the torus, from the center of the torus to the center of the tube. Expects a `Float`. Default `1`. + * @param tube Radius of the tube. Expects a `Float`. Default `0.4`. + * @param radialSegments Expects a `Integer`.Default is `12`. + * @param tubularSegments Expects a `Integer`. Default `48`. + * @param arc Central angle. Expects a `Float`. Default `Math.PI * 2` + */ + constructor(radius?: number, tube?: number, radialSegments?: number, tubularSegments?: number, arc?: number); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `TorusGeometry` + */ + override readonly type: string | "TorusGeometry"; + + /** + * An object with a property for each of the constructor parameters. + * @remarks Any modification after instantiation does not change the geometry. + */ + readonly parameters: { + readonly radius: number; + readonly tube: number; + readonly radialSegments: number; + readonly tubularSegments: number; + readonly arc: number; + }; + + /** @internal */ + static fromJSON(data: any): TorusGeometry; +} diff --git a/src-testing/src/geometries/TorusKnotGeometry.d.ts b/src-testing/src/geometries/TorusKnotGeometry.d.ts new file mode 100644 index 000000000..103b6916e --- /dev/null +++ b/src-testing/src/geometries/TorusKnotGeometry.d.ts @@ -0,0 +1,59 @@ +import { BufferGeometry } from "../core/BufferGeometry.js"; + +/** + * Creates a torus knot, the particular shape of which is defined by a pair of coprime integers, p and q + * If p and q are not coprime, the result will be a torus link. + * @example + * ```typescript + * const geometry = new THREE.TorusKnotGeometry(10, 3, 100, 16); + * const material = new THREE.MeshBasicMaterial({ + * color: 0xffff00 + * }); + * const torusKnot = new THREE.Mesh(geometry, material); + * scene.add(torusKnot); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/geometries/TorusKnotGeometry | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/TorusKnotGeometry.js | Source} + */ +export class TorusKnotGeometry extends BufferGeometry { + /** + * Create a new instance of {@link TorusKnotGeometry} + * @param radius Radius of the torus.. Default `1`. + * @param tube Expects a `Float`. Default `0.4`. + * @param tubularSegments Expects a `Integer`. Default `64`. + * @param radialSegments Expects a `Integer`. Default `8`. + * @param p This value determines, how many times the geometry winds around its axis of rotational symmetry. Expects a `Integer`. Default `2`. + * @param q This value determines, how many times the geometry winds around a circle in the interior of the torus. Expects a `Integer`. Default `3`. + */ + constructor( + radius?: number, + tube?: number, + tubularSegments?: number, + radialSegments?: number, + p?: number, + q?: number, + ); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `TorusKnotGeometry` + */ + override readonly type: string | "TorusKnotGeometry"; + + /** + * An object with a property for each of the constructor parameters. + * @remarks Any modification after instantiation does not change the geometry. + */ + readonly parameters: { + readonly radius: number; + readonly tube: number; + readonly tubularSegments: number; + readonly radialSegments: number; + readonly p: number; + readonly q: number; + }; + + /** @internal */ + static fromJSON(data: {}): TorusKnotGeometry; +} diff --git a/src-testing/src/geometries/TubeGeometry.d.ts b/src-testing/src/geometries/TubeGeometry.d.ts new file mode 100644 index 000000000..37e7129ad --- /dev/null +++ b/src-testing/src/geometries/TubeGeometry.d.ts @@ -0,0 +1,86 @@ +import { BufferGeometry } from "../core/BufferGeometry.js"; +import { Curve } from "../extras/core/Curve.js"; +import { Vector3 } from "../math/Vector3.js"; + +/** + * Creates a tube that extrudes along a 3d curve. + * @example + * ```typescript + * class CustomSinCurve extends THREE.Curve { + * constructor(scale = 1) { + * super(); + * this.scale = scale; + * } + * getPoint(t, optionalTarget = new THREE.Vector3()) { + * const tx = t * 3 - 1.5; + * const ty = Math.sin(2 * Math.PI * t); + * const tz = 0; + * return optionalTarget.set(tx, ty, tz).multiplyScalar(this.scale); + * } + * } + * const path = new CustomSinCurve(10); + * const geometry = new THREE.TubeGeometry(path, 20, 2, 8, false); + * const material = new THREE.MeshBasicMaterial({ + * color: 0x00ff00 + * }); + * const mesh = new THREE.Mesh(geometry, material); + * scene.add(mesh); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/geometries/TubeGeometry | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/TubeGeometry.js | Source} + */ +export class TubeGeometry extends BufferGeometry { + /** + * Create a new instance of {@link TubeGeometry} + * @param path A 3D path that inherits from the {@link THREE.Curve | Curve} base class. + * Default {@link THREE.QuadraticBezierCurve3 | new THREE.QuadraticBezierCurve3(new Vector3(-1, -1, 0 ), new Vector3(-1, 1, 0), new Vector3(1, 1, 0))}. + * @param tubularSegments The number of segments that make up the tube. Expects a `Integer`. Default `64`. + * @param radius The radius of the tube. Expects a `Float`. Default `1`. + * @param radialSegments The number of segments that make up the cross-section. Expects a `Integer`. Default `8`. + * @param closed Is the tube open or closed. Default `false`. + */ + constructor( + path?: Curve, + tubularSegments?: number, + radius?: number, + radialSegments?: number, + closed?: boolean, + ); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `TubeGeometry` + */ + override readonly type: string | "TubeGeometry"; + + /** + * An object with a property for each of the constructor parameters. + * @remarks Any modification after instantiation does not change the geometry. + */ + readonly parameters: { + readonly path: Curve; + readonly tubularSegments: number; + readonly radius: number; + readonly radialSegments: number; + readonly closed: boolean; + }; + + /** + * An array of {@link THREE.Vector3 | Vector3} tangents + */ + tangents: Vector3[]; + + /** + * An array of {@link THREE.Vector3 | Vector3} normals + */ + normals: Vector3[]; + + /** + * An array of {@link THREE.Vector3 | Vector3} binormals + */ + binormals: Vector3[]; + + /** @internal */ + static fromJSON(data: {}): TubeGeometry; +} diff --git a/src-testing/src/geometries/WireframeGeometry.d.ts b/src-testing/src/geometries/WireframeGeometry.d.ts new file mode 100644 index 000000000..6263316a6 --- /dev/null +++ b/src-testing/src/geometries/WireframeGeometry.d.ts @@ -0,0 +1,40 @@ +import { BufferGeometry } from "../core/BufferGeometry.js"; + +/** + * This can be used as a helper object to view a {@link BufferGeometry | geometry} as a wireframe. + * @example + * ```typescript + * const geometry = new THREE.SphereGeometry(100, 100, 100); + * const wireframe = new THREE.WireframeGeometry(geometry); + * const line = new THREE.LineSegments(wireframe); + * line.material.depthTest = false; + * line.material.opacity = 0.25; + * line.material.transparent = true; + * scene.add(line); + * ``` + * @see Example: {@link https://threejs.org/examples/#webgl_helpers | helpers} + * @see {@link https://threejs.org/docs/index.html#api/en/geometries/WireframeGeometry | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/WireframeGeometry.js | Source} + */ +export class WireframeGeometry extends BufferGeometry { + /** + * Create a new instance of {@link WireframeGeometry} + * @param geometry Any geometry object. Default `null`. + */ + constructor(geometry?: TBufferGeometry); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `WireframeGeometry` + */ + override readonly type: string | "WireframeGeometry"; + + /** + * An object with a property for each of the constructor parameters. + * @remarks Any modification after instantiation does not change the geometry. + */ + readonly parameters: { + readonly geometry: TBufferGeometry; + }; +} diff --git a/src-testing/src/helpers/ArrowHelper.d.ts b/src-testing/src/helpers/ArrowHelper.d.ts new file mode 100644 index 000000000..94896123c --- /dev/null +++ b/src-testing/src/helpers/ArrowHelper.d.ts @@ -0,0 +1,93 @@ +import { Object3D } from "../core/Object3D.js"; +import { ColorRepresentation } from "../math/Color.js"; +import { Vector3 } from "../math/Vector3.js"; +import { Line } from "../objects/Line.js"; +import { Mesh } from "../objects/Mesh.js"; + +/** + * An 3D arrow object for visualizing directions. + * @example + * ```typescript + * const dir = new THREE.Vector3(1, 2, 0); + * //normalize the direction vector (convert to vector of length 1) + * dir.normalize(); + * const origin = new THREE.Vector3(0, 0, 0); + * const length = 1; + * const hex = 0xffff00; + * const {@link ArrowHelper} = new THREE.ArrowHelper(dir, origin, length, hex); + * scene.add(arrowHelper); + * ``` + * @see Example: {@link https://threejs.org/examples/#webgl_shadowmesh | WebGL / shadowmesh} + * @see {@link https://threejs.org/docs/index.html#api/en/helpers/ArrowHelper | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/helpers/ArrowHelper.js | Source} + */ +export class ArrowHelper extends Object3D { + /** + * Create a new instance of {@link ArrowHelper} + * @param dir Direction from origin. Must be a unit vector. Default `new THREE.Vector3(0, 0, 1)` + * @param origin Point at which the arrow starts. Default `new THREE.Vector3(0, 0, 0)` + * @param length Length of the arrow. Default `1` + * @param hex Hexadecimal value to define color. Default `0xffff00` + * @param headLength The length of the head of the arrow. Default `0.2 * length` + * @param headWidth The width of the head of the arrow. Default `0.2 * headLength` + */ + constructor( + dir?: Vector3, + origin?: Vector3, + length?: number, + color?: ColorRepresentation, + headLength?: number, + headWidth?: number, + ); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @override + * @defaultValue `ArrowHelper` + */ + override readonly type: string | "ArrowHelper"; + + /** + * Contains the line part of the arrowHelper. + */ + line: Line; + + /** + * Contains the cone part of the arrowHelper. + */ + cone: Mesh; + + /** + * Sets the color of the arrowHelper. + * @param color The desired color. + */ + setColor(color: ColorRepresentation): void; + + /** + * @param dir The desired direction. Must be a unit vector. + */ + setDirection(dir: Vector3): void; + + /** + * Sets the length of the arrowhelper. + * @param length The desired length. + * @param headLength The length of the head of the arrow. Default `0.2 * length` + * @param headWidth The width of the head of the arrow. Default `0.2 * headLength` + */ + setLength(length: number, headLength?: number, headWidth?: number): void; + + /** + * Copy the given object into this object + * @remarks Note: event listeners and user-defined callbacks ({@link onAfterRender | .onAfterRender} and {@link onBeforeRender | .onBeforeRender}) are not copied. + * @param source + */ + override copy(source: this): this; + + /** + * Frees the GPU-related resources allocated by this instance + * @remarks + * Call this method whenever this instance is no longer used in your app. + */ + dispose(): void; +} diff --git a/src-testing/src/helpers/AxesHelper.d.ts b/src-testing/src/helpers/AxesHelper.d.ts new file mode 100644 index 000000000..c0633c102 --- /dev/null +++ b/src-testing/src/helpers/AxesHelper.d.ts @@ -0,0 +1,50 @@ +import { ColorRepresentation } from "../math/Color.js"; +import { LineSegments } from "../objects/LineSegments.js"; + +/** + * An axis object to visualize the 3 axes in a simple way. + * @remarks + * The X axis is red + * The Y axis is green + * The Z axis is blue. + * @example + * ```typescript + * const {@link AxesHelper} = new THREE.AxesHelper(5); + * scene.add(axesHelper); + * ``` + * @see Example: {@link https://threejs.org/examples/#webgl_buffergeometry_compression | WebGL / buffergeometry / compression} + * @see Example: {@link https://threejs.org/examples/#webgl_geometry_convex | WebGL / geometry / convex} + * @see Example: {@link https://threejs.org/examples/#webgl_loader_nrrd | WebGL / loader / nrrd} + * @see {@link https://threejs.org/docs/index.html#api/en/helpers/AxesHelper | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/helpers/AxesHelper.js | Source} + */ +export class AxesHelper extends LineSegments { + /** + * Create a new instance of {@link AxesHelper} + * @param size Size of the lines representing the axes. Default `1` + */ + constructor(size?: number); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @override + * @defaultValue `AxesHelper` + */ + override readonly type: string | "AxesHelper"; + + /** + * Sets the axes colors to {@link Color | xAxisColor}, {@link Color | yAxisColor}, {@link Color | zAxisColor}. + * @param xAxisColor + * @param yAxisColor + * @param zAxisColor + */ + setColors(xAxisColor: ColorRepresentation, yAxisColor: ColorRepresentation, zAxisColor: ColorRepresentation): this; + + /** + * Frees the GPU-related resources allocated by this instance + * @remarks + * Call this method whenever this instance is no longer used in your app. + */ + dispose(): void; +} diff --git a/src-testing/src/helpers/Box3Helper.d.ts b/src-testing/src/helpers/Box3Helper.d.ts new file mode 100644 index 000000000..78e1c6f82 --- /dev/null +++ b/src-testing/src/helpers/Box3Helper.d.ts @@ -0,0 +1,44 @@ +import { Box3 } from "../math/Box3.js"; +import { ColorRepresentation } from "../math/Color.js"; +import { LineSegments } from "../objects/LineSegments.js"; + +/** + * Helper object to visualize a {@link THREE.Box3 | Box3}. + * @example + * ```typescript + * const box = new THREE.Box3(); + * box.setFromCenterAndSize(new THREE.Vector3(1, 1, 1), new THREE.Vector3(2, 1, 3)); + * const helper = new THREE.Box3Helper(box, 0xffff00); + * scene.add(helper); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/helpers/Box3Helper | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/helpers/Box3Helper.js | Source} + */ +export class Box3Helper extends LineSegments { + /** + * Creates a new wireframe box that represents the passed Box3. + * @param box The Box3 to show. + * @param color The box's color. Default `0xffff00` + */ + constructor(box: Box3, color?: ColorRepresentation); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @override + * @defaultValue `Box3Helper` + */ + override readonly type: string | "Box3Helper"; + + /** + * The Box3 being visualized. + */ + box: Box3; + + /** + * Frees the GPU-related resources allocated by this instance + * @remarks + * Call this method whenever this instance is no longer used in your app. + */ + dispose(): void; +} diff --git a/src-testing/src/helpers/BoxHelper.d.ts b/src-testing/src/helpers/BoxHelper.d.ts new file mode 100644 index 000000000..d049a5b72 --- /dev/null +++ b/src-testing/src/helpers/BoxHelper.d.ts @@ -0,0 +1,64 @@ +import { BufferGeometry } from "../core/BufferGeometry.js"; +import { Object3D } from "../core/Object3D.js"; +import { LineBasicMaterial } from "../materials/LineBasicMaterial.js"; +import { ColorRepresentation } from "../math/Color.js"; +import { LineSegments } from "../objects/LineSegments.js"; + +/** + * Helper object to graphically show the world-axis-aligned bounding box around an object + * @remarks + * The actual bounding box is handled with {@link THREE.Box3 | Box3}, this is just a visual helper for debugging + * It can be automatically resized with the {@link THREE.BoxHelper.update | BoxHelper.update} method when the object it's created from is transformed + * Note that the object must have a {@link THREE.BufferGeometry | BufferGeometry} for this to work, so it won't work with {@link Sprite | Sprites}. + * @example + * ```typescript + * const sphere = new THREE.SphereGeometry(); + * const object = new THREE.Mesh(sphere, new THREE.MeshBasicMaterial(0xff0000)); + * const box = new THREE.BoxHelper(object, 0xffff00); + * scene.add(box); + * ``` + * @see Example: {@link https://threejs.org/examples/#webgl_helpers | WebGL / helpers} + * @see Example: {@link https://threejs.org/examples/#webgl_loader_nrrd | WebGL / loader / nrrd} + * @see Example: {@link https://threejs.org/examples/#webgl_buffergeometry_drawrange | WebGL / buffergeometry / drawrange} + * @see {@link https://threejs.org/docs/index.html#api/en/helpers/BoxHelper | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/helpers/BoxHelper.js | Source} + */ +export class BoxHelper extends LineSegments { + /** + * Creates a new wireframe box that bounds the passed object + * @remarks + * Internally this uses {@link THREE.Box3.setFromObject | Box3.setFromObject} to calculate the dimensions + * Note that this includes any children. + * @param object The object3D to show the world-axis-aligned bounding box. + * @param color Hexadecimal value that defines the box's color. Default `0xffff00` + */ + constructor(object: Object3D, color?: ColorRepresentation); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @override + * @defaultValue `BoxHelper` + */ + override readonly type: string | "BoxHelper"; + + /** + * Updates the helper's geometry to match the dimensions of the object, including any children + * @remarks + * See {@link THREE.Box3.setFromObject | Box3.setFromObject}. + */ + update(object?: Object3D): void; + + /** + * Updates the wireframe box for the passed object. + * @param object {@link THREE.Object3D | Object3D} to create the helper of. + */ + setFromObject(object: Object3D): this; + + /** + * Frees the GPU-related resources allocated by this instance + * @remarks + * Call this method whenever this instance is no longer used in your app. + */ + dispose(): void; +} diff --git a/src-testing/src/helpers/CameraHelper.d.ts b/src-testing/src/helpers/CameraHelper.d.ts new file mode 100644 index 000000000..469dcaa0d --- /dev/null +++ b/src-testing/src/helpers/CameraHelper.d.ts @@ -0,0 +1,80 @@ +import { Camera } from "../cameras/Camera.js"; +import { Color } from "../math/Color.js"; +import { Matrix4 } from "../math/Matrix4.js"; +import { LineSegments } from "../objects/LineSegments.js"; + +/** + * This helps with visualizing what a camera contains in its frustum + * @remarks + * It visualizes the frustum of a camera using a {@link THREE.LineSegments | LineSegments}. + * @remarks {@link CameraHelper} must be a child of the scene. + * @example + * ```typescript + * const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); + * const helper = new THREE.CameraHelper(camera); + * scene.add(helper); + * ``` + * @see Example: {@link https://threejs.org/examples/#webgl_camera | WebGL / camera} + * @see Example: {@link https://threejs.org/examples/#webgl_geometry_extrude_splines | WebGL / extrude / splines} + * @see {@link https://threejs.org/docs/index.html#api/en/helpers/CameraHelper | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/helpers/CameraHelper.js | Source} + */ +export class CameraHelper extends LineSegments { + /** + * This create a new {@link CameraHelper} for the specified camera. + * @param camera The camera to visualize. + */ + constructor(camera: Camera); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @override + * @defaultValue `CameraHelper` + */ + override readonly type: string | "CameraHelper"; + + /** + * The camera being visualized. + */ + camera: Camera; + + /** + * This contains the points used to visualize the camera. + */ + pointMap: { [id: string]: number[] }; + + /** + * Reference to the {@link THREE.Camera.matrixWorld | camera.matrixWorld}. + */ + matrix: Matrix4; + + /** + * Is set to `false`, as the helper is using the {@link THREE.Camera.matrixWorld | camera.matrixWorld}. + * @see {@link THREE.Object3D.matrixAutoUpdate | Object3D.matrixAutoUpdate}. + * @defaultValue `false`. + */ + override matrixAutoUpdate: boolean; + + /** + * Defines the colors of the helper. + * @param frustum + * @param cone + * @param up + * @param target + * @param cross + */ + setColors(frustum: Color, cone: Color, up: Color, target: Color, cross: Color): this; + + /** + * Updates the helper based on the projectionMatrix of the camera. + */ + update(): void; + + /** + * Frees the GPU-related resources allocated by this instance + * @remarks + * Call this method whenever this instance is no longer used in your app. + */ + dispose(): void; +} diff --git a/src-testing/src/helpers/DirectionalLightHelper.d.ts b/src-testing/src/helpers/DirectionalLightHelper.d.ts new file mode 100644 index 000000000..729eccedd --- /dev/null +++ b/src-testing/src/helpers/DirectionalLightHelper.d.ts @@ -0,0 +1,81 @@ +import { Object3D } from "../core/Object3D.js"; +import { DirectionalLight } from "../lights/DirectionalLight.js"; +import { ColorRepresentation } from "../math/Color.js"; +import { Matrix4 } from "../math/Matrix4.js"; +import { Line } from "../objects/Line.js"; + +/** + * Helper object to assist with visualizing a {@link THREE.DirectionalLight | DirectionalLight}'s effect on the scene + * @remarks + * This consists of plane and a line representing the light's position and direction. + * @example + * ```typescript + * const light = new THREE.DirectionalLight(0xFFFFFF); + * scene.add(light); + * + * const helper = new THREE.DirectionalLightHelper(light, 5); + * scene.add(helper); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/helpers/DirectionalLightHelper | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/helpers/DirectionalLightHelper.js | Source} + */ +export class DirectionalLightHelper extends Object3D { + /** + * Create a new instance of {@link DirectionalLightHelper} + * @param light The light to be visualized. + * @param size Dimensions of the plane. Default `1` + * @param color If this is not the set the helper will take the color of the light. Default `light.color` + */ + constructor(light: DirectionalLight, size?: number, color?: ColorRepresentation); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @override + * @defaultValue `DirectionalLightHelper` + */ + override readonly type: string | "DirectionalLightHelper"; + + /** + * Contains the line mesh showing the location of the directional light. + */ + lightPlane: Line; + + /** + * Reference to the {@link THREE.DirectionalLight | directionalLight} being visualized. + */ + light: DirectionalLight; + + /** + * Reference to the {@link THREE.DirectionalLight.matrixWorld | light.matrixWorld}. + */ + matrix: Matrix4; + + /** + * Is set to `false`, as the helper is using the {@link THREE.DirectionalLight.matrixWorld | light.matrixWorld}. + * @see {@link THREE.Object3D.matrixAutoUpdate | Object3D.matrixAutoUpdate}. + * @defaultValue `false`. + */ + override matrixAutoUpdate: boolean; + + /** + * The color parameter passed in the constructor. + * @remarks If this is changed, the helper's color will update the next time {@link update} is called. + * @defaultValue `undefined` + */ + color: ColorRepresentation | undefined; + + targetLine: Line; // TODO: Double check if this need to be exposed or not. + + /** + * Updates the helper to match the position and direction of the {@link light | DirectionalLight} being visualized. + */ + update(): void; + + /** + * Frees the GPU-related resources allocated by this instance + * @remarks + * Call this method whenever this instance is no longer used in your app. + */ + dispose(): void; +} diff --git a/src-testing/src/helpers/GridHelper.d.ts b/src-testing/src/helpers/GridHelper.d.ts new file mode 100644 index 000000000..0b786b992 --- /dev/null +++ b/src-testing/src/helpers/GridHelper.d.ts @@ -0,0 +1,47 @@ +import { BufferGeometry } from "../core/BufferGeometry.js"; +import { LineBasicMaterial } from "../materials/LineBasicMaterial.js"; +import { ColorRepresentation } from "../math/Color.js"; +import { LineSegments } from "../objects/LineSegments.js"; + +/** + * The {@link GridHelper} is an object to define grids + * @remarks + * Grids are two-dimensional arrays of lines. + * @example + * ```typescript + * const size = 10; + * const divisions = 10; + * const {@link GridHelper} = new THREE.GridHelper(size, divisions); + * scene.add(gridHelper); + * ``` + * @see Example: {@link https://threejs.org/examples/#webgl_helpers | WebGL / helpers} + * @see {@link https://threejs.org/docs/index.html#api/en/helpers/GridHelper | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/helpers/GridHelper.js | Source} + */ +export class GridHelper extends LineSegments { + /** + * Creates a new {@link GridHelper} of size 'size' and divided into 'divisions' segments per side + * @remarks + * Colors are optional. + * @param size The size of the grid. Default `10` + * @param divisions The number of divisions across the grid. Default `10` + * @param colorCenterLine The color of the centerline. This can be a {@link THREE.Color | Color}, a hexadecimal value and an CSS-Color name. Default `0x444444` + * @param colorGrid The color of the lines of the grid. This can be a {@link THREE.Color | Color}, a hexadecimal value and an CSS-Color name. Default `0x888888` + */ + constructor(size?: number, divisions?: number, color1?: ColorRepresentation, color2?: ColorRepresentation); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @override + * @defaultValue `GridHelper` + */ + override readonly type: string | "GridHelper"; + + /** + * Frees the GPU-related resources allocated by this instance + * @remarks + * Call this method whenever this instance is no longer used in your app. + */ + dispose(): void; +} diff --git a/src-testing/src/helpers/HemisphereLightHelper.d.ts b/src-testing/src/helpers/HemisphereLightHelper.d.ts new file mode 100644 index 000000000..80366b63b --- /dev/null +++ b/src-testing/src/helpers/HemisphereLightHelper.d.ts @@ -0,0 +1,72 @@ +import { Object3D } from "../core/Object3D.js"; +import { HemisphereLight } from "../lights/HemisphereLight.js"; +import { MeshBasicMaterial } from "../materials/MeshBasicMaterial.js"; +import { ColorRepresentation } from "../math/Color.js"; +import { Matrix4 } from "../math/Matrix4.js"; + +/** + * Creates a visual aid consisting of a spherical {@link THREE.Mesh | Mesh} for a {@link THREE.HemisphereLight | HemisphereLight}. + * @example + * ```typescript + * const light = new THREE.HemisphereLight(0xffffbb, 0x080820, 1); + * const helper = new THREE.HemisphereLightHelper(light, 5); + * scene.add(helper); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/helpers/HemisphereLightHelper | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/helpers/HemisphereLightHelper.js | Source} + */ +export class HemisphereLightHelper extends Object3D { + /** + * Create a new instance of {@link HemisphereLightHelper} + * @param light The light being visualized. + * @param size Thr sphere size + * @param color If this is not the set the helper will take the color of the light. + */ + constructor(light: HemisphereLight, size: number, color?: ColorRepresentation); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @override + * @defaultValue `HemisphereLightHelper` + */ + override readonly type: string | "HemisphereLightHelper"; + + /** + * Reference to the HemisphereLight being visualized. + */ + light: HemisphereLight; + + /** + * Reference to the {@link THREE.HemisphereLight.matrixWorld | light.matrixWorld}. + */ + matrix: Matrix4; + + /** + * Is set to `false`, as the helper is using the {@link THREE.HemisphereLight.matrixWorld | light.matrixWorld}. + * @see {@link THREE.Object3D.matrixAutoUpdate | Object3D.matrixAutoUpdate}. + * @defaultValue `false`. + */ + override matrixAutoUpdate: boolean; + + material: MeshBasicMaterial; // TODO: Double check if this need to be exposed or not. + + /** + * The color parameter passed in the constructor. + * @remarks If this is changed, the helper's color will update the next time {@link update} is called. + * @defaultValue `undefined` + */ + color: ColorRepresentation | undefined; + + /** + * Updates the helper to match the position and direction of the {@link .light | HemisphereLight}. + */ + update(): void; + + /** + * Frees the GPU-related resources allocated by this instance + * @remarks + * Call this method whenever this instance is no longer used in your app. + */ + dispose(): void; +} diff --git a/src-testing/src/helpers/PlaneHelper.d.ts b/src-testing/src/helpers/PlaneHelper.d.ts new file mode 100644 index 000000000..43c9821cb --- /dev/null +++ b/src-testing/src/helpers/PlaneHelper.d.ts @@ -0,0 +1,50 @@ +import { Plane } from "../math/Plane.js"; +import { LineSegments } from "../objects/LineSegments.js"; + +/** + * Helper object to visualize a {@link THREE.Plane | Plane}. + * @example + * ```typescript + * const plane = new THREE.Plane(new THREE.Vector3(1, 1, 0.2), 3); + * const helper = new THREE.PlaneHelper(plane, 1, 0xffff00); + * scene.add(helper); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/helpers/PlaneHelper | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/helpers/PlaneHelper.js | Source} + */ +export class PlaneHelper extends LineSegments { + /** + * Creates a new wireframe representation of the passed plane. + * @param plane The plane to visualize. + * @param size Side length of plane helper. Expects a `Float`. Default `1` + * @param hex Color. Default `0xffff00` + */ + constructor(plane: Plane, size?: number, hex?: number); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @override + * @defaultValue `PlaneHelper` + */ + override readonly type: string | "PlaneHelper"; + + /** + * The {@link Plane | plane} being visualized. + */ + plane: Plane; + + /** + * The side lengths of plane helper. + * @remarks Expects a `Float` + * @defaultValue `1` + */ + size: number; + + /** + * Frees the GPU-related resources allocated by this instance + * @remarks + * Call this method whenever this instance is no longer used in your app. + */ + dispose(): void; +} diff --git a/src-testing/src/helpers/PointLightHelper.d.ts b/src-testing/src/helpers/PointLightHelper.d.ts new file mode 100644 index 000000000..7d61da5e3 --- /dev/null +++ b/src-testing/src/helpers/PointLightHelper.d.ts @@ -0,0 +1,73 @@ +import { Object3D } from "../core/Object3D.js"; +import { PointLight } from "../lights/PointLight.js"; +import { ColorRepresentation } from "../math/Color.js"; +import { Matrix4 } from "../math/Matrix4.js"; + +/** + * This displays a helper object consisting of a spherical {@link THREE.Mesh | Mesh} for visualizing a {@link THREE.PointLight | PointLight}. + * @example + * ```typescript + * const pointLight = new THREE.PointLight(0xff0000, 1, 100); + * pointLight.position.set(10, 10, 10); + * scene.add(pointLight); + * const sphereSize = 1; + * const {@link PointLightHelper} = new THREE.PointLightHelper(pointLight, sphereSize); + * scene.add(pointLightHelper); + * ``` + * @see Example: {@link https://threejs.org/examples/#webgl_helpers | WebGL / helpers} + * @see {@link https://threejs.org/docs/index.html#api/en/helpers/PointLightHelper | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/helpers/PointLightHelper.js | Source} + */ +export class PointLightHelper extends Object3D { + /** + * Create a new instance of {@link PointLightHelper} + * @param light The light to be visualized. + * @param sphereSize The size of the sphere helper. Expects a `Float`. Default `1` + * @param color If this is not the set the helper will take the color of the light. + */ + constructor(light: PointLight, sphereSize?: number, color?: ColorRepresentation); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @override + * @defaultValue `PointLightHelper` + */ + override readonly type: string | "PointLightHelper"; + + /** + * The {@link THREE.PointLight | PointLight} that is being visualized. + */ + light: PointLight; + + /** + * Reference to the {@link THREE.PointLight.matrixWorld | light.matrixWorld}. + */ + matrix: Matrix4; + + /** + * The color parameter passed in the constructor. + * @remarks If this is changed, the helper's color will update the next time {@link update} is called. + * @defaultValue `undefined` + */ + color: ColorRepresentation | undefined; + + /** + * Is set to `false`, as the helper is using the {@link THREE.PointLight.matrixWorld | light.matrixWorld}. + * @see {@link THREE.Object3D.matrixAutoUpdate | Object3D.matrixAutoUpdate}. + * @defaultValue `false`. + */ + override matrixAutoUpdate: boolean; + + /** + * Updates the helper to match the position of the {@link THREE..light | .light}. + */ + update(): void; + + /** + * Frees the GPU-related resources allocated by this instance + * @remarks + * Call this method whenever this instance is no longer used in your app. + */ + dispose(): void; +} diff --git a/src-testing/src/helpers/PolarGridHelper.d.ts b/src-testing/src/helpers/PolarGridHelper.d.ts new file mode 100644 index 000000000..994d71c94 --- /dev/null +++ b/src-testing/src/helpers/PolarGridHelper.d.ts @@ -0,0 +1,55 @@ +import { ColorRepresentation } from "../math/Color.js"; +import { LineSegments } from "../objects/LineSegments.js"; + +/** + * The {@link PolarGridHelper} is an object to define polar grids + * @remarks + * Grids are two-dimensional arrays of lines. + * @example + * ```typescript + * const radius = 10; + * const sectors = 16; + * const rings = 8; + * const divisions = 64; + * const helper = new THREE.PolarGridHelper(radius, sectors, rings, divisions); + * scene.add(helper); + * ``` + * @see Example: {@link https://threejs.org/examples/#webgl_helpers | WebGL / helpers} + * @see {@link https://threejs.org/docs/index.html#api/en/helpers/PolarGridHelper | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/helpers/PolarGridHelper.js | Source} + */ +export class PolarGridHelper extends LineSegments { + /** + * Creates a new {@link PolarGridHelper} of radius 'radius' with 'sectors' number of sectors and 'rings' number of rings, where each circle is smoothed into 'divisions' number of line segments. + * @remarks Colors are optional. + * @param radius The radius of the polar grid. This can be any positive number. Default `10`. + * @param sectors The number of sectors the grid will be divided into. This can be any positive integer. Default `16`. + * @param rings The number of rings. This can be any positive integer. Default `8`. + * @param divisions The number of line segments used for each circle. This can be any positive integer that is 3 or greater. Default `64`. + * @param color1 The first color used for grid elements. This can be a {@link THREE.Color | Color}, a hexadecimal value and an CSS-Color name. Default `0x444444`. + * @param color2 The second color used for grid elements. This can be a {@link THREE.Color | Color}, a hexadecimal value and an CSS-Color name. Default `0x888888`. + */ + constructor( + radius?: number, + radials?: number, + circles?: number, + divisions?: number, + color1?: ColorRepresentation, + color2?: ColorRepresentation, + ); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @override + * @defaultValue `PolarGridHelper` + */ + override readonly type: string | "PolarGridHelper"; + + /** + * Frees the GPU-related resources allocated by this instance + * @remarks + * Call this method whenever this instance is no longer used in your app. + */ + dispose(): void; +} diff --git a/src-testing/src/helpers/SkeletonHelper.d.ts b/src-testing/src/helpers/SkeletonHelper.d.ts new file mode 100644 index 000000000..772ebf30e --- /dev/null +++ b/src-testing/src/helpers/SkeletonHelper.d.ts @@ -0,0 +1,78 @@ +import { Object3D } from "../core/Object3D.js"; +import { Matrix4 } from "../math/Matrix4.js"; +import { Bone } from "../objects/Bone.js"; +import { LineSegments } from "../objects/LineSegments.js"; +import { SkinnedMesh } from "../objects/SkinnedMesh.js"; + +/** + * A helper object to assist with visualizing a {@link Skeleton | Skeleton} + * @remarks + * The helper is rendered using a {@link LineBasicMaterial | LineBasicMaterial}. + * @example + * ```typescript + * const helper = new THREE.SkeletonHelper(skinnedMesh); + * scene.add(helper); + * ``` + * @see Example: {@link https://threejs.org/examples/#webgl_animation_skinning_blending | WebGL / animation / skinning / blending} + * @see Example: {@link https://threejs.org/examples/#webgl_animation_skinning_morph | WebGL / animation / skinning / morph} + * @see Example: {@link https://threejs.org/examples/#webgl_loader_bvh | WebGL / loader / bvh } + * @see {@link https://threejs.org/docs/index.html#api/en/helpers/SkeletonHelper | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/helpers/SkeletonHelper.js | Source} + */ +export class SkeletonHelper extends LineSegments { + /** + * Create a new instance of {@link SkeletonHelper} + * @param object Usually an instance of {@link THREE.SkinnedMesh | SkinnedMesh}. + * However, any instance of {@link THREE.Object3D | Object3D} can be used if it represents a hierarchy of {@link Bone | Bone}s (via {@link THREE.Object3D.children | Object3D.children}). + */ + constructor(object: SkinnedMesh | Object3D); + + /** + * Read-only flag to check if a given object is of type {@link SkeletonHelper}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isSkeletonHelper = true; + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @override + * @defaultValue `SkeletonHelper` + */ + override readonly type: string | "SkeletonHelper"; + + /** + * The list of bones that the helper renders as {@link Line | Lines}. + */ + bones: Bone[]; + + /** + * The object passed in the constructor. + */ + root: SkinnedMesh | Object3D; + + /** + * Reference to the {@link THREE.Object3D.matrixWorld | root.matrixWorld}. + */ + matrix: Matrix4; + + /** + * Is set to `false`, as the helper is using the {@link THREE.Object3D.matrixWorld | root.matrixWorld}. + * @see {@link THREE.Object3D.matrixAutoUpdate | Object3D.matrixAutoUpdate}. + * @defaultValue `false`. + */ + override matrixAutoUpdate: boolean; + + /** + * Updates the helper. + */ + update(): void; + + /** + * Frees the GPU-related resources allocated by this instance + * @remarks + * Call this method whenever this instance is no longer used in your app. + */ + dispose(): void; +} diff --git a/src-testing/src/helpers/SpotLightHelper.d.ts b/src-testing/src/helpers/SpotLightHelper.d.ts new file mode 100644 index 000000000..f620ed990 --- /dev/null +++ b/src-testing/src/helpers/SpotLightHelper.d.ts @@ -0,0 +1,77 @@ +import { Object3D } from "../core/Object3D.js"; +import { Light } from "../lights/Light.js"; +import { ColorRepresentation } from "../math/Color.js"; +import { Matrix4 } from "../math/Matrix4.js"; +import { LineSegments } from "../objects/LineSegments.js"; + +/** + * This displays a cone shaped helper object for a {@link THREE.SpotLight | SpotLight}. + * @example + * ```typescript + * const spotLight = new THREE.SpotLight(0xffffff); + * spotLight.position.set(10, 10, 10); + * scene.add(spotLight); + * const {@link SpotLightHelper} = new THREE.SpotLightHelper(spotLight); + * scene.add(spotLightHelper); + * ``` + * @see Example: {@link https://threejs.org/examples/#webgl_lights_spotlights | WebGL/ lights / spotlights } + * @see {@link https://threejs.org/docs/index.html#api/en/helpers/SpotLightHelper | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/helpers/SpotLightHelper.js | Source} + */ +export class SpotLightHelper extends Object3D { + /** + * Create a new instance of {@link SpotLightHelper} + * @param light The {@link THREE.SpotLight | SpotLight} to be visualized. + * @param color If this is not the set the helper will take the color of the light. Default `light.color` + */ + constructor(light: Light, color?: ColorRepresentation); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @override + * @defaultValue `SpotLightHelper` + */ + override readonly type: string | "SpotLightHelper"; + + /** + * {@link THREE.LineSegments | LineSegments} used to visualize the light. + */ + cone: LineSegments; + + /** + * Reference to the {@link THREE.SpotLight | SpotLight} being visualized. + */ + light: Light; + + /** + * Reference to the spotLight's {@link Object3D.matrixWorld | matrixWorld}. + */ + matrix: Matrix4; + + /** + * The color parameter passed in the constructor. + * If this is changed, the helper's color will update the next time {@link SpotLightHelper.update | update} is called. + * @defaultValue `undefined` + */ + color: ColorRepresentation | undefined; + + /** + * Is set to `false`, as the helper is using the {@link THREE.Light.matrixWorld | light.matrixWorld}. + * @see {@link THREE.Object3D.matrixAutoUpdate | Object3D.matrixAutoUpdate}. + * @defaultValue `false`. + */ + override matrixAutoUpdate: boolean; + + /** + * Updates the light helper. + */ + update(): void; + + /** + * Frees the GPU-related resources allocated by this instance + * @remarks + * Call this method whenever this instance is no longer used in your app. + */ + dispose(): void; +} diff --git a/src-testing/src/lights/AmbientLight.d.ts b/src-testing/src/lights/AmbientLight.d.ts new file mode 100644 index 000000000..7000a37e7 --- /dev/null +++ b/src-testing/src/lights/AmbientLight.d.ts @@ -0,0 +1,36 @@ +import { ColorRepresentation } from "../math/Color.js"; +import { Light } from "./Light.js"; + +/** + * This light globally illuminates all objects in the scene equally. + * @remarks This light cannot be used to cast shadows as it does not have a direction. + * @example + * ```typescript + * const light = new THREE.AmbientLight(0x404040); // soft white light + * scene.add(light); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/lights/AmbientLight | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/lights/AmbientLight.js | Source} + */ +export class AmbientLight extends Light { + /** + * Creates a new {@link AmbientLight}. + * @param color Numeric value of the RGB component of the color. Default `0xffffff` + * @param intensity Numeric value of the light's strength/intensity. Expects a `Float`. Default `1` + */ + constructor(color?: ColorRepresentation, intensity?: number); + + /** + * Read-only flag to check if a given object is of type {@link AmbientLight}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isAmbientLight: true; + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `AmbientLight` + */ + override readonly type: string | "AmbientLight"; +} diff --git a/src-testing/src/lights/DirectionalLight.d.ts b/src-testing/src/lights/DirectionalLight.d.ts new file mode 100644 index 000000000..3d43b7d89 --- /dev/null +++ b/src-testing/src/lights/DirectionalLight.d.ts @@ -0,0 +1,103 @@ +import { Object3D } from "../core/Object3D.js"; +import { ColorRepresentation } from "../math/Color.js"; +import { Vector3 } from "../math/Vector3.js"; +import { DirectionalLightShadow } from "./DirectionalLightShadow.js"; +import { Light } from "./Light.js"; + +/** + * A light that gets emitted in a specific direction + * @remarks + * This light will behave as though it is infinitely far away and the rays produced from it are all parallel + * The common use case for this is to simulate daylight; the sun is far enough away that its position can be considered to be infinite, and all light rays coming from it are parallel. + * A common point of confusion for directional lights is that setting the rotation has no effect + * @remarks + * This is because three.js's {@link DirectionalLight} is the equivalent to what is often called a 'Target Direct Light' in other applications. + * This means that its direction is calculated as pointing from the light's {@link THREE.Object3D.position | position} to the {@link THREE.DirectionalLight.target | target}'s + * position (as opposed to a 'Free Direct Light' that just has a rotation component). + * See the {@link THREE.DirectionalLight.target | target} property below for details on updating the target. + * @example + * ```typescript + * // White directional light at half intensity shining from the top. + * const {@link DirectionalLight} = new THREE.DirectionalLight(0xffffff, 0.5); + * scene.add(directionalLight); + * ``` + * @see Example: {@link https://threejs.org/examples/#misc_controls_fly | controls / fly } + * @see Example: {@link https://threejs.org/examples/#webgl_effects_parallaxbarrier | effects / parallaxbarrier } + * @see Example: {@link https://threejs.org/examples/#webgl_effects_stereo | effects / stereo } + * @see Example: {@link https://threejs.org/examples/#webgl_geometry_extrude_splines | geometry / extrude / splines } + * @see Example: {@link https://threejs.org/examples/#webgl_materials_bumpmap | materials / bumpmap } + * @see {@link https://threejs.org/docs/index.html#api/en/lights/DirectionalLight | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/lights/DirectionalLight.js | Source} + */ +export class DirectionalLight extends Light { + /** + * Creates a new {@link DirectionalLight}. + * @param color Hexadecimal color of the light. Default `0xffffff` _(white)_. + * @param intensity Numeric value of the light's strength/intensity. Expects a `Float`. Default `1` + */ + constructor(color?: ColorRepresentation, intensity?: number); + + /** + * Read-only flag to check if a given object is of type {@link DirectionalLight}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isDirectionalLight: true; + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `DirectionalLight` + */ + override readonly type: string | "DirectionalLight"; + + /** + * Whether the object gets rendered into shadow map. + * @remarks + * If set to `true` light will cast dynamic shadows. + * **Warning**: This is expensive and requires tweaking to get shadows looking right. + * @see {@link THREE.DirectionalLightShadow | DirectionalLightShadow} for details. + * @defaultValue `false` + */ + override castShadow: boolean; + + /** + * This is set equal to {@link THREE.Object3D.DEFAULT_UP}, so that the light shines from the top down. + * @defaultValue {@link Object3D.DEFAULT_UP} _(0, 1, 0)_ + */ + override readonly position: Vector3; + + /** + * A {@link THREE.DirectionalLightShadow | DirectionalLightShadow} used to calculate shadows for this light. + * @defaultValue `new THREE.DirectionalLightShadow()` + */ + shadow: DirectionalLightShadow; + + /** + * The {@link DirectionalLight} points from its {@link DirectionalLight.position | position} to target.position. + * @remarks **Note**: For the target's position to be changed to anything other than the default, + * it must be added to the {@link THREE.Scene | scene} using + * ```typescript + * Scene.add( light.target ); + * ``` + * This is so that the target's {@link THREE.Object3D.matrixWorld | matrixWorld} gets automatically updated each frame. + * + * It is also possible to set the target to be another object in the scene (anything with a {@link THREE.Object3D.position | position} property), + * like so: + * ```typescript + * const targetObject = new THREE.Object3D(); + * scene.add(targetObject); + * light.target = targetObject; + * ``` + * The {@link DirectionalLight} will now track the target object. + * @defaultValue `new THREE.Object3D()` at _(0, 0, 0)_ + */ + target: Object3D; + + /** + * Frees the GPU-related resources allocated by this instance + * @remarks + * Call this method whenever this instance is no longer used in your app. + */ + dispose(): void; +} diff --git a/src-testing/src/lights/DirectionalLightShadow.d.ts b/src-testing/src/lights/DirectionalLightShadow.d.ts new file mode 100644 index 000000000..805e4fa0b --- /dev/null +++ b/src-testing/src/lights/DirectionalLightShadow.d.ts @@ -0,0 +1,73 @@ +import { OrthographicCamera } from "../cameras/OrthographicCamera.js"; +import { LightShadow } from "./LightShadow.js"; + +/** + * This is used internally by {@link DirectionalLight | DirectionalLights} for calculating shadows. + * Unlike the other shadow classes, this uses an {@link THREE.OrthographicCamera | OrthographicCamera} to calculate the shadows, + * rather than a {@link THREE.PerspectiveCamera | PerspectiveCamera} + * @remarks + * This is because light rays from a {@link THREE.DirectionalLight | DirectionalLight} are parallel. + * @example + * ```typescript + * //Create a WebGLRenderer and turn on shadows in the renderer + * const renderer = new THREE.WebGLRenderer(); + * renderer.shadowMap.enabled = true; + * renderer.shadowMap.type = THREE.PCFSoftShadowMap; // default THREE.PCFShadowMap + * //Create a DirectionalLight and turn on shadows for the light + * const light = new THREE.DirectionalLight(0xffffff, 1); + * light.position.set(0, 1, 0); //default; light shining from top + * light.castShadow = true; // default false + * scene.add(light); + * //Set up shadow properties for the light + * light.shadow.mapSize.width = 512; // default + * light.shadow.mapSize.height = 512; // default + * light.shadow.camera.near = 0.5; // default + * light.shadow.camera.far = 500; // default + * //Create a sphere that cast shadows (but does not receive them) + * const sphereGeometry = new THREE.SphereGeometry(5, 32, 32); + * const sphereMaterial = new THREE.MeshStandardMaterial({ + * color: 0xff0000 + * }); + * const sphere = new THREE.Mesh(sphereGeometry, sphereMaterial); + * sphere.castShadow = true; //default is false + * sphere.receiveShadow = false; //default + * scene.add(sphere); + * //Create a plane that receives shadows (but does not cast them) + * const planeGeometry = new THREE.PlaneGeometry(20, 20, 32, 32); + * const planeMaterial = new THREE.MeshStandardMaterial({ + * color: 0x00ff00 + * }) + * const plane = new THREE.Mesh(planeGeometry, planeMaterial); + * plane.receiveShadow = true; + * scene.add(plane); + * //Create a helper for the shadow camera (optional) + * const helper = new THREE.CameraHelper(light.shadow.camera); + * scene.add(helper); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/lights/shadows/DirectionalLightShadow | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/lights/DirectionalLightShadow.js | Source} + */ +export class DirectionalLightShadow extends LightShadow { + /** + * Create a new instance of {@link DirectionalLightShadow} + */ + constructor(); + + /** + * Read-only flag to check if a given object is of type {@link DirectionalLightShadow}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isDirectionalLightShadow: true; + + /** + * The light's view of the world. + * @remarks This is used to generate a depth map of the scene; objects behind other objects from the light's perspective will be in shadow. + * @defaultValue is an {@link THREE.OrthographicCamera | OrthographicCamera} with + * {@link OrthographicCamera.left | left} and {@link OrthographicCamera.bottom | bottom} set to -5, + * {@link OrthographicCamera.right | right} and {@link OrthographicCamera.top | top} set to 5, + * the {@link OrthographicCamera.near | near} clipping plane at 0.5 and + * the {@link OrthographicCamera.far | far} clipping plane at 500. + */ + camera: OrthographicCamera; +} diff --git a/src-testing/src/lights/HemisphereLight.d.ts b/src-testing/src/lights/HemisphereLight.d.ts new file mode 100644 index 000000000..1a796dfc8 --- /dev/null +++ b/src-testing/src/lights/HemisphereLight.d.ts @@ -0,0 +1,61 @@ +import { Color, ColorRepresentation } from "../math/Color.js"; +import { Vector3 } from "../math/Vector3.js"; +import { Light } from "./Light.js"; + +/** + * A light source positioned directly above the scene, with color fading from the sky color to the ground color. + * @remarks This light cannot be used to cast shadows. + * @example + * ```typescript + * const light = new THREE.HemisphereLight(0xffffbb, 0x080820, 1); + * scene.add(light); + * ``` + * @see Example: {@link https://threejs.org/examples/#webgl_animation_skinning_blending | animation / skinning / blending } + * @see Example: {@link https://threejs.org/examples/#webgl_lights_hemisphere | lights / hemisphere } + * @see Example: {@link https://threejs.org/examples/#misc_controls_pointerlock | controls / pointerlock } + * @see Example: {@link https://threejs.org/examples/#webgl_loader_collada_kinematics | loader / collada / kinematics } + * @see Example: {@link https://threejs.org/examples/#webgl_loader_stl | loader / stl } + * @see {@link https://threejs.org/docs/index.html#api/en/lights/HemisphereLight | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/lights/HemisphereLight.js | Source} + */ +export class HemisphereLight extends Light { + /** + * Creates a new {@link HemisphereLight}. + * @param skyColor Hexadecimal color of the sky. Expects a `Integer`. Default `0xffffff` _(white)_. + * @param groundColor Hexadecimal color of the ground. Expects a `Integer`. Default `0xffffff` _(white)_. + * @param intensity Numeric value of the light's strength/intensity. Expects a `Float`. Default `1`. + */ + constructor(skyColor?: ColorRepresentation, groundColor?: ColorRepresentation, intensity?: number); + + /** + * Read-only flag to check if a given object is of type {@link HemisphereLight}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isHemisphereLight: true; + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `HemisphereLight` + */ + override readonly type: string | "HemisphereLight"; + + /** + * This is set equal to {@link THREE.Object3D.DEFAULT_UP}, so that the light shines from the top down. + * @defaultValue {@link Object3D.DEFAULT_UP} _(0, 1, 0)_ + */ + override readonly position: Vector3; + + /** + * The light's sky color, as passed in the constructor. + * @defaultValue `new THREE.Color()` set to white _(0xffffff)_. + */ + override color: Color; + + /** + * The light's ground color, as passed in the constructor. + * @defaultValue `new THREE.Color()` set to white _(0xffffff)_. + */ + groundColor: Color; +} diff --git a/src-testing/src/lights/Light.d.ts b/src-testing/src/lights/Light.d.ts new file mode 100644 index 000000000..3ae757e3b --- /dev/null +++ b/src-testing/src/lights/Light.d.ts @@ -0,0 +1,82 @@ +import { JSONMeta, Object3D, Object3DJSON } from "../core/Object3D.js"; +import { Color, ColorRepresentation } from "../math/Color.js"; +import { LightShadow, LightShadowJSON } from "./LightShadow.js"; + +export interface LightJSON extends Object3DJSON { + color: number; + intensity: number; + + groundColor?: number; + + distance?: number; + angle?: number; + decay?: number; + penumbra?: number; + + shadow?: LightShadowJSON; + target?: string; +} + +/** + * Abstract base class for lights. + * @remarks All other light types inherit the properties and methods described here. + */ +export abstract class Light extends Object3D { + /** + * Creates a new {@link Light} + * @remarks + * **Note** that this is not intended to be called directly (use one of derived classes instead). + * @param color Hexadecimal color of the light. Default `0xffffff` _(white)_. + * @param intensity Numeric value of the light's strength/intensity. Expects a `Float`. Default `1`. + */ + constructor(color?: ColorRepresentation, intensity?: number); + + /** + * Read-only flag to check if a given object is of type {@link HemisphereLight}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isLight: true; + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `Light` + */ + override readonly type: string | "Light"; + + /** + * Color of the light. \ + * @defaultValue `new THREE.Color(0xffffff)` _(white)_. + */ + color: Color; + + /** + * The light's intensity, or strength. + * The units of intensity depend on the type of light. + * @defaultValue `1` + */ + intensity: number; + + /** + * A {@link THREE.LightShadow | LightShadow} used to calculate shadows for this light. + * @remarks Available only on Light's that support shadows. + */ + shadow: TShadowSupport; + + /** + * Copies value of all the properties from the {@link Light | source} to this instance. + * @param source + * @param recursive + */ + copy(source: this, recursive?: boolean): this; + + /** + * Frees the GPU-related resources allocated by this instance + * @remarks + * Call this method whenever this instance is no longer used in your app. + */ + dispose(): void; + + toJSON(meta?: JSONMeta): LightJSON; +} diff --git a/src-testing/src/lights/LightProbe.d.ts b/src-testing/src/lights/LightProbe.d.ts new file mode 100644 index 000000000..a63ffdc57 --- /dev/null +++ b/src-testing/src/lights/LightProbe.d.ts @@ -0,0 +1,47 @@ +import { SphericalHarmonics3 } from "../math/SphericalHarmonics3.js"; +import { Light } from "./Light.js"; + +/** + * Light probes are an alternative way of adding light to a 3D scene. + * @remarks + * Unlike classical light sources (e.g + * directional, point or spot lights), light probes do not emit light + * Instead they store information about light passing through 3D space + * During rendering, the light that hits a 3D object is approximated by using the data from the light probe. + * Light probes are usually created from (radiance) environment maps + * The class {@link THREE.LightProbeGenerator | LightProbeGenerator} can be used to create light probes from + * instances of {@link THREE.CubeTexture | CubeTexture} or {@link THREE.WebGLCubeRenderTarget | WebGLCubeRenderTarget} + * However, light estimation data could also be provided in other forms e.g + * by WebXR + * This enables the rendering of augmented reality content that reacts to real world lighting. + * The current probe implementation in three.js supports so-called diffuse light probes + * This type of light probe is functionally equivalent to an irradiance environment map. + * @see Example: {@link https://threejs.org/examples/#webgl_lightprobe | WebGL / light probe } + * @see Example: {@link https://threejs.org/examples/#webgl_lightprobe_cubecamera | WebGL / light probe / cube camera } + * @see {@link https://threejs.org/docs/index.html#api/en/lights/LightProbe | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/lights/LightProbe.js | Source} + */ +export class LightProbe extends Light { + /** + * Creates a new LightProbe. + * @param sh An instance of {@link THREE.SphericalHarmonics3 | SphericalHarmonics3}. Default `new THREE.SphericalHarmonics3()``. + * @param intensity Numeric value of the light probe's intensity. Expects a `Float`. Default `1`. + */ + constructor(sh?: SphericalHarmonics3, intensity?: number); + + /** + * Read-only flag to check if a given object is of type {@link DirectionalLight}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isLightProbe: true; + + /** + * A light probe uses spherical harmonics to encode lighting information. + * @defaultValue `new THREE.SphericalHarmonics3()` + */ + sh: SphericalHarmonics3; + + /** @internal */ + fromJSON(json: {}): LightProbe; +} diff --git a/src-testing/src/lights/LightShadow.d.ts b/src-testing/src/lights/LightShadow.d.ts new file mode 100644 index 000000000..53c163c3e --- /dev/null +++ b/src-testing/src/lights/LightShadow.d.ts @@ -0,0 +1,169 @@ +import { Camera } from "../cameras/Camera.js"; +import { Object3DJSONObject } from "../core/Object3D.js"; +import { Frustum } from "../math/Frustum.js"; +import { Matrix4 } from "../math/Matrix4.js"; +import { Vector2, Vector2Tuple } from "../math/Vector2.js"; +import { Vector4 } from "../math/Vector4.js"; +import { WebGLRenderTarget } from "../renderers/WebGLRenderTarget.js"; +import { Light } from "./Light.js"; + +export interface LightShadowJSON { + intensity?: number; + bias?: number; + normalBias?: number; + radius?: number; + mapSize?: Vector2Tuple; + + camera: Omit; +} + +/** + * Serves as a base class for the other shadow classes. + * @see {@link https://threejs.org/docs/index.html#api/en/lights/shadows/LightShadow | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/lights/LightShadow.js | Source} + */ +export class LightShadow { + /** + * Create a new instance of {@link LightShadow} + * @param camera The light's view of the world. + */ + constructor(camera: TCamera); + + /** + * The light's view of the world. + * @remark This is used to generate a depth map of the scene; objects behind other objects from the light's perspective will be in shadow. + */ + camera: TCamera; + + /** + * The intensity of the shadow. The default is `1`. Valid values are in the range `[0, 1]`. + */ + intensity: number; + + /** + * Shadow map bias, how much to add or subtract from the normalized depth when deciding whether a surface is in shadow. + * @remark The Very tiny adjustments here (in the order of 0.0001) may help reduce artifacts in shadows. + * @remarks Expects a `Float` + * @defaultValue `0` + */ + bias: number; + + /** + * Defines how much the position used to query the shadow map is offset along the object normal. + * @remark The Increasing this value can be used to reduce shadow acne especially in large scenes where light shines onto geometry at a shallow angle. + * @remark The cost is that shadows may appear distorted. + * @remarks Expects a `Float` + * @defaultValue `0` + */ + normalBias: number; + + /** + * Setting this to values greater than 1 will blur the edges of the shadow.toi + * @remark High values will cause unwanted banding effects in the shadows - a greater {@link LightShadow.mapSize | mapSize + * will allow for a higher value to be used here before these effects become visible. + * @remark If {@link THREE.WebGLRenderer.shadowMap.type | WebGLRenderer.shadowMap.type} is set to {@link Renderer | PCFSoftShadowMap}, + * radius has no effect and it is recommended to increase softness by decreasing {@link LightShadow.mapSize | mapSize} instead. + * @remark Note that this has no effect if the {@link THREE.WebGLRenderer.shadowMap | WebGLRenderer.shadowMap}.{@link THREE.WebGLShadowMap.type | type} + * is set to {@link THREE.BasicShadowMap | BasicShadowMap}. + * @remarks Expects a `Float` + * @defaultValue `1` + */ + radius: number; + + /** + * The amount of samples to use when blurring a VSM shadow map. + * @remarks Expects a `Integer` + * @defaultValue `8` + */ + blurSamples: number; + + /** + * A {@link THREE.Vector2 | Vector2} defining the width and height of the shadow map. + * @remarks Higher values give better quality shadows at the cost of computation time. + * @remarks Values must be powers of 2, up to the {@link THREE.WebGLRenderer.capabilities | WebGLRenderer.capabilities}.maxTextureSize for a given device, + * although the width and height don't have to be the same (so, for example, (512, 1024) is valid). + * @defaultValue `new THREE.Vector2(512, 512)` + */ + mapSize: Vector2; + + /** + * The depth map generated using the internal camera; a location beyond a pixel's depth is in shadow. Computed internally during rendering. + * @defaultValue null + */ + map: WebGLRenderTarget | null; + + /** + * The distribution map generated using the internal camera; an occlusion is calculated based on the distribution of depths. Computed internally during rendering. + * @defaultValue null + */ + mapPass: WebGLRenderTarget | null; + + /** + * Model to shadow camera space, to compute location and depth in shadow map. + * Stored in a {@link Matrix4 | Matrix4}. + * @remarks This is computed internally during rendering. + * @defaultValue new THREE.Matrix4() + */ + matrix: Matrix4; + + /** + * Enables automatic updates of the light's shadow. If you do not require dynamic lighting / shadows, you may set this to `false`. + * @defaultValue `true` + */ + autoUpdate: boolean; + + /** + * When set to `true`, shadow maps will be updated in the next `render` call. + * If you have set {@link autoUpdate} to `false`, you will need to set this property to `true` and then make a render call to update the light's shadow. + * @defaultValue `false` + */ + needsUpdate: boolean; + + /** + * Used internally by the renderer to get the number of viewports that need to be rendered for this shadow. + */ + getViewportCount(): number; + + /** + * Copies value of all the properties from the {@link {@link LightShadow} | source} to this Light. + * @param source + */ + copy(source: LightShadow): this; + + /** + * Creates a new {@link LightShadow} with the same properties as this one. + */ + clone(recursive?: boolean): this; + + /** + * Serialize this LightShadow. + */ + toJSON(): LightShadowJSON; + + /** + * Gets the shadow cameras frustum + * @remarks + * Used internally by the renderer to cull objects. + */ + getFrustum(): Frustum; + + /** + * Update the matrices for the camera and shadow, used internally by the renderer. + * @param light The light for which the shadow is being rendered. + */ + updateMatrices(light: Light): void; + + getViewport(viewportIndex: number): Vector4; + + /** + * Used internally by the renderer to extend the shadow map to contain all viewports + */ + getFrameExtents(): Vector2; + + /** + * Frees the GPU-related resources allocated by this instance + * @remarks + * Call this method whenever this instance is no longer used in your app. + */ + dispose(): void; +} diff --git a/src-testing/src/lights/PointLight.d.ts b/src-testing/src/lights/PointLight.d.ts new file mode 100644 index 000000000..c13044e12 --- /dev/null +++ b/src-testing/src/lights/PointLight.d.ts @@ -0,0 +1,102 @@ +import { ColorRepresentation } from "../math/Color.js"; +import { Light } from "./Light.js"; +import { PointLightShadow } from "./PointLightShadow.js"; + +/** + * A light that gets emitted from a single point in all directions + * @remarks + * A common use case for this is to replicate the light emitted from a bare lightbulb. + * @example + * ```typescript + * const light = new THREE.PointLight(0xff0000, 1, 100); + * light.position.set(50, 50, 50); + * scene.add(light); + * ``` + * @see Example: {@link https://threejs.org/examples/#webgl_lights_pointlights | lights / pointlights } + * @see Example: {@link https://threejs.org/examples/#webgl_effects_anaglyph | effects / anaglyph } + * @see Example: {@link https://threejs.org/examples/#webgl_geometry_text | geometry / text } + * @see Example: {@link https://threejs.org/examples/#webgl_lensflares | lensflares } + * @see {@link https://threejs.org/docs/index.html#api/en/lights/PointLight | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/lights/PointLight.js | Source} + */ +export class PointLight extends Light { + /** + * Creates a new PointLight. + * @param color Hexadecimal color of the light. Default is 0xffffff (white). Expects a `Integer` + * @param intensity Numeric value of the light's strength/intensity. Expects a `Float`. Default `1` + * @param distance Maximum range of the light. Default is 0 (no limit). + * @param decay The amount the light dims along the distance of the light. Expects a `Float`. Default `2` + */ + constructor(color?: ColorRepresentation, intensity?: number, distance?: number, decay?: number); + + /** + * Read-only flag to check if a given object is of type {@link PointLight}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isPointLight: true; + + /** + * @default 'PointLight' + */ + type: string; + + /** + * The light's intensity. + * + * When **{@link WebGLRenderer.useLegacyLights | legacy lighting mode} is disabled** — intensity is the luminous intensity of the light measured in candela (cd). + * @remarks Changing the intensity will also change the light's power. + * @remarks Expects a `Float` + * @defaultValue `1` + */ + intensity: number; + + /** + * When **Default mode** — When distance is zero, light does not attenuate. When distance is non-zero, + * light will attenuate linearly from maximum intensity at the light's position down to zero at this distance from the light. + * + * When **{@link WebGLRenderer.useLegacyLights | legacy lighting mode} is disabled** — When distance is zero, + * light will attenuate according to inverse-square law to infinite distance. + * When distance is non-zero, light will attenuate according to inverse-square law until near the distance cutoff, + * where it will then attenuate quickly and smoothly to 0. Inherently, cutoffs are not physically correct. + * + * @defaultValue `0.0` + * @remarks Expects a `Float` + */ + distance: number; + + /** + * If set to `true` light will cast dynamic shadows. + * **Warning**: This is expensive and requires tweaking to get shadows looking right. + * @see {@link THREE.PointLightShadow | PointLightShadow} for details. + * @defaultValue `false` + */ + castShadow: boolean; + + /** + * The amount the light dims along the distance of the light. + * In context of physically-correct rendering the default value should not be changed. + * @remarks Expects a `Float` + * @defaultValue `2` + */ + decay: number; + + /** + * A {@link THREE.PointLightShadow | PointLightShadow} used to calculate shadows for this light. + * The lightShadow's {@link LightShadow.camera | camera} is set to + * a {@link THREE.PerspectiveCamera | PerspectiveCamera} with {@link PerspectiveCamera.fov | fov} of 90, + * {@link PerspectiveCamera.aspect | aspect} of 1, + * {@link PerspectiveCamera.near | near} clipping plane at 0.5 + * and {@link PerspectiveCamera.far | far} clipping plane at 500. + * @defaultValue new THREE.PointLightShadow() + */ + shadow: PointLightShadow; + + /** + * The light's power. + * When **{@link WebGLRenderer.useLegacyLights | legacy lighting mode} is disabled** — power is the luminous power of the light measured in lumens (lm). + * @remarks Changing the power will also change the light's intensity. + * @remarks Expects a `Float` + */ + power: number; +} diff --git a/src-testing/src/lights/PointLightShadow.d.ts b/src-testing/src/lights/PointLightShadow.d.ts new file mode 100644 index 000000000..1d0e7e4af --- /dev/null +++ b/src-testing/src/lights/PointLightShadow.d.ts @@ -0,0 +1,22 @@ +import { PerspectiveCamera } from "../cameras/PerspectiveCamera.js"; +import { Light } from "./Light.js"; +import { LightShadow } from "./LightShadow.js"; + +/** + * Shadow for {@link THREE.PointLight | PointLight} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/lights/PointLightShadow.js | Source} + */ +export class PointLightShadow extends LightShadow { + /** + * Read-only flag to check if a given object is of type {@link PointLightShadow}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isPointLightShadow = true; + + /** + * Update the matrices for the camera and shadow, used internally by the renderer. + * @param light The light for which the shadow is being rendered. + */ + override updateMatrices(light: Light, viewportIndex?: number): void; +} diff --git a/src-testing/src/lights/RectAreaLight.d.ts b/src-testing/src/lights/RectAreaLight.d.ts new file mode 100644 index 000000000..2861e9794 --- /dev/null +++ b/src-testing/src/lights/RectAreaLight.d.ts @@ -0,0 +1,82 @@ +import { ColorRepresentation } from "../math/Color.js"; +import { Light } from "./Light.js"; + +/** + * {@link RectAreaLight} emits light uniformly across the face a rectangular plane + * @remarks + * This light type can be used to simulate light sources such as bright windows or strip lighting. + * Important Notes: + * - There is no shadow support. + * - Only {@link MeshStandardMaterial | MeshStandardMaterial} and {@link MeshPhysicalMaterial | MeshPhysicalMaterial} are supported. + * - You have to include {@link https://threejs.org/examples/jsm/lights/RectAreaLightUniformsLib.js | RectAreaLightUniformsLib} into your scene and call `init()`. + * @example + * ```typescript + * const width = 10; + * const height = 10; + * const intensity = 1; + * const rectLight = new THREE.RectAreaLight(0xffffff, intensity, width, height); + * rectLight.position.set(5, 5, 0); + * rectLight.lookAt(0, 0, 0); + * scene.add(rectLight) + * const rectLightHelper = new RectAreaLightHelper(rectLight); + * rectLight.add(rectLightHelper); + * ``` + * @see Example: {@link https://threejs.org/examples/#webgl_lights_rectarealight | WebGL / {@link RectAreaLight} } + * @see {@link https://threejs.org/docs/index.html#api/en/lights/RectAreaLight | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/lights/RectAreaLight.js | Source} + */ +export class RectAreaLight extends Light { + /** + * Creates a new {@link RectAreaLight}. + * @param color Hexadecimal color of the light. Default `0xffffff` _(white)_. + * @param intensity The light's intensity, or brightness. Expects a `Float`. Default `1` + * @param width Width of the light. Expects a `Float`. Default `10` + * @param height Height of the light. Expects a `Float`. Default `10` + */ + constructor(color?: ColorRepresentation, intensity?: number, width?: number, height?: number); + + /** + * Read-only flag to check if a given object is of type {@link RectAreaLight}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isRectAreaLight: true; + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `RectAreaLight` + */ + override readonly type: string | "RectAreaLight"; + + /** + * The width of the light. + * @remarks Expects a `Float` + * @defaultValue `10` + */ + width: number; + + /** + * The height of the light. + * @remarks Expects a `Float` + * @defaultValue `10` + */ + height: number; + + /** + * The light's intensity. + * @remarks Changing the intensity will also change the light's power. + * When **{@link WebGLRenderer.useLegacyLights | legacy lighting mode} is disabled** — intensity is the luminance (brightness) of the light measured in nits (cd/m^2). + * @remarks Expects a `Float` + * @defaultValue `1` + */ + intensity: number; + + /** + * The light's power. + * @remarks Changing the power will also change the light's intensity. + * When **{@link WebGLRenderer.useLegacyLights | legacy lighting mode} is disabled** — power is the luminous power of the light measured in lumens (lm). + * @remarks Expects a `Float` + */ + power: number; +} diff --git a/src-testing/src/lights/SpotLight.d.ts b/src-testing/src/lights/SpotLight.d.ts new file mode 100644 index 000000000..7f42488a8 --- /dev/null +++ b/src-testing/src/lights/SpotLight.d.ts @@ -0,0 +1,164 @@ +import { Object3D } from "../core/Object3D.js"; +import { ColorRepresentation } from "../math/Color.js"; +import { Vector3 } from "../math/Vector3.js"; +import { Texture } from "../textures/Texture.js"; +import { Light } from "./Light.js"; +import { SpotLightShadow } from "./SpotLightShadow.js"; + +/** + * This light gets emitted from a single point in one direction, along a cone that increases in size the further from the light it gets. + * @example + * ```typescript + * // white {@link SpotLight} shining from the side, modulated by a texture, casting a shadow + * const {@link SpotLight} = new THREE.SpotLight(0xffffff); + * spotLight.position.set(100, 1000, 100); + * spotLight.map = new THREE.TextureLoader().load(url); + * spotLight.castShadow = true; + * spotLight.shadow.mapSize.width = 1024; + * spotLight.shadow.mapSize.height = 1024; + * spotLight.shadow.camera.near = 500; + * spotLight.shadow.camera.far = 4000; + * spotLight.shadow.camera.fov = 30; + * scene.add(spotLight); + * ``` + * @see Example: {@link https://threejs.org/examples/#webgl_lights_spotlight | lights / {@link SpotLight} } + * @see Example: {@link https://threejs.org/examples/#webgl_lights_spotlights | lights / spotlights } + * @see {@link https://threejs.org/docs/index.html#api/en/lights/SpotLight | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/lights/SpotLight.js | Source} + */ +export class SpotLight extends Light { + /** + * Creates a new SpotLight. + * @param color Hexadecimal color of the light. Default `0xffffff` _(white)_. + * @param intensity Numeric value of the light's strength/intensity. Expects a `Float`. Default `1`. + * @param distance Maximum range of the light. Default is 0 (no limit). Expects a `Float`. + * @param angle Maximum angle of light dispersion from its direction whose upper bound is Math.PI/2. + * @param penumbra Percent of the {@link SpotLight} cone that is attenuated due to penumbra. Takes values between zero and 1. Expects a `Float`. Default `0`. + * @param decay The amount the light dims along the distance of the light. Expects a `Float`. Default `2`. + */ + constructor( + color?: ColorRepresentation, + intensity?: number, + distance?: number, + angle?: number, + penumbra?: number, + decay?: number, + ); + + /** + * Read-only flag to check if a given object is of type {@link SpotLight}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isSpotLight: true; + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `SpotLight` + */ + override readonly type: string | "SpotLight"; + + /** + * This is set equal to {@link THREE.Object3D.DEFAULT_UP | Object3D.DEFAULT_UP} (0, 1, 0), so that the light shines from the top down. + * @defaultValue `{@link Object3D.DEFAULT_UP}` + */ + readonly position: Vector3; + + /** + * The {@link SpotLight} points from its {@link SpotLight.position | position} to target.position. + * @remarks + * **Note**: For the target's position to be changed to anything other than the default, + * it must be added to the {@link Scene | scene} using + * + * ```typescript + * scene.add( light.target ); + * ``` + * + * This is so that the target's {@link Object3D.matrixWorld | matrixWorld} gets automatically updated each frame. + * It is also possible to set the target to be another object in the scene (anything with a {@link THREE.Object3D.position | position} property), like so: + * ```typescript + * const targetObject = new THREE.Object3D(); + * scene.add(targetObject); + * light.target = targetObject; + * ``` + * The {@link SpotLight} will now track the target object. + * @defaultValue `new THREE.Object3D()` _The default position of the target is *(0, 0, 0)*._ + */ + target: Object3D; + + /** + * If set to `true` light will cast dynamic shadows. + * @remarks **Warning**: This is expensive and requires tweaking to get shadows looking right. the {@link THREE.SpotLightShadow | SpotLightShadow} for details. + * @defaultValue `false` + */ + override castShadow: boolean; + + /** + * The light's intensity. + * @remarks Changing the intensity will also change the light's power. + * When **{@link WebGLRenderer.useLegacyLights | legacy lighting mode} is disabled** — intensity is the luminous intensity of the light measured in candela (cd). + * @remarks Expects a `Float` + * @defaultValue `1` + */ + intensity: number; + + /** + * When **Default mode** — When distance is zero, light does not attenuate. When distance is non-zero, + * light will attenuate linearly from maximum intensity at the light's position down to zero at this distance from the light. + * + * When **{@link WebGLRenderer.useLegacyLights | legacy lighting mode} is disabled** — When distance is zero, + * light will attenuate according to inverse-square law to infinite distance. + * When distance is non-zero, light will attenuate according to inverse-square law until near the distance cutoff, + * where it will then attenuate quickly and smoothly to `0`. Inherently, cutoffs are not physically correct. + * @remarks Expects a `Float` + * @defaultValue `0.0` + */ + distance: number; + + /** + * Maximum extent of the spotlight, in radians, from its direction. + * @remarks Should be no more than `Math.PI/2`. + * @remarks Expects a `Float` + * @defaultValue `Math.PI / 3` + */ + angle: number; + + /** + * The amount the light dims along the distance of the light. + * In context of physically-correct rendering the default value should not be changed. + * @remarks Expects a `Float` + * @defaultValue `2` + */ + decay: number; + + /** + * A {@link THREE.SpotLightShadow | SpotLightShadow} used to calculate shadows for this light. + * @defaultValue `new THREE.SpotLightShadow()` + */ + shadow: SpotLightShadow; + + /** + * The light's power. + * @remarks Changing the power will also change the light's intensity. + * When **{@link WebGLRenderer.useLegacyLights | legacy lighting mode} is disabled** — power is the luminous power of the light measured in lumens (lm). + * @remarks Expects a `Float` + */ + power: number; + + /** + * Percent of the {@link SpotLight} cone that is attenuated due to penumbra. + * @remarks Takes values between zero and 1. + * @remarks Expects a `Float` + * @defaultValue `0.0` + */ + penumbra: number; + + /** + * A {@link THREE.Texture | Texture} used to modulate the color of the light. + * The spot light color is mixed with the _RGB_ value of this texture, with a ratio corresponding to its alpha value. + * The cookie-like masking effect is reproduced using pixel values (0, 0, 0, 1-cookie_value). + * @remarks **Warning**: {@link SpotLight.map} is disabled if {@link SpotLight.castShadow} is `false`. + */ + map: Texture | null; +} diff --git a/src-testing/src/lights/SpotLightShadow.d.ts b/src-testing/src/lights/SpotLightShadow.d.ts new file mode 100644 index 000000000..77f075c44 --- /dev/null +++ b/src-testing/src/lights/SpotLightShadow.d.ts @@ -0,0 +1,72 @@ +import { PerspectiveCamera } from "../cameras/PerspectiveCamera.js"; +import { LightShadow } from "./LightShadow.js"; + +/** + * This is used internally by {@link SpotLight | SpotLights} for calculating shadows. + * @example + * ```typescript + * //Create a WebGLRenderer and turn on shadows in the renderer + * const renderer = new THREE.WebGLRenderer(); + * renderer.shadowMap.enabled = true; + * renderer.shadowMap.type = THREE.PCFSoftShadowMap; // default THREE.PCFShadowMap + * //Create a SpotLight and turn on shadows for the light + * const light = new THREE.SpotLight(0xffffff); + * light.castShadow = true; // default false + * scene.add(light); + * //Set up shadow properties for the light + * light.shadow.mapSize.width = 512; // default + * light.shadow.mapSize.height = 512; // default + * light.shadow.camera.near = 0.5; // default + * light.shadow.camera.far = 500; // default + * light.shadow.focus = 1; // default + * //Create a sphere that cast shadows (but does not receive them) + * const sphereGeometry = new THREE.SphereGeometry(5, 32, 32); + * const sphereMaterial = new THREE.MeshStandardMaterial({ + * color: 0xff0000 + * }); + * const sphere = new THREE.Mesh(sphereGeometry, sphereMaterial); + * sphere.castShadow = true; //default is false + * sphere.receiveShadow = false; //default + * scene.add(sphere); + * //Create a plane that receives shadows (but does not cast them) + * const planeGeometry = new THREE.PlaneGeometry(20, 20, 32, 32); + * const planeMaterial = new THREE.MeshStandardMaterial({ + * color: 0x00ff00 + * }) + * const plane = new THREE.Mesh(planeGeometry, planeMaterial); + * plane.receiveShadow = true; + * scene.add(plane); + * //Create a helper for the shadow camera (optional) + * const helper = new THREE.CameraHelper(light.shadow.camera); + * scene.add(helper); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/lights/shadows/SpotLightShadow | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/lights/SpotLightShadow.js | Source} + */ +export class SpotLightShadow extends LightShadow { + /** + * Read-only flag to check if a given object is of type {@link SpotLightShadow}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isSpotLightShadow: true; + + /** + * The light's view of the world. + * @remarks This is used to generate a depth map of the scene; objects behind other objects from the light's perspective will be in shadow. + * @remarks + * The {@link THREE.PerspectiveCamera.fov | fov} will track the {@link THREE.SpotLight.angle | angle} property + * of the owning {@link SpotLight | SpotLight} via the {@link SpotLightShadow.update | update} method. + * Similarly, the {@link THREE.PerspectiveCamera.aspect | aspect} property will track the aspect of the {@link LightShadow.mapSize | mapSize}. + * If the {@link SpotLight.distance | distance} property of the light is set, the {@link THREE.PerspectiveCamera.far | far} clipping plane will track that, otherwise it defaults to `500`. + * @defaultValue is a {@link THREE.PerspectiveCamera | PerspectiveCamera} with {@link THREE.PerspectiveCamera.near | near} clipping plane at `0.5`. + */ + camera: PerspectiveCamera; + + /** + * Used to focus the shadow camera. + * @remarks The camera's field of view is set as a percentage of the spotlight's field-of-view. Range is `[0, 1]`. 0`. + * @defaultValue `1` + */ + focus: number; +} diff --git a/src-testing/src/lights/webgpu/IESSpotLight.d.ts b/src-testing/src/lights/webgpu/IESSpotLight.d.ts new file mode 100644 index 000000000..bf1b66006 --- /dev/null +++ b/src-testing/src/lights/webgpu/IESSpotLight.d.ts @@ -0,0 +1,6 @@ +import { Texture } from "../../textures/Texture.js"; +import { SpotLight } from "../SpotLight.js"; + +export default class IESSpotLight extends SpotLight { + iesMap: Texture | null; +} diff --git a/src-testing/src/loaders/AnimationLoader.d.ts b/src-testing/src/loaders/AnimationLoader.d.ts new file mode 100644 index 000000000..567f30f30 --- /dev/null +++ b/src-testing/src/loaders/AnimationLoader.d.ts @@ -0,0 +1,9 @@ +import { AnimationClip } from "../animation/AnimationClip.js"; +import { Loader } from "./Loader.js"; +import { LoadingManager } from "./LoadingManager.js"; + +export class AnimationLoader extends Loader { + constructor(manager?: LoadingManager); + + parse(json: readonly unknown[]): AnimationClip[]; +} diff --git a/src-testing/src/loaders/AudioLoader.d.ts b/src-testing/src/loaders/AudioLoader.d.ts new file mode 100644 index 000000000..0204bef47 --- /dev/null +++ b/src-testing/src/loaders/AudioLoader.d.ts @@ -0,0 +1,6 @@ +import { Loader } from "./Loader.js"; +import { LoadingManager } from "./LoadingManager.js"; + +export class AudioLoader extends Loader { + constructor(manager?: LoadingManager); +} diff --git a/src-testing/src/loaders/BufferGeometryLoader.d.ts b/src-testing/src/loaders/BufferGeometryLoader.d.ts new file mode 100644 index 000000000..0aa994011 --- /dev/null +++ b/src-testing/src/loaders/BufferGeometryLoader.d.ts @@ -0,0 +1,10 @@ +import { BufferGeometry } from "../core/BufferGeometry.js"; +import { InstancedBufferGeometry } from "../core/InstancedBufferGeometry.js"; +import { Loader } from "./Loader.js"; +import { LoadingManager } from "./LoadingManager.js"; + +export class BufferGeometryLoader extends Loader { + constructor(manager?: LoadingManager); + + parse(json: unknown): InstancedBufferGeometry | BufferGeometry; +} diff --git a/src-testing/src/loaders/Cache.d.ts b/src-testing/src/loaders/Cache.d.ts new file mode 100644 index 000000000..0742af8f5 --- /dev/null +++ b/src-testing/src/loaders/Cache.d.ts @@ -0,0 +1,21 @@ +declare const Cache: { + /** + * @default false + */ + enabled: boolean; + + /** + * @default {} + */ + files: any; + + add(key: string, file: any): void; + + get(key: string): any; + + remove(key: string): void; + + clear(): void; +}; + +export { Cache }; diff --git a/src-testing/src/loaders/CompressedTextureLoader.d.ts b/src-testing/src/loaders/CompressedTextureLoader.d.ts new file mode 100644 index 000000000..eeca01ded --- /dev/null +++ b/src-testing/src/loaders/CompressedTextureLoader.d.ts @@ -0,0 +1,14 @@ +import { CompressedTexture } from "../textures/CompressedTexture.js"; +import { Loader } from "./Loader.js"; +import { LoadingManager } from "./LoadingManager.js"; + +export class CompressedTextureLoader extends Loader { + constructor(manager?: LoadingManager); + + load( + url: string, + onLoad?: (data: CompressedTexture) => void, + onProgress?: (event: ProgressEvent) => void, + onError?: (err: unknown) => void, + ): CompressedTexture; +} diff --git a/src-testing/src/loaders/CubeTextureLoader.d.ts b/src-testing/src/loaders/CubeTextureLoader.d.ts new file mode 100644 index 000000000..f6cd285c4 --- /dev/null +++ b/src-testing/src/loaders/CubeTextureLoader.d.ts @@ -0,0 +1,14 @@ +import { CubeTexture } from "../textures/CubeTexture.js"; +import { Loader } from "./Loader.js"; +import { LoadingManager } from "./LoadingManager.js"; + +export class CubeTextureLoader extends Loader { + constructor(manager?: LoadingManager); + + load( + url: readonly string[], + onLoad?: (data: CubeTexture) => void, + onProgress?: (event: ProgressEvent) => void, + onError?: (err: unknown) => void, + ): CubeTexture; +} diff --git a/src-testing/src/loaders/DataTextureLoader.d.ts b/src-testing/src/loaders/DataTextureLoader.d.ts new file mode 100644 index 000000000..0cc8d7475 --- /dev/null +++ b/src-testing/src/loaders/DataTextureLoader.d.ts @@ -0,0 +1,14 @@ +import { DataTexture } from "../textures/DataTexture.js"; +import { Loader } from "./Loader.js"; +import { LoadingManager } from "./LoadingManager.js"; + +export class DataTextureLoader extends Loader { + constructor(manager?: LoadingManager); + + load( + url: string, + onLoad?: (data: DataTexture, texData: object) => void, + onProgress?: (event: ProgressEvent) => void, + onError?: (err: unknown) => void, + ): DataTexture; +} diff --git a/src-testing/src/loaders/FileLoader.d.ts b/src-testing/src/loaders/FileLoader.d.ts new file mode 100644 index 000000000..25ceba9cd --- /dev/null +++ b/src-testing/src/loaders/FileLoader.d.ts @@ -0,0 +1,19 @@ +import { Loader } from "./Loader.js"; +import { LoadingManager } from "./LoadingManager.js"; + +export class FileLoader extends Loader { + constructor(manager?: LoadingManager); + + load( + url: string, + onLoad?: (data: string | ArrayBuffer) => void, + onProgress?: (event: ProgressEvent) => void, + onError?: (err: unknown) => void, + ): void; + + mimeType: string | undefined; + responseType: string | undefined; + + setMimeType(mimeType: string): FileLoader; + setResponseType(responseType: string): FileLoader; +} diff --git a/src-testing/src/loaders/ImageBitmapLoader.d.ts b/src-testing/src/loaders/ImageBitmapLoader.d.ts new file mode 100644 index 000000000..f182d326a --- /dev/null +++ b/src-testing/src/loaders/ImageBitmapLoader.d.ts @@ -0,0 +1,22 @@ +import { Loader } from "./Loader.js"; +import { LoadingManager } from "./LoadingManager.js"; + +export class ImageBitmapLoader extends Loader { + constructor(manager?: LoadingManager); + + load( + url: string, + onLoad?: (data: ImageBitmap) => void, + onProgress?: (event: ProgressEvent) => void, + onError?: (err: unknown) => void, + ): void; + + /** + * @default { premultiplyAlpha: 'none' } + */ + options: undefined | object; + + readonly isImageBitmapLoader: true; + + setOptions(options: object): ImageBitmapLoader; +} diff --git a/src-testing/src/loaders/ImageLoader.d.ts b/src-testing/src/loaders/ImageLoader.d.ts new file mode 100644 index 000000000..2189198e4 --- /dev/null +++ b/src-testing/src/loaders/ImageLoader.d.ts @@ -0,0 +1,17 @@ +import { Loader } from "./Loader.js"; +import { LoadingManager } from "./LoadingManager.js"; + +/** + * A loader for loading an image. + * Unlike other loaders, this one emits events instead of using predefined callbacks. So if you're interested in getting notified when things happen, you need to add listeners to the object. + */ +export class ImageLoader extends Loader { + constructor(manager?: LoadingManager); + + load( + url: string, + onLoad?: (data: HTMLImageElement) => void, + onProgress?: (event: ProgressEvent) => void, + onError?: (err: unknown) => void, + ): HTMLImageElement; +} diff --git a/src-testing/src/loaders/Loader.d.ts b/src-testing/src/loaders/Loader.d.ts new file mode 100644 index 000000000..0f65e66f3 --- /dev/null +++ b/src-testing/src/loaders/Loader.d.ts @@ -0,0 +1,50 @@ +import { LoadingManager } from "./LoadingManager.js"; + +/** + * Base class for implementing loaders. + */ +export class Loader { + constructor(manager?: LoadingManager); + + /** + * @default 'anonymous' + */ + crossOrigin: string; + + /** + * @default false + */ + withCredentials: boolean; + + /** + * @default '' + */ + path: string; + + /** + * @default '' + */ + resourcePath: string; + manager: LoadingManager; + + /** + * @default {} + */ + requestHeader: { [header: string]: string }; + + load( + url: TUrl, + onLoad: (data: TData) => void, + onProgress?: (event: ProgressEvent) => void, + onError?: (err: unknown) => void, + ): void; + loadAsync(url: TUrl, onProgress?: (event: ProgressEvent) => void): Promise; + + setCrossOrigin(crossOrigin: string): this; + setWithCredentials(value: boolean): this; + setPath(path: string): this; + setResourcePath(resourcePath: string): this; + setRequestHeader(requestHeader: { [header: string]: string }): this; + + static DEFAULT_MATERIAL_NAME: string; +} diff --git a/src-testing/src/loaders/LoaderUtils.d.ts b/src-testing/src/loaders/LoaderUtils.d.ts new file mode 100644 index 000000000..2f00baeff --- /dev/null +++ b/src-testing/src/loaders/LoaderUtils.d.ts @@ -0,0 +1,10 @@ +export class LoaderUtils { + /** + * @deprecated decodeText() has been deprecated with r165 and will be removed with r175. Use TextDecoder instead. + */ + static decodeText(array: BufferSource): string; + + static extractUrlBase(url: string): string; + + static resolveURL(url: string, path: string): string; +} diff --git a/src-testing/src/loaders/LoadingManager.d.ts b/src-testing/src/loaders/LoadingManager.d.ts new file mode 100644 index 000000000..ab5b546cd --- /dev/null +++ b/src-testing/src/loaders/LoadingManager.d.ts @@ -0,0 +1,69 @@ +import { Loader } from "./Loader.js"; + +export const DefaultLoadingManager: LoadingManager; + +/** + * Handles and keeps track of loaded and pending data. + */ +export class LoadingManager { + constructor( + onLoad?: () => void, + onProgress?: (url: string, loaded: number, total: number) => void, + onError?: (url: string) => void, + ); + + /** + * Will be called when loading of an item starts. + * @param url The url of the item that started loading. + * @param loaded The number of items already loaded so far. + * @param total The total amount of items to be loaded. + */ + onStart?: ((url: string, loaded: number, total: number) => void) | undefined; + + /** + * Will be called when all items finish loading. + * The default is a function with empty body. + */ + onLoad: () => void; + + /** + * Will be called for each loaded item. + * The default is a function with empty body. + * @param url The url of the item just loaded. + * @param loaded The number of items already loaded so far. + * @param total The total amount of items to be loaded. + */ + onProgress: (url: string, loaded: number, total: number) => void; + + /** + * Will be called when item loading fails. + * The default is a function with empty body. + * @param url The url of the item that errored. + */ + onError: (url: string) => void; + + /** + * If provided, the callback will be passed each resource URL before a request is sent. + * The callback may return the original URL, or a new URL to override loading behavior. + * This behavior can be used to load assets from .ZIP files, drag-and-drop APIs, and Data URIs. + * @param callback URL modifier callback. Called with url argument, and must return resolvedURL. + */ + setURLModifier(callback?: (url: string) => string): this; + + /** + * Given a URL, uses the URL modifier callback (if any) and returns a resolved URL. + * If no URL modifier is set, returns the original URL. + * @param url the url to load + */ + resolveURL(url: string): string; + + itemStart(url: string): void; + itemEnd(url: string): void; + itemError(url: string): void; + + // handlers + + addHandler(regex: RegExp, loader: Loader): this; + removeHandler(regex: RegExp): this; + getHandler(file: string): Loader | null; +} diff --git a/src-testing/src/loaders/MaterialLoader.d.ts b/src-testing/src/loaders/MaterialLoader.d.ts new file mode 100644 index 000000000..742c22a04 --- /dev/null +++ b/src-testing/src/loaders/MaterialLoader.d.ts @@ -0,0 +1,21 @@ +import { Material } from "../materials/Material.js"; +import { Texture } from "../textures/Texture.js"; +import { Loader } from "./Loader.js"; +import { LoadingManager } from "./LoadingManager.js"; + +export class MaterialLoader extends Loader { + /** + * @default {} + */ + textures: { [key: string]: Texture }; + + constructor(manager?: LoadingManager); + + parse(json: unknown): Material; + + setTextures(textures: { [key: string]: Texture }): this; + + createMaterialFromType(type: string): Material; + + static createMaterialFromType(type: string): Material; +} diff --git a/src-testing/src/loaders/ObjectLoader.d.ts b/src-testing/src/loaders/ObjectLoader.d.ts new file mode 100644 index 000000000..306c75700 --- /dev/null +++ b/src-testing/src/loaders/ObjectLoader.d.ts @@ -0,0 +1,35 @@ +import { AnimationClip } from "../animation/AnimationClip.js"; +import { BufferGeometry } from "../core/BufferGeometry.js"; +import { InstancedBufferGeometry } from "../core/InstancedBufferGeometry.js"; +import { Object3D } from "../core/Object3D.js"; +import { Material } from "../materials/Material.js"; +import { Source } from "../textures/Source.js"; +import { Texture } from "../textures/Texture.js"; +import { Loader } from "./Loader.js"; +import { LoadingManager } from "./LoadingManager.js"; + +export class ObjectLoader extends Loader { + constructor(manager?: LoadingManager); + + load( + url: string, + onLoad?: (data: Object3D) => void, + onProgress?: (event: ProgressEvent) => void, + onError?: (err: unknown) => void, + ): void; + + parse(json: unknown, onLoad?: (object: Object3D) => void): Object3D; + parseAsync(json: unknown): Promise; + parseGeometries(json: unknown): { [key: string]: InstancedBufferGeometry | BufferGeometry }; + parseMaterials(json: unknown, textures: { [key: string]: Texture }): { [key: string]: Material }; + parseAnimations(json: unknown): { [key: string]: AnimationClip }; + parseImages(json: unknown, onLoad?: () => void): { [key: string]: Source }; + parseImagesAsync(json: unknown): Promise<{ [key: string]: Source }>; + parseTextures(json: unknown, images: { [key: string]: Source }): { [key: string]: Texture }; + parseObject( + data: unknown, + geometries: { [key: string]: InstancedBufferGeometry | BufferGeometry }, + materials: { [key: string]: Material }, + animations: { [key: string]: AnimationClip }, + ): Object3D; +} diff --git a/src-testing/src/loaders/TextureLoader.d.ts b/src-testing/src/loaders/TextureLoader.d.ts new file mode 100644 index 000000000..3cc07f5c3 --- /dev/null +++ b/src-testing/src/loaders/TextureLoader.d.ts @@ -0,0 +1,18 @@ +import { Texture } from "../textures/Texture.js"; +import { Loader } from "./Loader.js"; +import { LoadingManager } from "./LoadingManager.js"; + +/** + * Class for loading a texture. + * Unlike other loaders, this one emits events instead of using predefined callbacks. So if you're interested in getting notified when things happen, you need to add listeners to the object. + */ +export class TextureLoader extends Loader { + constructor(manager?: LoadingManager); + + load( + url: string, + onLoad?: (data: Texture) => void, + onProgress?: (event: ProgressEvent) => void, + onError?: (err: unknown) => void, + ): Texture; +} diff --git a/src-testing/src/loaders/nodes/NodeLoader.d.ts b/src-testing/src/loaders/nodes/NodeLoader.d.ts new file mode 100644 index 000000000..9083b2315 --- /dev/null +++ b/src-testing/src/loaders/nodes/NodeLoader.d.ts @@ -0,0 +1,21 @@ +import { Node } from "../../nodes/Nodes.js"; +import { Texture } from "../../textures/Texture.js"; +import { Loader } from "../Loader.js"; +import { LoadingManager } from "../LoadingManager.js"; + +export interface NodeLoaderResult { + [hash: string]: Node; +} + +export default class NodeLoader extends Loader { + textures: { [key: string]: Texture }; + nodes: { [type: string]: Node }; + + constructor(manager?: LoadingManager); + + parseNodes(json: unknown): NodeLoaderResult; + parse(json: unknown): Node; + setTextures(textures: { [key: string]: Texture }): this; + setNodes(value: { [type: string]: Node }): this; + createNodeFromType(type: string): Node; +} diff --git a/src-testing/src/loaders/nodes/NodeMaterialLoader.d.ts b/src-testing/src/loaders/nodes/NodeMaterialLoader.d.ts new file mode 100644 index 000000000..89dee9c6a --- /dev/null +++ b/src-testing/src/loaders/nodes/NodeMaterialLoader.d.ts @@ -0,0 +1,11 @@ +import NodeMaterial from "../../materials/nodes/NodeMaterial.js"; +import { MaterialLoader } from "../MaterialLoader.js"; +import { NodeLoaderResult } from "./NodeLoader.js"; + +export default class NodeMaterialLoader extends MaterialLoader { + nodes: NodeLoaderResult; + nodeMaterials: { [type: string]: NodeMaterial }; + + setNodes(value: NodeLoaderResult): this; + setNodeMaterials(value: { [type: string]: NodeMaterial }): this; +} diff --git a/src-testing/src/loaders/nodes/NodeObjectLoader.d.ts b/src-testing/src/loaders/nodes/NodeObjectLoader.d.ts new file mode 100644 index 000000000..0dbcef8a5 --- /dev/null +++ b/src-testing/src/loaders/nodes/NodeObjectLoader.d.ts @@ -0,0 +1,22 @@ +import { Material } from "../../materials/Material.js"; +import NodeMaterial from "../../materials/nodes/NodeMaterial.js"; +import { Node } from "../../nodes/Nodes.js"; +import { Texture } from "../../textures/Texture.js"; +import { LoadingManager } from "../LoadingManager.js"; +import { ObjectLoader } from "../ObjectLoader.js"; +import { NodeLoaderResult } from "./NodeLoader.js"; + +export default class NodeObjectLoader extends ObjectLoader { + nodes: { [type: string]: Node }; + nodeMaterials: { [type: string]: NodeMaterial }; + + constructor(manager?: LoadingManager); + + setNodes(value: { [type: string]: Node }): this; + + setNodeMaterials(value: { [type: string]: NodeMaterial }): this; + + parseNodes(json: unknown, textures: { [key: string]: Texture }): NodeLoaderResult; + + parseMaterials(json: unknown, textures: { [key: string]: Texture }): { [key: string]: Material }; +} diff --git a/src-testing/src/materials/LineBasicMaterial.d.ts b/src-testing/src/materials/LineBasicMaterial.d.ts new file mode 100644 index 000000000..7f8bac230 --- /dev/null +++ b/src-testing/src/materials/LineBasicMaterial.d.ts @@ -0,0 +1,55 @@ +import { Color, ColorRepresentation } from "../math/Color.js"; +import { Texture } from "../textures/Texture.js"; +import { Material, MaterialParameters } from "./Material.js"; + +export interface LineBasicMaterialParameters extends MaterialParameters { + color?: ColorRepresentation | undefined; + fog?: boolean | undefined; + linewidth?: number | undefined; + linecap?: string | undefined; + linejoin?: string | undefined; +} + +export class LineBasicMaterial extends Material { + constructor(parameters?: LineBasicMaterialParameters); + + /** + * Read-only flag to check if a given object is of type {@link LineBasicMaterial}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isLineBasicMaterial: true; + + /** + * @default 0xffffff + */ + color: Color; + + /** + * Whether the material is affected by fog. Default is true. + * @default true + */ + fog: boolean; + + /** + * @default 1 + */ + linewidth: number; + + /** + * @default 'round' + */ + linecap: string; + + /** + * @default 'round' + */ + linejoin: string; + + /** + * Sets the color of the lines using data from a {@link Texture}. + */ + map: Texture | null; + + setValues(parameters: LineBasicMaterialParameters): void; +} diff --git a/src-testing/src/materials/LineDashedMaterial.d.ts b/src-testing/src/materials/LineDashedMaterial.d.ts new file mode 100644 index 000000000..514bb3f93 --- /dev/null +++ b/src-testing/src/materials/LineDashedMaterial.d.ts @@ -0,0 +1,35 @@ +import { LineBasicMaterial, LineBasicMaterialParameters } from "./LineBasicMaterial.js"; + +export interface LineDashedMaterialParameters extends LineBasicMaterialParameters { + scale?: number | undefined; + dashSize?: number | undefined; + gapSize?: number | undefined; +} + +export class LineDashedMaterial extends LineBasicMaterial { + constructor(parameters?: LineDashedMaterialParameters); + + /** + * Read-only flag to check if a given object is of type {@link LineDashedMaterial}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isLineDashedMaterial: true; + + /** + * @default 1 + */ + scale: number; + + /** + * @default 1 + */ + dashSize: number; + + /** + * @default 1 + */ + gapSize: number; + + setValues(parameters: LineDashedMaterialParameters): void; +} diff --git a/src-testing/src/materials/Material.d.ts b/src-testing/src/materials/Material.d.ts new file mode 100644 index 000000000..731bcc89e --- /dev/null +++ b/src-testing/src/materials/Material.d.ts @@ -0,0 +1,629 @@ +import { Camera } from "../cameras/Camera.js"; +import { + Blending, + BlendingDstFactor, + BlendingEquation, + BlendingSrcFactor, + Combine, + DepthModes, + NormalMapTypes, + PixelFormat, + Side, + StencilFunc, + StencilOp, +} from "../constants.js"; +import { BufferGeometry } from "../core/BufferGeometry.js"; +import { EventDispatcher } from "../core/EventDispatcher.js"; +import { JSONMeta, Object3D } from "../core/Object3D.js"; +import { Color, ColorRepresentation } from "../math/Color.js"; +import { Plane } from "../math/Plane.js"; +import { Group } from "../objects/Group.js"; +import { WebGLProgramParametersWithUniforms } from "../renderers/webgl/WebGLPrograms.js"; +import { WebGLRenderer } from "../renderers/WebGLRenderer.js"; +import { Scene } from "../scenes/Scene.js"; +import { EulerTuple, SourceJSON, TextureJSON, Vector2Tuple } from "../Three.js"; + +export interface MaterialParameters { + alphaHash?: boolean | undefined; + alphaTest?: number | undefined; + alphaToCoverage?: boolean | undefined; + blendAlpha?: number | undefined; + blendColor?: ColorRepresentation | undefined; + blendDst?: BlendingDstFactor | undefined; + blendDstAlpha?: number | undefined; + blendEquation?: BlendingEquation | undefined; + blendEquationAlpha?: number | undefined; + blending?: Blending | undefined; + blendSrc?: BlendingSrcFactor | BlendingDstFactor | undefined; + blendSrcAlpha?: number | undefined; + clipIntersection?: boolean | undefined; + clippingPlanes?: Plane[] | undefined; + clipShadows?: boolean | undefined; + colorWrite?: boolean | undefined; + defines?: any; + depthFunc?: DepthModes | undefined; + depthTest?: boolean | undefined; + depthWrite?: boolean | undefined; + name?: string | undefined; + opacity?: number | undefined; + polygonOffset?: boolean | undefined; + polygonOffsetFactor?: number | undefined; + polygonOffsetUnits?: number | undefined; + precision?: "highp" | "mediump" | "lowp" | null | undefined; + premultipliedAlpha?: boolean | undefined; + forceSinglePass?: boolean | undefined; + dithering?: boolean | undefined; + side?: Side | undefined; + shadowSide?: Side | undefined; + toneMapped?: boolean | undefined; + transparent?: boolean | undefined; + vertexColors?: boolean | undefined; + visible?: boolean | undefined; + format?: PixelFormat | undefined; + stencilWrite?: boolean | undefined; + stencilFunc?: StencilFunc | undefined; + stencilRef?: number | undefined; + stencilWriteMask?: number | undefined; + stencilFuncMask?: number | undefined; + stencilFail?: StencilOp | undefined; + stencilZFail?: StencilOp | undefined; + stencilZPass?: StencilOp | undefined; + userData?: Record | undefined; +} + +export interface MaterialJSON { + metadata: { version: number; type: string; generator: string }; + + uuid: string; + type: string; + + name?: string; + + color?: number; + roughness?: number; + metalness?: number; + + sheen?: number; + sheenColor?: number; + sheenRoughness?: number; + emissive?: number; + emissiveIntensity?: number; + + specular?: number; + specularIntensity?: number; + specularColor?: number; + shininess?: number; + clearcoat?: number; + clearcoatRoughness?: number; + clearcoatMap?: string; + clearcoatRoughnessMap?: string; + clearcoatNormalMap?: string; + clearcoatNormalScale?: Vector2Tuple; + + dispersion?: number; + + iridescence?: number; + iridescenceIOR?: number; + iridescenceThicknessRange?: number; + iridescenceMap?: string; + iridescenceThicknessMap?: string; + + anisotropy?: number; + anisotropyRotation?: number; + anisotropyMap?: string; + + map?: string; + matcap?: string; + alphaMap?: string; + + lightMap?: string; + lightMapIntensity?: number; + + aoMap?: string; + aoMapIntensity?: number; + + bumpMap?: string; + bumpScale?: number; + + normalMap?: string; + normalMapType?: NormalMapTypes; + normalScale?: Vector2Tuple; + + displacementMap?: string; + displacementScale?: number; + displacementBias?: number; + + roughnessMap?: string; + metalnessMap?: string; + + emissiveMap?: string; + specularMap?: string; + specularIntensityMap?: string; + specularColorMap?: string; + + envMap?: string; + combine?: Combine; + + envMapRotation?: EulerTuple; + envMapIntensity?: number; + reflectivity?: number; + refractionRatio?: number; + + gradientMap?: string; + + transmission?: number; + transmissionMap?: string; + thickness?: number; + thicknessMap?: string; + attenuationDistance?: number; + attenuationColor?: number; + + size?: number; + shadowSide?: number; + sizeAttenuation?: boolean; + + blending?: Blending; + side?: Side; + vertexColors?: boolean; + + opacity?: number; + transparent?: boolean; + + blendSrc?: BlendingSrcFactor; + blendDst?: BlendingDstFactor; + blendEquation?: BlendingEquation; + blendSrcAlpha?: number | null; + blendDstAlpha?: number | null; + blendEquationAlpha?: number | null; + blendColor?: number; + blendAlpha?: number; + + depthFunc?: DepthModes; + depthTest?: boolean; + depthWrite?: boolean; + colorWrite?: boolean; + + stencilWriteMask?: number; + stencilFunc?: StencilFunc; + stencilRef?: number; + stencilFuncMask?: number; + stencilFail?: StencilOp; + stencilZFail?: StencilOp; + stencilZPass?: StencilOp; + stencilWrite?: boolean; + + rotation?: number; + + polygonOffset?: boolean; + polygonOffsetFactor?: number; + polygonOffsetUnits?: number; + + linewidth?: number; + dashSize?: number; + gapSize?: number; + scale?: number; + + dithering?: boolean; + + alphaTest?: number; + alphaHash?: boolean; + alphaToCoverage?: boolean; + premultipliedAlpha?: boolean; + forceSinglePass?: boolean; + + wireframe?: boolean; + wireframeLinewidth?: number; + wireframeLinecap?: string; + wireframeLinejoin?: string; + + flatShading?: boolean; + + visible?: boolean; + + toneMapped?: boolean; + + fog?: boolean; + + userData?: Record; + + textures?: Array>; + images?: SourceJSON[]; +} + +/** + * Materials describe the appearance of objects. They are defined in a (mostly) renderer-independent way, so you don't have to rewrite materials if you decide to use a different renderer. + */ +export class Material extends EventDispatcher<{ dispose: {} }> { + static get type(): string; + + get type(): string; + + constructor(); + + /** + * Read-only flag to check if a given object is of type {@link Material}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isMaterial: true; + + /** + * Enables alpha hashed transparency, an alternative to {@link .transparent} or {@link .alphaTest}. The material + * will not be rendered if opacity is lower than a random threshold. Randomization introduces some grain or noise, + * but approximates alpha blending without the associated problems of sorting. Using TAARenderPass can reduce the + * resulting noise. + */ + alphaHash: boolean; + + /** + * Enables alpha to coverage. Can only be used with MSAA-enabled rendering contexts (meaning when the renderer was + * created with *antialias* parameter set to `true`). Enabling this will smooth aliasing on clip plane edges and + * alphaTest-clipped edges. + * @default false + */ + alphaToCoverage: boolean; + + /** + * Represents the alpha value of the constant blend color. This property has only an effect when using custom + * blending with {@link ConstantAlphaFactor} or {@link OneMinusConstantAlphaFactor}. + * @default 0 + */ + blendAlpha: number; + + /** + * Represent the RGB values of the constant blend color. This property has only an effect when using custom + * blending with {@link ConstantColorFactor} or {@link OneMinusConstantColorFactor}. + * @default 0x000000 + */ + blendColor: Color; + + /** + * Blending destination. It's one of the blending mode constants defined in Three.js. Default is {@link OneMinusSrcAlphaFactor}. + * @default THREE.OneMinusSrcAlphaFactor + */ + blendDst: BlendingDstFactor; + + /** + * The tranparency of the .blendDst. Default is null. + * @default null + */ + blendDstAlpha: number | null; + + /** + * Blending equation to use when applying blending. It's one of the constants defined in Three.js. Default is {@link AddEquation}. + * @default THREE.AddEquation + */ + blendEquation: BlendingEquation; + + /** + * The tranparency of the .blendEquation. Default is null. + * @default null + */ + blendEquationAlpha: number | null; + + /** + * Which blending to use when displaying objects with this material. Default is {@link NormalBlending}. + * @default THREE.NormalBlending + */ + blending: Blending; + + /** + * Blending source. It's one of the blending mode constants defined in Three.js. Default is {@link SrcAlphaFactor}. + * @default THREE.SrcAlphaFactor + */ + blendSrc: BlendingSrcFactor | BlendingDstFactor; + + /** + * The tranparency of the .blendSrc. Default is null. + * @default null + */ + blendSrcAlpha: number | null; + + /** + * Changes the behavior of clipping planes so that only their intersection is clipped, rather than their union. Default is false. + * @default false + */ + clipIntersection: boolean; + + /** + * User-defined clipping planes specified as THREE.Plane objects in world space. + * These planes apply to the objects this material is attached to. + * Points in space whose signed distance to the plane is negative are clipped (not rendered). + * See the WebGL / clipping /intersection example. Default is null. + * @default null + */ + clippingPlanes: Plane[] | null; + + /** + * Defines whether to clip shadows according to the clipping planes specified on this material. Default is false. + * @default false + */ + clipShadows: boolean; + + /** + * Whether to render the material's color. This can be used in conjunction with a mesh's .renderOrder property to create invisible objects that occlude other objects. Default is true. + * @default true + */ + colorWrite: boolean; + + /** + * Custom defines to be injected into the shader. These are passed in form of an object literal, with key/value pairs. { MY_CUSTOM_DEFINE: '' , PI2: Math.PI * 2 }. + * The pairs are defined in both vertex and fragment shaders. Default is undefined. + * @default undefined + */ + defines: undefined | { [key: string]: any }; + + /** + * Which depth function to use. Default is {@link LessEqualDepth}. See the depth mode constants for all possible values. + * @default THREE.LessEqualDepth + */ + depthFunc: DepthModes; + + /** + * Whether to have depth test enabled when rendering this material. When the depth test is disabled, the depth write + * will also be implicitly disabled. + * @default true + */ + depthTest: boolean; + + /** + * Whether rendering this material has any effect on the depth buffer. Default is true. + * When drawing 2D overlays it can be useful to disable the depth writing in order to layer several things together without creating z-index artifacts. + * @default true + */ + depthWrite: boolean; + + /** + * Unique number of this material instance. + */ + id: number; + + /** + * Whether rendering this material has any effect on the stencil buffer. Default is *false*. + * @default false + */ + stencilWrite: boolean; + + /** + * The stencil comparison function to use. Default is {@link AlwaysStencilFunc}. See stencil operation constants for all possible values. + * @default THREE.AlwaysStencilFunc + */ + stencilFunc: StencilFunc; + + /** + * The value to use when performing stencil comparisons or stencil operations. Default is *0*. + * @default 0 + */ + stencilRef: number; + + /** + * The bit mask to use when writing to the stencil buffer. Default is *0xFF*. + * @default 0xff + */ + stencilWriteMask: number; + + /** + * The bit mask to use when comparing against the stencil buffer. Default is *0xFF*. + * @default 0xff + */ + stencilFuncMask: number; + + /** + * Which stencil operation to perform when the comparison function returns false. Default is {@link KeepStencilOp}. See the stencil operation constants for all possible values. + * @default THREE.KeepStencilOp + */ + stencilFail: StencilOp; + + /** + * Which stencil operation to perform when the comparison function returns true but the depth test fails. + * Default is {@link KeepStencilOp}. + * See the stencil operation constants for all possible values. + * @default THREE.KeepStencilOp + */ + stencilZFail: StencilOp; + + /** + * Which stencil operation to perform when the comparison function returns true and the depth test passes. + * Default is {@link KeepStencilOp}. + * See the stencil operation constants for all possible values. + * @default THREE.KeepStencilOp + */ + stencilZPass: StencilOp; + + /** + * Material name. Default is an empty string. + * @default '' + */ + name: string; + + /** + * Opacity. Default is 1. + * @default 1 + */ + opacity: number; + + /** + * Whether to use polygon offset. Default is false. This corresponds to the POLYGON_OFFSET_FILL WebGL feature. + * @default false + */ + polygonOffset: boolean; + + /** + * Sets the polygon offset factor. Default is 0. + * @default 0 + */ + polygonOffsetFactor: number; + + /** + * Sets the polygon offset units. Default is 0. + * @default 0 + */ + polygonOffsetUnits: number; + + /** + * Override the renderer's default precision for this material. Can be "highp", "mediump" or "lowp". Defaults is null. + * @default null + */ + precision: "highp" | "mediump" | "lowp" | null; + + /** + * Whether to premultiply the alpha (transparency) value. See WebGL / Materials / Transparency for an example of the difference. Default is false. + * @default false + */ + premultipliedAlpha: boolean; + + /** + * @default false + */ + forceSinglePass: boolean; + + /** + * Whether to apply dithering to the color to remove the appearance of banding. Default is false. + * @default false + */ + dithering: boolean; + + /** + * Defines which of the face sides will be rendered - front, back or both. + * Default is {@link THREE.FrontSide}. Other options are {@link THREE.BackSide} and {@link THREE.DoubleSide}. + * + * @default {@link THREE.FrontSide} + */ + side: Side; + + /** + * Defines which of the face sides will cast shadows. Default is *null*. + * If *null*, the value is opposite that of side, above. + * @default null + */ + shadowSide: Side | null; + + /** + * Defines whether this material is tone mapped according to the renderer's + * {@link WebGLRenderer.toneMapping toneMapping} setting. It is ignored when rendering to a render target or using + * post processing. + * @default true + */ + toneMapped: boolean; + + /** + * Defines whether this material is transparent. This has an effect on rendering as transparent objects need special treatment and are rendered after non-transparent objects. + * When set to true, the extent to which the material is transparent is controlled by setting it's .opacity property. + * @default false + */ + transparent: boolean; + + /** + * UUID of this material instance. This gets automatically assigned, so this shouldn't be edited. + */ + uuid: string; + + /** + * Defines whether vertex coloring is used. Default is false. + * @default false + */ + vertexColors: boolean; + + /** + * Defines whether this material is visible. Default is true. + * @default true + */ + visible: boolean; + + /** + * An object that can be used to store custom data about the Material. It should not hold references to functions as these will not be cloned. + * @default {} + */ + userData: Record; + + /** + * This starts at 0 and counts how many times .needsUpdate is set to true. + * @default 0 + */ + version: number; + + /** + * Gets the alpha value to be used when running an alpha test. Default is 0. + * @default 0 + */ + get alphaTest(): number; + + /** + * Sets the alpha value to be used when running an alpha test. Default is 0. + * @default 0 + */ + set alphaTest(value: number); + + /** + * An optional callback that is executed immediately before the material is used to render a 3D object. + * Unlike properties, the callback is not supported by {@link .clone()}, {@link .copy()} and {@link .toJSON()}. + * This callback is only supported in `WebGLRenderer` (not `WebGPURenderer`). + */ + onBeforeRender( + renderer: WebGLRenderer, + scene: Scene, + camera: Camera, + geometry: BufferGeometry, + object: Object3D, + group: Group, + ): void; + + /** + * An optional callback that is executed immediately before the shader program is compiled. + * This function is called with the shader source code as a parameter. + * Useful for the modification of built-in materials. + * Unlike properties, the callback is not supported by {@link .clone()}, {@link .copy()} and {@link .toJSON()}. + * This callback is only supported in `WebGLRenderer` (not `WebGPURenderer`). + * @param parameters WebGL program parameters + * @param renderer WebGLRenderer context that is initializing the material + */ + onBeforeCompile(parameters: WebGLProgramParametersWithUniforms, renderer: WebGLRenderer): void; + + /** + * In case onBeforeCompile is used, this callback can be used to identify values of settings used in onBeforeCompile, so three.js can reuse a cached shader or recompile the shader as needed. + */ + customProgramCacheKey(): string; + + /** + * Sets the properties based on the values. + * @param values A container with parameters. + */ + setValues(values: MaterialParameters): void; + + /** + * Convert the material to three.js JSON format. + * @param meta Object containing metadata such as textures or images for the material. + */ + toJSON(meta?: JSONMeta): MaterialJSON; + + /** + * Return a new material with the same parameters as this material. + */ + clone(): this; + + /** + * Copy the parameters from the passed material into this material. + * @param material + */ + copy(material: Material): this; + + /** + * Frees the GPU-related resources allocated by this instance. Call this method whenever this instance is no longer + * used in your app. + * + * Material textures must be disposed of by the dispose() method of {@link Texture}. + */ + dispose(): void; + + /** + * Specifies that the material needs to be updated, WebGL wise. Set it to true if you made changes that need to be reflected in WebGL. + * This property is automatically set to true when instancing a new material. + * @default false + */ + set needsUpdate(value: boolean); + + /** + * @deprecated onBuild() has been removed. + */ + onBuild(object: Object3D, parameters: WebGLProgramParametersWithUniforms, renderer: WebGLRenderer): void; +} diff --git a/src-testing/src/materials/Materials.d.ts b/src-testing/src/materials/Materials.d.ts new file mode 100644 index 000000000..dbca5e5b7 --- /dev/null +++ b/src-testing/src/materials/Materials.d.ts @@ -0,0 +1,18 @@ +export * from "./LineBasicMaterial.js"; +export * from "./LineDashedMaterial.js"; +export * from "./Material.js"; +export * from "./MeshBasicMaterial.js"; +export * from "./MeshDepthMaterial.js"; +export * from "./MeshDistanceMaterial.js"; +export * from "./MeshLambertMaterial.js"; +export * from "./MeshMatcapMaterial.js"; +export * from "./MeshNormalMaterial.js"; +export * from "./MeshPhongMaterial.js"; +export * from "./MeshPhysicalMaterial.js"; +export * from "./MeshStandardMaterial.js"; +export * from "./MeshToonMaterial.js"; +export * from "./PointsMaterial.js"; +export * from "./RawShaderMaterial.js"; +export * from "./ShaderMaterial.js"; +export * from "./ShadowMaterial.js"; +export * from "./SpriteMaterial.js"; diff --git a/src-testing/src/materials/MeshBasicMaterial.d.ts b/src-testing/src/materials/MeshBasicMaterial.d.ts new file mode 100644 index 000000000..37ca083d7 --- /dev/null +++ b/src-testing/src/materials/MeshBasicMaterial.d.ts @@ -0,0 +1,134 @@ +import { Combine } from "../constants.js"; +import { Color, ColorRepresentation } from "../math/Color.js"; +import { Euler } from "../math/Euler.js"; +import { Texture } from "../textures/Texture.js"; +import { Material, MaterialParameters } from "./Material.js"; + +/** + * parameters is an object with one or more properties defining the material's appearance. + */ +export interface MeshBasicMaterialParameters extends MaterialParameters { + color?: ColorRepresentation | undefined; + opacity?: number | undefined; + map?: Texture | null | undefined; + lightMap?: Texture | null; + lightMapIntensity?: number | undefined; + aoMap?: Texture | null | undefined; + aoMapIntensity?: number | undefined; + specularMap?: Texture | null | undefined; + alphaMap?: Texture | null | undefined; + fog?: boolean | undefined; + envMap?: Texture | null | undefined; + envMapRotation?: Euler | undefined; + combine?: Combine | undefined; + reflectivity?: number | undefined; + refractionRatio?: number | undefined; + wireframe?: boolean | undefined; + wireframeLinewidth?: number | undefined; + wireframeLinecap?: string | undefined; + wireframeLinejoin?: string | undefined; +} + +export class MeshBasicMaterial extends Material { + constructor(parameters?: MeshBasicMaterialParameters); + + /** + * Read-only flag to check if a given object is of type {@link MeshBasicMaterial}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isMeshBasicMaterial: true; + + /** + * @default new THREE.Color( 0xffffff ) + */ + color: Color; + + /** + * @default null + */ + map: Texture | null; + + /** + * @default null + */ + lightMap: Texture | null; + + /** + * @default 1 + */ + lightMapIntensity: number; + + /** + * @default null + */ + aoMap: Texture | null; + + /** + * @default 1 + */ + aoMapIntensity: number; + + /** + * @default null + */ + specularMap: Texture | null; + + /** + * @default null + */ + alphaMap: Texture | null; + + /** + * @default null + */ + envMap: Texture | null; + + /** + * The rotation of the environment map in radians. Default is `(0,0,0)`. + */ + envMapRotation: Euler; + + /** + * @default THREE.MultiplyOperation + */ + combine: Combine; + + /** + * @default 1 + */ + reflectivity: number; + + /** + * @default 0.98 + */ + refractionRatio: number; + + /** + * @default false + */ + wireframe: boolean; + + /** + * @default 1 + */ + wireframeLinewidth: number; + + /** + * @default 'round' + */ + wireframeLinecap: string; + + /** + * @default 'round' + */ + wireframeLinejoin: string; + + /** + * Whether the material is affected by fog. Default is true. + * @default fog + */ + fog: boolean; + + setValues(parameters: MeshBasicMaterialParameters): void; +} diff --git a/src-testing/src/materials/MeshDepthMaterial.d.ts b/src-testing/src/materials/MeshDepthMaterial.d.ts new file mode 100644 index 000000000..dcdcd18b6 --- /dev/null +++ b/src-testing/src/materials/MeshDepthMaterial.d.ts @@ -0,0 +1,71 @@ +import { DepthPackingStrategies } from "../constants.js"; +import { Texture } from "../textures/Texture.js"; +import { Material, MaterialParameters } from "./Material.js"; + +export interface MeshDepthMaterialParameters extends MaterialParameters { + map?: Texture | null | undefined; + alphaMap?: Texture | null | undefined; + depthPacking?: DepthPackingStrategies | undefined; + displacementMap?: Texture | null | undefined; + displacementScale?: number | undefined; + displacementBias?: number | undefined; + wireframe?: boolean | undefined; + wireframeLinewidth?: number | undefined; +} + +export class MeshDepthMaterial extends Material { + constructor(parameters?: MeshDepthMaterialParameters); + /** + * Read-only flag to check if a given object is of type {@link MeshDepthMaterial}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isMeshDepthMaterial: true; + + /** + * @default null + */ + map: Texture | null; + + /** + * @default null + */ + alphaMap: Texture | null; + + /** + * @default THREE.BasicDepthPacking + */ + depthPacking: DepthPackingStrategies; + + /** + * @default null + */ + displacementMap: Texture | null; + + /** + * @default 1 + */ + displacementScale: number; + + /** + * @default 0 + */ + displacementBias: number; + + /** + * @default false + */ + wireframe: boolean; + + /** + * @default 1 + */ + wireframeLinewidth: number; + + /** + * @default false + */ + fog: boolean; + + setValues(parameters: MeshDepthMaterialParameters): void; +} diff --git a/src-testing/src/materials/MeshDistanceMaterial.d.ts b/src-testing/src/materials/MeshDistanceMaterial.d.ts new file mode 100644 index 000000000..4e6a8754b --- /dev/null +++ b/src-testing/src/materials/MeshDistanceMaterial.d.ts @@ -0,0 +1,57 @@ +import { Vector3 } from "../math/Vector3.js"; +import { Texture } from "../textures/Texture.js"; +import { Material, MaterialParameters } from "./Material.js"; + +export interface MeshDistanceMaterialParameters extends MaterialParameters { + map?: Texture | null | undefined; + alphaMap?: Texture | null | undefined; + displacementMap?: Texture | null | undefined; + displacementScale?: number | undefined; + displacementBias?: number | undefined; + farDistance?: number | undefined; + nearDistance?: number | undefined; + referencePosition?: Vector3 | undefined; +} + +export class MeshDistanceMaterial extends Material { + constructor(parameters?: MeshDistanceMaterialParameters); + + /** + * Read-only flag to check if a given object is of type {@link MeshDistanceMaterial}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isMeshDistanceMaterial: true; + + /** + * @default null + */ + map: Texture | null; + + /** + * @default null + */ + alphaMap: Texture | null; + + /** + * @default null + */ + displacementMap: Texture | null; + + /** + * @default 1 + */ + displacementScale: number; + + /** + * @default 0 + */ + displacementBias: number; + + /** + * @default false + */ + fog: boolean; + + setValues(parameters: MeshDistanceMaterialParameters): void; +} diff --git a/src-testing/src/materials/MeshLambertMaterial.d.ts b/src-testing/src/materials/MeshLambertMaterial.d.ts new file mode 100644 index 000000000..868fbbbe0 --- /dev/null +++ b/src-testing/src/materials/MeshLambertMaterial.d.ts @@ -0,0 +1,199 @@ +import { Combine, NormalMapTypes } from "../constants.js"; +import { Color, ColorRepresentation } from "../math/Color.js"; +import { Euler } from "../math/Euler.js"; +import { Vector2 } from "../math/Vector2.js"; +import { Texture } from "../textures/Texture.js"; +import { Material, MaterialParameters } from "./Material.js"; + +export interface MeshLambertMaterialParameters extends MaterialParameters { + bumpMap?: Texture | undefined; + bumpScale?: number | undefined; + color?: ColorRepresentation | undefined; + displacementMap?: Texture | undefined; + displacementScale?: number | undefined; + displacementBias?: number | undefined; + emissive?: ColorRepresentation | undefined; + emissiveIntensity?: number | undefined; + emissiveMap?: Texture | null | undefined; + flatShading?: boolean | undefined; + map?: Texture | null | undefined; + lightMap?: Texture | null | undefined; + lightMapIntensity?: number | undefined; + normalMap?: Texture | undefined; + normalScale?: Vector2 | undefined; + aoMap?: Texture | null | undefined; + aoMapIntensity?: number | undefined; + specularMap?: Texture | null | undefined; + alphaMap?: Texture | null | undefined; + envMap?: Texture | null | undefined; + envMapRotation?: Euler | undefined; + combine?: Combine | undefined; + reflectivity?: number | undefined; + refractionRatio?: number | undefined; + wireframe?: boolean | undefined; + wireframeLinewidth?: number | undefined; + wireframeLinecap?: string | undefined; + wireframeLinejoin?: string | undefined; + fog?: boolean | undefined; +} + +export class MeshLambertMaterial extends Material { + constructor(parameters?: MeshLambertMaterialParameters); + + /** + * Read-only flag to check if a given object is of type {@link MeshLambertMaterial}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isMeshLambertMaterial: true; + + /** + * @default new THREE.Color( 0xffffff ) + */ + color: Color; + + /** + * @default null + */ + bumpMap: Texture | null; + + /** + * @default 1 + */ + bumpScale: number; + + /** + * @default null + */ + displacementMap: Texture | null; + + /** + * @default 1 + */ + displacementScale: number; + + /** + * @default 0 + */ + displacementBias: number; + + /** + * @default new THREE.Color( 0x000000 ) + */ + emissive: Color; + + /** + * @default 1 + */ + emissiveIntensity: number; + + /** + * @default null + */ + emissiveMap: Texture | null; + + /** + * @default false + */ + flatShading: boolean; + + /** + * @default null + */ + map: Texture | null; + + /** + * @default null + */ + lightMap: Texture | null; + + /** + * @default 1 + */ + lightMapIntensity: number; + + /** + * @default null + */ + normalMap: Texture | null; + + normalMapType: NormalMapTypes; + + /** + * @default new THREE.Vector2( 1, 1 ) + */ + normalScale: Vector2; + + /** + * @default null + */ + aoMap: Texture | null; + + /** + * @default 1 + */ + aoMapIntensity: number; + + /** + * @default null + */ + specularMap: Texture | null; + + /** + * @default null + */ + alphaMap: Texture | null; + + /** + * @default null + */ + envMap: Texture | null; + + /** + * The rotation of the environment map in radians. Default is `(0,0,0)`. + */ + envMapRotation: Euler; + + /** + * @default THREE.MultiplyOperation + */ + combine: Combine; + + /** + * @default 1 + */ + reflectivity: number; + + /** + * @default 0.98 + */ + refractionRatio: number; + + /** + * @default false + */ + wireframe: boolean; + + /** + * @default 1 + */ + wireframeLinewidth: number; + + /** + * @default 'round' + */ + wireframeLinecap: string; + + /** + * @default 'round' + */ + wireframeLinejoin: string; + + /** + * Whether the material is affected by fog. Default is true. + * @default fog + */ + fog: boolean; + + setValues(parameters: MeshLambertMaterialParameters): void; +} diff --git a/src-testing/src/materials/MeshMatcapMaterial.d.ts b/src-testing/src/materials/MeshMatcapMaterial.d.ts new file mode 100644 index 000000000..7f7334d4b --- /dev/null +++ b/src-testing/src/materials/MeshMatcapMaterial.d.ts @@ -0,0 +1,112 @@ +import { NormalMapTypes } from "../constants.js"; +import { Color, ColorRepresentation } from "../math/Color.js"; +import { Vector2 } from "../math/Vector2.js"; +import { Texture } from "../textures/Texture.js"; +import { Material, MaterialParameters } from "./Material.js"; + +export interface MeshMatcapMaterialParameters extends MaterialParameters { + color?: ColorRepresentation | undefined; + matcap?: Texture | null | undefined; + map?: Texture | null | undefined; + bumpMap?: Texture | null | undefined; + bumpScale?: number | undefined; + normalMap?: Texture | null | undefined; + normalMapType?: NormalMapTypes | undefined; + normalScale?: Vector2 | undefined; + displacementMap?: Texture | null | undefined; + displacementScale?: number | undefined; + displacementBias?: number | undefined; + alphaMap?: Texture | null | undefined; + fog?: boolean | undefined; + flatShading?: boolean | undefined; +} + +export class MeshMatcapMaterial extends Material { + constructor(parameters?: MeshMatcapMaterialParameters); + + /** + * Read-only flag to check if a given object is of type {@link MeshMatcapMaterial}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isMeshMatcapMaterial: true; + + /** + * @default { 'MATCAP': '' } + */ + defines: { [key: string]: any }; + + /** + * @default new THREE.Color( 0xffffff ) + */ + color: Color; + + /** + * @default null + */ + matcap: Texture | null; + + /** + * @default null + */ + map: Texture | null; + + /** + * @default null + */ + bumpMap: Texture | null; + + /** + * @default 1 + */ + bumpScale: number; + + /** + * @default null + */ + normalMap: Texture | null; + + /** + * @default THREE.TangentSpaceNormalMap + */ + normalMapType: NormalMapTypes; + + /** + * @default new Vector2( 1, 1 ) + */ + normalScale: Vector2; + + /** + * @default null + */ + displacementMap: Texture | null; + + /** + * @default 1 + */ + displacementScale: number; + + /** + * @default 0 + */ + displacementBias: number; + + /** + * @default null + */ + alphaMap: Texture | null; + + /** + * Define whether the material is rendered with flat shading. Default is false. + * @default false + */ + flatShading: boolean; + + /** + * Whether the material is affected by fog. Default is true. + * @default fog + */ + fog: boolean; + + setValues(parameters: MeshMatcapMaterialParameters): void; +} diff --git a/src-testing/src/materials/MeshNormalMaterial.d.ts b/src-testing/src/materials/MeshNormalMaterial.d.ts new file mode 100644 index 000000000..715ada4e6 --- /dev/null +++ b/src-testing/src/materials/MeshNormalMaterial.d.ts @@ -0,0 +1,88 @@ +import { NormalMapTypes } from "../constants.js"; +import { Vector2 } from "../math/Vector2.js"; +import { Texture } from "../textures/Texture.js"; +import { Material, MaterialParameters } from "./Material.js"; + +export interface MeshNormalMaterialParameters extends MaterialParameters { + bumpMap?: Texture | null | undefined; + bumpScale?: number | undefined; + normalMap?: Texture | null | undefined; + normalMapType?: NormalMapTypes | undefined; + normalScale?: Vector2 | undefined; + displacementMap?: Texture | null | undefined; + displacementScale?: number | undefined; + displacementBias?: number | undefined; + wireframe?: boolean | undefined; + wireframeLinewidth?: number | undefined; + + flatShading?: boolean | undefined; +} + +export class MeshNormalMaterial extends Material { + constructor(parameters?: MeshNormalMaterialParameters); + + /** + * Read-only flag to check if a given object is of type {@link MeshNormalMaterial}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isMeshNormalMaterial: true; + + /** + * @default null + */ + bumpMap: Texture | null; + + /** + * @default 1 + */ + bumpScale: number; + + /** + * @default null + */ + normalMap: Texture | null; + + /** + * @default THREE.TangentSpaceNormalMap + */ + normalMapType: NormalMapTypes; + + /** + * @default new THREE.Vector2( 1, 1 ) + */ + normalScale: Vector2; + + /** + * @default null + */ + displacementMap: Texture | null; + + /** + * @default 1 + */ + displacementScale: number; + + /** + * @default 0 + */ + displacementBias: number; + + /** + * @default false + */ + wireframe: boolean; + + /** + * @default 1 + */ + wireframeLinewidth: number; + + /** + * Define whether the material is rendered with flat shading. Default is false. + * @default false + */ + flatShading: boolean; + + setValues(parameters: MeshNormalMaterialParameters): void; +} diff --git a/src-testing/src/materials/MeshPhongMaterial.d.ts b/src-testing/src/materials/MeshPhongMaterial.d.ts new file mode 100644 index 000000000..2b002524b --- /dev/null +++ b/src-testing/src/materials/MeshPhongMaterial.d.ts @@ -0,0 +1,223 @@ +import { Combine, NormalMapTypes } from "../constants.js"; +import { Color, ColorRepresentation } from "../math/Color.js"; +import { Euler } from "../math/Euler.js"; +import { Vector2 } from "../math/Vector2.js"; +import { Texture } from "../textures/Texture.js"; +import { Material, MaterialParameters } from "./Material.js"; + +export interface MeshPhongMaterialParameters extends MaterialParameters { + /** geometry color in hexadecimal. Default is 0xffffff. */ + color?: ColorRepresentation | undefined; + specular?: ColorRepresentation | undefined; + shininess?: number | undefined; + opacity?: number | undefined; + map?: Texture | null | undefined; + lightMap?: Texture | null | undefined; + lightMapIntensity?: number | undefined; + aoMap?: Texture | null | undefined; + aoMapIntensity?: number | undefined; + emissive?: ColorRepresentation | undefined; + emissiveIntensity?: number | undefined; + emissiveMap?: Texture | null | undefined; + bumpMap?: Texture | null | undefined; + bumpScale?: number | undefined; + normalMap?: Texture | null | undefined; + normalMapType?: NormalMapTypes | undefined; + normalScale?: Vector2 | undefined; + displacementMap?: Texture | null | undefined; + displacementScale?: number | undefined; + displacementBias?: number | undefined; + specularMap?: Texture | null | undefined; + alphaMap?: Texture | null | undefined; + envMap?: Texture | null | undefined; + envMapRotation?: Euler | undefined; + combine?: Combine | undefined; + reflectivity?: number | undefined; + refractionRatio?: number | undefined; + wireframe?: boolean | undefined; + wireframeLinewidth?: number | undefined; + wireframeLinecap?: string | undefined; + wireframeLinejoin?: string | undefined; + fog?: boolean | undefined; + flatShading?: boolean | undefined; +} + +export class MeshPhongMaterial extends Material { + constructor(parameters?: MeshPhongMaterialParameters); + + /** + * Read-only flag to check if a given object is of type {@link MeshPhongMaterial}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isMeshPhongMaterial: true; + + /** + * @default new THREE.Color( 0xffffff ) + */ + color: Color; + + /** + * @default new THREE.Color( 0x111111 ) + */ + specular: Color; + + /** + * @default 30 + */ + shininess: number; + + /** + * @default null + */ + map: Texture | null; + + /** + * @default null + */ + lightMap: Texture | null; + + /** + * @default null + */ + lightMapIntensity: number; + + /** + * @default null + */ + aoMap: Texture | null; + + /** + * @default null + */ + aoMapIntensity: number; + + /** + * @default new THREE.Color( 0x000000 ) + */ + emissive: Color; + + /** + * @default 1 + */ + emissiveIntensity: number; + + /** + * @default null + */ + emissiveMap: Texture | null; + + /** + * @default null + */ + bumpMap: Texture | null; + + /** + * @default 1 + */ + bumpScale: number; + + /** + * @default null + */ + normalMap: Texture | null; + + /** + * @default THREE.TangentSpaceNormalMap + */ + normalMapType: NormalMapTypes; + + /** + * @default new Vector2( 1, 1 ) + */ + normalScale: Vector2; + + /** + * @default null + */ + displacementMap: Texture | null; + + /** + * @default 1 + */ + displacementScale: number; + + /** + * @default 0 + */ + displacementBias: number; + + /** + * @default null + */ + specularMap: Texture | null; + + /** + * @default null + */ + alphaMap: Texture | null; + + /** + * @default null + */ + envMap: Texture | null; + + /** + * The rotation of the environment map in radians. Default is `(0,0,0)`. + */ + envMapRotation: Euler; + + /** + * @default THREE.MultiplyOperation + */ + combine: Combine; + + /** + * @default 1 + */ + reflectivity: number; + + /** + * @default 0.98 + */ + refractionRatio: number; + + /** + * @default false + */ + wireframe: boolean; + + /** + * @default 1 + */ + wireframeLinewidth: number; + + /** + * @default 'round' + */ + wireframeLinecap: string; + + /** + * @default 'round' + */ + wireframeLinejoin: string; + + /** + * Define whether the material is rendered with flat shading. Default is false. + * @default false + */ + flatShading: boolean; + + /** + * @deprecated Use {@link MeshStandardMaterial THREE.MeshStandardMaterial} instead. + */ + metal: boolean; + + /** + * Whether the material is affected by fog. Default is true. + * @default fog + */ + fog: boolean; + + setValues(parameters: MeshPhongMaterialParameters): void; +} diff --git a/src-testing/src/materials/MeshPhysicalMaterial.d.ts b/src-testing/src/materials/MeshPhysicalMaterial.d.ts new file mode 100644 index 000000000..f201ad662 --- /dev/null +++ b/src-testing/src/materials/MeshPhysicalMaterial.d.ts @@ -0,0 +1,231 @@ +import { Color, ColorRepresentation } from "../math/Color.js"; +import { Vector2 } from "../math/Vector2.js"; +import { Texture } from "../textures/Texture.js"; +import { MeshStandardMaterial, MeshStandardMaterialParameters } from "./MeshStandardMaterial.js"; + +export interface MeshPhysicalMaterialParameters extends MeshStandardMaterialParameters { + anisotropyRotation?: number | undefined; + anisotropyMap?: Texture | null | undefined; + + clearcoatMap?: Texture | null | undefined; + clearcoatRoughness?: number | undefined; + clearcoatRoughnessMap?: Texture | null | undefined; + clearcoatNormalScale?: Vector2 | undefined; + clearcoatNormalMap?: Texture | null | undefined; + + ior?: number | undefined; + + reflectivity?: number | undefined; + + iridescenceMap?: Texture | null | undefined; + iridescenceIOR?: number | undefined; + iridescenceThicknessRange?: [number, number] | undefined; + iridescenceThicknessMap?: Texture | null | undefined; + + sheenColor?: ColorRepresentation | undefined; + sheenColorMap?: Texture | null | undefined; + sheenRoughness?: number | undefined; + sheenRoughnessMap?: Texture | null | undefined; + + transmissionMap?: Texture | null | undefined; + + thickness?: number | undefined; + thicknessMap?: Texture | null | undefined; + attenuationDistance?: number | undefined; + attenuationColor?: ColorRepresentation | undefined; + + specularIntensity?: number | undefined; + specularIntensityMap?: Texture | null | undefined; + specularColor?: ColorRepresentation | undefined; + specularColorMap?: Texture | null | undefined; + + anisotropy?: number | undefined; + clearcoat?: number | undefined; + iridescence?: number | undefined; + dispersion?: number | undefined; + sheen?: number | undefined; + transmission?: number | undefined; +} + +export class MeshPhysicalMaterial extends MeshStandardMaterial { + constructor(parameters?: MeshPhysicalMaterialParameters); + + /** + * Read-only flag to check if a given object is of type {@link MeshPhysicalMaterial}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isMeshPhysicalMaterial: true; + + /** + * @default { 'STANDARD': '', 'PHYSICAL': '' } + */ + defines: { [key: string]: any }; + + /** + * @default 0 + */ + anisotropyRotation?: number; + + /** + * @default null + */ + anisotropyMap?: Texture | null; + + /** + * @default null + */ + clearcoatMap: Texture | null; + + /** + * @default 0 + */ + clearcoatRoughness: number; + + /** + * @default null + */ + clearcoatRoughnessMap: Texture | null; + + /** + * @default new THREE.Vector2( 1, 1 ) + */ + clearcoatNormalScale: Vector2; + + /** + * @default null + */ + clearcoatNormalMap: Texture | null; + + /** + * @default 1.5 + */ + ior: number; + + /** + * @default 0.5 + */ + get reflectivity(): number; + set reflectivity(reflectivity: number); + + /** + * @default null + */ + iridescenceMap: Texture | null; + + /** + * @default 1.3 + */ + iridescenceIOR: number; + + /** + * @default [100, 400] + */ + iridescenceThicknessRange: [number, number]; + + /** + * @default null + */ + iridescenceThicknessMap: Texture | null; + + /** + * @default Color( 0x000000 ) + */ + sheenColor: Color; + + /** + * @default null + */ + sheenColorMap: Texture | null; + + /** + * @default 1.0 + */ + sheenRoughness: number; + + /** + * @default null + */ + sheenRoughnessMap: Texture | null; + + /** + * @default null + */ + transmissionMap: Texture | null; + + /** + * @default 0.01 + */ + thickness: number; + + /** + * @default null + */ + thicknessMap: Texture | null; + + /** + * @default 0.0 + */ + attenuationDistance: number; + + /** + * @default Color( 1, 1, 1 ) + */ + attenuationColor: Color; + + /** + * @default 1.0 + */ + specularIntensity: number; + + /** + * @default null + */ + specularIntensityMap: Texture | null; + + /** + * @default Color(1, 1, 1) + */ + specularColor: Color; + + /** + * @default null + */ + specularColorMap: Texture | null; + + /** + * @default 0 + */ + get anisotropy(): number; + set anisotropy(value: number); + + /** + * @default 0 + */ + get clearcoat(): number; + set clearcoat(value: number); + + /** + * @default 0 + */ + get iridescence(): number; + set iridescence(value: number); + + /** + * @default 0 + */ + get dispersion(): number; + set dispersion(value: number); + + /** + * @default 0.0 + */ + get sheen(): number; + set sheen(value: number); + + /** + * @default 0 + */ + get transmission(): number; + set transmission(value: number); +} diff --git a/src-testing/src/materials/MeshStandardMaterial.d.ts b/src-testing/src/materials/MeshStandardMaterial.d.ts new file mode 100644 index 000000000..b4493a1d7 --- /dev/null +++ b/src-testing/src/materials/MeshStandardMaterial.d.ts @@ -0,0 +1,213 @@ +import { NormalMapTypes } from "../constants.js"; +import { Color, ColorRepresentation } from "../math/Color.js"; +import { Euler } from "../math/Euler.js"; +import { Vector2 } from "../math/Vector2.js"; +import { Texture } from "../textures/Texture.js"; +import { Material, MaterialParameters } from "./Material.js"; + +export interface MeshStandardMaterialParameters extends MaterialParameters { + color?: ColorRepresentation | undefined; + roughness?: number | undefined; + metalness?: number | undefined; + map?: Texture | null | undefined; + lightMap?: Texture | null | undefined; + lightMapIntensity?: number | undefined; + aoMap?: Texture | null | undefined; + aoMapIntensity?: number | undefined; + emissive?: ColorRepresentation | undefined; + emissiveIntensity?: number | undefined; + emissiveMap?: Texture | null | undefined; + bumpMap?: Texture | null | undefined; + bumpScale?: number | undefined; + normalMap?: Texture | null | undefined; + normalMapType?: NormalMapTypes | undefined; + normalScale?: Vector2 | undefined; + displacementMap?: Texture | null | undefined; + displacementScale?: number | undefined; + displacementBias?: number | undefined; + roughnessMap?: Texture | null | undefined; + metalnessMap?: Texture | null | undefined; + alphaMap?: Texture | null | undefined; + envMap?: Texture | null | undefined; + envMapRotation?: Euler | undefined; + envMapIntensity?: number | undefined; + wireframe?: boolean | undefined; + wireframeLinewidth?: number | undefined; + fog?: boolean | undefined; + flatShading?: boolean | undefined; +} + +export class MeshStandardMaterial extends Material { + constructor(parameters?: MeshStandardMaterialParameters); + + /** + * Read-only flag to check if a given object is of type {@link MeshStandardMaterial}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isMeshStandardMaterial: true; + + /** + * @default { 'STANDARD': '' } + */ + defines: { [key: string]: any }; + + /** + * @default new THREE.Color( 0xffffff ) + */ + color: Color; + + /** + * @default 1 + */ + roughness: number; + + /** + * @default 0 + */ + metalness: number; + + /** + * @default null + */ + map: Texture | null; + + /** + * @default null + */ + lightMap: Texture | null; + + /** + * @default 1 + */ + lightMapIntensity: number; + + /** + * @default null + */ + aoMap: Texture | null; + + /** + * @default 1 + */ + aoMapIntensity: number; + + /** + * @default new THREE.Color( 0x000000 ) + */ + emissive: Color; + + /** + * @default 1 + */ + emissiveIntensity: number; + + /** + * @default null + */ + emissiveMap: Texture | null; + + /** + * @default null + */ + bumpMap: Texture | null; + + /** + * @default 1 + */ + bumpScale: number; + + /** + * @default null + */ + normalMap: Texture | null; + + /** + * @default THREE.TangentSpaceNormalMap + */ + normalMapType: NormalMapTypes; + + /** + * @default new THREE.Vector2( 1, 1 ) + */ + normalScale: Vector2; + + /** + * @default null + */ + displacementMap: Texture | null; + + /** + * @default 1 + */ + displacementScale: number; + + /** + * @default 0 + */ + displacementBias: number; + + /** + * @default null + */ + roughnessMap: Texture | null; + + /** + * @default null + */ + metalnessMap: Texture | null; + + /** + * @default null + */ + alphaMap: Texture | null; + + /** + * @default null + */ + envMap: Texture | null; + + /** + * The rotation of the environment map in radians. Default is `(0,0,0)`. + */ + envMapRotation: Euler; + + /** + * @default 1 + */ + envMapIntensity: number; + + /** + * @default false + */ + wireframe: boolean; + + /** + * @default 1 + */ + wireframeLinewidth: number; + + /** + * @default 'round' + */ + wireframeLinecap: string; + + /** + * @default 'round' + */ + wireframeLinejoin: string; + + /** + * Define whether the material is rendered with flat shading. Default is false. + * @default false + */ + flatShading: boolean; + + /** + * Whether the material is affected by fog. Default is true. + * @default fog + */ + fog: boolean; + + setValues(parameters: MeshStandardMaterialParameters): void; +} diff --git a/src-testing/src/materials/MeshToonMaterial.d.ts b/src-testing/src/materials/MeshToonMaterial.d.ts new file mode 100644 index 000000000..14c71b27a --- /dev/null +++ b/src-testing/src/materials/MeshToonMaterial.d.ts @@ -0,0 +1,173 @@ +import { NormalMapTypes } from "../constants.js"; +import { Color, ColorRepresentation } from "../math/Color.js"; +import { Vector2 } from "../math/Vector2.js"; +import { Texture } from "../textures/Texture.js"; +import { Material, MaterialParameters } from "./Material.js"; + +export interface MeshToonMaterialParameters extends MaterialParameters { + /** geometry color in hexadecimal. Default is 0xffffff. */ + color?: ColorRepresentation | undefined; + opacity?: number | undefined; + gradientMap?: Texture | null | undefined; + map?: Texture | null | undefined; + lightMap?: Texture | null | undefined; + lightMapIntensity?: number | undefined; + aoMap?: Texture | null | undefined; + aoMapIntensity?: number | undefined; + emissive?: ColorRepresentation | undefined; + emissiveIntensity?: number | undefined; + emissiveMap?: Texture | null | undefined; + bumpMap?: Texture | null | undefined; + bumpScale?: number | undefined; + normalMap?: Texture | null | undefined; + normalMapType?: NormalMapTypes | undefined; + normalScale?: Vector2 | undefined; + displacementMap?: Texture | null | undefined; + displacementScale?: number | undefined; + displacementBias?: number | undefined; + alphaMap?: Texture | null | undefined; + wireframe?: boolean | undefined; + wireframeLinewidth?: number | undefined; + wireframeLinecap?: string | undefined; + wireframeLinejoin?: string | undefined; + fog?: boolean | undefined; +} + +export class MeshToonMaterial extends Material { + constructor(parameters?: MeshToonMaterialParameters); + + /** + * Read-only flag to check if a given object is of type {@link MeshToonMaterial}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isMeshToonMaterial: true; + + /** + * @default { 'TOON': '' } + */ + defines: { [key: string]: any }; + + /** + * @default new THREE.Color( 0xffffff ) + */ + color: Color; + + /** + * @default null + */ + gradientMap: Texture | null; + + /** + * @default null + */ + map: Texture | null; + + /** + * @default null + */ + lightMap: Texture | null; + + /** + * @default 1 + */ + lightMapIntensity: number; + + /** + * @default null + */ + aoMap: Texture | null; + + /** + * @default 1 + */ + aoMapIntensity: number; + + /** + * @default new THREE.Color( 0x000000 ) + */ + emissive: Color; + + /** + * @default 1 + */ + emissiveIntensity: number; + + /** + * @default null + */ + emissiveMap: Texture | null; + + /** + * @default null + */ + bumpMap: Texture | null; + + /** + * @default 1 + */ + bumpScale: number; + + /** + * @default null + */ + normalMap: Texture | null; + + /** + * @default THREE.TangentSpaceNormalMap + */ + normalMapType: NormalMapTypes; + + /** + * @default new THREE.Vector2( 1, 1 ) + */ + normalScale: Vector2; + + /** + * @default null + */ + displacementMap: Texture | null; + + /** + * @default 1 + */ + displacementScale: number; + + /** + * @default 0 + */ + displacementBias: number; + + /** + * @default null + */ + alphaMap: Texture | null; + + /** + * @default false + */ + wireframe: boolean; + + /** + * @default 1 + */ + wireframeLinewidth: number; + + /** + * @default 'round' + */ + wireframeLinecap: string; + + /** + * @default 'round' + */ + wireframeLinejoin: string; + + /** + * Whether the material is affected by fog. Default is true. + * @default fog + */ + fog: boolean; + + setValues(parameters: MeshToonMaterialParameters): void; +} diff --git a/src-testing/src/materials/PointsMaterial.d.ts b/src-testing/src/materials/PointsMaterial.d.ts new file mode 100644 index 000000000..a47a0817b --- /dev/null +++ b/src-testing/src/materials/PointsMaterial.d.ts @@ -0,0 +1,56 @@ +import { Color, ColorRepresentation } from "../math/Color.js"; +import { Texture } from "../textures/Texture.js"; +import { Material, MaterialParameters } from "./Material.js"; + +export interface PointsMaterialParameters extends MaterialParameters { + color?: ColorRepresentation | undefined; + map?: Texture | null | undefined; + alphaMap?: Texture | null | undefined; + size?: number | undefined; + sizeAttenuation?: boolean | undefined; + fog?: boolean | undefined; +} + +export class PointsMaterial extends Material { + constructor(parameters?: PointsMaterialParameters); + + /** + * Read-only flag to check if a given object is of type {@link PointsMaterial}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isPointsMaterial: true; + + /** + * @default new THREE.Color( 0xffffff ) + */ + color: Color; + + /** + * @default null + */ + map: Texture | null; + + /** + * @default null + */ + alphaMap: Texture | null; + + /** + * @default 1 + */ + size: number; + + /** + * @default true + */ + sizeAttenuation: boolean; + + /** + * Whether the material is affected by fog. Default is true. + * @default fog + */ + fog: boolean; + + setValues(parameters: PointsMaterialParameters): void; +} diff --git a/src-testing/src/materials/RawShaderMaterial.d.ts b/src-testing/src/materials/RawShaderMaterial.d.ts new file mode 100644 index 000000000..6ff6b67f0 --- /dev/null +++ b/src-testing/src/materials/RawShaderMaterial.d.ts @@ -0,0 +1,12 @@ +import { ShaderMaterial, ShaderMaterialParameters } from "./ShaderMaterial.js"; + +export class RawShaderMaterial extends ShaderMaterial { + constructor(parameters?: ShaderMaterialParameters); + + /** + * Read-only flag to check if a given object is of type {@link RawShaderMaterial}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isRawShaderMaterial: true; +} diff --git a/src-testing/src/materials/ShaderMaterial.d.ts b/src-testing/src/materials/ShaderMaterial.d.ts new file mode 100644 index 000000000..53e07a821 --- /dev/null +++ b/src-testing/src/materials/ShaderMaterial.d.ts @@ -0,0 +1,162 @@ +import { GLSLVersion } from "../constants.js"; +import { JSONMeta } from "../core/Object3D.js"; +import { UniformsGroup } from "../core/UniformsGroup.js"; +import { Matrix3, Matrix3Tuple } from "../math/Matrix3.js"; +import { Matrix4, Matrix4Tuple } from "../math/Matrix4.js"; +import { Vector2Tuple } from "../math/Vector2.js"; +import { Vector3Tuple } from "../math/Vector3.js"; +import { Vector4Tuple } from "../math/Vector4.js"; +import { IUniform } from "../renderers/shaders/UniformsLib.js"; +import { Material, MaterialJSON, MaterialParameters } from "./Material.js"; + +export interface ShaderMaterialParameters extends MaterialParameters { + uniforms?: { [uniform: string]: IUniform } | undefined; + uniformsGroups?: UniformsGroup[] | undefined; + vertexShader?: string | undefined; + fragmentShader?: string | undefined; + linewidth?: number | undefined; + wireframe?: boolean | undefined; + wireframeLinewidth?: number | undefined; + lights?: boolean | undefined; + clipping?: boolean | undefined; + fog?: boolean | undefined; + extensions?: + | { + clipCullDistance?: boolean | undefined; + multiDraw?: boolean | undefined; + } + | undefined; + glslVersion?: GLSLVersion | undefined; +} + +export type ShaderMaterialUniformJSON = { + type: "t"; + value: string; +} | { + type: "c"; + value: number; +} | { + type: "v2"; + value: Vector2Tuple; +} | { + type: "v3"; + value: Vector3Tuple; +} | { + type: "v4"; + value: Vector4Tuple; +} | { + type: "m3"; + value: Matrix3Tuple; +} | { + type: "m4"; + value: Matrix4Tuple; +} | { + value: unknown; +}; + +export interface ShaderMaterialJSON extends MaterialJSON { + glslVersion: number | null; + uniforms: Record; + + defines?: Record; + + vertexShader: string; + ragmentShader: string; + + lights: boolean; + clipping: boolean; + + extensions?: Record; +} + +export class ShaderMaterial extends Material { + constructor(parameters?: ShaderMaterialParameters); + + /** + * Read-only flag to check if a given object is of type {@link ShaderMaterial}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isShaderMaterial: true; + + /** + * @default {} + */ + defines: { [key: string]: any }; + + /** + * @default {} + */ + uniforms: { [uniform: string]: IUniform }; + + uniformsGroups: UniformsGroup[]; + + vertexShader: string; + + fragmentShader: string; + + /** + * @default 1 + */ + linewidth: number; + + /** + * @default false + */ + wireframe: boolean; + + /** + * @default 1 + */ + wireframeLinewidth: number; + + /** + * @default false + */ + fog: boolean; + + /** + * @default false + */ + lights: boolean; + + /** + * @default false + */ + clipping: boolean; + + /** + * @default { + * clipCullDistance: false, + * multiDraw: false + * } + */ + extensions: { + clipCullDistance: boolean; + multiDraw: boolean; + }; + + /** + * @default { 'color': [ 1, 1, 1 ], 'uv': [ 0, 0 ], 'uv1': [ 0, 0 ] } + */ + defaultAttributeValues: any; + + /** + * @default undefined + */ + index0AttributeName: string | undefined; + + /** + * @default false + */ + uniformsNeedUpdate: boolean; + + /** + * @default null + */ + glslVersion: GLSLVersion | null; + + setValues(parameters: ShaderMaterialParameters): void; + + toJSON(meta?: JSONMeta): ShaderMaterialJSON; +} diff --git a/src-testing/src/materials/ShadowMaterial.d.ts b/src-testing/src/materials/ShadowMaterial.d.ts new file mode 100644 index 000000000..fc7a7ae06 --- /dev/null +++ b/src-testing/src/materials/ShadowMaterial.d.ts @@ -0,0 +1,34 @@ +import { Color, ColorRepresentation } from "../math/Color.js"; +import { Material, MaterialParameters } from "./Material.js"; + +export interface ShadowMaterialParameters extends MaterialParameters { + color?: ColorRepresentation | undefined; + fog?: boolean | undefined; +} + +export class ShadowMaterial extends Material { + constructor(parameters?: ShadowMaterialParameters); + + /** + * Read-only flag to check if a given object is of type {@link ShadowMaterial}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isShadowMaterial: true; + + /** + * @default new THREE.Color( 0x000000 ) + */ + color: Color; + + /** + * @default true + */ + transparent: boolean; + + /** + * Whether the material is affected by fog. Default is true. + * @default fog + */ + fog: boolean; +} diff --git a/src-testing/src/materials/SpriteMaterial.d.ts b/src-testing/src/materials/SpriteMaterial.d.ts new file mode 100644 index 000000000..4fa5db8a0 --- /dev/null +++ b/src-testing/src/materials/SpriteMaterial.d.ts @@ -0,0 +1,61 @@ +import { Color, ColorRepresentation } from "../math/Color.js"; +import { Texture } from "../textures/Texture.js"; +import { Material, MaterialParameters } from "./Material.js"; + +export interface SpriteMaterialParameters extends MaterialParameters { + color?: ColorRepresentation | undefined; + map?: Texture | null | undefined; + alphaMap?: Texture | null | undefined; + rotation?: number | undefined; + sizeAttenuation?: boolean | undefined; + fog?: boolean | undefined; +} + +export class SpriteMaterial extends Material { + constructor(parameters?: SpriteMaterialParameters); + /** + * Read-only flag to check if a given object is of type {@link SpriteMaterial}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isSpriteMaterial: true; + + /** + * @default new THREE.Color( 0xffffff ) + */ + color: Color; + + /** + * @default null + */ + map: Texture | null; + + /** + * @default null + */ + alphaMap: Texture | null; + + /** + * @default 0 + */ + rotation: number; + + /** + * @default true + */ + sizeAttenuation: boolean; + + /** + * @default true + */ + transparent: boolean; + + /** + * Whether the material is affected by fog. Default is true. + * @default fog + */ + fog: boolean; + + setValues(parameters: SpriteMaterialParameters): void; + copy(source: SpriteMaterial): this; +} diff --git a/src-testing/src/materials/nodes/InstancedPointsNodeMaterial.d.ts b/src-testing/src/materials/nodes/InstancedPointsNodeMaterial.d.ts new file mode 100644 index 000000000..9784e7f52 --- /dev/null +++ b/src-testing/src/materials/nodes/InstancedPointsNodeMaterial.d.ts @@ -0,0 +1,33 @@ +import { Color } from "../../math/Color.js"; +import Node from "../../nodes/core/Node.js"; +import { Texture } from "../../textures/Texture.js"; +import { PointsMaterialParameters } from "../PointsMaterial.js"; +import NodeMaterial, { NodeMaterialParameters } from "./NodeMaterial.js"; + +export interface InstancedPointsNodeMaterialParameters extends NodeMaterialParameters, PointsMaterialParameters { + useAlphaToCoverage?: boolean | undefined; + useColor?: boolean | undefined; + pointWidth?: number | undefined; + pointColorNode?: Node | null | undefined; + pointWidthNode?: Node | null | undefined; +} + +declare class InstancedPointsNodeMaterial extends NodeMaterial { + useAlphaToCoverage: boolean; + useColor: boolean | undefined; + pointWidth: number; + pointColorNode: Node | null; + pointWidthNode: Node | null; + + // Properties from LineDashedMaterial + readonly isPointsMaterial: true; + color: Color; + map: Texture | null; + alphaMap: Texture | null; + size: number; + sizeAttenuation: boolean; + + constructor(params?: InstancedPointsNodeMaterialParameters); +} + +export default InstancedPointsNodeMaterial; diff --git a/src-testing/src/materials/nodes/Line2NodeMaterial.d.ts b/src-testing/src/materials/nodes/Line2NodeMaterial.d.ts new file mode 100644 index 000000000..13c65ffd6 --- /dev/null +++ b/src-testing/src/materials/nodes/Line2NodeMaterial.d.ts @@ -0,0 +1,53 @@ +import { Color } from "../../math/Color.js"; +import Node from "../../nodes/core/Node.js"; +import { Texture } from "../../textures/Texture.js"; +import { LineDashedMaterialParameters } from "../LineDashedMaterial.js"; +import NodeMaterial, { NodeMaterialParameters } from "./NodeMaterial.js"; + +export interface Line2NodeMaterialParameters extends NodeMaterialParameters, LineDashedMaterialParameters { + dashed?: boolean | undefined; +} + +export default class Line2NodeMaterial extends NodeMaterial { + lights: boolean; + + // Properties from LineDashedMaterial + readonly isLineDashedMaterial: true; + scale: number; + dashSize: number; + gapSize: number; + + // Properties from LineBasicMaterial + readonly isLineBasicMaterial: true; + color: Color; + fog: boolean; + linewidth: number; + linecap: string; + linejoin: string; + map: Texture | null; + + useAlphaToCoverage: boolean; + useColor: boolean; + useDash: boolean; + useWorldUnits: boolean; + + dashOffset: number; + lineWidth: number; + + lineColorNode: Node | null; + + offsetNode: Node | null; + dashScaleNode: Node | null; + dashSizeNode: Node | null; + gapSizeNode: Node | null; + + constructor(parameters?: Line2NodeMaterialParameters); + + setupShaders(): void; + + get worldUnits(): boolean; + set worldUnits(value: boolean); + + get dashed(): boolean; + set dashed(value: boolean); +} diff --git a/src-testing/src/materials/nodes/LineBasicNodeMaterial.d.ts b/src-testing/src/materials/nodes/LineBasicNodeMaterial.d.ts new file mode 100644 index 000000000..84b8db897 --- /dev/null +++ b/src-testing/src/materials/nodes/LineBasicNodeMaterial.d.ts @@ -0,0 +1,22 @@ +import { Color } from "../../math/Color.js"; +import { Texture } from "../../textures/Texture.js"; +import { LineBasicMaterialParameters } from "../LineBasicMaterial.js"; +import NodeMaterial, { NodeMaterialParameters } from "./NodeMaterial.js"; + +export interface LineBasicNodeMaterialParameters extends NodeMaterialParameters, LineBasicMaterialParameters { +} + +export default class LineBasicNodeMaterial extends NodeMaterial { + readonly isLineBasicNodeMaterial: true; + + // Properties from LineBasicMaterial + readonly isLineBasicMaterial: true; + color: Color; + fog: boolean; + linewidth: number; + linecap: string; + linejoin: string; + map: Texture | null; + + constructor(parameters?: LineBasicNodeMaterialParameters); +} diff --git a/src-testing/src/materials/nodes/LineDashedNodeMaterial.d.ts b/src-testing/src/materials/nodes/LineDashedNodeMaterial.d.ts new file mode 100644 index 000000000..10715e2cd --- /dev/null +++ b/src-testing/src/materials/nodes/LineDashedNodeMaterial.d.ts @@ -0,0 +1,29 @@ +import Node from "../../nodes/core/Node.js"; +import { LineDashedMaterialParameters } from "../LineDashedMaterial.js"; +import NodeMaterial, { NodeMaterialParameters } from "./NodeMaterial.js"; + +export interface LineDashedNodeMaterialParameters extends NodeMaterialParameters, LineDashedMaterialParameters { + offsetNode?: Node | null | undefined; + dashScaleNode?: Node | null | undefined; + dashSizeNode?: Node | null | undefined; + gapSizeNode?: Node | null | undefined; +} + +declare class LineDashedNodeMaterial extends NodeMaterial { + readonly isLineDashedNodeMaterial: true; + + offsetNode: Node | null; + dashScaleNode: Node | null; + dashSizeNode: Node | null; + gapSizeNode: Node | null; + + // Properties from LineDashedMaterial + readonly isLineDashedMaterial: true; + scale: number; + dashSize: number; + gapSize: number; + + constructor(parameters?: LineDashedMaterialParameters); +} + +export default LineDashedNodeMaterial; diff --git a/src-testing/src/materials/nodes/MeshBasicNodeMaterial.d.ts b/src-testing/src/materials/nodes/MeshBasicNodeMaterial.d.ts new file mode 100644 index 000000000..515fa5f67 --- /dev/null +++ b/src-testing/src/materials/nodes/MeshBasicNodeMaterial.d.ts @@ -0,0 +1,36 @@ +import { Combine } from "../../constants.js"; +import { Color } from "../../math/Color.js"; +import { Euler } from "../../math/Euler.js"; +import { Texture } from "../../textures/Texture.js"; +import { MeshBasicMaterialParameters } from "../MeshBasicMaterial.js"; +import NodeMaterial, { NodeMaterialParameters } from "./NodeMaterial.js"; + +export interface MeshBasicNodeMaterialParameters extends NodeMaterialParameters, MeshBasicMaterialParameters { +} + +export default class MeshBasicNodeMaterial extends NodeMaterial { + readonly isMeshBasicNodeMaterial: true; + + // Properties from MeshBasicMaterial + readonly isMeshBasicMaterial: true; + color: Color; + map: Texture | null; + lightMap: Texture | null; + lightMapIntensity: number; + aoMap: Texture | null; + aoMapIntensity: number; + specularMap: Texture | null; + alphaMap: Texture | null; + envMap: Texture | null; + envMapRotation: Euler; + combine: Combine; + reflectivity: number; + refractionRatio: number; + wireframe: boolean; + wireframeLinewidth: number; + wireframeLinecap: string; + wireframeLinejoin: string; + fog: boolean; + + constructor(parameters?: MeshBasicNodeMaterialParameters); +} diff --git a/src-testing/src/materials/nodes/MeshLambertNodeMaterial.d.ts b/src-testing/src/materials/nodes/MeshLambertNodeMaterial.d.ts new file mode 100644 index 000000000..aedda10a7 --- /dev/null +++ b/src-testing/src/materials/nodes/MeshLambertNodeMaterial.d.ts @@ -0,0 +1,49 @@ +import { Combine, NormalMapTypes } from "../../constants.js"; +import { Color } from "../../math/Color.js"; +import { Euler } from "../../math/Euler.js"; +import { Vector2 } from "../../math/Vector2.js"; +import { Texture } from "../../textures/Texture.js"; +import { MeshLambertMaterialParameters } from "../MeshLambertMaterial.js"; +import NodeMaterial, { NodeMaterialParameters } from "./NodeMaterial.js"; + +export interface MeshLambertNodeMaterialParameters extends NodeMaterialParameters, MeshLambertMaterialParameters {} + +declare class MeshLambertNodeMaterial extends NodeMaterial { + readonly isMeshLambertNodeMaterial: true; + + // Properties from MeshLambertMaterial + readonly isMeshLambertMaterial: true; + color: Color; + bumpMap: Texture | null; + bumpScale: number; + displacementMap: Texture | null; + displacementScale: number; + displacementBias: number; + emissive: Color; + emissiveIntensity: number; + emissiveMap: Texture | null; + flatShading: boolean; + map: Texture | null; + lightMap: Texture | null; + lightMapIntensity: number; + normalMap: Texture | null; + normalMapType: NormalMapTypes; + normalScale: Vector2; + aoMap: Texture | null; + aoMapIntensity: number; + specularMap: Texture | null; + alphaMap: Texture | null; + envMap: Texture | null; + envMapRotation: Euler; + combine: Combine; + reflectivity: number; + refractionRatio: number; + wireframe: boolean; + wireframeLinewidth: number; + wireframeLinecap: string; + wireframeLinejoin: string; + + constructor(parameters?: MeshLambertNodeMaterialParameters); +} + +export default MeshLambertNodeMaterial; diff --git a/src-testing/src/materials/nodes/MeshMatcapNodeMaterial.d.ts b/src-testing/src/materials/nodes/MeshMatcapNodeMaterial.d.ts new file mode 100644 index 000000000..cc0d2f9a0 --- /dev/null +++ b/src-testing/src/materials/nodes/MeshMatcapNodeMaterial.d.ts @@ -0,0 +1,32 @@ +import { NormalMapTypes } from "../../constants.js"; +import { Color } from "../../math/Color.js"; +import { Vector2 } from "../../math/Vector2.js"; +import { Texture } from "../../textures/Texture.js"; +import { MeshMatcapMaterialParameters } from "../MeshMatcapMaterial.js"; +import NodeMaterial, { NodeMaterialParameters } from "./NodeMaterial.js"; + +export interface MeshMatcapNodeMaterialParameters extends NodeMaterialParameters, MeshMatcapMaterialParameters { +} + +export default class MeshMatcapNodeMaterial extends NodeMaterial { + readonly isMeshMatcapNodeMaterial: true; + + // Properties from MeshMatcapMaterial + readonly isMeshMatcapMaterial: true; + color: Color; + matcap: Texture | null; + map: Texture | null; + bumpMap: Texture | null; + bumpScale: number; + normalMap: Texture | null; + normalMapType: NormalMapTypes; + normalScale: Vector2; + displacementMap: Texture | null; + displacementScale: number; + displacementBias: number; + alphaMap: Texture | null; + flatShading: boolean; + fog: boolean; + + constructor(parameters?: MeshMatcapNodeMaterialParameters); +} diff --git a/src-testing/src/materials/nodes/MeshNormalNodeMaterial.d.ts b/src-testing/src/materials/nodes/MeshNormalNodeMaterial.d.ts new file mode 100644 index 000000000..761998bac --- /dev/null +++ b/src-testing/src/materials/nodes/MeshNormalNodeMaterial.d.ts @@ -0,0 +1,28 @@ +import { NormalMapTypes } from "../../constants.js"; +import { Vector2 } from "../../math/Vector2.js"; +import { Texture } from "../../textures/Texture.js"; +import { MeshNormalMaterialParameters } from "../MeshNormalMaterial.js"; +import NodeMaterial, { NodeMaterialParameters } from "./NodeMaterial.js"; + +export interface MeshBasicNodeMaterialParameters extends NodeMaterialParameters, MeshNormalMaterialParameters { +} + +export default class MeshNormalNodeMaterial extends NodeMaterial { + readonly isMeshNormalNodeMaterial: true; + + // Properties from MeshNormalMaterial + readonly isMeshNormalMaterial: true; + bumpMap: Texture | null; + bumpScale: number; + normalMap: Texture | null; + normalMapType: NormalMapTypes; + normalScale: Vector2; + displacementMap: Texture | null; + displacementScale: number; + displacementBias: number; + wireframe: boolean; + wireframeLinewidth: number; + flatShading: boolean; + + constructor(parameters?: MeshBasicNodeMaterialParameters); +} diff --git a/src-testing/src/materials/nodes/MeshPhongNodeMaterial.d.ts b/src-testing/src/materials/nodes/MeshPhongNodeMaterial.d.ts new file mode 100644 index 000000000..3680e533c --- /dev/null +++ b/src-testing/src/materials/nodes/MeshPhongNodeMaterial.d.ts @@ -0,0 +1,56 @@ +import { Combine, NormalMapTypes } from "../../constants.js"; +import { Color } from "../../math/Color.js"; +import { Euler } from "../../math/Euler.js"; +import { Vector2 } from "../../math/Vector2.js"; +import Node from "../../nodes/core/Node.js"; +import { Texture } from "../../textures/Texture.js"; +import { MeshPhongMaterialParameters } from "../MeshPhongMaterial.js"; +import NodeMaterial, { NodeMaterialParameters } from "./NodeMaterial.js"; + +export interface MeshPhongNodeMaterialParameters extends NodeMaterialParameters, MeshPhongMaterialParameters { +} + +export default class MeshPhongNodeMaterial extends NodeMaterial { + readonly isMeshPhongNodeMaterial: true; + + shininessNode: Node | null; + specularNode: Node | null; + + // Properties from MeshPhongMaterial + readonly isMeshPhongMaterial: true; + color: Color; + specular: Color; + shininess: number; + map: Texture | null; + lightMap: Texture | null; + lightMapIntensity: number; + aoMap: Texture | null; + aoMapIntensity: number; + emissive: Color; + emissiveIntensity: number; + emissiveMap: Texture | null; + bumpMap: Texture | null; + bumpScale: number; + normalMap: Texture | null; + normalMapType: NormalMapTypes; + normalScale: Vector2; + displacementMap: Texture | null; + displacementScale: number; + displacementBias: number; + specularMap: Texture | null; + alphaMap: Texture | null; + envMap: Texture | null; + envMapRotation: Euler; + combine: Combine; + reflectivity: number; + refractionRatio: number; + wireframe: boolean; + wireframeLinewidth: number; + wireframeLinecap: string; + wireframeLinejoin: string; + flatShading: boolean; + metal: boolean; + fog: boolean; + + constructor(parameters?: MeshPhongNodeMaterialParameters); +} diff --git a/src-testing/src/materials/nodes/MeshPhysicalNodeMaterial.d.ts b/src-testing/src/materials/nodes/MeshPhysicalNodeMaterial.d.ts new file mode 100644 index 000000000..e7da3ee90 --- /dev/null +++ b/src-testing/src/materials/nodes/MeshPhysicalNodeMaterial.d.ts @@ -0,0 +1,93 @@ +import { Color } from "../../math/Color.js"; +import { Vector2 } from "../../math/Vector2.js"; +import Node from "../../nodes/core/Node.js"; +import { ShaderNodeObject } from "../../nodes/tsl/TSLCore.js"; +import { Texture } from "../../textures/Texture.js"; +import { MeshPhysicalMaterialParameters } from "../MeshPhysicalMaterial.js"; +import MeshStandardNodeMaterial, { MeshStandardNodeMaterialParameters } from "./MeshStandardNodeMaterial.js"; + +export interface MeshPhysicalNodeMaterialParameters + extends MeshStandardNodeMaterialParameters, MeshPhysicalMaterialParameters +{ +} + +export default class MeshPhysicalNodeMaterial extends MeshStandardNodeMaterial { + readonly isMeshPhysicalNodeMaterial: true; + + clearcoatNode: Node | null; + clearcoatRoughnessNode: Node | null; + clearcoatNormalNode: Node | null; + + sheenNode: Node | null; + sheenRoughnessNode: Node | null; + + iridescenceNode: Node | null; + iridescenceIORNode: Node | null; + iridescenceThicknessNode: Node | null; + + iorNode: Node | null; + + specularIntensityNode: Node | null; + specularColorNode: Node | null; + + transmissionNode: Node | null; + thicknessNode: Node | null; + attenuationDistanceNode: Node | null; + attenuationColorNode: Node | null; + dispersionNode: Node | null; + + anisotropyNode: Node | null; + + // Properties from MeshPhysicalMaterial + readonly isMeshPhysicalMaterial: true; + anisotropyRotation: number; + anisotropyMap: Texture | null; + clearcoatMap: Texture | null; + clearcoatRoughness: number; + clearcoatRoughnessMap: Texture | null; + clearcoatNormalScale: Vector2; + clearcoatNormalMap: Texture | null; + ior: number; + get reflectivity(): number; + set reflectivity(reflectivity: number); + iridescenceMap: Texture | null; + iridescenceIOR: number; + iridescenceThicknessRange: [number, number]; + iridescenceThicknessMap: Texture | null; + sheenColor: Color; + sheenColorMap: Texture | null; + sheenRoughness: number; + sheenRoughnessMap: Texture | null; + transmissionMap: Texture | null; + thickness: number; + thicknessMap: Texture | null; + attenuationDistance: number; + attenuationColor: Color; + specularIntensity: number; + specularIntensityMap: Texture | null; + specularColor: Color; + specularColorMap: Texture | null; + get anisotropy(): number; + set anisotropy(value: number); + get clearcoat(): number; + set clearcoat(value: number); + get iridescence(): number; + set iridescence(value: number); + get dispersion(): number; + set dispersion(value: number); + get sheen(): number; + set sheen(value: number); + get transmission(): number; + set transmission(value: number); + + constructor(parameters?: MeshPhysicalNodeMaterialParameters); + + get useClearcoat(): boolean; + get useIridescence(): boolean; + get useSheen(): boolean; + get useAnisotropy(): boolean; + get useTransmission(): boolean; + get useDispersion(): boolean; + + setupClearcoatNormal(): ShaderNodeObject; +} diff --git a/src-testing/src/materials/nodes/MeshSSSNodeMaterial.d.ts b/src-testing/src/materials/nodes/MeshSSSNodeMaterial.d.ts new file mode 100644 index 000000000..bccbec30c --- /dev/null +++ b/src-testing/src/materials/nodes/MeshSSSNodeMaterial.d.ts @@ -0,0 +1,16 @@ +import ConstNode from "../../nodes/core/ConstNode.js"; +import Node from "../../nodes/core/Node.js"; +import MeshPhysicalNodeMaterial, { MeshPhysicalNodeMaterialParameters } from "./MeshPhysicalNodeMaterial.js"; + +export default class MeshSSSNodeMaterial extends MeshPhysicalNodeMaterial { + thicknessColorNode: Node | null; + thicknessDistortionNode: ConstNode; + thicknessAmbientNode: ConstNode; + thicknessAttenuationNode: ConstNode; + thicknessPowerNode: ConstNode; + thicknessScaleNode: ConstNode; + + constructor(parameters?: MeshPhysicalNodeMaterialParameters); + + get useSSS(): boolean; +} diff --git a/src-testing/src/materials/nodes/MeshStandardNodeMaterial.d.ts b/src-testing/src/materials/nodes/MeshStandardNodeMaterial.d.ts new file mode 100644 index 000000000..9c3329042 --- /dev/null +++ b/src-testing/src/materials/nodes/MeshStandardNodeMaterial.d.ts @@ -0,0 +1,56 @@ +import { NormalMapTypes } from "../../constants.js"; +import { Color } from "../../math/Color.js"; +import { Euler } from "../../math/Euler.js"; +import { Vector2 } from "../../math/Vector2.js"; +import Node from "../../nodes/core/Node.js"; +import { Texture } from "../../textures/Texture.js"; +import { MeshStandardMaterialParameters } from "../MeshStandardMaterial.js"; +import NodeMaterial, { NodeMaterialParameters } from "./NodeMaterial.js"; + +export interface MeshStandardNodeMaterialParameters extends NodeMaterialParameters, MeshStandardMaterialParameters { +} + +export default class MeshStandardNodeMaterial extends NodeMaterial { + readonly isMeshStandardNodeMaterial: true; + + emissiveNode: Node | null; + + metalnessNode: Node | null; + roughnessNode: Node | null; + + // Properties from MeshStandardMaterial + readonly isMeshStandardMaterial: true; + color: Color; + roughness: number; + metalness: number; + map: Texture | null; + lightMap: Texture | null; + lightMapIntensity: number; + aoMap: Texture | null; + aoMapIntensity: number; + emissive: Color; + emissiveIntensity: number; + emissiveMap: Texture | null; + bumpMap: Texture | null; + bumpScale: number; + normalMap: Texture | null; + normalMapType: NormalMapTypes; + normalScale: Vector2; + displacementMap: Texture | null; + displacementScale: number; + displacementBias: number; + roughnessMap: Texture | null; + metalnessMap: Texture | null; + alphaMap: Texture | null; + envMap: Texture | null; + envMapRotation: Euler; + envMapIntensity: number; + wireframe: boolean; + wireframeLinewidth: number; + wireframeLinecap: string; + wireframeLinejoin: string; + flatShading: boolean; + fog: boolean; + + constructor(parameters?: MeshStandardNodeMaterialParameters); +} diff --git a/src-testing/src/materials/nodes/MeshToonNodeMaterial.d.ts b/src-testing/src/materials/nodes/MeshToonNodeMaterial.d.ts new file mode 100644 index 000000000..e1dee0fb3 --- /dev/null +++ b/src-testing/src/materials/nodes/MeshToonNodeMaterial.d.ts @@ -0,0 +1,42 @@ +import { NormalMapTypes } from "../../constants.js"; +import { Color } from "../../math/Color.js"; +import { Vector2 } from "../../math/Vector2.js"; +import { Texture } from "../../textures/Texture.js"; +import { MeshToonMaterialParameters } from "../MeshToonMaterial.js"; +import NodeMaterial, { NodeMaterialParameters } from "./NodeMaterial.js"; + +export interface MeshToonNodeMaterialParameters extends NodeMaterialParameters, MeshToonMaterialParameters { +} + +export default class MeshToonNodeMaterial extends NodeMaterial { + readonly isMeshToonNodeMaterial: true; + + // Properties from MeshToonMaterial + readonly isMeshToonMaterial: true; + color: Color; + gradientMap: Texture | null; + map: Texture | null; + lightMap: Texture | null; + lightMapIntensity: number; + aoMap: Texture | null; + aoMapIntensity: number; + emissive: Color; + emissiveIntensity: number; + emissiveMap: Texture | null; + bumpMap: Texture | null; + bumpScale: number; + normalMap: Texture | null; + normalMapType: NormalMapTypes; + normalScale: Vector2; + displacementMap: Texture | null; + displacementScale: number; + displacementBias: number; + alphaMap: Texture | null; + wireframe: boolean; + wireframeLinewidth: number; + wireframeLinecap: string; + wireframeLinejoin: string; + fog: boolean; + + constructor(parameters?: MeshToonNodeMaterialParameters); +} diff --git a/src-testing/src/materials/nodes/NodeMaterial.ts b/src-testing/src/materials/nodes/NodeMaterial.ts new file mode 100644 index 000000000..3c77c74e6 --- /dev/null +++ b/src-testing/src/materials/nodes/NodeMaterial.ts @@ -0,0 +1,535 @@ +import { Material } from '../Material.js'; +import { NormalBlending } from '../../constants.js'; + +import { getNodeChildren, getCacheKey } from '../../nodes/core/NodeUtils.js'; +import { attribute } from '../../nodes/core/AttributeNode.js'; +import { output, diffuseColor, emissive, varyingProperty } from '../../nodes/core/PropertyNode.js'; +import { + materialAlphaTest, + materialColor, + materialOpacity, + materialEmissive, + materialNormal, + materialLightMap, + materialAOMap, +} from '../../nodes/accessors/MaterialNode.js'; +import { modelViewProjection } from '../../nodes/accessors/ModelViewProjectionNode.js'; +import { normalLocal } from '../../nodes/accessors/Normal.js'; +import { instance } from '../../nodes/accessors/InstanceNode.js'; +import { batch } from '../../nodes/accessors/BatchNode.js'; +import { materialReference } from '../../nodes/accessors/MaterialReferenceNode.js'; +import { positionLocal, positionView } from '../../nodes/accessors/Position.js'; +import { skinningReference } from '../../nodes/accessors/SkinningNode.js'; +import { morphReference } from '../../nodes/accessors/MorphNode.js'; +import { mix } from '../../nodes/math/MathNode.js'; +import { float, vec3, vec4 } from '../../nodes/tsl/TSLBase.js'; +import AONode from '../../nodes/lighting/AONode.js'; +import { lightingContext } from '../../nodes/lighting/LightingContextNode.js'; +import IrradianceNode from '../../nodes/lighting/IrradianceNode.js'; +import { + depth, + perspectiveDepthToLogarithmicDepth, + viewZToOrthographicDepth, +} from '../../nodes/display/ViewportDepthNode.js'; +import { cameraFar, cameraNear } from '../../nodes/accessors/Camera.js'; +import { clipping, clippingAlpha } from '../../nodes/accessors/ClippingNode.js'; +import NodeMaterialObserver from './manager/NodeMaterialObserver.js'; + +class NodeMaterial extends Material { + static get type() { + return 'NodeMaterial'; + } + + constructor() { + super(); + + this.isNodeMaterial = true; + + this.type = this.constructor.type; + + this.forceSinglePass = false; + + this.fog = true; + this.lights = false; + + this.lightsNode = null; + this.envNode = null; + this.aoNode = null; + + this.colorNode = null; + this.normalNode = null; + this.opacityNode = null; + this.backdropNode = null; + this.backdropAlphaNode = null; + this.alphaTestNode = null; + + this.positionNode = null; + this.geometryNode = null; + + this.depthNode = null; + this.shadowNode = null; + this.shadowPositionNode = null; + + this.outputNode = null; + this.mrtNode = null; + + this.fragmentNode = null; + this.vertexNode = null; + } + + customProgramCacheKey() { + return this.type + getCacheKey(this); + } + + build(builder) { + this.setup(builder); + } + + setupObserver(builder) { + return new NodeMaterialObserver(builder); + } + + setup(builder) { + builder.context.setupNormal = () => this.setupNormal(builder); + + // < VERTEX STAGE > + + builder.addStack(); + + builder.stack.outputNode = this.vertexNode || this.setupPosition(builder); + + if (this.geometryNode !== null) { + builder.stack.outputNode = builder.stack.outputNode.bypass(this.geometryNode); + } + + builder.addFlow('vertex', builder.removeStack()); + + // < FRAGMENT STAGE > + + builder.addStack(); + + let resultNode; + + const clippingNode = this.setupClipping(builder); + + if (this.depthWrite === true) this.setupDepth(builder); + + if (this.fragmentNode === null) { + this.setupDiffuseColor(builder); + this.setupVariants(builder); + + const outgoingLightNode = this.setupLighting(builder); + + if (clippingNode !== null) builder.stack.add(clippingNode); + + // force unsigned floats - useful for RenderTargets + + const basicOutput = vec4(outgoingLightNode, diffuseColor.a).max(0); + + resultNode = this.setupOutput(builder, basicOutput); + + // OUTPUT NODE + + output.assign(resultNode); + + // + + if (this.outputNode !== null) resultNode = this.outputNode; + + // MRT + + const renderTarget = builder.renderer.getRenderTarget(); + + if (renderTarget !== null) { + const mrt = builder.renderer.getMRT(); + const materialMRT = this.mrtNode; + + if (mrt !== null) { + resultNode = mrt; + + if (materialMRT !== null) { + resultNode = mrt.merge(materialMRT); + } + } else if (materialMRT !== null) { + resultNode = materialMRT; + } + } + } else { + let fragmentNode = this.fragmentNode; + + if (fragmentNode.isOutputStructNode !== true) { + fragmentNode = vec4(fragmentNode); + } + + resultNode = this.setupOutput(builder, fragmentNode); + } + + builder.stack.outputNode = resultNode; + + builder.addFlow('fragment', builder.removeStack()); + + // < MONITOR > + + builder.monitor = this.setupObserver(builder); + } + + setupClipping(builder) { + if (builder.clippingContext === null) return null; + + const { globalClippingCount, localClippingCount } = builder.clippingContext; + + let result = null; + + if (globalClippingCount || localClippingCount) { + const samples = builder.renderer.samples; + + if (this.alphaToCoverage && samples > 1) { + // to be added to flow when the color/alpha value has been determined + result = clippingAlpha(); + } else { + builder.stack.add(clipping()); + } + } + + return result; + } + + setupDepth(builder) { + const { renderer, camera } = builder; + + // Depth + + let depthNode = this.depthNode; + + if (depthNode === null) { + const mrt = renderer.getMRT(); + + if (mrt && mrt.has('depth')) { + depthNode = mrt.get('depth'); + } else if (renderer.logarithmicDepthBuffer === true) { + if (camera.isPerspectiveCamera) { + depthNode = perspectiveDepthToLogarithmicDepth(modelViewProjection().w, cameraNear, cameraFar); + } else { + depthNode = viewZToOrthographicDepth(positionView.z, cameraNear, cameraFar); + } + } + } + + if (depthNode !== null) { + depth.assign(depthNode).append(); + } + } + + setupPosition(builder) { + const { object } = builder; + const geometry = object.geometry; + + builder.addStack(); + + // Vertex + + if (geometry.morphAttributes.position || geometry.morphAttributes.normal || geometry.morphAttributes.color) { + morphReference(object).append(); + } + + if (object.isSkinnedMesh === true) { + skinningReference(object).append(); + } + + if (this.displacementMap) { + const displacementMap = materialReference('displacementMap', 'texture'); + const displacementScale = materialReference('displacementScale', 'float'); + const displacementBias = materialReference('displacementBias', 'float'); + + positionLocal.addAssign( + normalLocal.normalize().mul(displacementMap.x.mul(displacementScale).add(displacementBias)), + ); + } + + if (object.isBatchedMesh) { + batch(object).append(); + } + + if (object.instanceMatrix && object.instanceMatrix.isInstancedBufferAttribute === true) { + instance(object).append(); + } + + if (this.positionNode !== null) { + positionLocal.assign(this.positionNode); + } + + const mvp = modelViewProjection(); + + builder.context.vertex = builder.removeStack(); + builder.context.mvp = mvp; + + return mvp; + } + + setupDiffuseColor({ object, geometry }) { + let colorNode = this.colorNode ? vec4(this.colorNode) : materialColor; + + // VERTEX COLORS + + if (this.vertexColors === true && geometry.hasAttribute('color')) { + colorNode = vec4(colorNode.xyz.mul(attribute('color', 'vec3')), colorNode.a); + } + + // Instanced colors + + if (object.instanceColor) { + const instanceColor = varyingProperty('vec3', 'vInstanceColor'); + + colorNode = instanceColor.mul(colorNode); + } + + if (object.isBatchedMesh && object._colorsTexture) { + const batchColor = varyingProperty('vec3', 'vBatchColor'); + + colorNode = batchColor.mul(colorNode); + } + + // COLOR + + diffuseColor.assign(colorNode); + + // OPACITY + + const opacityNode = this.opacityNode ? float(this.opacityNode) : materialOpacity; + diffuseColor.a.assign(diffuseColor.a.mul(opacityNode)); + + // ALPHA TEST + + if (this.alphaTestNode !== null || this.alphaTest > 0) { + const alphaTestNode = this.alphaTestNode !== null ? float(this.alphaTestNode) : materialAlphaTest; + + diffuseColor.a.lessThanEqual(alphaTestNode).discard(); + } + + if (this.transparent === false && this.blending === NormalBlending && this.alphaToCoverage === false) { + diffuseColor.a.assign(1.0); + } + } + + setupVariants(/*builder*/) { + // Interface function. + } + + setupOutgoingLight() { + return this.lights === true ? vec3(0) : diffuseColor.rgb; + } + + setupNormal() { + return this.normalNode ? vec3(this.normalNode) : materialNormal; + } + + setupEnvironment(/*builder*/) { + let node = null; + + if (this.envNode) { + node = this.envNode; + } else if (this.envMap) { + node = this.envMap.isCubeTexture + ? materialReference('envMap', 'cubeTexture') + : materialReference('envMap', 'texture'); + } + + return node; + } + + setupLightMap(builder) { + let node = null; + + if (builder.material.lightMap) { + node = new IrradianceNode(materialLightMap); + } + + return node; + } + + setupLights(builder) { + const materialLightsNode = []; + + // + + const envNode = this.setupEnvironment(builder); + + if (envNode && envNode.isLightingNode) { + materialLightsNode.push(envNode); + } + + const lightMapNode = this.setupLightMap(builder); + + if (lightMapNode && lightMapNode.isLightingNode) { + materialLightsNode.push(lightMapNode); + } + + if (this.aoNode !== null || builder.material.aoMap) { + const aoNode = this.aoNode !== null ? this.aoNode : materialAOMap; + + materialLightsNode.push(new AONode(aoNode)); + } + + let lightsN = this.lightsNode || builder.lightsNode; + + if (materialLightsNode.length > 0) { + lightsN = builder.renderer.lighting.createNode([...lightsN.getLights(), ...materialLightsNode]); + } + + return lightsN; + } + + setupLightingModel(/*builder*/) { + // Interface function. + } + + setupLighting(builder) { + const { material } = builder; + const { backdropNode, backdropAlphaNode, emissiveNode } = this; + + // OUTGOING LIGHT + + const lights = this.lights === true || this.lightsNode !== null; + + const lightsNode = lights ? this.setupLights(builder) : null; + + let outgoingLightNode = this.setupOutgoingLight(builder); + + if (lightsNode && lightsNode.getScope().hasLights) { + const lightingModel = this.setupLightingModel(builder); + + outgoingLightNode = lightingContext(lightsNode, lightingModel, backdropNode, backdropAlphaNode); + } else if (backdropNode !== null) { + outgoingLightNode = vec3( + backdropAlphaNode !== null ? mix(outgoingLightNode, backdropNode, backdropAlphaNode) : backdropNode, + ); + } + + // EMISSIVE + + if ( + (emissiveNode && emissiveNode.isNode === true) || + (material.emissive && material.emissive.isColor === true) + ) { + emissive.assign(vec3(emissiveNode ? emissiveNode : materialEmissive)); + + outgoingLightNode = outgoingLightNode.add(emissive); + } + + return outgoingLightNode; + } + + setupOutput(builder, outputNode) { + // FOG + + if (this.fog === true) { + const fogNode = builder.fogNode; + + if (fogNode) outputNode = vec4(fogNode.mix(outputNode.rgb, fogNode.colorNode), outputNode.a); + } + + return outputNode; + } + + setDefaultValues(material) { + // This approach is to reuse the native refreshUniforms* + // and turn available the use of features like transmission and environment in core + + for (const property in material) { + const value = material[property]; + + if (this[property] === undefined) { + this[property] = value; + + if (value && value.clone) this[property] = value.clone(); + } + } + + const descriptors = Object.getOwnPropertyDescriptors(material.constructor.prototype); + + for (const key in descriptors) { + if ( + Object.getOwnPropertyDescriptor(this.constructor.prototype, key) === undefined && + descriptors[key].get !== undefined + ) { + Object.defineProperty(this.constructor.prototype, key, descriptors[key]); + } + } + } + + toJSON(meta) { + const isRoot = meta === undefined || typeof meta === 'string'; + + if (isRoot) { + meta = { + textures: {}, + images: {}, + nodes: {}, + }; + } + + const data = Material.prototype.toJSON.call(this, meta); + const nodeChildren = getNodeChildren(this); + + data.inputNodes = {}; + + for (const { property, childNode } of nodeChildren) { + data.inputNodes[property] = childNode.toJSON(meta).uuid; + } + + // TODO: Copied from Object3D.toJSON + + function extractFromCache(cache) { + const values = []; + + for (const key in cache) { + const data = cache[key]; + delete data.metadata; + values.push(data); + } + + return values; + } + + if (isRoot) { + const textures = extractFromCache(meta.textures); + const images = extractFromCache(meta.images); + const nodes = extractFromCache(meta.nodes); + + if (textures.length > 0) data.textures = textures; + if (images.length > 0) data.images = images; + if (nodes.length > 0) data.nodes = nodes; + } + + return data; + } + + copy(source) { + this.lightsNode = source.lightsNode; + this.envNode = source.envNode; + + this.colorNode = source.colorNode; + this.normalNode = source.normalNode; + this.opacityNode = source.opacityNode; + this.backdropNode = source.backdropNode; + this.backdropAlphaNode = source.backdropAlphaNode; + this.alphaTestNode = source.alphaTestNode; + + this.positionNode = source.positionNode; + this.geometryNode = source.geometryNode; + + this.depthNode = source.depthNode; + this.shadowNode = source.shadowNode; + this.shadowPositionNode = source.shadowPositionNode; + + this.outputNode = source.outputNode; + this.mrtNode = source.mrtNode; + + this.fragmentNode = source.fragmentNode; + this.vertexNode = source.vertexNode; + + return super.copy(source); + } +} + +export default NodeMaterial; diff --git a/src-testing/src/materials/nodes/NodeMaterials.d.ts b/src-testing/src/materials/nodes/NodeMaterials.d.ts new file mode 100644 index 000000000..395273cd9 --- /dev/null +++ b/src-testing/src/materials/nodes/NodeMaterials.d.ts @@ -0,0 +1,18 @@ +export { default as InstancedPointsNodeMaterial } from "./InstancedPointsNodeMaterial.js"; +export { default as Line2NodeMaterial } from "./Line2NodeMaterial.js"; +export { default as LineBasicNodeMaterial } from "./LineBasicNodeMaterial.js"; +export { default as LineDashedNodeMaterial } from "./LineDashedNodeMaterial.js"; +export { default as MeshBasicNodeMaterial } from "./MeshBasicNodeMaterial.js"; +export { default as MeshLambertNodeMaterial } from "./MeshLambertNodeMaterial.js"; +export { default as MeshMatcapNodeMaterial } from "./MeshMatcapNodeMaterial.js"; +export { default as MeshNormalNodeMaterial } from "./MeshNormalNodeMaterial.js"; +export { default as MeshPhongNodeMaterial } from "./MeshPhongNodeMaterial.js"; +export { default as MeshPhysicalNodeMaterial } from "./MeshPhysicalNodeMaterial.js"; +export { default as MeshSSSNodeMaterial } from "./MeshSSSNodeMaterial.js"; +export { default as MeshStandardNodeMaterial } from "./MeshStandardNodeMaterial.js"; +export { default as MeshToonNodeMaterial } from "./MeshToonNodeMaterial.js"; +export { default as NodeMaterial } from "./NodeMaterial.js"; +export { default as PointsNodeMaterial } from "./PointsNodeMaterial.js"; +export { default as ShadowNodeMaterial } from "./ShadowNodeMaterial.js"; +export { default as SpriteNodeMaterial } from "./SpriteNodeMaterial.js"; +export { default as VolumeNodeMaterial } from "./VolumeNodeMaterial.js"; diff --git a/src-testing/src/materials/nodes/PointsNodeMaterial.d.ts b/src-testing/src/materials/nodes/PointsNodeMaterial.d.ts new file mode 100644 index 000000000..836f55a6d --- /dev/null +++ b/src-testing/src/materials/nodes/PointsNodeMaterial.d.ts @@ -0,0 +1,21 @@ +import { Color } from "../../math/Color.js"; +import { Texture } from "../../textures/Texture.js"; +import { PointsMaterialParameters } from "../PointsMaterial.js"; +import NodeMaterial, { NodeMaterialParameters } from "./NodeMaterial.js"; + +export interface PointsNodeMaterialParameters extends NodeMaterialParameters, PointsMaterialParameters { +} + +export default class PointsNodeMaterial extends NodeMaterial { + readonly isPointsNodeMaterial: true; + + // Properties from PointsMaterial + readonly isPointsMaterial: true; + color: Color; + map: Texture | null; + alphaMap: Texture | null; + size: number; + sizeAttenuation: boolean; + + constructor(parameters?: PointsNodeMaterialParameters); +} diff --git a/src-testing/src/materials/nodes/ShadowNodeMaterial.d.ts b/src-testing/src/materials/nodes/ShadowNodeMaterial.d.ts new file mode 100644 index 000000000..c53d92437 --- /dev/null +++ b/src-testing/src/materials/nodes/ShadowNodeMaterial.d.ts @@ -0,0 +1,17 @@ +import { Color } from "../../math/Color.js"; +import { ShadowMaterialParameters } from "../ShadowMaterial.js"; +import NodeMaterial, { NodeMaterialParameters } from "./NodeMaterial.js"; + +export interface ShadowNodeMaterialParameters extends NodeMaterialParameters, ShadowMaterialParameters { +} + +export default class ShadowNodeMaterial extends NodeMaterial { + readonly isShadowNodeMaterial: true; + + // Properties from ShadowMaterial + readonly isShadowMaterial: true; + color: Color; + fog: boolean; + + constructor(parameters?: ShadowNodeMaterialParameters); +} diff --git a/src-testing/src/materials/nodes/SpriteNodeMaterial.d.ts b/src-testing/src/materials/nodes/SpriteNodeMaterial.d.ts new file mode 100644 index 000000000..e34845d78 --- /dev/null +++ b/src-testing/src/materials/nodes/SpriteNodeMaterial.d.ts @@ -0,0 +1,26 @@ +import { Color } from "../../math/Color.js"; +import Node from "../../nodes/core/Node.js"; +import { Texture } from "../../textures/Texture.js"; +import { SpriteMaterialParameters } from "../SpriteMaterial.js"; +import NodeMaterial, { NodeMaterialParameters } from "./NodeMaterial.js"; + +export interface SpriteNodeMaterialParameters extends NodeMaterialParameters, SpriteMaterialParameters { +} + +export default class SpriteNodeMaterial extends NodeMaterial { + isSpriteNodeMaterial: true; + + rotationNode: Node | null; + scaleNode: Node | null; + + // Properties from SpriteMaterial + readonly isSpriteMaterial: true; + color: Color; + map: Texture | null; + alphaMap: Texture | null; + rotation: number; + sizeAttenuation: boolean; + fog: boolean; + + constructor(parameters?: SpriteNodeMaterialParameters); +} diff --git a/src-testing/src/materials/nodes/VolumeNodeMaterial.d.ts b/src-testing/src/materials/nodes/VolumeNodeMaterial.d.ts new file mode 100644 index 000000000..4f2c6e260 --- /dev/null +++ b/src-testing/src/materials/nodes/VolumeNodeMaterial.d.ts @@ -0,0 +1,10 @@ +import Node from "../../nodes/core/Node.js"; +import NodeMaterial, { NodeMaterialParameters } from "./NodeMaterial.js"; + +export default class VolumeNodeMaterial extends NodeMaterial { + lights: boolean; + readonly isVolumeNodeMaterial: true; + testNode: Node | null; + + constructor(parameters?: NodeMaterialParameters); +} diff --git a/src-testing/src/materials/nodes/manager/NodeMaterialObserver.ts b/src-testing/src/materials/nodes/manager/NodeMaterialObserver.ts new file mode 100644 index 000000000..8ab1a6d67 --- /dev/null +++ b/src-testing/src/materials/nodes/manager/NodeMaterialObserver.ts @@ -0,0 +1,308 @@ +const refreshUniforms = [ + 'alphaMap', + 'alphaTest', + 'anisotropy', + 'anisotropyMap', + 'anisotropyRotation', + 'aoMap', + 'attenuationColor', + 'attenuationDistance', + 'bumpMap', + 'clearcoat', + 'clearcoatMap', + 'clearcoatNormalMap', + 'clearcoatNormalScale', + 'clearcoatRoughness', + 'color', + 'dispersion', + 'displacementMap', + 'emissive', + 'emissiveMap', + 'envMap', + 'gradientMap', + 'ior', + 'iridescence', + 'iridescenceIOR', + 'iridescenceMap', + 'iridescenceThicknessMap', + 'lightMap', + 'map', + 'matcap', + 'metalness', + 'metalnessMap', + 'normalMap', + 'normalScale', + 'opacity', + 'roughness', + 'roughnessMap', + 'sheen', + 'sheenColor', + 'sheenColorMap', + 'sheenRoughnessMap', + 'shininess', + 'specular', + 'specularColor', + 'specularColorMap', + 'specularIntensity', + 'specularIntensityMap', + 'specularMap', + 'thickness', + 'transmission', + 'transmissionMap', +]; + +class NodeMaterialObserver { + constructor(builder) { + this.renderObjects = new WeakMap(); + this.hasNode = this.containsNode(builder); + this.hasAnimation = builder.object.isSkinnedMesh === true; + this.refreshUniforms = refreshUniforms; + this.renderId = 0; + } + + firstInitialization(renderObject) { + const hasInitialized = this.renderObjects.has(renderObject); + + if (hasInitialized === false) { + this.getRenderObjectData(renderObject); + + return true; + } + + return false; + } + + getRenderObjectData(renderObject) { + let data = this.renderObjects.get(renderObject); + + if (data === undefined) { + const { geometry, material } = renderObject; + + data = { + material: this.getMaterialData(material), + geometry: { + attributes: this.getAttributesData(geometry.attributes), + indexVersion: geometry.index ? geometry.index.version : null, + drawRange: { start: geometry.drawRange.start, count: geometry.drawRange.count }, + }, + worldMatrix: renderObject.object.matrixWorld.clone(), + }; + + if (renderObject.object.center) { + data.center = renderObject.object.center.clone(); + } + + if (renderObject.object.morphTargetInfluences) { + data.morphTargetInfluences = renderObject.object.morphTargetInfluences.slice(); + } + + if (renderObject.bundle !== null) { + data.version = renderObject.bundle.version; + } + + this.renderObjects.set(renderObject, data); + } + + return data; + } + + getAttributesData(attributes) { + const attributesData = {}; + + for (const name in attributes) { + const attribute = attributes[name]; + + attributesData[name] = { + version: attribute.version, + }; + } + + return attributesData; + } + + containsNode(builder) { + const material = builder.material; + + for (const property in material) { + if (material[property] && material[property].isNode) return true; + } + + if (builder.renderer.nodes.modelViewMatrix !== null || builder.renderer.nodes.modelNormalViewMatrix !== null) + return true; + + return false; + } + + getMaterialData(material) { + const data = {}; + + for (const property of this.refreshUniforms) { + const value = material[property]; + + if (value === null || value === undefined) continue; + + if (typeof value === 'object' && value.clone !== undefined) { + if (value.isTexture === true) { + data[property] = { id: value.id, version: value.version }; + } else { + data[property] = value.clone(); + } + } else { + data[property] = value; + } + } + + return data; + } + + equals(renderObject) { + const { object, material, geometry } = renderObject; + + const renderObjectData = this.getRenderObjectData(renderObject); + + // world matrix + + if (renderObjectData.worldMatrix.equals(object.matrixWorld) !== true) { + renderObjectData.worldMatrix.copy(object.matrixWorld); + + return false; + } + + // material + + const materialData = renderObjectData.material; + + for (const property in materialData) { + const value = materialData[property]; + const mtlValue = material[property]; + + if (value.equals !== undefined) { + if (value.equals(mtlValue) === false) { + value.copy(mtlValue); + + return false; + } + } else if (mtlValue.isTexture === true) { + if (value.id !== mtlValue.id || value.version !== mtlValue.version) { + value.id = mtlValue.id; + value.version = mtlValue.version; + + return false; + } + } else if (value !== mtlValue) { + materialData[property] = mtlValue; + + return false; + } + } + + // geometry + + const storedGeometryData = renderObjectData.geometry; + const attributes = geometry.attributes; + const storedAttributes = storedGeometryData.attributes; + + const storedAttributeNames = Object.keys(storedAttributes); + const currentAttributeNames = Object.keys(attributes); + + if (storedAttributeNames.length !== currentAttributeNames.length) { + renderObjectData.geometry.attributes = this.getAttributesData(attributes); + return false; + } + + // Compare each attribute + for (const name of storedAttributeNames) { + const storedAttributeData = storedAttributes[name]; + const attribute = attributes[name]; + + if (attribute === undefined) { + // Attribute was removed + delete storedAttributes[name]; + return false; + } + + if (storedAttributeData.version !== attribute.version) { + storedAttributeData.version = attribute.version; + return false; + } + } + + // Check index + const index = geometry.index; + const storedIndexVersion = storedGeometryData.indexVersion; + const currentIndexVersion = index ? index.version : null; + + if (storedIndexVersion !== currentIndexVersion) { + storedGeometryData.indexVersion = currentIndexVersion; + return false; + } + + // Check drawRange + if ( + storedGeometryData.drawRange.start !== geometry.drawRange.start || + storedGeometryData.drawRange.count !== geometry.drawRange.count + ) { + storedGeometryData.drawRange.start = geometry.drawRange.start; + storedGeometryData.drawRange.count = geometry.drawRange.count; + return false; + } + + // morph targets + + if (renderObjectData.morphTargetInfluences) { + let morphChanged = false; + + for (let i = 0; i < renderObjectData.morphTargetInfluences.length; i++) { + if (renderObjectData.morphTargetInfluences[i] !== object.morphTargetInfluences[i]) { + morphChanged = true; + } + } + + if (morphChanged) return true; + } + + // center + + if (renderObjectData.center) { + if (renderObjectData.center.equals(object.center) === false) { + renderObjectData.center.copy(object.center); + + return true; + } + } + + // bundle + + if (renderObject.bundle !== null) { + renderObjectData.version = renderObject.bundle.version; + } + + return true; + } + + needsRefresh(renderObject, nodeFrame) { + if (this.hasNode || this.hasAnimation || this.firstInitialization(renderObject)) return true; + + const { renderId } = nodeFrame; + + if (this.renderId !== renderId) { + this.renderId = renderId; + + return true; + } + + const isStatic = renderObject.object.static === true; + const isBundle = + renderObject.bundle !== null && + renderObject.bundle.static === true && + this.getRenderObjectData(renderObject).version === renderObject.bundle.version; + + if (isStatic || isBundle) return false; + + const notEqual = this.equals(renderObject) !== true; + + return notEqual; + } +} + +export default NodeMaterialObserver; diff --git a/src-testing/src/math/Box2.d.ts b/src-testing/src/math/Box2.d.ts new file mode 100644 index 000000000..de05083d0 --- /dev/null +++ b/src-testing/src/math/Box2.d.ts @@ -0,0 +1,48 @@ +import { Vector2 } from "./Vector2.js"; + +// Math ////////////////////////////////////////////////////////////////////////////////// + +export class Box2 { + constructor(min?: Vector2, max?: Vector2); + + /** + * @default new THREE.Vector2( + Infinity, + Infinity ) + */ + min: Vector2; + + /** + * @default new THREE.Vector2( - Infinity, - Infinity ) + */ + max: Vector2; + + set(min: Vector2, max: Vector2): Box2; + setFromPoints(points: Vector2[]): Box2; + setFromCenterAndSize(center: Vector2, size: Vector2): Box2; + clone(): this; + copy(box: Box2): this; + makeEmpty(): Box2; + isEmpty(): boolean; + getCenter(target: Vector2): Vector2; + getSize(target: Vector2): Vector2; + expandByPoint(point: Vector2): Box2; + expandByVector(vector: Vector2): Box2; + expandByScalar(scalar: number): Box2; + containsPoint(point: Vector2): boolean; + containsBox(box: Box2): boolean; + getParameter(point: Vector2, target: Vector2): Vector2; + intersectsBox(box: Box2): boolean; + clampPoint(point: Vector2, target: Vector2): Vector2; + distanceToPoint(point: Vector2): number; + intersect(box: Box2): Box2; + union(box: Box2): Box2; + translate(offset: Vector2): Box2; + equals(box: Box2): boolean; + /** + * @deprecated Use {@link Box2#isEmpty .isEmpty()} instead. + */ + empty(): any; + /** + * @deprecated Use {@link Box2#intersectsBox .intersectsBox()} instead. + */ + isIntersectionBox(b: any): any; +} diff --git a/src-testing/src/math/Box3.d.ts b/src-testing/src/math/Box3.d.ts new file mode 100644 index 000000000..2e7b11bc9 --- /dev/null +++ b/src-testing/src/math/Box3.d.ts @@ -0,0 +1,66 @@ +import { BufferAttribute } from "../core/BufferAttribute.js"; +import { Object3D } from "../core/Object3D.js"; +import { Matrix4 } from "./Matrix4.js"; +import { Plane } from "./Plane.js"; +import { Sphere } from "./Sphere.js"; +import { Triangle } from "./Triangle.js"; +import { Vector3 } from "./Vector3.js"; + +export class Box3 { + constructor(min?: Vector3, max?: Vector3); + + /** + * @default new THREE.Vector3( + Infinity, + Infinity, + Infinity ) + */ + min: Vector3; + + /** + * @default new THREE.Vector3( - Infinity, - Infinity, - Infinity ) + */ + max: Vector3; + readonly isBox3: true; + + set(min: Vector3, max: Vector3): this; + setFromArray(array: ArrayLike): this; + setFromBufferAttribute(bufferAttribute: BufferAttribute): this; + setFromPoints(points: Vector3[]): this; + setFromCenterAndSize(center: Vector3, size: Vector3): this; + setFromObject(object: Object3D, precise?: boolean): this; + clone(): this; + copy(box: Box3): this; + makeEmpty(): this; + isEmpty(): boolean; + getCenter(target: Vector3): Vector3; + getSize(target: Vector3): Vector3; + expandByPoint(point: Vector3): this; + expandByVector(vector: Vector3): this; + expandByScalar(scalar: number): this; + expandByObject(object: Object3D, precise?: boolean): this; + containsPoint(point: Vector3): boolean; + containsBox(box: Box3): boolean; + getParameter(point: Vector3, target: Vector3): Vector3; + intersectsBox(box: Box3): boolean; + intersectsSphere(sphere: Sphere): boolean; + intersectsPlane(plane: Plane): boolean; + intersectsTriangle(triangle: Triangle): boolean; + clampPoint(point: Vector3, target: Vector3): Vector3; + distanceToPoint(point: Vector3): number; + getBoundingSphere(target: Sphere): Sphere; + intersect(box: Box3): this; + union(box: Box3): this; + applyMatrix4(matrix: Matrix4): this; + translate(offset: Vector3): this; + equals(box: Box3): boolean; + /** + * @deprecated Use {@link Box3#isEmpty .isEmpty()} instead. + */ + empty(): any; + /** + * @deprecated Use {@link Box3#intersectsBox .intersectsBox()} instead. + */ + isIntersectionBox(b: any): any; + /** + * @deprecated Use {@link Box3#intersectsSphere .intersectsSphere()} instead. + */ + isIntersectionSphere(s: any): any; +} diff --git a/src-testing/src/math/Color.d.ts b/src-testing/src/math/Color.d.ts new file mode 100644 index 000000000..a0e265f83 --- /dev/null +++ b/src-testing/src/math/Color.d.ts @@ -0,0 +1,375 @@ +import { Matrix3 } from "./Matrix3.js"; +import { Vector3 } from "./Vector3.js"; + +import { BufferAttribute } from "../core/BufferAttribute.js"; +import { InterleavedBufferAttribute } from "../core/InterleavedBufferAttribute.js"; + +export { SRGBToLinear } from "./ColorManagement.js"; + +declare const _colorKeywords: { + aliceblue: 0xf0f8ff; + antiquewhite: 0xfaebd7; + aqua: 0x00ffff; + aquamarine: 0x7fffd4; + azure: 0xf0ffff; + beige: 0xf5f5dc; + bisque: 0xffe4c4; + black: 0x000000; + blanchedalmond: 0xffebcd; + blue: 0x0000ff; + blueviolet: 0x8a2be2; + brown: 0xa52a2a; + burlywood: 0xdeb887; + cadetblue: 0x5f9ea0; + chartreuse: 0x7fff00; + chocolate: 0xd2691e; + coral: 0xff7f50; + cornflowerblue: 0x6495ed; + cornsilk: 0xfff8dc; + crimson: 0xdc143c; + cyan: 0x00ffff; + darkblue: 0x00008b; + darkcyan: 0x008b8b; + darkgoldenrod: 0xb8860b; + darkgray: 0xa9a9a9; + darkgreen: 0x006400; + darkgrey: 0xa9a9a9; + darkkhaki: 0xbdb76b; + darkmagenta: 0x8b008b; + darkolivegreen: 0x556b2f; + darkorange: 0xff8c00; + darkorchid: 0x9932cc; + darkred: 0x8b0000; + darksalmon: 0xe9967a; + darkseagreen: 0x8fbc8f; + darkslateblue: 0x483d8b; + darkslategray: 0x2f4f4f; + darkslategrey: 0x2f4f4f; + darkturquoise: 0x00ced1; + darkviolet: 0x9400d3; + deeppink: 0xff1493; + deepskyblue: 0x00bfff; + dimgray: 0x696969; + dimgrey: 0x696969; + dodgerblue: 0x1e90ff; + firebrick: 0xb22222; + floralwhite: 0xfffaf0; + forestgreen: 0x228b22; + fuchsia: 0xff00ff; + gainsboro: 0xdcdcdc; + ghostwhite: 0xf8f8ff; + gold: 0xffd700; + goldenrod: 0xdaa520; + gray: 0x808080; + green: 0x008000; + greenyellow: 0xadff2f; + grey: 0x808080; + honeydew: 0xf0fff0; + hotpink: 0xff69b4; + indianred: 0xcd5c5c; + indigo: 0x4b0082; + ivory: 0xfffff0; + khaki: 0xf0e68c; + lavender: 0xe6e6fa; + lavenderblush: 0xfff0f5; + lawngreen: 0x7cfc00; + lemonchiffon: 0xfffacd; + lightblue: 0xadd8e6; + lightcoral: 0xf08080; + lightcyan: 0xe0ffff; + lightgoldenrodyellow: 0xfafad2; + lightgray: 0xd3d3d3; + lightgreen: 0x90ee90; + lightgrey: 0xd3d3d3; + lightpink: 0xffb6c1; + lightsalmon: 0xffa07a; + lightseagreen: 0x20b2aa; + lightskyblue: 0x87cefa; + lightslategray: 0x778899; + lightslategrey: 0x778899; + lightsteelblue: 0xb0c4de; + lightyellow: 0xffffe0; + lime: 0x00ff00; + limegreen: 0x32cd32; + linen: 0xfaf0e6; + magenta: 0xff00ff; + maroon: 0x800000; + mediumaquamarine: 0x66cdaa; + mediumblue: 0x0000cd; + mediumorchid: 0xba55d3; + mediumpurple: 0x9370db; + mediumseagreen: 0x3cb371; + mediumslateblue: 0x7b68ee; + mediumspringgreen: 0x00fa9a; + mediumturquoise: 0x48d1cc; + mediumvioletred: 0xc71585; + midnightblue: 0x191970; + mintcream: 0xf5fffa; + mistyrose: 0xffe4e1; + moccasin: 0xffe4b5; + navajowhite: 0xffdead; + navy: 0x000080; + oldlace: 0xfdf5e6; + olive: 0x808000; + olivedrab: 0x6b8e23; + orange: 0xffa500; + orangered: 0xff4500; + orchid: 0xda70d6; + palegoldenrod: 0xeee8aa; + palegreen: 0x98fb98; + paleturquoise: 0xafeeee; + palevioletred: 0xdb7093; + papayawhip: 0xffefd5; + peachpuff: 0xffdab9; + peru: 0xcd853f; + pink: 0xffc0cb; + plum: 0xdda0dd; + powderblue: 0xb0e0e6; + purple: 0x800080; + rebeccapurple: 0x663399; + red: 0xff0000; + rosybrown: 0xbc8f8f; + royalblue: 0x4169e1; + saddlebrown: 0x8b4513; + salmon: 0xfa8072; + sandybrown: 0xf4a460; + seagreen: 0x2e8b57; + seashell: 0xfff5ee; + sienna: 0xa0522d; + silver: 0xc0c0c0; + skyblue: 0x87ceeb; + slateblue: 0x6a5acd; + slategray: 0x708090; + slategrey: 0x708090; + snow: 0xfffafa; + springgreen: 0x00ff7f; + steelblue: 0x4682b4; + tan: 0xd2b48c; + teal: 0x008080; + thistle: 0xd8bfd8; + tomato: 0xff6347; + turquoise: 0x40e0d0; + violet: 0xee82ee; + wheat: 0xf5deb3; + white: 0xffffff; + whitesmoke: 0xf5f5f5; + yellow: 0xffff00; + yellowgreen: 0x9acd32; +}; + +export type ColorRepresentation = Color | string | number; + +export interface HSL { + h: number; + s: number; + l: number; +} + +export interface RGB { + r: number; + g: number; + b: number; +} + +/** + * Class representing a color. + * + * A Color instance is represented by RGB components in the linear working color space, which defaults to + * `LinearSRGBColorSpace`. Inputs conventionally using `SRGBColorSpace` (such as hexadecimals and CSS strings) are + * converted to the working color space automatically. + * + * ``` + * // converted automatically from SRGBColorSpace to LinearSRGBColorSpace + * const color = new THREE.Color().setHex( 0x112233 ); + * ``` + * + * Source color spaces may be specified explicitly, to ensure correct conversions. + * + * ``` + * // assumed already LinearSRGBColorSpace; no conversion + * const color = new THREE.Color().setRGB( 0.5, 0.5, 0.5 ); + * + * // converted explicitly from SRGBColorSpace to LinearSRGBColorSpace + * const color = new THREE.Color().setRGB( 0.5, 0.5, 0.5, SRGBColorSpace ); + * ``` + * + * If THREE.ColorManagement is disabled, no conversions occur. For details, see Color management. + * + * Iterating through a Color instance will yield its components (r, g, b) in the corresponding order. + */ +export class Color { + constructor(color?: ColorRepresentation); + constructor(r: number, g: number, b: number); + + readonly isColor: true; + + /** + * Red channel value between `0.0` and `1.0`. Default is `1`. + * @default 1 + */ + r: number; + + /** + * Green channel value between `0.0` and `1.0`. Default is `1`. + * @default 1 + */ + g: number; + + /** + * Blue channel value between `0.0` and `1.0`. Default is `1`. + * @default 1 + */ + b: number; + + set(...args: [color: ColorRepresentation] | [r: number, g: number, b: number]): this; + + /** + * Sets this color's {@link r}, {@link g} and {@link b} components from the x, y, and z components of the specified + * {@link Vector3 | vector}. + */ + setFromVector3(vector: Vector3): this; + + setScalar(scalar: number): Color; + setHex(hex: number, colorSpace?: string): Color; + + /** + * Sets this color from RGB values. + * @param r Red channel value between 0 and 1. + * @param g Green channel value between 0 and 1. + * @param b Blue channel value between 0 and 1. + */ + setRGB(r: number, g: number, b: number, colorSpace?: string): Color; + + /** + * Sets this color from HSL values. + * Based on MochiKit implementation by Bob Ippolito. + * + * @param h Hue channel value between 0 and 1. + * @param s Saturation value channel between 0 and 1. + * @param l Value channel value between 0 and 1. + */ + setHSL(h: number, s: number, l: number, colorSpace?: string): Color; + + /** + * Sets this color from a CSS context style string. + * @param contextStyle Color in CSS context style format. + */ + setStyle(style: string, colorSpace?: string): Color; + + /** + * Sets this color from a color name. + * Faster than {@link Color#setStyle .setStyle()} method if you don't need the other CSS-style formats. + * @param style Color name in X11 format. + */ + setColorName(style: string, colorSpace?: string): Color; + + /** + * Clones this color. + */ + clone(): this; + + /** + * Copies given color. + * @param color Color to copy. + */ + copy(color: Color): this; + + /** + * Copies given color making conversion from `SRGBColorSpace` to `LinearSRGBColorSpace`. + * @param color Color to copy. + */ + copySRGBToLinear(color: Color): Color; + + /** + * Copies given color making conversion from `LinearSRGBColorSpace` to `SRGBColorSpace`. + * @param color Color to copy. + */ + copyLinearToSRGB(color: Color): Color; + + /** + * Converts this color from `SRGBColorSpace` to `LinearSRGBColorSpace`. + */ + convertSRGBToLinear(): Color; + + /** + * Converts this color from `LinearSRGBColorSpace` to `SRGBColorSpace`. + */ + convertLinearToSRGB(): Color; + + /** + * Returns the hexadecimal value of this color. + */ + getHex(colorSpace?: string): number; + + /** + * Returns the string formated hexadecimal value of this color. + */ + getHexString(colorSpace?: string): string; + + getHSL(target: HSL, colorSpace?: string): HSL; + + getRGB(target: RGB, colorSpace?: string): RGB; + + /** + * Returns the value of this color in CSS context style. + * Example: rgb(r, g, b) + */ + getStyle(colorSpace?: string): string; + + offsetHSL(h: number, s: number, l: number): this; + + add(color: Color): this; + addColors(color1: Color, color2: Color): this; + addScalar(s: number): this; + + /** + * Applies the transform {@link Matrix3 | m} to this color's RGB components. + */ + applyMatrix3(m: Matrix3): this; + + sub(color: Color): this; + multiply(color: Color): this; + multiplyScalar(s: number): this; + lerp(color: Color, alpha: number): this; + lerpColors(color1: Color, color2: Color, alpha: number): this; + lerpHSL(color: Color, alpha: number): this; + equals(color: Color): boolean; + + /** + * Sets this color's red, green and blue value from the provided array or array-like. + * @param array the source array or array-like. + * @param offset (optional) offset into the array-like. Default is 0. + */ + fromArray(array: number[] | ArrayLike, offset?: number): this; + + /** + * Returns an array [red, green, blue], or copies red, green and blue into the provided array. + * @param array (optional) array to store the color to. If this is not provided, a new array will be created. + * @param offset (optional) optional offset into the array. + * @return The created or provided array. + */ + toArray(array?: number[], offset?: number): number[]; + + /** + * Copies red, green and blue into the provided array-like. + * @param array array-like to store the color to. + * @param offset (optional) optional offset into the array-like. + * @return The provided array-like. + */ + toArray(xyz: ArrayLike, offset?: number): ArrayLike; + + /** + * This method defines the serialization result of Color. + * @return The color as a hexadecimal value. + */ + toJSON(): number; + + fromBufferAttribute(attribute: BufferAttribute | InterleavedBufferAttribute, index: number): this; + + [Symbol.iterator](): Generator; + + /** + * List of X11 color names. + */ + static NAMES: typeof _colorKeywords; +} diff --git a/src-testing/src/math/ColorManagement.d.ts b/src-testing/src/math/ColorManagement.d.ts new file mode 100644 index 000000000..eaa520d8c --- /dev/null +++ b/src-testing/src/math/ColorManagement.d.ts @@ -0,0 +1,49 @@ +import { ColorSpaceTransfer } from "../constants.js"; +import { Color } from "./Color.js"; +import { Matrix3 } from "./Matrix3.js"; +import { Vector3 } from "./Vector3.js"; + +export interface ColorSpaceDefinition { + primaries: [number, number, number, number, number, number]; + whitePoint: [number, number]; + transfer: ColorSpaceTransfer; + toXYZ: Matrix3; + fromXYZ: Matrix3; + luminanceCoefficients: [number, number, number]; + workingColorSpaceConfig?: { unpackColorSpace: string }; + outputColorSpaceConfig?: { drawingBufferColorSpace: string }; +} + +export interface ColorManagement { + /** + * @default true + */ + enabled: boolean; + + /** + * @default LinearSRGBColorSpace + */ + workingColorSpace: string; + + spaces: Record; + + convert: (color: Color, sourceColorSpace: string, targetColorSpace: string) => Color; + + fromWorkingColorSpace: (color: Color, targetColorSpace: string) => Color; + + toWorkingColorSpace: (color: Color, sourceColorSpace: string) => Color; + + getPrimaries: (colorSpace: string) => [number, number, number, number, number, number]; + + getTransfer: (colorSpace: string) => ColorSpaceTransfer; + + getLuminanceCoefficients: (target: Vector3, colorSpace?: string) => [number, number, number]; + + define: (colorSpaces: Record) => void; +} + +export const ColorManagement: ColorManagement; + +export function SRGBToLinear(c: number): number; + +export function LinearToSRGB(c: number): number; diff --git a/src-testing/src/math/Cylindrical.d.ts b/src-testing/src/math/Cylindrical.d.ts new file mode 100644 index 000000000..6764f8154 --- /dev/null +++ b/src-testing/src/math/Cylindrical.d.ts @@ -0,0 +1,26 @@ +import { Vector3 } from "./Vector3.js"; + +export class Cylindrical { + constructor(radius?: number, theta?: number, y?: number); + + /** + * @default 1 + */ + radius: number; + + /** + * @default 0 + */ + theta: number; + + /** + * @default 0 + */ + y: number; + + clone(): this; + copy(other: Cylindrical): this; + set(radius: number, theta: number, y: number): this; + setFromVector3(vec3: Vector3): this; + setFromCartesianCoords(x: number, y: number, z: number): this; +} diff --git a/src-testing/src/math/Euler.d.ts b/src-testing/src/math/Euler.d.ts new file mode 100644 index 000000000..81be13d82 --- /dev/null +++ b/src-testing/src/math/Euler.d.ts @@ -0,0 +1,50 @@ +import { Matrix4 } from "./Matrix4.js"; +import { Quaternion } from "./Quaternion.js"; +import { Vector3 } from "./Vector3.js"; + +export type EulerOrder = "XYZ" | "YXZ" | "ZXY" | "ZYX" | "YZX" | "XZY"; + +export type EulerTuple = [x: number, y: number, z: number, order?: EulerOrder]; + +export class Euler { + constructor(x?: number, y?: number, z?: number, order?: EulerOrder); + + /** + * @default 0 + */ + x: number; + + /** + * @default 0 + */ + y: number; + + /** + * @default 0 + */ + z: number; + + /** + * @default THREE.Euler.DEFAULT_ORDER + */ + order: EulerOrder; + readonly isEuler: true; + + _onChangeCallback: () => void; + + set(x: number, y: number, z: number, order?: EulerOrder): Euler; + clone(): this; + copy(euler: Euler): this; + setFromRotationMatrix(m: Matrix4, order?: EulerOrder, update?: boolean): Euler; + setFromQuaternion(q: Quaternion, order?: EulerOrder, update?: boolean): Euler; + setFromVector3(v: Vector3, order?: EulerOrder): Euler; + reorder(newOrder: EulerOrder): Euler; + equals(euler: Euler): boolean; + fromArray(array: EulerTuple): Euler; + toArray(array?: Partial, offset?: number): EulerTuple; + _onChange(callback: () => void): this; + + static DEFAULT_ORDER: "XYZ"; + + [Symbol.iterator](): Generator; +} diff --git a/src-testing/src/math/Frustum.d.ts b/src-testing/src/math/Frustum.d.ts new file mode 100644 index 000000000..364c8e926 --- /dev/null +++ b/src-testing/src/math/Frustum.d.ts @@ -0,0 +1,30 @@ +import { CoordinateSystem } from "../constants.js"; +import { Object3D } from "../core/Object3D.js"; +import { Sprite } from "../objects/Sprite.js"; +import { Box3 } from "./Box3.js"; +import { Matrix4 } from "./Matrix4.js"; +import { Plane } from "./Plane.js"; +import { Sphere } from "./Sphere.js"; +import { Vector3 } from "./Vector3.js"; + +/** + * Frustums are used to determine what is inside the camera's field of view. They help speed up the rendering process. + */ +export class Frustum { + constructor(p0?: Plane, p1?: Plane, p2?: Plane, p3?: Plane, p4?: Plane, p5?: Plane); + + /** + * Array of 6 vectors. + */ + planes: Plane[]; + + set(p0: Plane, p1: Plane, p2: Plane, p3: Plane, p4: Plane, p5: Plane): Frustum; + clone(): this; + copy(frustum: Frustum): this; + setFromProjectionMatrix(m: Matrix4, coordinateSystem?: CoordinateSystem): this; + intersectsObject(object: Object3D): boolean; + intersectsSprite(sprite: Sprite): boolean; + intersectsSphere(sphere: Sphere): boolean; + intersectsBox(box: Box3): boolean; + containsPoint(point: Vector3): boolean; +} diff --git a/src-testing/src/math/Interpolant.d.ts b/src-testing/src/math/Interpolant.d.ts new file mode 100644 index 000000000..9d2b1aced --- /dev/null +++ b/src-testing/src/math/Interpolant.d.ts @@ -0,0 +1,10 @@ +export abstract class Interpolant { + constructor(parameterPositions: any, sampleValues: any, sampleSize: number, resultBuffer?: any); + + parameterPositions: any; + sampleValues: any; + valueSize: number; + resultBuffer: any; + + evaluate(time: number): any; +} diff --git a/src-testing/src/math/Line3.d.ts b/src-testing/src/math/Line3.d.ts new file mode 100644 index 000000000..ab7e749bc --- /dev/null +++ b/src-testing/src/math/Line3.d.ts @@ -0,0 +1,29 @@ +import { Matrix4 } from "./Matrix4.js"; +import { Vector3 } from "./Vector3.js"; + +export class Line3 { + constructor(start?: Vector3, end?: Vector3); + + /** + * @default new THREE.Vector3() + */ + start: Vector3; + + /** + * @default new THREE.Vector3() + */ + end: Vector3; + + set(start?: Vector3, end?: Vector3): Line3; + clone(): this; + copy(line: Line3): this; + getCenter(target: Vector3): Vector3; + delta(target: Vector3): Vector3; + distanceSq(): number; + distance(): number; + at(t: number, target: Vector3): Vector3; + closestPointToPointParameter(point: Vector3, clampToLine?: boolean): number; + closestPointToPoint(point: Vector3, clampToLine: boolean, target: Vector3): Vector3; + applyMatrix4(matrix: Matrix4): Line3; + equals(line: Line3): boolean; +} diff --git a/src-testing/src/math/MathUtils.d.ts b/src-testing/src/math/MathUtils.d.ts new file mode 100644 index 000000000..48f10a3c3 --- /dev/null +++ b/src-testing/src/math/MathUtils.d.ts @@ -0,0 +1,137 @@ +import { Quaternion } from "./Quaternion.js"; + +/** + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/math/MathUtils.js|src/math/MathUtils.js} + */ + +export const DEG2RAD: number; + +export const RAD2DEG: number; + +export function generateUUID(): string; + +/** + * Clamps the x to be between a and b. + * + * @param value Value to be clamped. + * @param min Minimum value. + * @param max Maximum value. + */ +export function clamp(value: number, min: number, max: number): number; + +export function euclideanModulo(n: number, m: number): number; + +/** + * Linear mapping of x from range [a1, a2] to range [b1, b2]. + * + * @param x Value to be mapped. + * @param a1 Minimum value for range A. + * @param a2 Maximum value for range A. + * @param b1 Minimum value for range B. + * @param b2 Maximum value for range B. + */ +export function mapLinear(x: number, a1: number, a2: number, b1: number, b2: number): number; + +export function inverseLerp(x: number, y: number, t: number): number; + +/** + * Returns a value linearly interpolated from two known points based + * on the given interval - t = 0 will return x and t = 1 will return y. + * + * @param x Start point. + * @param y End point. + * @param t interpolation factor in the closed interval [0, 1] + */ +export function lerp(x: number, y: number, t: number): number; + +/** + * Smoothly interpolate a number from x toward y in a spring-like + * manner using the dt to maintain frame rate independent movement. + * + * @param x Current point. + * @param y Target point. + * @param lambda A higher lambda value will make the movement more sudden, and a lower value will make the movement more gradual. + * @param dt Delta time in seconds. + */ +export function damp(x: number, y: number, lambda: number, dt: number): number; + +/** + * Returns a value that alternates between 0 and length. + * + * @param x The value to pingpong. + * @param length The positive value the export function will pingpong to. Default is 1. + */ +export function pingpong(x: number, length?: number): number; + +export function smoothstep(x: number, min: number, max: number): number; + +export function smootherstep(x: number, min: number, max: number): number; + +/** + * Random integer from low to high interval. + */ +export function randInt(low: number, high: number): number; + +/** + * Random float from low to high interval. + */ +export function randFloat(low: number, high: number): number; + +/** + * Random float from - range / 2 to range / 2 interval. + */ +export function randFloatSpread(range: number): number; + +/** + * Deterministic pseudo-random float in the interval [ 0, 1 ]. + */ +export function seededRandom(seed?: number): number; + +export function degToRad(degrees: number): number; + +export function radToDeg(radians: number): number; + +export function isPowerOfTwo(value: number): boolean; + +export function ceilPowerOfTwo(value: number): number; + +export function floorPowerOfTwo(value: number): number; + +export function setQuaternionFromProperEuler(q: Quaternion, a: number, b: number, c: number, order: string): void; + +export function denormalize( + value: number, + array: Float32Array | Uint32Array | Uint16Array | Uint8Array | Int32Array | Int16Array | Int8Array, +): number; + +export function normalize( + value: number, + array: Float32Array | Uint32Array | Uint16Array | Uint8Array | Int32Array | Int16Array | Int8Array, +): number; + +export const MathUtils: { + DEG2RAD: typeof DEG2RAD; + RAD2DEG: typeof RAD2DEG; + generateUUID: typeof generateUUID; + clamp: typeof clamp; + euclideanModulo: typeof euclideanModulo; + mapLinear: typeof mapLinear; + inverseLerp: typeof inverseLerp; + lerp: typeof lerp; + damp: typeof damp; + pingpong: typeof pingpong; + smoothstep: typeof smoothstep; + smootherstep: typeof smootherstep; + randInt: typeof randInt; + randFloat: typeof randFloat; + randFloatSpread: typeof randFloatSpread; + seededRandom: typeof seededRandom; + degToRad: typeof degToRad; + radToDeg: typeof radToDeg; + isPowerOfTwo: typeof isPowerOfTwo; + ceilPowerOfTwo: typeof ceilPowerOfTwo; + floorPowerOfTwo: typeof floorPowerOfTwo; + setQuaternionFromProperEuler: typeof setQuaternionFromProperEuler; + normalize: typeof normalize; + denormalize: typeof denormalize; +}; diff --git a/src-testing/src/math/Matrix2.d.ts b/src-testing/src/math/Matrix2.d.ts new file mode 100644 index 000000000..40ed4c8aa --- /dev/null +++ b/src-testing/src/math/Matrix2.d.ts @@ -0,0 +1,53 @@ +export type Matrix2Tuple = [ + n11: number, + n12: number, + n21: number, + n22: number, +]; + +/** + * A class representing a 2x2 {@link https://en.wikipedia.org/wiki/Matrix_(mathematics) matrix}. + * + * @example + * const m = new Matrix2(); + */ +export class Matrix2 { + readonly isMatrix2: true; + + /** + * A {@link https://en.wikipedia.org/wiki/Row-_and_column-major_order column-major} list of matrix values. + */ + elements: Matrix2Tuple; + + /** + * Creates a 2x2 {@link https://en.wikipedia.org/wiki/Identity_matrix identity matrix}. + */ + constructor(); + + /** + * Creates a 2x2 matrix with the given arguments in row-major order. + */ + constructor(n11: number, n12: number, n21: number, n22: number); + + /** + * Resets this matrix to the 2x2 identity matrix: + */ + identity(): this; + + /** + * Sets the elements of this matrix based on an array in + * {@link https://en.wikipedia.org/wiki/Row-_and_column-major_order#Column-major_order column-major} format. + * + * @param array the array to read the elements from + * @param offset (optional) index of first element in the array. Default is `0`. + */ + fromArray(array: ArrayLike, offset?: number): this; + + /** + * Sets the 2x2 matrix values to the given + * {@link https://en.wikipedia.org/wiki/Row-_and_column-major_order row-major} sequence of values: + * [n11, n12, + * n21, n22] + */ + set(n11: number, n12: number, n21: number, n22: number): this; +} diff --git a/src-testing/src/math/Matrix3.d.ts b/src-testing/src/math/Matrix3.d.ts new file mode 100644 index 000000000..0b593fcb8 --- /dev/null +++ b/src-testing/src/math/Matrix3.d.ts @@ -0,0 +1,184 @@ +// https://threejs.org/docs/#api/en/math/Matrix3 + +import { Matrix4 } from "./Matrix4.js"; +import { Vector2 } from "./Vector2.js"; +import { Vector3 } from "./Vector3.js"; + +export type Matrix3Tuple = [ + n11: number, + n12: number, + n13: number, + n21: number, + n22: number, + n23: number, + n31: number, + n32: number, + n33: number, +]; + +export class Matrix3 { + readonly isMatrix3: true; + + /** + * Array with matrix values. + * @default [1, 0, 0, 0, 1, 0, 0, 0, 1] + */ + elements: Matrix3Tuple; + + /** + * Creates an identity matrix. + */ + constructor(); + /** + * Creates a 3x3 matrix with the given arguments in row-major order. + */ + constructor( + n11: number, + n12: number, + n13: number, + n21: number, + n22: number, + n23: number, + n31: number, + n32: number, + n33: number, + ); + + set( + n11: number, + n12: number, + n13: number, + n21: number, + n22: number, + n23: number, + n31: number, + n32: number, + n33: number, + ): Matrix3; + + identity(): this; + + copy(m: Matrix3): this; + + extractBasis(xAxis: Vector3, yAxis: Vector3, zAxis: Vector3): this; + + setFromMatrix4(m: Matrix4): Matrix3; + + /** + * Multiplies this matrix by m. + */ + multiply(m: Matrix3): this; + + premultiply(m: Matrix3): this; + + /** + * Sets this matrix to a x b. + */ + multiplyMatrices(a: Matrix3, b: Matrix3): this; + + multiplyScalar(s: number): this; + + determinant(): number; + + /** + * Inverts this matrix in place. + */ + invert(): this; + + /** + * Transposes this matrix in place. + */ + transpose(): this; + + getNormalMatrix(matrix4: Matrix4): this; + + /** + * Transposes this matrix into the supplied array r, and returns itself. + */ + transposeIntoArray(r: number[]): this; + + setUvTransform(tx: number, ty: number, sx: number, sy: number, rotation: number, cx: number, cy: number): this; + + scale(sx: number, sy: number): this; + + rotate(theta: number): this; + + translate(tx: number, ty: number): this; + + /** + * Sets this matrix as a 2D translation transform: + * + * ``` + * 1, 0, x, + * 0, 1, y, + * 0, 0, 1 + * ``` + * + * @param v the amount to translate. + */ + makeTranslation(v: Vector2): this; + /** + * Sets this matrix as a 2D translation transform: + * + * ``` + * 1, 0, x, + * 0, 1, y, + * 0, 0, 1 + * ``` + * + * @param x the amount to translate in the X axis. + * @param y the amount to translate in the Y axis. + */ + makeTranslation(x: number, y: number): this; + + /** + * Sets this matrix as a 2D rotational transformation by theta radians. The resulting matrix will be: + * + * ``` + * cos(θ) -sin(θ) 0 + * sin(θ) cos(θ) 0 + * 0 0 1 + * ``` + * + * @param theta Rotation angle in radians. Positive values rotate counterclockwise. + */ + makeRotation(theta: number): this; + + /** + * Sets this matrix as a 2D scale transform: + * + * ``` + * x, 0, 0, + * 0, y, 0, + * 0, 0, 1 + * ``` + * + * @param x the amount to scale in the X axis. + * @param y the amount to scale in the Y axis. + */ + makeScale(x: number, y: number): this; + + equals(matrix: Matrix3): boolean; + + /** + * Sets the values of this matrix from the provided array or array-like. + * @param array the source array or array-like. + * @param offset (optional) offset into the array-like. Default is 0. + */ + fromArray(array: ArrayLike, offset?: number): this; + + /** + * Writes the elements of this matrix to an array in + * {@link https://en.wikipedia.org/wiki/Row-_and_column-major_order#Column-major_order column-major} format. + */ + toArray(): Matrix3Tuple; + /** + * Writes the elements of this matrix to an array in + * {@link https://en.wikipedia.org/wiki/Row-_and_column-major_order#Column-major_order column-major} format. + * @param array array to store the resulting vector in. If not given a new array will be created. + * @param offset (optional) offset in the array at which to put the result. + */ + toArray>(array: TArray, offset?: number): TArray; + + clone(): this; +} diff --git a/src-testing/src/math/Matrix4.d.ts b/src-testing/src/math/Matrix4.d.ts new file mode 100644 index 000000000..9ef2a9ceb --- /dev/null +++ b/src-testing/src/math/Matrix4.d.ts @@ -0,0 +1,284 @@ +import { CoordinateSystem } from "../constants.js"; +import { Euler } from "./Euler.js"; +import { Matrix3 } from "./Matrix3.js"; +import { Quaternion } from "./Quaternion.js"; +import { Vector3 } from "./Vector3.js"; + +export type Matrix4Tuple = [ + n11: number, + n12: number, + n13: number, + n14: number, + n21: number, + n22: number, + n23: number, + n24: number, + n31: number, + n32: number, + n33: number, + n34: number, + n41: number, + n42: number, + n43: number, + n44: number, +]; + +/** + * A 4x4 Matrix. + * + * @example + * // Simple rig for rotating around 3 axes + * const m = new THREE.Matrix4(); + * const m1 = new THREE.Matrix4(); + * const m2 = new THREE.Matrix4(); + * const m3 = new THREE.Matrix4(); + * const alpha = 0; + * const beta = Math.PI; + * const gamma = Math.PI/2; + * m1.makeRotationX( alpha ); + * m2.makeRotationY( beta ); + * m3.makeRotationZ( gamma ); + * m.multiplyMatrices( m1, m2 ); + * m.multiply( m3 ); + */ +export class Matrix4 { + readonly isMatrix4: true; + + /** + * Array with matrix values. + * @default [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] + */ + elements: Matrix4Tuple; + + /** + * Creates an identity matrix. + */ + constructor(); + /** + * Creates a 4x4 matrix with the given arguments in row-major order. + */ + constructor( + n11: number, + n12: number, + n13: number, + n14: number, + n21: number, + n22: number, + n23: number, + n24: number, + n31: number, + n32: number, + n33: number, + n34: number, + n41: number, + n42: number, + n43: number, + n44: number, + ); + + /** + * Sets all fields of this matrix. + */ + set( + n11: number, + n12: number, + n13: number, + n14: number, + n21: number, + n22: number, + n23: number, + n24: number, + n31: number, + n32: number, + n33: number, + n34: number, + n41: number, + n42: number, + n43: number, + n44: number, + ): this; + + /** + * Resets this matrix to identity. + */ + identity(): this; + + clone(): Matrix4; + + copy(m: Matrix4): this; + + copyPosition(m: Matrix4): this; + + /** + * Set the upper 3x3 elements of this matrix to the values of the Matrix3 m. + */ + setFromMatrix3(m: Matrix3): this; + + extractBasis(xAxis: Vector3, yAxis: Vector3, zAxis: Vector3): this; + + makeBasis(xAxis: Vector3, yAxis: Vector3, zAxis: Vector3): this; + + /** + * Copies the rotation component of the supplied matrix m into this matrix rotation component. + */ + extractRotation(m: Matrix4): this; + + makeRotationFromEuler(euler: Euler): this; + + makeRotationFromQuaternion(q: Quaternion): this; + + /** + * Constructs a rotation matrix, looking from eye towards center with defined up vector. + */ + lookAt(eye: Vector3, target: Vector3, up: Vector3): this; + + /** + * Multiplies this matrix by m. + */ + multiply(m: Matrix4): this; + + premultiply(m: Matrix4): this; + + /** + * Sets this matrix to a x b. + */ + multiplyMatrices(a: Matrix4, b: Matrix4): this; + + /** + * Multiplies this matrix by s. + */ + multiplyScalar(s: number): this; + + /** + * Computes determinant of this matrix. + * Based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm + */ + determinant(): number; + + /** + * Transposes this matrix. + */ + transpose(): this; + + /** + * Sets the position component for this matrix from vector v. + */ + setPosition(v: Vector3): this; + setPosition(x: number, y: number, z: number): this; + + /** + * Inverts this matrix. + */ + invert(): this; + + /** + * Multiplies the columns of this matrix by vector v. + */ + scale(v: Vector3): this; + + getMaxScaleOnAxis(): number; + + /** + * Sets this matrix as translation transform. + */ + makeTranslation(v: Vector3): this; + makeTranslation(x: number, y: number, z: number): this; + + /** + * Sets this matrix as rotation transform around x axis by theta radians. + * + * @param theta Rotation angle in radians. + */ + makeRotationX(theta: number): this; + + /** + * Sets this matrix as rotation transform around y axis by theta radians. + * + * @param theta Rotation angle in radians. + */ + makeRotationY(theta: number): this; + + /** + * Sets this matrix as rotation transform around z axis by theta radians. + * + * @param theta Rotation angle in radians. + */ + makeRotationZ(theta: number): this; + + /** + * Sets this matrix as rotation transform around axis by angle radians. + * Based on http://www.gamedev.net/reference/articles/article1199.asp. + * + * @param axis Rotation axis. + * @param angle Rotation angle in radians. + */ + makeRotationAxis(axis: Vector3, angle: number): this; + + /** + * Sets this matrix as scale transform. + */ + makeScale(x: number, y: number, z: number): this; + + /** + * Sets this matrix as shear transform. + */ + makeShear(xy: number, xz: number, yx: number, yz: number, zx: number, zy: number): this; + + /** + * Sets this matrix to the transformation composed of translation, rotation and scale. + */ + compose(position: Vector3, quaternion: Quaternion, scale: Vector3): this; + + /** + * Decomposes this matrix into it's position, quaternion and scale components. + */ + decompose(position: Vector3, quaternion: Quaternion, scale: Vector3): this; + + /** + * Creates a perspective projection matrix. + */ + makePerspective( + left: number, + right: number, + top: number, + bottom: number, + near: number, + far: number, + coordinateSystem?: CoordinateSystem, + ): this; + + /** + * Creates an orthographic projection matrix. + */ + makeOrthographic( + left: number, + right: number, + top: number, + bottom: number, + near: number, + far: number, + coordinateSystem?: CoordinateSystem, + ): this; + + equals(matrix: Matrix4): boolean; + + /** + * Sets the values of this matrix from the provided array or array-like. + * @param array the source array or array-like. + * @param offset (optional) offset into the array-like. Default is 0. + */ + fromArray(array: ArrayLike, offset?: number): this; + + /** + * Writes the elements of this matrix to an array in + * {@link https://en.wikipedia.org/wiki/Row-_and_column-major_order#Column-major_order column-major} format. + */ + toArray(): Matrix4Tuple; + /** + * Writes the elements of this matrix to an array in + * {@link https://en.wikipedia.org/wiki/Row-_and_column-major_order#Column-major_order column-major} format. + * @param array array to store the resulting vector in. + * @param offset (optional) offset in the array at which to put the result. + */ + toArray>(array: TArray, offset?: number): TArray; +} diff --git a/src-testing/src/math/Plane.d.ts b/src-testing/src/math/Plane.d.ts new file mode 100644 index 000000000..59fa23912 --- /dev/null +++ b/src-testing/src/math/Plane.d.ts @@ -0,0 +1,47 @@ +import { Box3 } from "./Box3.js"; +import { Line3 } from "./Line3.js"; +import { Matrix3 } from "./Matrix3.js"; +import { Matrix4 } from "./Matrix4.js"; +import { Sphere } from "./Sphere.js"; +import { Vector3 } from "./Vector3.js"; + +export class Plane { + constructor(normal?: Vector3, constant?: number); + + /** + * @default new THREE.Vector3( 1, 0, 0 ) + */ + normal: Vector3; + + /** + * @default 0 + */ + constant: number; + + readonly isPlane: true; + + set(normal: Vector3, constant: number): Plane; + setComponents(x: number, y: number, z: number, w: number): Plane; + setFromNormalAndCoplanarPoint(normal: Vector3, point: Vector3): Plane; + setFromCoplanarPoints(a: Vector3, b: Vector3, c: Vector3): Plane; + clone(): this; + copy(plane: Plane): this; + normalize(): Plane; + negate(): Plane; + distanceToPoint(point: Vector3): number; + distanceToSphere(sphere: Sphere): number; + projectPoint(point: Vector3, target: Vector3): Vector3; + intersectLine(line: Line3, target: Vector3): Vector3 | null; + intersectsLine(line: Line3): boolean; + intersectsBox(box: Box3): boolean; + intersectsSphere(sphere: Sphere): boolean; + coplanarPoint(target: Vector3): Vector3; + applyMatrix4(matrix: Matrix4, optionalNormalMatrix?: Matrix3): Plane; + translate(offset: Vector3): Plane; + equals(plane: Plane): boolean; + + /** + * @deprecated Use {@link Plane#intersectsLine .intersectsLine()} instead. + */ + isIntersectionLine(l: any): any; +} diff --git a/src-testing/src/math/Quaternion.d.ts b/src-testing/src/math/Quaternion.d.ts new file mode 100644 index 000000000..7485b6956 --- /dev/null +++ b/src-testing/src/math/Quaternion.d.ts @@ -0,0 +1,189 @@ +import { BufferAttribute } from "../core/BufferAttribute.js"; +import { InterleavedBufferAttribute } from "../core/InterleavedBufferAttribute.js"; +import { Euler } from "./Euler.js"; +import { Matrix4 } from "./Matrix4.js"; +import { Vector3, Vector3Like } from "./Vector3.js"; + +export interface QuaternionLike { + readonly x: number; + readonly y: number; + readonly z: number; + readonly w: number; +} + +export type QuaternionTuple = [x: number, y: number, z: number, w: number]; + +/** + * Implementation of a quaternion. This is used for rotating things without incurring in the dreaded gimbal lock issue, amongst other advantages. + * + * @example + * const quaternion = new THREE.Quaternion(); + * quaternion.setFromAxisAngle( new THREE.Vector3( 0, 1, 0 ), Math.PI / 2 ); + * const vector = new THREE.Vector3( 1, 0, 0 ); + * vector.applyQuaternion( quaternion ); + */ +export class Quaternion { + /** + * @param x x coordinate + * @param y y coordinate + * @param z z coordinate + * @param w w coordinate + */ + constructor(x?: number, y?: number, z?: number, w?: number); + + /** + * @default 0 + */ + x: number; + + /** + * @default 0 + */ + y: number; + + /** + * @default 0 + */ + z: number; + + /** + * @default 1 + */ + w: number; + readonly isQuaternion: true; + + /** + * Sets values of this quaternion. + */ + set(x: number, y: number, z: number, w: number): this; + + /** + * Clones this quaternion. + */ + clone(): this; + + /** + * Copies values of q to this quaternion. + */ + copy(q: QuaternionLike): this; + + /** + * Sets this quaternion from rotation specified by Euler angles. + */ + setFromEuler(euler: Euler, update?: boolean): this; + + /** + * Sets this quaternion from rotation specified by axis and angle. + * Adapted from http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm. + * Axis have to be normalized, angle is in radians. + */ + setFromAxisAngle(axis: Vector3Like, angle: number): this; + + /** + * Sets this quaternion from rotation component of m. Adapted from http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm. + */ + setFromRotationMatrix(m: Matrix4): this; + setFromUnitVectors(vFrom: Vector3, vTo: Vector3Like): this; + angleTo(q: Quaternion): number; + rotateTowards(q: Quaternion, step: number): this; + + identity(): this; + + /** + * Inverts this quaternion. + */ + invert(): this; + + conjugate(): this; + dot(v: Quaternion): number; + lengthSq(): number; + + /** + * Computes length of this quaternion. + */ + length(): number; + + /** + * Normalizes this quaternion. + */ + normalize(): this; + + /** + * Multiplies this quaternion by b. + */ + multiply(q: Quaternion): this; + premultiply(q: Quaternion): this; + + /** + * Sets this quaternion to a x b + * Adapted from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm. + */ + multiplyQuaternions(a: Quaternion, b: Quaternion): this; + + slerp(qb: Quaternion, t: number): this; + slerpQuaternions(qa: Quaternion, qb: Quaternion, t: number): this; + equals(v: Quaternion): boolean; + + /** + * Sets this quaternion's x, y, z and w value from the provided array or array-like. + * @param array the source array or array-like. + * @param offset (optional) offset into the array. Default is 0. + */ + fromArray(array: number[] | ArrayLike, offset?: number): this; + + /** + * Returns an array [x, y, z, w], or copies x, y, z and w into the provided array. + * @param array (optional) array to store the quaternion to. If this is not provided, a new array will be created. + * @param offset (optional) optional offset into the array. + * @return The created or provided array. + */ + toArray(array?: number[], offset?: number): number[]; + toArray(array?: QuaternionTuple, offset?: 0): QuaternionTuple; + + /** + * Copies x, y, z and w into the provided array-like. + * @param array array-like to store the quaternion to. + * @param offset (optional) optional offset into the array. + * @return The provided array-like. + */ + toArray(array: ArrayLike, offset?: number): ArrayLike; + + /** + * This method defines the serialization result of Quaternion. + * @return The numerical elements of this quaternion in an array of format [x, y, z, w]. + */ + toJSON(): [number, number, number, number]; + + /** + * Sets x, y, z, w properties of this quaternion from the attribute. + * @param attribute the source attribute. + * @param index index in the attribute. + */ + fromBufferAttribute(attribute: BufferAttribute | InterleavedBufferAttribute, index: number): this; + + _onChange(callback: () => void): this; + _onChangeCallback: () => void; + + static slerpFlat( + dst: number[], + dstOffset: number, + src0: number[], + srcOffset: number, + src1: number[], + stcOffset1: number, + t: number, + ): void; + + static multiplyQuaternionsFlat( + dst: number[], + dstOffset: number, + src0: number[], + srcOffset: number, + src1: number[], + stcOffset1: number, + ): number[]; + + random(): this; + + [Symbol.iterator](): Generator; +} diff --git a/src-testing/src/math/Ray.d.ts b/src-testing/src/math/Ray.d.ts new file mode 100644 index 000000000..98b9fd70f --- /dev/null +++ b/src-testing/src/math/Ray.d.ts @@ -0,0 +1,60 @@ +import { Box3 } from "./Box3.js"; +import { Matrix4 } from "./Matrix4.js"; +import { Plane } from "./Plane.js"; +import { Sphere } from "./Sphere.js"; +import { Vector3 } from "./Vector3.js"; + +export class Ray { + constructor(origin?: Vector3, direction?: Vector3); + + /** + * @default new THREE.Vector3() + */ + origin: Vector3; + + /** + * @default new THREE.Vector3( 0, 0, - 1 ) + */ + direction: Vector3; + + set(origin: Vector3, direction: Vector3): Ray; + clone(): this; + copy(ray: Ray): this; + at(t: number, target: Vector3): Vector3; + lookAt(v: Vector3): Ray; + recast(t: number): Ray; + closestPointToPoint(point: Vector3, target: Vector3): Vector3; + distanceToPoint(point: Vector3): number; + distanceSqToPoint(point: Vector3): number; + distanceSqToSegment( + v0: Vector3, + v1: Vector3, + optionalPointOnRay?: Vector3, + optionalPointOnSegment?: Vector3, + ): number; + intersectSphere(sphere: Sphere, target: Vector3): Vector3 | null; + intersectsSphere(sphere: Sphere): boolean; + distanceToPlane(plane: Plane): number; + intersectPlane(plane: Plane, target: Vector3): Vector3 | null; + intersectsPlane(plane: Plane): boolean; + intersectBox(box: Box3, target: Vector3): Vector3 | null; + intersectsBox(box: Box3): boolean; + intersectTriangle(a: Vector3, b: Vector3, c: Vector3, backfaceCulling: boolean, target: Vector3): Vector3 | null; + applyMatrix4(matrix4: Matrix4): Ray; + equals(ray: Ray): boolean; + + /** + * @deprecated Use {@link Ray#intersectsBox .intersectsBox()} instead. + */ + isIntersectionBox(b: any): any; + + /** + * @deprecated Use {@link Ray#intersectsPlane .intersectsPlane()} instead. + */ + isIntersectionPlane(p: any): any; + + /** + * @deprecated Use {@link Ray#intersectsSphere .intersectsSphere()} instead. + */ + isIntersectionSphere(s: any): any; +} diff --git a/src-testing/src/math/Sphere.d.ts b/src-testing/src/math/Sphere.d.ts new file mode 100644 index 000000000..a423a6f97 --- /dev/null +++ b/src-testing/src/math/Sphere.d.ts @@ -0,0 +1,47 @@ +import { Box3 } from "./Box3.js"; +import { Matrix4 } from "./Matrix4.js"; +import { Plane } from "./Plane.js"; +import { Vector3 } from "./Vector3.js"; + +export class Sphere { + constructor(center?: Vector3, radius?: number); + + /** + * Read-only flag to check if a given object is of type {@link Sphere}. + */ + readonly isSphere: true; + + /** + * @default new Vector3() + */ + center: Vector3; + + /** + * @default 1 + */ + radius: number; + + set(center: Vector3, radius: number): Sphere; + setFromPoints(points: Vector3[], optionalCenter?: Vector3): Sphere; + clone(): this; + copy(sphere: Sphere): this; + expandByPoint(point: Vector3): this; + isEmpty(): boolean; + makeEmpty(): this; + containsPoint(point: Vector3): boolean; + distanceToPoint(point: Vector3): number; + intersectsSphere(sphere: Sphere): boolean; + intersectsBox(box: Box3): boolean; + intersectsPlane(plane: Plane): boolean; + clampPoint(point: Vector3, target: Vector3): Vector3; + getBoundingBox(target: Box3): Box3; + applyMatrix4(matrix: Matrix4): Sphere; + translate(offset: Vector3): Sphere; + equals(sphere: Sphere): boolean; + union(sphere: Sphere): this; + + /** + * @deprecated Use {@link Sphere#isEmpty .isEmpty()} instead. + */ + empty(): any; +} diff --git a/src-testing/src/math/Spherical.d.ts b/src-testing/src/math/Spherical.d.ts new file mode 100644 index 000000000..8d4815a17 --- /dev/null +++ b/src-testing/src/math/Spherical.d.ts @@ -0,0 +1,27 @@ +import { Vector3 } from "./Vector3.js"; + +export class Spherical { + constructor(radius?: number, phi?: number, theta?: number); + + /** + * @default 1 + */ + radius: number; + + /** + * @default 0 + */ + phi: number; + + /** + * @default 0 + */ + theta: number; + + set(radius: number, phi: number, theta: number): this; + clone(): this; + copy(other: Spherical): this; + makeSafe(): this; + setFromVector3(v: Vector3): this; + setFromCartesianCoords(x: number, y: number, z: number): this; +} diff --git a/src-testing/src/math/SphericalHarmonics3.d.ts b/src-testing/src/math/SphericalHarmonics3.d.ts new file mode 100644 index 000000000..5981a0b48 --- /dev/null +++ b/src-testing/src/math/SphericalHarmonics3.d.ts @@ -0,0 +1,50 @@ +import { Vector3 } from "./Vector3.js"; + +export class SphericalHarmonics3 { + constructor(); + + /** + * @default [new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3(), + * new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3()] + */ + coefficients: Vector3[]; + readonly isSphericalHarmonics3: true; + + set(coefficients: Vector3[]): SphericalHarmonics3; + zero(): SphericalHarmonics3; + add(sh: SphericalHarmonics3): SphericalHarmonics3; + addScaledSH(sh: SphericalHarmonics3, s: number): SphericalHarmonics3; + scale(s: number): SphericalHarmonics3; + lerp(sh: SphericalHarmonics3, alpha: number): SphericalHarmonics3; + equals(sh: SphericalHarmonics3): boolean; + copy(sh: SphericalHarmonics3): SphericalHarmonics3; + clone(): this; + + /** + * Sets the values of this spherical harmonics from the provided array or array-like. + * @param array the source array or array-like. + * @param offset (optional) offset into the array. Default is 0. + */ + fromArray(array: number[] | ArrayLike, offset?: number): this; + + /** + * Returns an array with the values of this spherical harmonics, or copies them into the provided array. + * @param array (optional) array to store the spherical harmonics to. If this is not provided, a new array will be created. + * @param offset (optional) optional offset into the array. + * @return The created or provided array. + */ + toArray(array?: number[], offset?: number): number[]; + + /** + * Returns an array with the values of this spherical harmonics, or copies them into the provided array-like. + * @param array array-like to store the spherical harmonics to. + * @param offset (optional) optional offset into the array-like. + * @return The provided array-like. + */ + toArray(array: ArrayLike, offset?: number): ArrayLike; + + getAt(normal: Vector3, target: Vector3): Vector3; + getIrradianceAt(normal: Vector3, target: Vector3): Vector3; + + static getBasisAt(normal: Vector3, shBasis: number[]): void; +} diff --git a/src-testing/src/math/Triangle.d.ts b/src-testing/src/math/Triangle.d.ts new file mode 100644 index 000000000..9f0e7935b --- /dev/null +++ b/src-testing/src/math/Triangle.d.ts @@ -0,0 +1,110 @@ +import { Box3 } from "./Box3.js"; +import { Plane } from "./Plane.js"; +import { Vector2 } from "./Vector2.js"; +import { Vector3 } from "./Vector3.js"; +import { Vector4 } from "./Vector4.js"; + +import { BufferAttribute } from "../core/BufferAttribute.js"; +import { InterleavedBufferAttribute } from "../core/InterleavedBufferAttribute.js"; + +export class Triangle { + constructor(a?: Vector3, b?: Vector3, c?: Vector3); + + /** + * @default new THREE.Vector3() + */ + a: Vector3; + + /** + * @default new THREE.Vector3() + */ + b: Vector3; + + /** + * @default new THREE.Vector3() + */ + c: Vector3; + + set(a: Vector3, b: Vector3, c: Vector3): Triangle; + setFromPointsAndIndices(points: Vector3[], i0: number, i1: number, i2: number): this; + setFromAttributeAndIndices( + attribute: BufferAttribute | InterleavedBufferAttribute, + i0: number, + i1: number, + i2: number, + ): this; + clone(): this; + copy(triangle: Triangle): this; + getArea(): number; + getMidpoint(target: Vector3): Vector3; + getNormal(target: Vector3): Vector3; + getPlane(target: Plane): Plane; + getBarycoord(point: Vector3, target: Vector3): Vector3 | null; + getInterpolation(point: Vector3, v1: Vector2, v2: Vector2, v3: Vector2, target: Vector2): Vector2 | null; + getInterpolation(point: Vector3, v1: Vector3, v2: Vector3, v3: Vector3, target: Vector3): Vector3 | null; + getInterpolation(point: Vector3, v1: Vector4, v2: Vector4, v3: Vector4, target: Vector4): Vector4 | null; + containsPoint(point: Vector3): boolean; + intersectsBox(box: Box3): boolean; + isFrontFacing(direction: Vector3): boolean; + closestPointToPoint(point: Vector3, target: Vector3): Vector3; + equals(triangle: Triangle): boolean; + + static getNormal(a: Vector3, b: Vector3, c: Vector3, target: Vector3): Vector3; + static getBarycoord(point: Vector3, a: Vector3, b: Vector3, c: Vector3, target: Vector3): Vector3 | null; + static containsPoint(point: Vector3, a: Vector3, b: Vector3, c: Vector3): boolean; + static getInterpolation( + point: Vector3, + p1: Vector3, + p2: Vector3, + p3: Vector3, + v1: Vector2, + v2: Vector2, + v3: Vector2, + target: Vector2, + ): Vector2 | null; + static getInterpolation( + point: Vector3, + p1: Vector3, + p2: Vector3, + p3: Vector3, + v1: Vector3, + v2: Vector3, + v3: Vector3, + target: Vector3, + ): Vector3 | null; + static getInterpolation( + point: Vector3, + p1: Vector3, + p2: Vector3, + p3: Vector3, + v1: Vector4, + v2: Vector4, + v3: Vector4, + target: Vector4, + ): Vector4 | null; + static getInterpolatedAttribute( + attr: BufferAttribute, + i1: number, + i2: number, + i3: number, + barycoord: Vector3, + target: Vector2, + ): Vector2; + static getInterpolatedAttribute( + attr: BufferAttribute, + i1: number, + i2: number, + i3: number, + barycoord: Vector3, + target: Vector3, + ): Vector3; + static getInterpolatedAttribute( + attr: BufferAttribute, + i1: number, + i2: number, + i3: number, + barycoord: Vector3, + target: Vector4, + ): Vector4; + static isFrontFacing(a: Vector3, b: Vector3, c: Vector3, direction: Vector3): boolean; +} diff --git a/src-testing/src/math/Vector2.d.ts b/src-testing/src/math/Vector2.d.ts new file mode 100644 index 000000000..fd2a84a1d --- /dev/null +++ b/src-testing/src/math/Vector2.d.ts @@ -0,0 +1,321 @@ +import { BufferAttribute } from "../core/BufferAttribute.js"; +import { Matrix3 } from "./Matrix3.js"; + +export type Vector2Tuple = [x: number, y: number]; + +export interface Vector2Like { + readonly x: number; + readonly y: number; +} + +/** + * 2D vector. + */ +export class Vector2 { + constructor(x?: number, y?: number); + + /** + * @default 0 + */ + x: number; + + /** + * @default 0 + */ + y: number; + width: number; + height: number; + readonly isVector2: true; + + /** + * Sets value of this vector. + */ + set(x: number, y: number): this; + + /** + * Sets the x and y values of this vector both equal to scalar. + */ + setScalar(scalar: number): this; + + /** + * Sets X component of this vector. + */ + setX(x: number): this; + + /** + * Sets Y component of this vector. + */ + setY(y: number): this; + + /** + * Sets a component of this vector. + */ + setComponent(index: number, value: number): this; + + /** + * Gets a component of this vector. + */ + getComponent(index: number): number; + + /** + * Returns a new Vector2 instance with the same `x` and `y` values. + */ + clone(): this; + + /** + * Copies value of v to this vector. + */ + copy(v: Vector2Like): this; + + /** + * Adds v to this vector. + */ + add(v: Vector2Like): this; + + /** + * Adds the scalar value s to this vector's x and y values. + */ + addScalar(s: number): this; + + /** + * Sets this vector to a + b. + */ + addVectors(a: Vector2Like, b: Vector2Like): this; + + /** + * Adds the multiple of v and s to this vector. + */ + addScaledVector(v: Vector2Like, s: number): this; + + /** + * Subtracts v from this vector. + */ + sub(v: Vector2Like): this; + + /** + * Subtracts s from this vector's x and y components. + */ + subScalar(s: number): this; + + /** + * Sets this vector to a - b. + */ + subVectors(a: Vector2Like, b: Vector2Like): this; + + /** + * Multiplies this vector by v. + */ + multiply(v: Vector2Like): this; + + /** + * Multiplies this vector by scalar s. + */ + multiplyScalar(scalar: number): this; + + /** + * Divides this vector by v. + */ + divide(v: Vector2Like): this; + + /** + * Divides this vector by scalar s. + * Set vector to ( 0, 0 ) if s == 0. + */ + divideScalar(s: number): this; + + /** + * Multiplies this vector (with an implicit 1 as the 3rd component) by m. + */ + applyMatrix3(m: Matrix3): this; + + /** + * If this vector's x or y value is greater than v's x or y value, replace that value with the corresponding min value. + */ + min(v: Vector2Like): this; + + /** + * If this vector's x or y value is less than v's x or y value, replace that value with the corresponding max value. + */ + max(v: Vector2Like): this; + + /** + * If this vector's x or y value is greater than the max vector's x or y value, it is replaced by the corresponding value. + * If this vector's x or y value is less than the min vector's x or y value, it is replaced by the corresponding value. + * @param min the minimum x and y values. + * @param max the maximum x and y values in the desired range. + */ + clamp(min: Vector2Like, max: Vector2Like): this; + + /** + * If this vector's x or y values are greater than the max value, they are replaced by the max value. + * If this vector's x or y values are less than the min value, they are replaced by the min value. + * @param min the minimum value the components will be clamped to. + * @param max the maximum value the components will be clamped to. + */ + clampScalar(min: number, max: number): this; + + /** + * If this vector's length is greater than the max value, it is replaced by the max value. + * If this vector's length is less than the min value, it is replaced by the min value. + * @param min the minimum value the length will be clamped to. + * @param max the maximum value the length will be clamped to. + */ + clampLength(min: number, max: number): this; + + /** + * The components of the vector are rounded down to the nearest integer value. + */ + floor(): this; + + /** + * The x and y components of the vector are rounded up to the nearest integer value. + */ + ceil(): this; + + /** + * The components of the vector are rounded to the nearest integer value. + */ + round(): this; + + /** + * The components of the vector are rounded towards zero (up if negative, down if positive) to an integer value. + */ + roundToZero(): this; + + /** + * Inverts this vector. + */ + negate(): this; + + /** + * Computes dot product of this vector and v. + */ + dot(v: Vector2Like): number; + + /** + * Computes cross product of this vector and v. + */ + cross(v: Vector2Like): number; + + /** + * Computes squared length of this vector. + */ + lengthSq(): number; + + /** + * Computes length of this vector. + */ + length(): number; + + /** + * Computes the Manhattan length of this vector. + * + * see {@link http://en.wikipedia.org/wiki/Taxicab_geometry|Wikipedia: Taxicab Geometry} + */ + manhattanLength(): number; + + /** + * Normalizes this vector. + */ + normalize(): this; + + /** + * computes the angle in radians with respect to the positive x-axis + */ + angle(): number; + + /** + * Returns the angle between this vector and vector {@link Vector2 | v} in radians. + */ + angleTo(v: Vector2): number; + + /** + * Computes distance of this vector to v. + */ + distanceTo(v: Vector2Like): number; + + /** + * Computes squared distance of this vector to v. + */ + distanceToSquared(v: Vector2Like): number; + + /** + * Computes the Manhattan length (distance) from this vector to the given vector v + * + * see {@link http://en.wikipedia.org/wiki/Taxicab_geometry|Wikipedia: Taxicab Geometry} + */ + manhattanDistanceTo(v: Vector2Like): number; + + /** + * Normalizes this vector and multiplies it by l. + */ + setLength(length: number): this; + + /** + * Linearly interpolates between this vector and v, where alpha is the distance along the line - alpha = 0 will be this vector, and alpha = 1 will be v. + * @param v vector to interpolate towards. + * @param alpha interpolation factor in the closed interval [0, 1]. + */ + lerp(v: Vector2Like, alpha: number): this; + + /** + * Sets this vector to be the vector linearly interpolated between v1 and v2 where alpha is the distance along the line connecting the two vectors - alpha = 0 will be v1, and alpha = 1 will be v2. + * @param v1 the starting vector. + * @param v2 vector to interpolate towards. + * @param alpha interpolation factor in the closed interval [0, 1]. + */ + lerpVectors(v1: Vector2Like, v2: Vector2Like, alpha: number): this; + + /** + * Checks for strict equality of this vector and v. + */ + equals(v: Vector2Like): boolean; + + /** + * Sets this vector's x and y value from the provided array or array-like. + * @param array the source array or array-like. + * @param offset (optional) offset into the array. Default is 0. + */ + fromArray(array: number[] | ArrayLike, offset?: number): this; + + /** + * Returns an array [x, y], or copies x and y into the provided array. + * @param array (optional) array to store the vector to. If this is not provided, a new array will be created. + * @param offset (optional) optional offset into the array. + * @return The created or provided array. + */ + toArray(array?: number[], offset?: number): number[]; + toArray(array?: Vector2Tuple, offset?: 0): Vector2Tuple; + + /** + * Copies x and y into the provided array-like. + * @param array array-like to store the vector to. + * @param offset (optional) optional offset into the array. + * @return The provided array-like. + */ + toArray(array: ArrayLike, offset?: number): ArrayLike; + + /** + * Sets this vector's x and y values from the attribute. + * @param attribute the source attribute. + * @param index index in the attribute. + */ + fromBufferAttribute(attribute: BufferAttribute, index: number): this; + + /** + * Rotates the vector around center by angle radians. + * @param center the point around which to rotate. + * @param angle the angle to rotate, in radians. + */ + rotateAround(center: Vector2Like, angle: number): this; + + /** + * Sets this vector's x and y from Math.random + */ + random(): this; + + /** + * Iterating through a Vector2 instance will yield its components (x, y) in the corresponding order. + */ + [Symbol.iterator](): Iterator; +} diff --git a/src-testing/src/math/Vector3.d.ts b/src-testing/src/math/Vector3.d.ts new file mode 100644 index 000000000..56e907ceb --- /dev/null +++ b/src-testing/src/math/Vector3.d.ts @@ -0,0 +1,301 @@ +import { Camera } from "../cameras/Camera.js"; +import { BufferAttribute } from "../core/BufferAttribute.js"; +import { InterleavedBufferAttribute } from "../core/InterleavedBufferAttribute.js"; +import { RGB } from "./Color.js"; +import { Cylindrical } from "./Cylindrical.js"; +import { Euler } from "./Euler.js"; +import { Matrix3 } from "./Matrix3.js"; +import { Matrix4 } from "./Matrix4.js"; +import { QuaternionLike } from "./Quaternion.js"; +import { Spherical } from "./Spherical.js"; + +export type Vector3Tuple = [number, number, number]; + +export interface Vector3Like { + readonly x: number; + readonly y: number; + readonly z: number; +} + +/** + * 3D vector. + * + * see {@link https://github.com/mrdoob/three.js/blob/master/src/math/Vector3.js} + * + * @example + * const a = new THREE.Vector3( 1, 0, 0 ); + * const b = new THREE.Vector3( 0, 1, 0 ); + * const c = new THREE.Vector3(); + * c.crossVectors( a, b ); + */ +export class Vector3 { + constructor(x?: number, y?: number, z?: number); + + /** + * @default 0 + */ + x: number; + + /** + * @default 0 + */ + y: number; + + /** + * @default 0 + */ + z: number; + readonly isVector3: true; + + /** + * Sets value of this vector. + */ + set(x: number, y: number, z: number): this; + + /** + * Sets all values of this vector. + */ + setScalar(scalar: number): this; + + /** + * Sets x value of this vector. + */ + setX(x: number): this; + + /** + * Sets y value of this vector. + */ + setY(y: number): this; + + /** + * Sets z value of this vector. + */ + setZ(z: number): this; + + setComponent(index: number, value: number): this; + + getComponent(index: number): number; + + /** + * Clones this vector. + */ + clone(): this; + + /** + * Copies value of v to this vector. + */ + copy(v: Vector3Like): this; + + /** + * Adds v to this vector. + */ + add(v: Vector3Like): this; + + addScalar(s: number): this; + + /** + * Sets this vector to a + b. + */ + addVectors(a: Vector3Like, b: Vector3Like): this; + + addScaledVector(v: Vector3, s: number): this; + + /** + * Subtracts v from this vector. + */ + sub(a: Vector3Like): this; + + subScalar(s: number): this; + + /** + * Sets this vector to a - b. + */ + subVectors(a: Vector3Like, b: Vector3Like): this; + + multiply(v: Vector3Like): this; + + /** + * Multiplies this vector by scalar s. + */ + multiplyScalar(s: number): this; + + multiplyVectors(a: Vector3Like, b: Vector3Like): this; + + applyEuler(euler: Euler): this; + + applyAxisAngle(axis: Vector3, angle: number): this; + + applyMatrix3(m: Matrix3): this; + + applyNormalMatrix(m: Matrix3): this; + + applyMatrix4(m: Matrix4): this; + + applyQuaternion(q: QuaternionLike): this; + + project(camera: Camera): this; + + unproject(camera: Camera): this; + + transformDirection(m: Matrix4): this; + + divide(v: Vector3Like): this; + + /** + * Divides this vector by scalar s. + * Set vector to ( 0, 0, 0 ) if s == 0. + */ + divideScalar(s: number): this; + + min(v: Vector3Like): this; + + max(v: Vector3Like): this; + + clamp(min: Vector3Like, max: Vector3Like): this; + + clampScalar(min: number, max: number): this; + + clampLength(min: number, max: number): this; + + floor(): this; + + ceil(): this; + + round(): this; + + roundToZero(): this; + + /** + * Inverts this vector. + */ + negate(): this; + + /** + * Computes dot product of this vector and v. + */ + dot(v: Vector3Like): number; + + /** + * Computes squared length of this vector. + */ + lengthSq(): number; + + /** + * Computes length of this vector. + */ + length(): number; + + /** + * Computes the Manhattan length of this vector. + * + * see {@link http://en.wikipedia.org/wiki/Taxicab_geometry|Wikipedia: Taxicab Geometry} + */ + manhattanLength(): number; + + /** + * Normalizes this vector. + */ + normalize(): this; + + /** + * Normalizes this vector and multiplies it by l. + */ + setLength(l: number): this; + lerp(v: Vector3Like, alpha: number): this; + + lerpVectors(v1: Vector3Like, v2: Vector3Like, alpha: number): this; + + /** + * Sets this vector to cross product of itself and v. + */ + cross(a: Vector3Like): this; + + /** + * Sets this vector to cross product of a and b. + */ + crossVectors(a: Vector3Like, b: Vector3Like): this; + projectOnVector(v: Vector3): this; + projectOnPlane(planeNormal: Vector3): this; + reflect(vector: Vector3Like): this; + angleTo(v: Vector3): number; + + /** + * Computes distance of this vector to v. + */ + distanceTo(v: Vector3Like): number; + + /** + * Computes squared distance of this vector to v. + */ + distanceToSquared(v: Vector3Like): number; + + /** + * Computes the Manhattan length (distance) from this vector to the given vector v + * + * see {@link http://en.wikipedia.org/wiki/Taxicab_geometry|Wikipedia: Taxicab Geometry} + */ + manhattanDistanceTo(v: Vector3Like): number; + + setFromSpherical(s: Spherical): this; + setFromSphericalCoords(r: number, phi: number, theta: number): this; + setFromCylindrical(s: Cylindrical): this; + setFromCylindricalCoords(radius: number, theta: number, y: number): this; + setFromMatrixPosition(m: Matrix4): this; + setFromMatrixScale(m: Matrix4): this; + setFromMatrixColumn(matrix: Matrix4, index: number): this; + setFromMatrix3Column(matrix: Matrix3, index: number): this; + + /** + * Sets this vector's {@link x}, {@link y} and {@link z} components from the x, y, and z components of the specified {@link Euler Euler Angle}. + */ + setFromEuler(e: Euler): this; + + /** + * Sets this vector's {@link x}, {@link y} and {@link z} components from the r, g, and b components of the specified + * {@link Color | color}. + */ + setFromColor(color: RGB): this; + + /** + * Checks for strict equality of this vector and v. + */ + equals(v: Vector3Like): boolean; + + /** + * Sets this vector's x, y and z value from the provided array or array-like. + * @param array the source array or array-like. + * @param offset (optional) offset into the array. Default is 0. + */ + fromArray(array: number[] | ArrayLike, offset?: number): this; + + /** + * Returns an array [x, y, z], or copies x, y and z into the provided array. + * @param array (optional) array to store the vector to. If this is not provided, a new array will be created. + * @param offset (optional) optional offset into the array. + * @return The created or provided array. + */ + toArray(array?: number[], offset?: number): number[]; + toArray(array?: Vector3Tuple, offset?: 0): Vector3Tuple; + + /** + * Copies x, y and z into the provided array-like. + * @param array array-like to store the vector to. + * @param offset (optional) optional offset into the array-like. + * @return The provided array-like. + */ + toArray(array: ArrayLike, offset?: number): ArrayLike; + + fromBufferAttribute(attribute: BufferAttribute | InterleavedBufferAttribute, index: number): this; + + /** + * Sets this vector's x, y and z from Math.random + */ + random(): this; + + randomDirection(): this; + + /** + * Iterating through a Vector3 instance will yield its components (x, y, z) in the corresponding order. + */ + [Symbol.iterator](): Iterator; +} diff --git a/src-testing/src/math/Vector4.d.ts b/src-testing/src/math/Vector4.d.ts new file mode 100644 index 000000000..88cf74ff2 --- /dev/null +++ b/src-testing/src/math/Vector4.d.ts @@ -0,0 +1,239 @@ +import { BufferAttribute } from "../core/BufferAttribute.js"; +import { Matrix4 } from "./Matrix4.js"; +import { QuaternionLike } from "./Quaternion.js"; + +export type Vector4Tuple = [number, number, number, number]; + +export interface Vector4Like { + readonly x: number; + readonly y: number; + readonly z: number; + readonly w: number; +} + +/** + * 4D vector. + */ +export class Vector4 { + constructor(x?: number, y?: number, z?: number, w?: number); + + /** + * @default 0 + */ + x: number; + + /** + * @default 0 + */ + y: number; + + /** + * @default 0 + */ + z: number; + + /** + * @default 0 + */ + w: number; + + width: number; + height: number; + readonly isVector4: true; + + /** + * Sets value of this vector. + */ + set(x: number, y: number, z: number, w: number): this; + + /** + * Sets all values of this vector. + */ + setScalar(scalar: number): this; + + /** + * Sets X component of this vector. + */ + setX(x: number): this; + + /** + * Sets Y component of this vector. + */ + setY(y: number): this; + + /** + * Sets Z component of this vector. + */ + setZ(z: number): this; + + /** + * Sets w component of this vector. + */ + setW(w: number): this; + + setComponent(index: number, value: number): this; + + getComponent(index: number): number; + + /** + * Clones this vector. + */ + clone(): this; + + /** + * Copies value of v to this vector. + */ + copy(v: Vector4Like): this; + + /** + * Adds v to this vector. + */ + add(v: Vector4Like): this; + + addScalar(scalar: number): this; + + /** + * Sets this vector to a + b. + */ + addVectors(a: Vector4Like, b: Vector4Like): this; + + addScaledVector(v: Vector4Like, s: number): this; + /** + * Subtracts v from this vector. + */ + sub(v: Vector4Like): this; + + subScalar(s: number): this; + + /** + * Sets this vector to a - b. + */ + subVectors(a: Vector4Like, b: Vector4Like): this; + + multiply(v: Vector4Like): this; + + /** + * Multiplies this vector by scalar s. + */ + multiplyScalar(s: number): this; + + applyMatrix4(m: Matrix4): this; + + /** + * Divides this vector by scalar s. + * Set vector to ( 0, 0, 0 ) if s == 0. + */ + divideScalar(s: number): this; + + /** + * http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm + * @param q is assumed to be normalized + */ + setAxisAngleFromQuaternion(q: QuaternionLike): this; + + /** + * http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/index.htm + * @param m assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) + */ + setAxisAngleFromRotationMatrix(m: Matrix4): this; + + /** + * Sets this vector to the position elements of the + * [transformation matrix]{@link https://en.wikipedia.org/wiki/Transformation_matrix} m. + */ + setFromMatrixPosition(m: Matrix4): this; + + min(v: Vector4Like): this; + max(v: Vector4Like): this; + clamp(min: Vector4Like, max: Vector4Like): this; + clampScalar(min: number, max: number): this; + floor(): this; + ceil(): this; + round(): this; + roundToZero(): this; + + /** + * Inverts this vector. + */ + negate(): this; + + /** + * Computes dot product of this vector and v. + */ + dot(v: Vector4Like): number; + + /** + * Computes squared length of this vector. + */ + lengthSq(): number; + + /** + * Computes length of this vector. + */ + length(): number; + + /** + * Computes the Manhattan length of this vector. + * + * see {@link http://en.wikipedia.org/wiki/Taxicab_geometry|Wikipedia: Taxicab Geometry} + */ + manhattanLength(): number; + + /** + * Normalizes this vector. + */ + normalize(): this; + + /** + * Normalizes this vector and multiplies it by l. + */ + setLength(length: number): this; + + /** + * Linearly interpolate between this vector and v with alpha factor. + */ + lerp(v: Vector4Like, alpha: number): this; + + lerpVectors(v1: Vector4Like, v2: Vector4Like, alpha: number): this; + + /** + * Checks for strict equality of this vector and v. + */ + equals(v: Vector4Like): boolean; + + /** + * Sets this vector's x, y, z and w value from the provided array or array-like. + * @param array the source array or array-like. + * @param offset (optional) offset into the array. Default is 0. + */ + fromArray(array: number[] | ArrayLike, offset?: number): this; + + /** + * Returns an array [x, y, z, w], or copies x, y, z and w into the provided array. + * @param array (optional) array to store the vector to. If this is not provided, a new array will be created. + * @param offset (optional) optional offset into the array. + * @return The created or provided array. + */ + toArray(array?: number[], offset?: number): number[]; + toArray(array?: Vector4Tuple, offset?: 0): Vector4Tuple; + + /** + * Copies x, y, z and w into the provided array-like. + * @param array array-like to store the vector to. + * @param offset (optional) optional offset into the array-like. + * @return The provided array-like. + */ + toArray(array: ArrayLike, offset?: number): ArrayLike; + + fromBufferAttribute(attribute: BufferAttribute, index: number): this; + + /** + * Sets this vector's x, y, z and w from Math.random + */ + random(): this; + + /** + * Iterating through a Vector4 instance will yield its components (x, y, z, w) in the corresponding order. + */ + [Symbol.iterator](): Iterator; +} diff --git a/src-testing/src/math/interpolants/CubicInterpolant.d.ts b/src-testing/src/math/interpolants/CubicInterpolant.d.ts new file mode 100644 index 000000000..282b98d7e --- /dev/null +++ b/src-testing/src/math/interpolants/CubicInterpolant.d.ts @@ -0,0 +1,7 @@ +import { Interpolant } from "../Interpolant.js"; + +export class CubicInterpolant extends Interpolant { + constructor(parameterPositions: any, samplesValues: any, sampleSize: number, resultBuffer?: any); + + interpolate_(i1: number, t0: number, t: number, t1: number): any; +} diff --git a/src-testing/src/math/interpolants/DiscreteInterpolant.d.ts b/src-testing/src/math/interpolants/DiscreteInterpolant.d.ts new file mode 100644 index 000000000..28bd458b8 --- /dev/null +++ b/src-testing/src/math/interpolants/DiscreteInterpolant.d.ts @@ -0,0 +1,7 @@ +import { Interpolant } from "../Interpolant.js"; + +export class DiscreteInterpolant extends Interpolant { + constructor(parameterPositions: any, samplesValues: any, sampleSize: number, resultBuffer?: any); + + interpolate_(i1: number, t0: number, t: number, t1: number): any; +} diff --git a/src-testing/src/math/interpolants/LinearInterpolant.d.ts b/src-testing/src/math/interpolants/LinearInterpolant.d.ts new file mode 100644 index 000000000..e6ff11c0b --- /dev/null +++ b/src-testing/src/math/interpolants/LinearInterpolant.d.ts @@ -0,0 +1,7 @@ +import { Interpolant } from "../Interpolant.js"; + +export class LinearInterpolant extends Interpolant { + constructor(parameterPositions: any, samplesValues: any, sampleSize: number, resultBuffer?: any); + + interpolate_(i1: number, t0: number, t: number, t1: number): any; +} diff --git a/src-testing/src/math/interpolants/QuaternionLinearInterpolant.d.ts b/src-testing/src/math/interpolants/QuaternionLinearInterpolant.d.ts new file mode 100644 index 000000000..dccb66976 --- /dev/null +++ b/src-testing/src/math/interpolants/QuaternionLinearInterpolant.d.ts @@ -0,0 +1,7 @@ +import { Interpolant } from "../Interpolant.js"; + +export class QuaternionLinearInterpolant extends Interpolant { + constructor(parameterPositions: any, samplesValues: any, sampleSize: number, resultBuffer?: any); + + interpolate_(i1: number, t0: number, t: number, t1: number): any; +} diff --git a/src-testing/src/nodes/Nodes.ts b/src-testing/src/nodes/Nodes.ts new file mode 100644 index 000000000..648eec734 --- /dev/null +++ b/src-testing/src/nodes/Nodes.ts @@ -0,0 +1,144 @@ +// constants +export * from './core/constants.js'; + +// core +export { default as AssignNode } from './core/AssignNode.js'; +export { default as AttributeNode } from './core/AttributeNode.js'; +export { default as BypassNode } from './core/BypassNode.js'; +export { default as CacheNode } from './core/CacheNode.js'; +export { default as ConstNode } from './core/ConstNode.js'; +export { default as ContextNode } from './core/ContextNode.js'; +export { default as IndexNode } from './core/IndexNode.js'; +export { default as LightingModel } from './core/LightingModel.js'; +export { default as Node } from './core/Node.js'; +export { default as VarNode } from './core/VarNode.js'; +export { default as NodeAttribute } from './core/NodeAttribute.js'; +export { default as NodeBuilder } from './core/NodeBuilder.js'; +export { default as NodeCache } from './core/NodeCache.js'; +export { default as NodeCode } from './core/NodeCode.js'; +export { default as NodeFrame } from './core/NodeFrame.js'; +export { default as NodeFunctionInput } from './core/NodeFunctionInput.js'; +export { default as NodeUniform } from './core/NodeUniform.js'; +export { default as NodeVar } from './core/NodeVar.js'; +export { default as NodeVarying } from './core/NodeVarying.js'; +export { default as ParameterNode } from './core/ParameterNode.js'; +export { default as PropertyNode } from './core/PropertyNode.js'; +export { default as StackNode } from './core/StackNode.js'; +export { default as TempNode } from './core/TempNode.js'; +export { default as UniformGroupNode } from './core/UniformGroupNode.js'; +export { default as UniformNode } from './core/UniformNode.js'; +export { default as VaryingNode } from './core/VaryingNode.js'; +export { default as OutputStructNode } from './core/OutputStructNode.js'; +export { default as MRTNode } from './core/MRTNode.js'; + +import * as NodeUtils from './core/NodeUtils.js'; +export { NodeUtils }; + +// utils +export { default as ArrayElementNode } from './utils/ArrayElementNode.js'; +export { default as ConvertNode } from './utils/ConvertNode.js'; +export { default as EquirectUVNode } from './utils/EquirectUVNode.js'; +export { default as FunctionOverloadingNode } from './utils/FunctionOverloadingNode.js'; +export { default as JoinNode } from './utils/JoinNode.js'; +export { default as LoopNode } from './utils/LoopNode.js'; +export { default as MatcapUVNode } from './utils/MatcapUVNode.js'; +export { default as MaxMipLevelNode } from './utils/MaxMipLevelNode.js'; +export { default as RemapNode } from './utils/RemapNode.js'; +export { default as RotateNode } from './utils/RotateNode.js'; +export { default as SetNode } from './utils/SetNode.js'; +export { default as SplitNode } from './utils/SplitNode.js'; +export { default as SpriteSheetUVNode } from './utils/SpriteSheetUVNode.js'; +export { default as StorageArrayElementNode } from './utils/StorageArrayElementNode.js'; +export { default as TriplanarTexturesNode } from './utils/TriplanarTexturesNode.js'; +export { default as ReflectorNode } from './utils/ReflectorNode.js'; +export { default as RTTNode } from './utils/RTTNode.js'; + +// accessors +export { default as UniformArrayNode } from './accessors/UniformArrayNode.js'; +export { default as BufferAttributeNode } from './accessors/BufferAttributeNode.js'; +export { default as BufferNode } from './accessors/BufferNode.js'; +export { default as VertexColorNode } from './accessors/VertexColorNode.js'; +export { default as CubeTextureNode } from './accessors/CubeTextureNode.js'; +export { default as InstanceNode } from './accessors/InstanceNode.js'; +export { default as BatchNode } from './accessors/BatchNode.js'; +export { default as MaterialNode } from './accessors/MaterialNode.js'; +export { default as MaterialReferenceNode } from './accessors/MaterialReferenceNode.js'; +export { default as RendererReferenceNode } from './accessors/RendererReferenceNode.js'; +export { default as MorphNode } from './accessors/MorphNode.js'; +export { default as ModelNode } from './accessors/ModelNode.js'; +export { default as ModelViewProjectionNode } from './accessors/ModelViewProjectionNode.js'; +export { default as Object3DNode } from './accessors/Object3DNode.js'; +export { default as PointUVNode } from './accessors/PointUVNode.js'; +export { default as ReferenceNode } from './accessors/ReferenceNode.js'; +export { default as SkinningNode } from './accessors/SkinningNode.js'; +export { default as SceneNode } from './accessors/SceneNode.js'; +export { default as StorageBufferNode } from './accessors/StorageBufferNode.js'; +export { default as TextureNode } from './accessors/TextureNode.js'; +export { default as TextureSizeNode } from './accessors/TextureSizeNode.js'; +export { default as StorageTextureNode } from './accessors/StorageTextureNode.js'; +export { default as Texture3DNode } from './accessors/Texture3DNode.js'; +export { default as UserDataNode } from './accessors/UserDataNode.js'; + +// display +export { default as BumpMapNode } from './display/BumpMapNode.js'; +export { default as ColorSpaceNode } from './display/ColorSpaceNode.js'; +export { default as FrontFacingNode } from './display/FrontFacingNode.js'; +export { default as NormalMapNode } from './display/NormalMapNode.js'; +export { default as PosterizeNode } from './display/PosterizeNode.js'; +export { default as ToneMappingNode } from './display/ToneMappingNode.js'; +export { default as ScreenNode } from './display/ScreenNode.js'; +export { default as ViewportTextureNode } from './display/ViewportTextureNode.js'; +export { default as ViewportSharedTextureNode } from './display/ViewportSharedTextureNode.js'; +export { default as ViewportDepthTextureNode } from './display/ViewportDepthTextureNode.js'; +export { default as ViewportDepthNode } from './display/ViewportDepthNode.js'; +export { default as RenderOutputNode } from './display/RenderOutputNode.js'; +export { default as PassNode } from './display/PassNode.js'; +export { default as ToonOutlinePassNode } from './display/ToonOutlinePassNode.js'; + +// code +export { default as ExpressionNode } from './code/ExpressionNode.js'; +export { default as CodeNode } from './code/CodeNode.js'; +export { default as FunctionCallNode } from './code/FunctionCallNode.js'; +export { default as FunctionNode } from './code/FunctionNode.js'; +export { default as ScriptableNode } from './code/ScriptableNode.js'; +export { default as ScriptableValueNode } from './code/ScriptableValueNode.js'; + +// fog +export { default as FogNode } from './fog/FogNode.js'; +export { default as FogRangeNode } from './fog/FogRangeNode.js'; +export { default as FogExp2Node } from './fog/FogExp2Node.js'; + +// geometry +export { default as RangeNode } from './geometry/RangeNode.js'; + +// gpgpu +export { default as ComputeNode } from './gpgpu/ComputeNode.js'; + +// lighting +export { default as PointLightNode } from './lighting/PointLightNode.js'; +export { default as DirectionalLightNode } from './lighting/DirectionalLightNode.js'; +export { default as RectAreaLightNode } from './lighting/RectAreaLightNode.js'; +export { default as SpotLightNode } from './lighting/SpotLightNode.js'; +export { default as IESSpotLightNode } from './lighting/IESSpotLightNode.js'; +export { default as AmbientLightNode } from './lighting/AmbientLightNode.js'; +export { default as LightsNode } from './lighting/LightsNode.js'; +export { default as LightingNode } from './lighting/LightingNode.js'; +export { default as LightingContextNode } from './lighting/LightingContextNode.js'; +export { default as HemisphereLightNode } from './lighting/HemisphereLightNode.js'; +export { default as LightProbeNode } from './lighting/LightProbeNode.js'; +export { default as EnvironmentNode } from './lighting/EnvironmentNode.js'; +export { default as BasicEnvironmentNode } from './lighting/BasicEnvironmentNode.js'; +export { default as IrradianceNode } from './lighting/IrradianceNode.js'; +export { default as AONode } from './lighting/AONode.js'; +export { default as AnalyticLightNode } from './lighting/AnalyticLightNode.js'; +export { default as ShadowNode } from './lighting/ShadowNode.js'; + +// pmrem +export { default as PMREMNode } from './pmrem/PMREMNode.js'; + +// parsers +export { default as GLSLNodeParser } from './parsers/GLSLNodeParser.js'; // @TODO: Move to jsm/renderers/webgl. + +// lighting models +export { default as PhongLightingModel } from './functions/PhongLightingModel.js'; +export { default as PhysicalLightingModel } from './functions/PhysicalLightingModel.js'; diff --git a/src-testing/src/nodes/TSL.d.ts b/src-testing/src/nodes/TSL.d.ts new file mode 100644 index 000000000..e3e3e439b --- /dev/null +++ b/src-testing/src/nodes/TSL.d.ts @@ -0,0 +1,156 @@ +// constants +export * from "./core/constants.js"; + +// core +export * from "./core/AssignNode.js"; +export * from "./core/AttributeNode.js"; +export * from "./core/BypassNode.js"; +export * from "./core/CacheNode.js"; +export * from "./core/ContextNode.js"; +export * from "./core/IndexNode.js"; +export * from "./core/MRTNode.js"; +export * from "./core/OutputStructNode.js"; +export * from "./core/ParameterNode.js"; +export * from "./core/PropertyNode.js"; +export * from "./core/StackNode.js"; +export * from "./core/UniformGroupNode.js"; +export * from "./core/UniformNode.js"; +export * from "./core/VaryingNode.js"; + +// math +export * from "./math/Hash.js"; +export * from "./math/MathUtils.js"; +export * from "./math/TriNoise3D.js"; + +// utils +export * from "./utils/EquirectUVNode.js"; +export * from "./utils/FunctionOverloadingNode.js"; +export * from "./utils/LoopNode.js"; +export * from "./utils/MatcapUVNode.js"; +export * from "./utils/MaxMipLevelNode.js"; +export * from "./utils/Oscillators.js"; +export * from "./utils/Packing.js"; +export * from "./utils/PostProcessingUtils.js"; +export * from "./utils/ReflectorNode.js"; +export * from "./utils/RemapNode.js"; +export * from "./utils/RotateNode.js"; +export * from "./utils/RTTNode.js"; +export * from "./utils/SpriteSheetUVNode.js"; +export * from "./utils/SpriteUtils.js"; +export * from "./utils/Timer.js"; +export * from "./utils/TriplanarTexturesNode.js"; +export * from "./utils/UVUtils.js"; +export * from "./utils/ViewportUtils.js"; + +// three.js shading language +export * from "./tsl/TSLBase.js"; + +// accessors +export * from "./accessors/AccessorsUtils.js"; +export * from "./accessors/BatchNode.js"; +export * from "./accessors/Bitangent.js"; +export * from "./accessors/BufferAttributeNode.js"; +export * from "./accessors/BufferNode.js"; +export * from "./accessors/Camera.js"; +export * from "./accessors/CubeTextureNode.js"; +export * from "./accessors/InstanceNode.js"; +export * from "./accessors/MaterialNode.js"; +export * from "./accessors/MaterialProperties.js"; +export * from "./accessors/MaterialReferenceNode.js"; +export * from "./accessors/ModelNode.js"; +export * from "./accessors/ModelViewProjectionNode.js"; +export * from "./accessors/MorphNode.js"; +export * from "./accessors/Normal.js"; +export * from "./accessors/Object3DNode.js"; +export * from "./accessors/PointUVNode.js"; +export * from "./accessors/Position.js"; +export * from "./accessors/ReferenceNode.js"; +export * from "./accessors/ReflectVector.js"; +export * from "./accessors/RendererReferenceNode.js"; +export * from "./accessors/SceneNode.js"; +export * from "./accessors/SkinningNode.js"; +export * from "./accessors/StorageBufferNode.js"; +export * from "./accessors/StorageTextureNode.js"; +export * from "./accessors/Tangent.js"; +export * from "./accessors/Texture3DNode.js"; +export * from "./accessors/TextureBicubic.js"; +export * from "./accessors/TextureNode.js"; +export * from "./accessors/TextureSizeNode.js"; +export * from "./accessors/UniformArrayNode.js"; +export * from "./accessors/UserDataNode.js"; +export * from "./accessors/UV.js"; +export * from "./accessors/VelocityNode.js"; +export * from "./accessors/VertexColorNode.js"; + +// display +export * from "./display/BlendMode.js"; +export * from "./display/BumpMapNode.js"; +export * from "./display/ColorAdjustment.js"; +export * from "./display/ColorSpaceNode.js"; +export * from "./display/FrontFacingNode.js"; +export * from "./display/NormalMapNode.js"; +export * from "./display/PosterizeNode.js"; +export * from "./display/RenderOutputNode.js"; +export * from "./display/ScreenNode.js"; +export * from "./display/ToneMappingNode.js"; +export * from "./display/ToonOutlinePassNode.js"; +export * from "./display/ViewportDepthNode.js"; +export * from "./display/ViewportDepthTextureNode.js"; +export * from "./display/ViewportSharedTextureNode.js"; +export * from "./display/ViewportTextureNode.js"; + +export * from "./display/PassNode.js"; + +export * from "./display/ColorSpaceFunctions.js"; +export * from "./display/ToneMappingFunctions.js"; + +// code +export * from "./code/CodeNode.js"; +export * from "./code/ExpressionNode.js"; +export * from "./code/FunctionCallNode.js"; +export * from "./code/FunctionNode.js"; +export * from "./code/ScriptableNode.js"; +export * from "./code/ScriptableValueNode.js"; + +// fog +export * from "./fog/FogExp2Node.js"; +export * from "./fog/FogNode.js"; +export * from "./fog/FogRangeNode.js"; + +// geometry +export * from "./geometry/RangeNode.js"; + +// gpgpu +export * from "./gpgpu/ComputeNode.js"; + +// lighting +export * from "./lighting/LightingContextNode.js"; +export * from "./lighting/LightNode.js"; +export * from "./lighting/LightsNode.js"; +export * from "./lighting/PointLightNode.js"; +export * from "./lighting/ShadowNode.js"; + +// pmrem +export * from "./pmrem/PMREMNode.js"; +export * from "./pmrem/PMREMUtils.js"; + +// procedural +export * from "./procedural/Checker.js"; + +// materialX +export * from "./materialx/MaterialXNodes.js"; + +// functions +export { default as BRDF_GGX } from "./functions/BSDF/BRDF_GGX.js"; +export { default as BRDF_Lambert } from "./functions/BSDF/BRDF_Lambert.js"; +export { default as D_GGX } from "./functions/BSDF/D_GGX.js"; +export { default as DFGApprox } from "./functions/BSDF/DFGApprox.js"; +export { default as F_Schlick } from "./functions/BSDF/F_Schlick.js"; +export { default as Schlick_to_F0 } from "./functions/BSDF/Schlick_to_F0.js"; +export { default as V_GGX_SmithCorrelated } from "./functions/BSDF/V_GGX_SmithCorrelated.js"; + +export * from "./lighting/LightUtils.js"; + +export { default as getGeometryRoughness } from "./functions/material/getGeometryRoughness.js"; +export { default as getRoughness } from "./functions/material/getRoughness.js"; +export { default as getShIrradianceAt } from "./functions/material/getShIrradianceAt.js"; diff --git a/src-testing/src/nodes/accessors/AccessorsUtils.d.ts b/src-testing/src/nodes/accessors/AccessorsUtils.d.ts new file mode 100644 index 000000000..e42044673 --- /dev/null +++ b/src-testing/src/nodes/accessors/AccessorsUtils.d.ts @@ -0,0 +1,9 @@ +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +export const TBNViewMatrix: ShaderNodeObject; + +export const parallaxDirection: ShaderNodeObject; +export const parallaxUV: (uv: ShaderNodeObject, scale: NodeRepresentation) => ShaderNodeObject; + +export const transformedBentNormalView: ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/BatchNode.d.ts b/src-testing/src/nodes/accessors/BatchNode.d.ts new file mode 100644 index 000000000..51db8b6bb --- /dev/null +++ b/src-testing/src/nodes/accessors/BatchNode.d.ts @@ -0,0 +1,13 @@ +import { BatchedMesh } from "../../objects/BatchedMesh.js"; +import Node from "../core/Node.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +export default class BatchNode extends Node { + batchMesh: BatchedMesh; + + batchingIdNode: Node | null; + + constructor(batchMesh: BatchedMesh); +} + +export const batch: (batchMesh: BatchedMesh) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/Bitangent.d.ts b/src-testing/src/nodes/accessors/Bitangent.d.ts new file mode 100644 index 000000000..bcdc4d6e2 --- /dev/null +++ b/src-testing/src/nodes/accessors/Bitangent.d.ts @@ -0,0 +1,9 @@ +import MathNode from "../math/MathNode.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +export const bitangentGeometry: ShaderNodeObject; +export const bitangentLocal: ShaderNodeObject; +export const bitangentView: ShaderNodeObject; +export const bitangentWorld: ShaderNodeObject; +export const transformedBitangentView: ShaderNodeObject; +export const transformedBitangentWorld: ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/BufferAttributeNode.ts b/src-testing/src/nodes/accessors/BufferAttributeNode.ts new file mode 100644 index 000000000..97456dbc2 --- /dev/null +++ b/src-testing/src/nodes/accessors/BufferAttributeNode.ts @@ -0,0 +1,135 @@ +import InputNode from '../core/InputNode.js'; +import { nodeObject, addMethodChaining } from '../tsl/TSLCore.js'; +import { varying } from '../core/VaryingNode.js'; + +import { InterleavedBufferAttribute } from '../../core/InterleavedBufferAttribute.js'; +import { InterleavedBuffer } from '../../core/InterleavedBuffer.js'; +import { StaticDrawUsage, DynamicDrawUsage } from '../../constants.js'; + +class BufferAttributeNode extends InputNode { + static get type() { + return 'BufferAttributeNode'; + } + + constructor(value, bufferType = null, bufferStride = 0, bufferOffset = 0) { + super(value, bufferType); + + this.isBufferNode = true; + + this.bufferType = bufferType; + this.bufferStride = bufferStride; + this.bufferOffset = bufferOffset; + + this.usage = StaticDrawUsage; + this.instanced = false; + + this.attribute = null; + + this.global = true; + + if (value && value.isBufferAttribute === true) { + this.attribute = value; + this.usage = value.usage; + this.instanced = value.isInstancedBufferAttribute; + } + } + + getHash(builder) { + if (this.bufferStride === 0 && this.bufferOffset === 0) { + let bufferData = builder.globalCache.getData(this.value); + + if (bufferData === undefined) { + bufferData = { + node: this, + }; + + builder.globalCache.setData(this.value, bufferData); + } + + return bufferData.node.uuid; + } + + return this.uuid; + } + + getNodeType(builder) { + if (this.bufferType === null) { + this.bufferType = builder.getTypeFromAttribute(this.attribute); + } + + return this.bufferType; + } + + setup(builder) { + if (this.attribute !== null) return; + + const type = this.getNodeType(builder); + const array = this.value; + const itemSize = builder.getTypeLength(type); + const stride = this.bufferStride || itemSize; + const offset = this.bufferOffset; + + const buffer = array.isInterleavedBuffer === true ? array : new InterleavedBuffer(array, stride); + const bufferAttribute = new InterleavedBufferAttribute(buffer, itemSize, offset); + + buffer.setUsage(this.usage); + + this.attribute = bufferAttribute; + this.attribute.isInstancedBufferAttribute = this.instanced; // @TODO: Add a possible: InstancedInterleavedBufferAttribute + } + + generate(builder) { + const nodeType = this.getNodeType(builder); + + const nodeAttribute = builder.getBufferAttributeFromNode(this, nodeType); + const propertyName = builder.getPropertyName(nodeAttribute); + + let output = null; + + if (builder.shaderStage === 'vertex' || builder.shaderStage === 'compute') { + this.name = propertyName; + + output = propertyName; + } else { + const nodeVarying = varying(this); + + output = nodeVarying.build(builder, nodeType); + } + + return output; + } + + getInputType(/*builder*/) { + return 'bufferAttribute'; + } + + setUsage(value) { + this.usage = value; + + if (this.attribute && this.attribute.isBufferAttribute === true) { + this.attribute.usage = value; + } + + return this; + } + + setInstanced(value) { + this.instanced = value; + + return this; + } +} + +export default BufferAttributeNode; + +export const bufferAttribute = (array, type, stride, offset) => + nodeObject(new BufferAttributeNode(array, type, stride, offset)); +export const dynamicBufferAttribute = (array, type, stride, offset) => + bufferAttribute(array, type, stride, offset).setUsage(DynamicDrawUsage); + +export const instancedBufferAttribute = (array, type, stride, offset) => + bufferAttribute(array, type, stride, offset).setInstanced(true); +export const instancedDynamicBufferAttribute = (array, type, stride, offset) => + dynamicBufferAttribute(array, type, stride, offset).setInstanced(true); + +addMethodChaining('toAttribute', bufferNode => bufferAttribute(bufferNode.value)); diff --git a/src-testing/src/nodes/accessors/BufferNode.d.ts b/src-testing/src/nodes/accessors/BufferNode.d.ts new file mode 100644 index 000000000..4db9ccccd --- /dev/null +++ b/src-testing/src/nodes/accessors/BufferNode.d.ts @@ -0,0 +1,17 @@ +import UniformNode from "../core/UniformNode.js"; +import { NodeOrType, ShaderNodeObject } from "../tsl/TSLCore.js"; + +export default class BufferNode extends UniformNode { + isBufferNode: true; + + bufferType: string; + bufferCount: number; + + constructor(value: unknown, bufferType: string, bufferCount?: number); +} + +export const buffer: ( + value: unknown, + nodeOrType: NodeOrType, + count: number, +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/Camera.d.ts b/src-testing/src/nodes/accessors/Camera.d.ts new file mode 100644 index 000000000..6fd332889 --- /dev/null +++ b/src-testing/src/nodes/accessors/Camera.d.ts @@ -0,0 +1,14 @@ +import { Matrix3 } from "../../math/Matrix3.js"; +import { Matrix4 } from "../../math/Matrix4.js"; +import { Vector3 } from "../../math/Vector3.js"; +import UniformNode from "../core/UniformNode.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +export const cameraNear: ShaderNodeObject>; +export const cameraFar: ShaderNodeObject>; +export const cameraProjectionMatrix: ShaderNodeObject>; +export const cameraProjectionMatrixInverse: ShaderNodeObject>; +export const cameraViewMatrix: ShaderNodeObject>; +export const cameraWorldMatrix: ShaderNodeObject>; +export const cameraNormalMatrix: ShaderNodeObject>; +export const cameraPosition: ShaderNodeObject>; diff --git a/src-testing/src/nodes/accessors/ClippingNode.d.ts b/src-testing/src/nodes/accessors/ClippingNode.d.ts new file mode 100644 index 000000000..bb2cac1cd --- /dev/null +++ b/src-testing/src/nodes/accessors/ClippingNode.d.ts @@ -0,0 +1,16 @@ +import Node from "../core/Node.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +export type ClippingNodeScope = typeof ClippingNode.ALPHA_TO_COVERAGE | typeof ClippingNode.DEFAULT; + +export default class ClippingNode extends Node { + scope: ClippingNodeScope; + + constructor(scope?: ClippingNodeScope); + + static ALPHA_TO_COVERAGE: "alphaToCoverage"; + static DEFAULT: "default"; +} + +export const clipping: () => ShaderNodeObject; +export const clippingAlpha: () => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/CubeTextureNode.d.ts b/src-testing/src/nodes/accessors/CubeTextureNode.d.ts new file mode 100644 index 000000000..c25d51999 --- /dev/null +++ b/src-testing/src/nodes/accessors/CubeTextureNode.d.ts @@ -0,0 +1,28 @@ +import { CubeTexture } from "../../textures/CubeTexture.js"; +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; +import TextureNode from "./TextureNode.js"; + +declare class CubeTextureNode extends TextureNode { + isCubeTextureNode: boolean; + uvNode: ShaderNodeObject | null; + levelNode: ShaderNodeObject | null; + + constructor( + value: CubeTexture, + uvNode?: ShaderNodeObject | null, + levelNode?: ShaderNodeObject | null, + biasNode?: ShaderNodeObject | null, + ); + + getDefaultUV(): Node; +} + +export default CubeTextureNode; + +export const cubeTexture: ( + value: CubeTexture, + uvNode?: NodeRepresentation, + levelNode?: NodeRepresentation, + biasNode?: NodeRepresentation, +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/InstanceNode.d.ts b/src-testing/src/nodes/accessors/InstanceNode.d.ts new file mode 100644 index 000000000..c6cd43993 --- /dev/null +++ b/src-testing/src/nodes/accessors/InstanceNode.d.ts @@ -0,0 +1,13 @@ +import { InstancedMesh } from "../../objects/InstancedMesh.js"; +import Node from "../core/Node.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +export default class InstanceNode extends Node { + instanceMesh: InstancedMesh; + instanceMatrixNode: Node | null; + instanceColorNode: Node | null; + + constructor(instanceMesh: InstancedMesh); +} + +export const instance: (instanceMesh: InstancedMesh) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/MaterialNode.d.ts b/src-testing/src/nodes/accessors/MaterialNode.d.ts new file mode 100644 index 000000000..a29160b0e --- /dev/null +++ b/src-testing/src/nodes/accessors/MaterialNode.d.ts @@ -0,0 +1,129 @@ +import { Vector2 } from "../../math/Vector2.js"; +import Node from "../core/Node.js"; +import UniformNode from "../core/UniformNode.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +export type MaterialNodeScope = + | typeof MaterialNode.ALPHA_TEST + | typeof MaterialNode.COLOR + | typeof MaterialNode.OPACITY + | typeof MaterialNode.SHININESS + | typeof MaterialNode.SPECULAR + | typeof MaterialNode.SPECULAR_STRENGTH + | typeof MaterialNode.SPECULAR_INTENSITY + | typeof MaterialNode.SPECULAR_COLOR + | typeof MaterialNode.REFLECTIVITY + | typeof MaterialNode.ROUGHNESS + | typeof MaterialNode.METALNESS + | typeof MaterialNode.NORMAL + | typeof MaterialNode.CLEARCOAT + | typeof MaterialNode.CLEARCOAT_ROUGHNESS + | typeof MaterialNode.CLEARCOAT_NORMAL + | typeof MaterialNode.EMISSIVE + | typeof MaterialNode.ROTATION + | typeof MaterialNode.SHEEN + | typeof MaterialNode.SHEEN_ROUGHNESS + | typeof MaterialNode.ANISOTROPY + | typeof MaterialNode.IRIDESCENCE + | typeof MaterialNode.IRIDESCENCE_IOR + | typeof MaterialNode.IRIDESCENCE_THICKNESS + | typeof MaterialNode.IOR + | typeof MaterialNode.TRANSMISSION + | typeof MaterialNode.THICKNESS + | typeof MaterialNode.ATTENUATION_DISTANCE + | typeof MaterialNode.ATTENUATION_COLOR + | typeof MaterialNode.LINE_SCALE + | typeof MaterialNode.LINE_DASH_SIZE + | typeof MaterialNode.LINE_GAP_SIZE + | typeof MaterialNode.LINE_WIDTH + | typeof MaterialNode.LINE_DASH_OFFSET + | typeof MaterialNode.POINT_WIDTH + | typeof MaterialNode.DISPERSION + | typeof MaterialNode.LIGHT_MAP + | typeof MaterialNode.AO_MAP + | typeof MaterialNode.REFRACTION_RATIO; + +export default class MaterialNode extends Node { + static ALPHA_TEST: "alphaTest"; + static COLOR: "color"; + static OPACITY: "opacity"; + static SHININESS: "shininess"; + static SPECULAR: "specular"; + static SPECULAR_STRENGTH: "specularStrength"; + static SPECULAR_INTENSITY: "specularIntensity"; + static SPECULAR_COLOR: "specularColor"; + static REFLECTIVITY: "reflectivity"; + static ROUGHNESS: "roughness"; + static METALNESS: "metalness"; + static NORMAL: "normal"; + static CLEARCOAT: "clearcoat"; + static CLEARCOAT_ROUGHNESS: "clearcoatRoughness"; + static CLEARCOAT_NORMAL: "clearcoatNormal"; + static EMISSIVE: "emissive"; + static ROTATION: "rotation"; + static SHEEN: "sheen"; + static SHEEN_ROUGHNESS: "sheenRoughness"; + static ANISOTROPY: "anisotropy"; + static IRIDESCENCE: "iridescence"; + static IRIDESCENCE_IOR: "iridescenceIOR"; + static IRIDESCENCE_THICKNESS: "iridescenceThickness"; + static IOR: "ior"; + static TRANSMISSION: "transmission"; + static THICKNESS: "thickness"; + static ATTENUATION_DISTANCE: "attenuationDistance"; + static ATTENUATION_COLOR: "attenuationColor"; + static LINE_SCALE: "scale"; + static LINE_DASH_SIZE: "dashSize"; + static LINE_GAP_SIZE: "gapSize"; + static LINE_WIDTH: "linewidth"; + static LINE_DASH_OFFSET: "dashOffset"; + static POINT_WIDTH: "pointWidth"; + static DISPERSION: "dispersion"; + static LIGHT_MAP: "light"; + static AO_MAP: "ao"; + static REFRACTION_RATIO: "refractionRatio"; + + scope: MaterialNodeScope; + constructor(scope?: MaterialNodeScope); +} + +export const materialAlphaTest: ShaderNodeObject; +export const materialColor: ShaderNodeObject; +export const materialShininess: ShaderNodeObject; +export const materialEmissive: ShaderNodeObject; +export const materialOpacity: ShaderNodeObject; +export const materialSpecular: ShaderNodeObject; + +export const materialSpecularIntensity: ShaderNodeObject; +export const materialSpecularColor: ShaderNodeObject; + +export const materialSpecularStrength: ShaderNodeObject; +export const materialReflectivity: ShaderNodeObject; +export const materialRoughness: ShaderNodeObject; +export const materialMetalness: ShaderNodeObject; +export const materialNormal: ShaderNodeObject; +export const materialClearcoat: ShaderNodeObject; +export const materialClearcoatRoughness: ShaderNodeObject; +export const materialClearcoatNormal: ShaderNodeObject; +export const materialRotation: ShaderNodeObject; +export const materialSheen: ShaderNodeObject; +export const materialSheenRoughness: ShaderNodeObject; +export const materialAnisotropy: ShaderNodeObject; +export const materialIridescence: ShaderNodeObject; +export const materialIridescenceIOR: ShaderNodeObject; +export const materialIridescenceThickness: ShaderNodeObject; +export const materialTransmission: ShaderNodeObject; +export const materialThickness: ShaderNodeObject; +export const materialIOR: ShaderNodeObject; +export const materialAttenuationDistance: ShaderNodeObject; +export const materialAttenuationColor: ShaderNodeObject; +export const materialLineScale: ShaderNodeObject; +export const materialLineDashSize: ShaderNodeObject; +export const materialLineGapSize: ShaderNodeObject; +export const materialLineWidth: ShaderNodeObject; +export const materialLineDashOffset: ShaderNodeObject; +export const materialPointWidth: ShaderNodeObject; +export const materialDispersion: ShaderNodeObject; +export const materialLightMap: ShaderNodeObject; +export const materialAOMap: ShaderNodeObject; +export const materialAnisotropyVector: ShaderNodeObject>; diff --git a/src-testing/src/nodes/accessors/MaterialProperties.d.ts b/src-testing/src/nodes/accessors/MaterialProperties.d.ts new file mode 100644 index 000000000..3e07ecf0b --- /dev/null +++ b/src-testing/src/nodes/accessors/MaterialProperties.d.ts @@ -0,0 +1,4 @@ +import UniformNode from "../core/UniformNode.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +export const materialRefractionRatio: ShaderNodeObject>; diff --git a/src-testing/src/nodes/accessors/MaterialReferenceNode.d.ts b/src-testing/src/nodes/accessors/MaterialReferenceNode.d.ts new file mode 100644 index 000000000..7b0cdf4ac --- /dev/null +++ b/src-testing/src/nodes/accessors/MaterialReferenceNode.d.ts @@ -0,0 +1,15 @@ +import { Material } from "../../materials/Material.js"; +import { NodeOrType, ShaderNodeObject } from "../tsl/TSLCore.js"; +import ReferenceNode from "./ReferenceNode.js"; + +export default class MaterialReferenceNode extends ReferenceNode { + readonly isMaterialReferenceNode: true; + + constructor(property: string, inputType: string, material?: Material | null); +} + +export const materialReference: ( + name: string, + nodeOrType: NodeOrType, + material?: Material | null, +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/ModelNode.d.ts b/src-testing/src/nodes/accessors/ModelNode.d.ts new file mode 100644 index 000000000..12280a2b6 --- /dev/null +++ b/src-testing/src/nodes/accessors/ModelNode.d.ts @@ -0,0 +1,24 @@ +import { Matrix4 } from "../../math/Matrix4.js"; +import Node from "../core/Node.js"; +import { UniformNode } from "../Nodes.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; +import Object3DNode from "./Object3DNode.js"; + +/** + * Similar to {@link Object3DNode} but the object comes from {@link NodeFrame} + */ +export default class ModelNode extends Object3DNode { + constructor(scope: string); +} + +export const modelDirection: ShaderNodeObject; +export const modelWorldMatrix: ShaderNodeObject; +export const modelPosition: ShaderNodeObject; +export const modelScale: ShaderNodeObject; +export const modelViewPosition: ShaderNodeObject; +export const modelNormalMatrix: ShaderNodeObject; +export const modelWorldMatrixInverse: ShaderNodeObject>; +export const modelViewMatrix: ShaderNodeObject; + +export const highPrecisionModelViewMatrix: ShaderNodeObject; +export const highPrecisionModelNormalViewMatrix: ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/ModelViewProjectionNode.d.ts b/src-testing/src/nodes/accessors/ModelViewProjectionNode.d.ts new file mode 100644 index 000000000..18302d638 --- /dev/null +++ b/src-testing/src/nodes/accessors/ModelViewProjectionNode.d.ts @@ -0,0 +1,8 @@ +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +export default class ModelViewProjectionNode extends Node { + constructor(positionNode?: Node); +} + +export const modelViewProjection: (position?: NodeRepresentation) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/MorphNode.d.ts b/src-testing/src/nodes/accessors/MorphNode.d.ts new file mode 100644 index 000000000..8987acf6e --- /dev/null +++ b/src-testing/src/nodes/accessors/MorphNode.d.ts @@ -0,0 +1,15 @@ +import { Mesh } from "../../objects/Mesh.js"; +import Node from "../core/Node.js"; +import UniformNode from "../core/UniformNode.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +declare class MorphNode extends Node { + mesh: Mesh; + morphBaseInfluence: UniformNode; + + constructor(mesh: Mesh); +} + +export default MorphNode; + +export const morphReference: (mesh: Mesh) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/Normal.d.ts b/src-testing/src/nodes/accessors/Normal.d.ts new file mode 100644 index 000000000..706130a8d --- /dev/null +++ b/src-testing/src/nodes/accessors/Normal.d.ts @@ -0,0 +1,25 @@ +import { Matrix4 } from "../../math/Matrix4.js"; +import AttributeNode from "../core/AttributeNode.js"; +import Node from "../core/Node.js"; +import VarNode from "../core/VarNode.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +export const normalGeometry: ShaderNodeObject; + +export const normalLocal: ShaderNodeObject; + +export const normalFlat: ShaderNodeObject; + +export const normalView: ShaderNodeObject; + +export const normalWorld: ShaderNodeObject; + +export const transformedNormalView: ShaderNodeObject; + +export const transformedNormalWorld: ShaderNodeObject; + +export const transformedClearcoatNormalView: ShaderNodeObject; + +export const transformNormal: (normal: Node, matrix?: Node) => ShaderNodeObject; + +export const transformNormalToView: (normal: Node) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/Object3DNode.d.ts b/src-testing/src/nodes/accessors/Object3DNode.d.ts new file mode 100644 index 000000000..21e6776c9 --- /dev/null +++ b/src-testing/src/nodes/accessors/Object3DNode.d.ts @@ -0,0 +1,22 @@ +import { Object3D } from "../../core/Object3D.js"; +import Node from "../core/Node.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +export default class Object3DNode extends Node { + scope: string; + object3d: Object3D | null; + + constructor(scope: string, object3d?: Object3D | null); + + static WORLD_MATRIX: "worldMatrix"; + static POSITION: "position"; + static SCALE: "scale"; + static VIEW_POSITION: "viewPosition"; + static DIRECTION: "direction"; +} + +export const objectDirection: (object3d: Object3D) => ShaderNodeObject; +export const objectWorldMatrix: (object3d: Object3D) => ShaderNodeObject; +export const objectPosition: (object3d: Object3D) => ShaderNodeObject; +export const objectScale: (object3d: Object3D) => ShaderNodeObject; +export const objectViewPosition: (object3d: Object3D) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/PointUVNode.d.ts b/src-testing/src/nodes/accessors/PointUVNode.d.ts new file mode 100644 index 000000000..2220e5563 --- /dev/null +++ b/src-testing/src/nodes/accessors/PointUVNode.d.ts @@ -0,0 +1,10 @@ +import Node from "../core/Node.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +export default class PointUVNode extends Node { + isPointUVNode: true; + + constructor(); +} + +export const pointUV: ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/Position.d.ts b/src-testing/src/nodes/accessors/Position.d.ts new file mode 100644 index 000000000..a9f6fc811 --- /dev/null +++ b/src-testing/src/nodes/accessors/Position.d.ts @@ -0,0 +1,10 @@ +import Node from "../core/Node.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +export const positionGeometry: ShaderNodeObject; +export const positionLocal: ShaderNodeObject; +export const positionPrevious: ShaderNodeObject; +export const positionWorld: ShaderNodeObject; +export const positionWorldDirection: ShaderNodeObject; +export const positionView: ShaderNodeObject; +export const positionViewDirection: ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/ReferenceBaseNode.d.ts b/src-testing/src/nodes/accessors/ReferenceBaseNode.d.ts new file mode 100644 index 000000000..586fde349 --- /dev/null +++ b/src-testing/src/nodes/accessors/ReferenceBaseNode.d.ts @@ -0,0 +1,27 @@ +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +declare class ReferenceBaseNode extends Node { + property: string; + uniformType: string; + object: T; + count: number | null; + + properties: string[]; + reference: T | null; + node: Node | null; + + constructor(property: string, uniformType: string, object?: T | null, count?: number | null); + + setNodeType(uniformType: string): void; +} + +export default ReferenceBaseNode; + +export const reference: (name: string, type: string, object: T) => ShaderNodeObject>; +export const referenceBuffer: ( + name: string, + type: string, + count: number, + object: T, +) => ShaderNodeObject>; diff --git a/src-testing/src/nodes/accessors/ReferenceNode.d.ts b/src-testing/src/nodes/accessors/ReferenceNode.d.ts new file mode 100644 index 000000000..1dea4d31f --- /dev/null +++ b/src-testing/src/nodes/accessors/ReferenceNode.d.ts @@ -0,0 +1,29 @@ +import Node from "../core/Node.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +declare class ReferenceNode extends Node { + property: string; + + uniformType: string; + + object: T; + count: number | null; + + properties: string[]; + reference: T | null; + node: Node | null; + + constructor(property: string, uniformType: string, object?: T | null, count?: number | null); + + setNodeType(uniformType: string): void; +} + +export default ReferenceNode; + +export const reference: (name: string, type: string, object: T) => ShaderNodeObject>; +export const referenceBuffer: ( + name: string, + type: string, + count: number, + object: T, +) => ShaderNodeObject>; diff --git a/src-testing/src/nodes/accessors/ReflectVector.d.ts b/src-testing/src/nodes/accessors/ReflectVector.d.ts new file mode 100644 index 000000000..4978b4975 --- /dev/null +++ b/src-testing/src/nodes/accessors/ReflectVector.d.ts @@ -0,0 +1,9 @@ +import Node from "../core/Node.js"; +import VarNode from "../core/VarNode.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +export const reflectView: ShaderNodeObject; +export const refractView: ShaderNodeObject; + +export const reflectVector: ShaderNodeObject; +export const refractVector: ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/RendererReferenceNode.d.ts b/src-testing/src/nodes/accessors/RendererReferenceNode.d.ts new file mode 100644 index 000000000..0e100b049 --- /dev/null +++ b/src-testing/src/nodes/accessors/RendererReferenceNode.d.ts @@ -0,0 +1,15 @@ +import Renderer from "../../renderers/common/Renderer.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; +import ReferenceNode from "./ReferenceNode.js"; + +export default class RendererReferenceNode extends ReferenceNode { + renderer: Renderer | null; + + constructor(property: string, inputType: string, renderer?: Renderer | null); +} + +export const rendererReference: ( + name: string, + type: string, + renderer?: Renderer | null, +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/SceneNode.d.ts b/src-testing/src/nodes/accessors/SceneNode.d.ts new file mode 100644 index 000000000..34bdea1be --- /dev/null +++ b/src-testing/src/nodes/accessors/SceneNode.d.ts @@ -0,0 +1,20 @@ +import { Scene } from "../../scenes/Scene.js"; +import Node from "../core/Node.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +export type SceneNodeScope = typeof SceneNode.BACKGROUND_BLURRINESS | typeof SceneNode.BACKGROUND_INTENSITY; + +declare class SceneNode extends Node { + scope: SceneNodeScope; + scene: Scene | null; + + constructor(scope?: SceneNodeScope, scene?: Scene | null); + + static BACKGROUND_BLURRINESS: "backgroundBlurriness"; + static BACKGROUND_INTENSITY: "backgroundIntensity"; +} + +export default SceneNode; + +export const backgroundBlurriness: ShaderNodeObject; +export const backgroundIntensity: ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/SkinningNode.d.ts b/src-testing/src/nodes/accessors/SkinningNode.d.ts new file mode 100644 index 000000000..3bef01c33 --- /dev/null +++ b/src-testing/src/nodes/accessors/SkinningNode.d.ts @@ -0,0 +1,30 @@ +import { SkinnedMesh } from "../../objects/SkinnedMesh.js"; +import Node from "../core/Node.js"; +import NodeBuilder from "../core/NodeBuilder.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +export default class SkinningNode extends Node { + skinnedMesh: SkinnedMesh; + useReference: boolean; + + skinIndexNode: Node; + skinWeightNode: Node; + + bindMatrixNode: Node; + bindMatrixInverseNode: Node; + boneMatricesNode: Node; + previousBoneMatricesNode: Node | null; + + constructor(skinnedMesh: SkinnedMesh, useReference?: boolean); + + getSkinnedPosition(boneMatrices?: Node, position?: Node): ShaderNodeObject; + + getSkinnedNormal(boneMatrices?: Node, normal?: Node): ShaderNodeObject; + + getPreviousSkinnedPosition(builder: NodeBuilder): ShaderNodeObject; + + needsPreviousBoneMatrices(builder: NodeBuilder): boolean; +} + +export const skinning: (skinnedMesh: SkinnedMesh) => ShaderNodeObject; +export const skinningReference: (skinnedMesh: SkinnedMesh) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/StorageBufferNode.d.ts b/src-testing/src/nodes/accessors/StorageBufferNode.d.ts new file mode 100644 index 000000000..d56cac59a --- /dev/null +++ b/src-testing/src/nodes/accessors/StorageBufferNode.d.ts @@ -0,0 +1,38 @@ +import StorageBufferAttribute from "../../renderers/common/StorageBufferAttribute.js"; +import StorageInstancedBufferAttribute from "../../renderers/common/StorageInstancedBufferAttribute.js"; +import { GPUBufferBindingType } from "../../renderers/webgpu/utils/WebGPUConstants.js"; +import { NodeOrType, NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; +import StorageArrayElementNode from "../utils/StorageArrayElementNode.js"; +import BufferNode from "./BufferNode.js"; + +export default class StorageBufferNode extends BufferNode { + readonly isStorageBufferNode: true; + bufferObject: boolean; + + access: GPUBufferBindingType; + + constructor( + value: StorageBufferAttribute | StorageInstancedBufferAttribute, + bufferType: string, + bufferCount?: number, + ); + + element(indexNode: NodeRepresentation): ShaderNodeObject; + + setBufferObject(value: boolean): this; + + setAccess(value: GPUBufferBindingType): this; + + toReadOnly(): this; +} + +export const storage: ( + value: StorageBufferAttribute | StorageInstancedBufferAttribute, + nodeOrType: NodeOrType, + count: number, +) => ShaderNodeObject; +export const storageObject: ( + value: StorageBufferAttribute | StorageInstancedBufferAttribute, + nodeOrType: NodeOrType, + count: number, +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/StorageTextureNode.d.ts b/src-testing/src/nodes/accessors/StorageTextureNode.d.ts new file mode 100644 index 000000000..0b4acdceb --- /dev/null +++ b/src-testing/src/nodes/accessors/StorageTextureNode.d.ts @@ -0,0 +1,40 @@ +import { GPUStorageTextureAccess } from "../../renderers/webgpu/utils/WebGPUConstants.js"; +import { Texture } from "../../textures/Texture.js"; +import Node from "../core/Node.js"; +import NodeBuilder from "../core/NodeBuilder.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; +import TextureNode from "./TextureNode.js"; + +export default class StorageTextureNode extends TextureNode { + storeNode: Node | null; + + readonly isStorageTextureNode: true; + + access: GPUStorageTextureAccess; + + constructor( + value: Texture, + uvNode?: ShaderNodeObject | null, + storeNode?: Node | null, + ); + + setAccess(value: GPUStorageTextureAccess): this; + + toReadOnly(): this; + + toWriteOnly(): this; + + generateStore(builder: NodeBuilder): void; +} + +export const storageTexture: ( + value: Texture, + uvNode?: NodeRepresentation, + storeNode?: NodeRepresentation, +) => ShaderNodeObject; + +export const textureStore: ( + value: Texture, + uvNode?: NodeRepresentation, + storeNode?: NodeRepresentation, +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/Tangent.d.ts b/src-testing/src/nodes/accessors/Tangent.d.ts new file mode 100644 index 000000000..94ec48330 --- /dev/null +++ b/src-testing/src/nodes/accessors/Tangent.d.ts @@ -0,0 +1,12 @@ +import AttributeNode from "../core/AttributeNode.js"; +import VarNode from "../core/VarNode.js"; +import VaryingNode from "../core/VaryingNode.js"; +import MathNode from "../math/MathNode.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +export const tangentGeometry: ShaderNodeObject; +export const tangentLocal: ShaderNodeObject; +export const tangentView: ShaderNodeObject; +export const tangentWorld: ShaderNodeObject; +export const transformedTangentView: ShaderNodeObject; +export const transformedTangentWorld: ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/Texture3DNode.d.ts b/src-testing/src/nodes/accessors/Texture3DNode.d.ts new file mode 100644 index 000000000..da589f034 --- /dev/null +++ b/src-testing/src/nodes/accessors/Texture3DNode.d.ts @@ -0,0 +1,17 @@ +import { CubeTexture } from "../../textures/CubeTexture.js"; +import { Texture } from "../../textures/Texture.js"; +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; +import TextureNode from "./TextureNode.js"; + +export default class Texture3DNode extends TextureNode { + readonly isTexture3DNode: true; + + constructor(value: Texture, uvNode?: ShaderNodeObject | null, levelNode?: ShaderNodeObject | null); +} + +export const texture3D: ( + value: Texture, + uvNode?: NodeRepresentation, + levelNode?: NodeRepresentation, +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/TextureBicubic.d.ts b/src-testing/src/nodes/accessors/TextureBicubic.d.ts new file mode 100644 index 000000000..b55ca57e9 --- /dev/null +++ b/src-testing/src/nodes/accessors/TextureBicubic.d.ts @@ -0,0 +1,4 @@ +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +export const textureBicubic: (textureNode: Node, lodNode?: NodeRepresentation) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/TextureNode.ts b/src-testing/src/nodes/accessors/TextureNode.ts new file mode 100644 index 000000000..f97a04d11 --- /dev/null +++ b/src-testing/src/nodes/accessors/TextureNode.ts @@ -0,0 +1,370 @@ +import UniformNode, { uniform } from '../core/UniformNode.js'; +import { uv } from './UV.js'; +import { textureSize } from './TextureSizeNode.js'; +import { colorSpaceToWorking } from '../display/ColorSpaceNode.js'; +import { expression } from '../code/ExpressionNode.js'; +import { maxMipLevel } from '../utils/MaxMipLevelNode.js'; +import { nodeProxy, vec3, nodeObject, int } from '../tsl/TSLBase.js'; +import { NodeUpdateType } from '../core/constants.js'; + +import { IntType, UnsignedIntType } from '../../constants.js'; + +class TextureNode extends UniformNode { + static get type() { + return 'TextureNode'; + } + + constructor(value, uvNode = null, levelNode = null, biasNode = null) { + super(value); + + this.isTextureNode = true; + + this.uvNode = uvNode; + this.levelNode = levelNode; + this.biasNode = biasNode; + this.compareNode = null; + this.depthNode = null; + this.gradNode = null; + + this.sampler = true; + this.updateMatrix = false; + this.updateType = NodeUpdateType.NONE; + + this.referenceNode = null; + + this._value = value; + this._matrixUniform = null; + + this.setUpdateMatrix(uvNode === null); + } + + set value(value) { + if (this.referenceNode) { + this.referenceNode.value = value; + } else { + this._value = value; + } + } + + get value() { + return this.referenceNode ? this.referenceNode.value : this._value; + } + + getUniformHash(/*builder*/) { + return this.value.uuid; + } + + getNodeType(/*builder*/) { + if (this.value.isDepthTexture === true) return 'float'; + + if (this.value.type === UnsignedIntType) { + return 'uvec4'; + } else if (this.value.type === IntType) { + return 'ivec4'; + } + + return 'vec4'; + } + + getInputType(/*builder*/) { + return 'texture'; + } + + getDefaultUV() { + return uv(this.value.channel); + } + + updateReference(/*state*/) { + return this.value; + } + + getTransformedUV(uvNode) { + if (this._matrixUniform === null) this._matrixUniform = uniform(this.value.matrix); + + return this._matrixUniform.mul(vec3(uvNode, 1)).xy; + } + + setUpdateMatrix(value) { + this.updateMatrix = value; + this.updateType = value ? NodeUpdateType.FRAME : NodeUpdateType.NONE; + + return this; + } + + setupUV(builder, uvNode) { + const texture = this.value; + + if ( + builder.isFlipY() && + (texture.isRenderTargetTexture === true || + texture.isFramebufferTexture === true || + texture.isDepthTexture === true) + ) { + if (this.sampler) { + uvNode = uvNode.flipY(); + } else { + uvNode = uvNode.setY(int(textureSize(this, this.levelNode).y).sub(uvNode.y).sub(1)); + } + } + + return uvNode; + } + + setup(builder) { + const properties = builder.getNodeProperties(this); + properties.referenceNode = this.referenceNode; + + // + + let uvNode = this.uvNode; + + if ((uvNode === null || builder.context.forceUVContext === true) && builder.context.getUV) { + uvNode = builder.context.getUV(this); + } + + if (!uvNode) uvNode = this.getDefaultUV(); + + if (this.updateMatrix === true) { + uvNode = this.getTransformedUV(uvNode); + } + + uvNode = this.setupUV(builder, uvNode); + + // + + let levelNode = this.levelNode; + + if (levelNode === null && builder.context.getTextureLevel) { + levelNode = builder.context.getTextureLevel(this); + } + + // + + properties.uvNode = uvNode; + properties.levelNode = levelNode; + properties.biasNode = this.biasNode; + properties.compareNode = this.compareNode; + properties.gradNode = this.gradNode; + properties.depthNode = this.depthNode; + } + + generateUV(builder, uvNode) { + return uvNode.build(builder, this.sampler === true ? 'vec2' : 'ivec2'); + } + + generateSnippet( + builder, + textureProperty, + uvSnippet, + levelSnippet, + biasSnippet, + depthSnippet, + compareSnippet, + gradSnippet, + ) { + const texture = this.value; + + let snippet; + + if (levelSnippet) { + snippet = builder.generateTextureLevel(texture, textureProperty, uvSnippet, levelSnippet, depthSnippet); + } else if (biasSnippet) { + snippet = builder.generateTextureBias(texture, textureProperty, uvSnippet, biasSnippet, depthSnippet); + } else if (gradSnippet) { + snippet = builder.generateTextureGrad(texture, textureProperty, uvSnippet, gradSnippet, depthSnippet); + } else if (compareSnippet) { + snippet = builder.generateTextureCompare(texture, textureProperty, uvSnippet, compareSnippet, depthSnippet); + } else if (this.sampler === false) { + snippet = builder.generateTextureLoad(texture, textureProperty, uvSnippet, depthSnippet); + } else { + snippet = builder.generateTexture(texture, textureProperty, uvSnippet, depthSnippet); + } + + return snippet; + } + + generate(builder, output) { + const properties = builder.getNodeProperties(this); + + const texture = this.value; + + if (!texture || texture.isTexture !== true) { + throw new Error('TextureNode: Need a three.js texture.'); + } + + const textureProperty = super.generate(builder, 'property'); + + if (output === 'sampler') { + return textureProperty + '_sampler'; + } else if (builder.isReference(output)) { + return textureProperty; + } else { + const nodeData = builder.getDataFromNode(this); + + let propertyName = nodeData.propertyName; + + if (propertyName === undefined) { + const { uvNode, levelNode, biasNode, compareNode, depthNode, gradNode } = properties; + + const uvSnippet = this.generateUV(builder, uvNode); + const levelSnippet = levelNode ? levelNode.build(builder, 'float') : null; + const biasSnippet = biasNode ? biasNode.build(builder, 'float') : null; + const depthSnippet = depthNode ? depthNode.build(builder, 'int') : null; + const compareSnippet = compareNode ? compareNode.build(builder, 'float') : null; + const gradSnippet = gradNode + ? [gradNode[0].build(builder, 'vec2'), gradNode[1].build(builder, 'vec2')] + : null; + + const nodeVar = builder.getVarFromNode(this); + + propertyName = builder.getPropertyName(nodeVar); + + const snippet = this.generateSnippet( + builder, + textureProperty, + uvSnippet, + levelSnippet, + biasSnippet, + depthSnippet, + compareSnippet, + gradSnippet, + ); + + builder.addLineFlowCode(`${propertyName} = ${snippet}`, this); + + nodeData.snippet = snippet; + nodeData.propertyName = propertyName; + } + + let snippet = propertyName; + const nodeType = this.getNodeType(builder); + + if (builder.needsToWorkingColorSpace(texture)) { + snippet = colorSpaceToWorking(expression(snippet, nodeType), texture.colorSpace) + .setup(builder) + .build(builder, nodeType); + } + + return builder.format(snippet, nodeType, output); + } + } + + setSampler(value) { + this.sampler = value; + + return this; + } + + getSampler() { + return this.sampler; + } + + // @TODO: Move to TSL + + uv(uvNode) { + const textureNode = this.clone(); + textureNode.uvNode = nodeObject(uvNode); + textureNode.referenceNode = this.getSelf(); + + return nodeObject(textureNode); + } + + blur(amountNode) { + const textureNode = this.clone(); + textureNode.biasNode = nodeObject(amountNode).mul(maxMipLevel(textureNode)); + textureNode.referenceNode = this.getSelf(); + + return nodeObject(textureNode); + } + + level(levelNode) { + const textureNode = this.clone(); + textureNode.levelNode = nodeObject(levelNode); + textureNode.referenceNode = this.getSelf(); + + return nodeObject(textureNode); + } + + size(levelNode) { + return textureSize(this, levelNode); + } + + bias(biasNode) { + const textureNode = this.clone(); + textureNode.biasNode = nodeObject(biasNode); + textureNode.referenceNode = this.getSelf(); + + return nodeObject(textureNode); + } + + compare(compareNode) { + const textureNode = this.clone(); + textureNode.compareNode = nodeObject(compareNode); + textureNode.referenceNode = this.getSelf(); + + return nodeObject(textureNode); + } + + grad(gradNodeX, gradNodeY) { + const textureNode = this.clone(); + textureNode.gradNode = [nodeObject(gradNodeX), nodeObject(gradNodeY)]; + textureNode.referenceNode = this.getSelf(); + + return nodeObject(textureNode); + } + + depth(depthNode) { + const textureNode = this.clone(); + textureNode.depthNode = nodeObject(depthNode); + textureNode.referenceNode = this.getSelf(); + + return nodeObject(textureNode); + } + + // -- + + serialize(data) { + super.serialize(data); + + data.value = this.value.toJSON(data.meta).uuid; + data.sampler = this.sampler; + data.updateMatrix = this.updateMatrix; + data.updateType = this.updateType; + } + + deserialize(data) { + super.deserialize(data); + + this.value = data.meta.textures[data.value]; + this.sampler = data.sampler; + this.updateMatrix = data.updateMatrix; + this.updateType = data.updateType; + } + + update() { + const texture = this.value; + const matrixUniform = this._matrixUniform; + + if (matrixUniform !== null) matrixUniform.value = texture.matrix; + + if (texture.matrixAutoUpdate === true) { + texture.updateMatrix(); + } + } + + clone() { + const newNode = new this.constructor(this.value, this.uvNode, this.levelNode, this.biasNode); + newNode.sampler = this.sampler; + + return newNode; + } +} + +export default TextureNode; + +export const texture = /*@__PURE__*/ nodeProxy(TextureNode); +export const textureLoad = (...params) => texture(...params).setSampler(false); + +//export const textureLevel = ( value, uv, level ) => texture( value, uv ).level( level ); + +export const sampler = aTexture => (aTexture.isNode === true ? aTexture : texture(aTexture)).convert('sampler'); diff --git a/src-testing/src/nodes/accessors/TextureSizeNode.d.ts b/src-testing/src/nodes/accessors/TextureSizeNode.d.ts new file mode 100644 index 000000000..0b995fccf --- /dev/null +++ b/src-testing/src/nodes/accessors/TextureSizeNode.d.ts @@ -0,0 +1,18 @@ +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +declare class TextureSizeNode extends Node { + readonly isTextureSizeNode: true; + + textureNode: Node; + levelNode: Node | null; + + constructor(textureNode: Node, levelNode?: Node | null); +} + +export default TextureSizeNode; + +export const textureSize: ( + textureNode: NodeRepresentation, + levelNode?: NodeRepresentation | null, +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/UV.d.ts b/src-testing/src/nodes/accessors/UV.d.ts new file mode 100644 index 000000000..aedabbd02 --- /dev/null +++ b/src-testing/src/nodes/accessors/UV.d.ts @@ -0,0 +1,4 @@ +import AttributeNode from "../core/AttributeNode.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +export const uv: (index?: number) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/UniformArrayNode.d.ts b/src-testing/src/nodes/accessors/UniformArrayNode.d.ts new file mode 100644 index 000000000..72e539cb4 --- /dev/null +++ b/src-testing/src/nodes/accessors/UniformArrayNode.d.ts @@ -0,0 +1,30 @@ +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; +import ArrayElementNode from "../utils/ArrayElementNode.js"; +import BufferNode from "./BufferNode.js"; + +declare class UniformArrayElementNode extends ArrayElementNode { + constructor(arrayBuffer: Node, indexNode: Node); +} + +declare class UniformArrayNode extends BufferNode { + array: unknown[]; + elementType: string | null; + + readonly isArrayBufferNode: true; + + constructor(value: unknown[], elementType?: string | null); + + getElementLength(): number; + + element(indexNode: NodeRepresentation): ShaderNodeObject; +} + +export default UniformArrayNode; + +export const uniformArray: (values: unknown[], nodeType?: string | null) => ShaderNodeObject; + +/** + * @deprecated uniforms() has been renamed to uniformArray(). + */ +export const uniforms: (values: unknown[], nodeType?: string | null) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/UserDataNode.d.ts b/src-testing/src/nodes/accessors/UserDataNode.d.ts new file mode 100644 index 000000000..647c18412 --- /dev/null +++ b/src-testing/src/nodes/accessors/UserDataNode.d.ts @@ -0,0 +1,15 @@ +import { ShaderNodeObject } from "../tsl/TSLCore.js"; +import ReferenceNode from "./ReferenceNode.js"; + +export type NodeUserData = Record; + +export default class UserDataNode extends ReferenceNode { + userData: NodeUserData | null; + constructor(property: string, inputType: string, userData?: NodeUserData | null); +} + +export const userData: ( + name: string, + inputType: string, + userData?: NodeUserData, +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/VelocityNode.d.ts b/src-testing/src/nodes/accessors/VelocityNode.d.ts new file mode 100644 index 000000000..32c040c16 --- /dev/null +++ b/src-testing/src/nodes/accessors/VelocityNode.d.ts @@ -0,0 +1,20 @@ +import { Matrix4 } from "../../math/Matrix4.js"; +import TempNode from "../core/TempNode.js"; +import UniformNode from "../core/UniformNode.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +declare class VelocityNode extends TempNode { + projectionMatrix: Matrix4 | null; + + previousModelWorldMatrix: UniformNode; + previousProjectionMatrix: UniformNode; + previousCameraViewMatrix: UniformNode; + + constructor(); + + setProjectionMatrix(projectionMatrix: Matrix4 | null): void; +} + +export default VelocityNode; + +export const velocity: ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/VertexColorNode.d.ts b/src-testing/src/nodes/accessors/VertexColorNode.d.ts new file mode 100644 index 000000000..b2bb76339 --- /dev/null +++ b/src-testing/src/nodes/accessors/VertexColorNode.d.ts @@ -0,0 +1,12 @@ +import AttributeNode from "../core/AttributeNode.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +export default class VertexColorNode extends AttributeNode { + readonly isVertexColorNode: true; + + index: number; + + constructor(index?: number); +} + +export const vertexColor: (index?: number) => ShaderNodeObject; diff --git a/src-testing/src/nodes/code/CodeNode.ts b/src-testing/src/nodes/code/CodeNode.ts new file mode 100644 index 000000000..2f4c60511 --- /dev/null +++ b/src-testing/src/nodes/code/CodeNode.ts @@ -0,0 +1,68 @@ +import Node from '../core/Node.js'; +import { nodeProxy } from '../tsl/TSLBase.js'; + +class CodeNode extends Node { + static get type() { + return 'CodeNode'; + } + + constructor(code = '', includes = [], language = '') { + super('code'); + + this.isCodeNode = true; + + this.code = code; + this.language = language; + + this.includes = includes; + } + + isGlobal() { + return true; + } + + setIncludes(includes) { + this.includes = includes; + + return this; + } + + getIncludes(/*builder*/) { + return this.includes; + } + + generate(builder) { + const includes = this.getIncludes(builder); + + for (const include of includes) { + include.build(builder); + } + + const nodeCode = builder.getCodeFromNode(this, this.getNodeType(builder)); + nodeCode.code = this.code; + + return nodeCode.code; + } + + serialize(data) { + super.serialize(data); + + data.code = this.code; + data.language = this.language; + } + + deserialize(data) { + super.deserialize(data); + + this.code = data.code; + this.language = data.language; + } +} + +export default CodeNode; + +export const code = /*@__PURE__*/ nodeProxy(CodeNode); + +export const js = (src, includes) => code(src, includes, 'js'); +export const wgsl = (src, includes) => code(src, includes, 'wgsl'); +export const glsl = (src, includes) => code(src, includes, 'glsl'); diff --git a/src-testing/src/nodes/code/ExpressionNode.d.ts b/src-testing/src/nodes/code/ExpressionNode.d.ts new file mode 100644 index 000000000..ce5fc783b --- /dev/null +++ b/src-testing/src/nodes/code/ExpressionNode.d.ts @@ -0,0 +1,9 @@ +import TempNode from "../core/TempNode.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +export default class ExpressionNode extends TempNode { + snipped: string; /* sic */ + constructor(snipped?: string, nodeType?: string); +} + +export const expression: (snipped?: string, nodeType?: string) => ShaderNodeObject; diff --git a/src-testing/src/nodes/code/FunctionCallNode.d.ts b/src-testing/src/nodes/code/FunctionCallNode.d.ts new file mode 100644 index 000000000..7bf6d7360 --- /dev/null +++ b/src-testing/src/nodes/code/FunctionCallNode.d.ts @@ -0,0 +1,25 @@ +import Node from "../core/Node.js"; +import TempNode from "../core/TempNode.js"; +import { ProxiedObject, ShaderNodeObject } from "../tsl/TSLCore.js"; +import FunctionNode, { FunctionNodeArguments } from "./FunctionNode.js"; + +export default class FunctionCallNode

extends TempNode { + functionNode: FunctionNode

; + parameters: { [name: string]: Node }; + + constructor(functionNode?: FunctionNode

, parameters?: P); + + setParameters(parameters: P): this; + getParameters(): P; +} + +export const call:

( + functionNode?: FunctionNode

, + parameters?: ProxiedObject

, +) => ShaderNodeObject>; + +declare module "../tsl/TSLCore.js" { + interface NodeElements { + call: typeof call; + } +} diff --git a/src-testing/src/nodes/code/FunctionNode.ts b/src-testing/src/nodes/code/FunctionNode.ts new file mode 100644 index 000000000..54d8a5c54 --- /dev/null +++ b/src-testing/src/nodes/code/FunctionNode.ts @@ -0,0 +1,87 @@ +import CodeNode from './CodeNode.js'; +import { nodeObject } from '../tsl/TSLBase.js'; + +class FunctionNode extends CodeNode { + static get type() { + return 'FunctionNode'; + } + + constructor(code = '', includes = [], language = '') { + super(code, includes, language); + } + + getNodeType(builder) { + return this.getNodeFunction(builder).type; + } + + getInputs(builder) { + return this.getNodeFunction(builder).inputs; + } + + getNodeFunction(builder) { + const nodeData = builder.getDataFromNode(this); + + let nodeFunction = nodeData.nodeFunction; + + if (nodeFunction === undefined) { + nodeFunction = builder.parser.parseFunction(this.code); + + nodeData.nodeFunction = nodeFunction; + } + + return nodeFunction; + } + + generate(builder, output) { + super.generate(builder); + + const nodeFunction = this.getNodeFunction(builder); + + const name = nodeFunction.name; + const type = nodeFunction.type; + + const nodeCode = builder.getCodeFromNode(this, type); + + if (name !== '') { + // use a custom property name + + nodeCode.name = name; + } + + const propertyName = builder.getPropertyName(nodeCode); + + const code = this.getNodeFunction(builder).getCode(propertyName); + + nodeCode.code = code + '\n'; + + if (output === 'property') { + return propertyName; + } else { + return builder.format(`${propertyName}()`, type, output); + } + } +} + +export default FunctionNode; + +const nativeFn = (code, includes = [], language = '') => { + for (let i = 0; i < includes.length; i++) { + const include = includes[i]; + + // TSL Function: glslFn, wgslFn + + if (typeof include === 'function') { + includes[i] = include.functionNode; + } + } + + const functionNode = nodeObject(new FunctionNode(code, includes, language)); + + const fn = (...params) => functionNode.call(...params); + fn.functionNode = functionNode; + + return fn; +}; + +export const glslFn = (code, includes) => nativeFn(code, includes, 'glsl'); +export const wgslFn = (code, includes) => nativeFn(code, includes, 'wgsl'); diff --git a/src-testing/src/nodes/code/ScriptableNode.d.ts b/src-testing/src/nodes/code/ScriptableNode.d.ts new file mode 100644 index 000000000..7922afe12 --- /dev/null +++ b/src-testing/src/nodes/code/ScriptableNode.d.ts @@ -0,0 +1,22 @@ +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +declare class Resources extends Map { + get(key: string, callback?: ((...args: TArgs) => void) | null, ...params: TArgs): unknown; +} + +export const global: Resources; + +declare class ScriptableNode extends Node { + codeNode: Node | null; + parameters: Record; + + constructor(codeNode?: Node | null, parameters?: Record); +} + +export default ScriptableNode; + +export const scriptable: ( + codeNode?: NodeRepresentation | null, + parameters?: Record, +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/code/ScriptableValueNode.d.ts b/src-testing/src/nodes/code/ScriptableValueNode.d.ts new file mode 100644 index 000000000..eccec90c6 --- /dev/null +++ b/src-testing/src/nodes/code/ScriptableValueNode.d.ts @@ -0,0 +1,10 @@ +import Node from "../core/Node.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +declare class ScriptableValueNode extends Node { + constructor(value: unknown); +} + +export default ScriptableValueNode; + +export const scriptableValue: (value?: unknown) => ShaderNodeObject; diff --git a/src-testing/src/nodes/core/AssignNode.d.ts b/src-testing/src/nodes/core/AssignNode.d.ts new file mode 100644 index 000000000..a5628e76c --- /dev/null +++ b/src-testing/src/nodes/core/AssignNode.d.ts @@ -0,0 +1,18 @@ +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; +import Node from "./Node.js"; +import NodeBuilder from "./NodeBuilder.js"; +import TempNode from "./TempNode.js"; + +export default class AssignNode extends TempNode { + constructor(targetNode: Node, sourceNode: Node); + + needsSplitAssign(builder: NodeBuilder): boolean; +} + +export const assign: (targetNode: NodeRepresentation, sourceNode: NodeRepresentation) => ShaderNodeObject; + +declare module "../tsl/TSLCore.js" { + interface NodeElements { + assign: typeof assign; + } +} diff --git a/src-testing/src/nodes/core/AttributeNode.d.ts b/src-testing/src/nodes/core/AttributeNode.d.ts new file mode 100644 index 000000000..179f07b74 --- /dev/null +++ b/src-testing/src/nodes/core/AttributeNode.d.ts @@ -0,0 +1,16 @@ +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; +import Node from "./Node.js"; +import NodeBuilder from "./NodeBuilder.js"; + +export default class AttributeNode extends Node { + constructor(attributeName: string, nodeType?: string | null); + + setAttributeName(attributeName: string): this; + + getAttributeName(builder: NodeBuilder): string; +} + +export const attribute: ( + name: string, + nodeType?: string | null, +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/core/BypassNode.d.ts b/src-testing/src/nodes/core/BypassNode.d.ts new file mode 100644 index 000000000..5d152654d --- /dev/null +++ b/src-testing/src/nodes/core/BypassNode.d.ts @@ -0,0 +1,18 @@ +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; +import Node from "./Node.js"; + +export default class BypassNode extends Node { + isBypassNode: true; + outputNode: Node; + callNode: Node; + + constructor(returnNode: Node, callNode: Node); +} + +export const bypass: (returnNode: NodeRepresentation, callNode: NodeRepresentation) => ShaderNodeObject; + +declare module "../tsl/TSLCore.js" { + interface NodeElements { + bypass: typeof bypass; + } +} diff --git a/src-testing/src/nodes/core/CacheNode.d.ts b/src-testing/src/nodes/core/CacheNode.d.ts new file mode 100644 index 000000000..4b7f173d1 --- /dev/null +++ b/src-testing/src/nodes/core/CacheNode.d.ts @@ -0,0 +1,20 @@ +import { ShaderNodeObject } from "../tsl/TSLCore.js"; +import Node from "./Node.js"; +import NodeCache from "./NodeCache.js"; + +export default class CacheNode extends Node { + node: Node; + parent: boolean; + + readonly isCacheNode: true; + + constructor(node: Node, parent?: boolean); +} + +export const cache: (node: Node, cache?: NodeCache) => ShaderNodeObject; + +declare module "../tsl/TSLCore.js" { + interface NodeElements { + cache: typeof cache; + } +} diff --git a/src-testing/src/nodes/core/ConstNode.d.ts b/src-testing/src/nodes/core/ConstNode.d.ts new file mode 100644 index 000000000..f866b0c0c --- /dev/null +++ b/src-testing/src/nodes/core/ConstNode.d.ts @@ -0,0 +1,9 @@ +import InputNode from "./InputNode.js"; +import NodeBuilder from "./NodeBuilder.js"; + +export default class ConstNode extends InputNode { + isConstNode: true; + constructor(value: Value, nodeType?: string | null); + + generateConst(builder: NodeBuilder): string; +} diff --git a/src-testing/src/nodes/core/ContextNode.ts b/src-testing/src/nodes/core/ContextNode.ts new file mode 100644 index 000000000..32b8ac0af --- /dev/null +++ b/src-testing/src/nodes/core/ContextNode.ts @@ -0,0 +1,61 @@ +import Node from './Node.js'; +import { addMethodChaining, nodeProxy } from '../tsl/TSLCore.js'; + +class ContextNode extends Node { + static get type() { + return 'ContextNode'; + } + + constructor(node, value = {}) { + super(); + + this.isContextNode = true; + + this.node = node; + this.value = value; + } + + getScope() { + return this.node.getScope(); + } + + getNodeType(builder) { + return this.node.getNodeType(builder); + } + + analyze(builder) { + this.node.build(builder); + } + + setup(builder) { + const previousContext = builder.getContext(); + + builder.setContext({ ...builder.context, ...this.value }); + + const node = this.node.build(builder); + + builder.setContext(previousContext); + + return node; + } + + generate(builder, output) { + const previousContext = builder.getContext(); + + builder.setContext({ ...builder.context, ...this.value }); + + const snippet = this.node.build(builder, output); + + builder.setContext(previousContext); + + return snippet; + } +} + +export default ContextNode; + +export const context = /*@__PURE__*/ nodeProxy(ContextNode); +export const label = (node, name) => context(node, { label: name }); + +addMethodChaining('context', context); +addMethodChaining('label', label); diff --git a/src-testing/src/nodes/core/IndexNode.d.ts b/src-testing/src/nodes/core/IndexNode.d.ts new file mode 100644 index 000000000..ebaba50ae --- /dev/null +++ b/src-testing/src/nodes/core/IndexNode.d.ts @@ -0,0 +1,28 @@ +import { ShaderNodeObject } from "../tsl/TSLCore.js"; +import Node from "./Node.js"; + +export type IndexNodeScope = + | typeof IndexNode.VERTEX + | typeof IndexNode.INSTANCE + | typeof IndexNode.INVOCATION_LOCAL + | typeof IndexNode.DRAW; + +declare class IndexNode extends Node { + scope: IndexNodeScope; + + readonly isInstanceNode: true; + + constructor(scope: IndexNodeScope); + + static VERTEX: "vertex"; + static INSTANCE: "instance"; + static INVOCATION_LOCAL: "invocationLocal"; + static DRAW: "draw"; +} + +export default IndexNode; + +export const vertexIndex: ShaderNodeObject; +export const instanceIndex: ShaderNodeObject; +export const invocationLocalIndex: ShaderNodeObject; +export const drawIndex: ShaderNodeObject; diff --git a/src-testing/src/nodes/core/InputNode.ts b/src-testing/src/nodes/core/InputNode.ts new file mode 100644 index 000000000..07af45dc3 --- /dev/null +++ b/src-testing/src/nodes/core/InputNode.ts @@ -0,0 +1,67 @@ +import Node from './Node.js'; +import { getValueType, getValueFromType, arrayBufferToBase64 } from './NodeUtils.js'; + +class InputNode extends Node { + static get type() { + return 'InputNode'; + } + + constructor(value, nodeType = null) { + super(nodeType); + + this.isInputNode = true; + + this.value = value; + this.precision = null; + } + + getNodeType(/*builder*/) { + if (this.nodeType === null) { + return getValueType(this.value); + } + + return this.nodeType; + } + + getInputType(builder) { + return this.getNodeType(builder); + } + + setPrecision(precision) { + this.precision = precision; + + return this; + } + + serialize(data) { + super.serialize(data); + + data.value = this.value; + + if (this.value && this.value.toArray) data.value = this.value.toArray(); + + data.valueType = getValueType(this.value); + data.nodeType = this.nodeType; + + if (data.valueType === 'ArrayBuffer') data.value = arrayBufferToBase64(data.value); + + data.precision = this.precision; + } + + deserialize(data) { + super.deserialize(data); + + this.nodeType = data.nodeType; + this.value = Array.isArray(data.value) ? getValueFromType(data.valueType, ...data.value) : data.value; + + this.precision = data.precision || null; + + if (this.value && this.value.fromArray) this.value = this.value.fromArray(data.value); + } + + generate(/*builder, output*/) { + console.warn('Abstract function.'); + } +} + +export default InputNode; diff --git a/src-testing/src/nodes/core/LightingModel.d.ts b/src-testing/src/nodes/core/LightingModel.d.ts new file mode 100644 index 000000000..f64dd07db --- /dev/null +++ b/src-testing/src/nodes/core/LightingModel.d.ts @@ -0,0 +1,46 @@ +import Node from "./Node.js"; +import NodeBuilder from "./NodeBuilder.js"; +import StackNode from "./StackNode.js"; + +export interface LightingModelReflectedLight { + directDiffuse: Node; + directSpecular: Node; + indirectDiffuse: Node; + indirectSpecular: Node; +} + +export interface LightingModelDirectInput { + lightDirection: Node; + lightColor: Node; + reflectedLight: LightingModelReflectedLight; +} + +export interface LightingModelDirectRectAreaInput { + lightColor: Node; + lightPosition: Node; + halfWidth: Node; + halfHeight: Node; + reflectedLight: LightingModelReflectedLight; + ltc_1: Node; + ltc_2: Node; +} + +export interface LightingModelIndirectInput { + radiance: Node; + irradiance: Node; + iblIrradiance: Node; + ambientOcclusion: Node; + reflectedLight: LightingModelReflectedLight; + backdrop: Node; + backdropAlpha: Node; + outgoingLight: Node; +} + +export default class LightingModel { + start(input: LightingModelIndirectInput, stack: StackNode, builder: NodeBuilder): void; + finish(input: LightingModelIndirectInput, stack: StackNode, builder: NodeBuilder): void; + direct(input: LightingModelDirectInput, stack: StackNode, builder: NodeBuilder): void; + directRectArea(input: LightingModelDirectRectAreaInput, stack: StackNode, builder: NodeBuilder): void; + indirect(input: LightingModelIndirectInput, stack: StackNode, builder: NodeBuilder): void; + ambientOcclusion(input: LightingModelIndirectInput, stack: StackNode, builder: NodeBuilder): void; +} diff --git a/src-testing/src/nodes/core/MRTNode.d.ts b/src-testing/src/nodes/core/MRTNode.d.ts new file mode 100644 index 000000000..ef223da73 --- /dev/null +++ b/src-testing/src/nodes/core/MRTNode.d.ts @@ -0,0 +1,24 @@ +import { Texture } from "../../textures/Texture.js"; +import { Node } from "../Nodes.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; +import OutputStructNode from "./OutputStructNode.js"; + +export function getTextureIndex(textures: ReadonlyArray, name: string): number; + +declare class MRTNode extends OutputStructNode { + outputNodes: { [name: string]: Node }; + + readonly isMRTNode: true; + + constructor(outputNodes: { [name: string]: Node }); + + has(name: string): boolean; + + get(name: string): Node; + + merge(mrtNode: MRTNode): ShaderNodeObject; +} + +export default MRTNode; + +export const mrt: (outputNodes: { [name: string]: Node }) => ShaderNodeObject; diff --git a/src-testing/src/nodes/core/Node.ts b/src-testing/src/nodes/core/Node.ts new file mode 100644 index 000000000..2e54fce07 --- /dev/null +++ b/src-testing/src/nodes/core/Node.ts @@ -0,0 +1,401 @@ +import { NodeUpdateType } from './constants.js'; +import { getNodeChildren, getCacheKey } from './NodeUtils.js'; + +import { EventDispatcher } from '../../core/EventDispatcher.js'; +import { MathUtils } from '../../math/MathUtils.js'; + +let _nodeId = 0; + +class Node extends EventDispatcher { + static get type() { + return 'Node'; + } + + constructor(nodeType = null) { + super(); + + this.nodeType = nodeType; + + this.updateType = NodeUpdateType.NONE; + this.updateBeforeType = NodeUpdateType.NONE; + this.updateAfterType = NodeUpdateType.NONE; + + this.uuid = MathUtils.generateUUID(); + + this.version = 0; + + this._cacheKey = null; + this._cacheKeyVersion = 0; + + this.global = false; + + this.isNode = true; + + Object.defineProperty(this, 'id', { value: _nodeId++ }); + } + + set needsUpdate(value) { + if (value === true) { + this.version++; + } + } + + get type() { + return this.constructor.type; + } + + onUpdate(callback, updateType) { + this.updateType = updateType; + this.update = callback.bind(this.getSelf()); + + return this; + } + + onFrameUpdate(callback) { + return this.onUpdate(callback, NodeUpdateType.FRAME); + } + + onRenderUpdate(callback) { + return this.onUpdate(callback, NodeUpdateType.RENDER); + } + + onObjectUpdate(callback) { + return this.onUpdate(callback, NodeUpdateType.OBJECT); + } + + onReference(callback) { + this.updateReference = callback.bind(this.getSelf()); + + return this; + } + + getSelf() { + // Returns non-node object. + + return this.self || this; + } + + updateReference(/*state*/) { + return this; + } + + isGlobal(/*builder*/) { + return this.global; + } + + *getChildren() { + for (const { childNode } of getNodeChildren(this)) { + yield childNode; + } + } + + dispose() { + this.dispatchEvent({ type: 'dispose' }); + } + + traverse(callback) { + callback(this); + + for (const childNode of this.getChildren()) { + childNode.traverse(callback); + } + } + + getCacheKey(force = false) { + force = force || this.version !== this._cacheKeyVersion; + + if (force === true || this._cacheKey === null) { + this._cacheKey = getCacheKey(this, force); + this._cacheKeyVersion = this.version; + } + + return this._cacheKey; + } + + getScope() { + return this; + } + + getHash(/*builder*/) { + return this.uuid; + } + + getUpdateType() { + return this.updateType; + } + + getUpdateBeforeType() { + return this.updateBeforeType; + } + + getUpdateAfterType() { + return this.updateAfterType; + } + + getElementType(builder) { + const type = this.getNodeType(builder); + const elementType = builder.getElementType(type); + + return elementType; + } + + getNodeType(builder) { + const nodeProperties = builder.getNodeProperties(this); + + if (nodeProperties.outputNode) { + return nodeProperties.outputNode.getNodeType(builder); + } + + return this.nodeType; + } + + getShared(builder) { + const hash = this.getHash(builder); + const nodeFromHash = builder.getNodeFromHash(hash); + + return nodeFromHash || this; + } + + setup(builder) { + const nodeProperties = builder.getNodeProperties(this); + + let index = 0; + + for (const childNode of this.getChildren()) { + nodeProperties['node' + index++] = childNode; + } + + // return a outputNode if exists + return null; + } + + analyze(builder) { + const usageCount = builder.increaseUsage(this); + + if (usageCount === 1) { + // node flow children + + const nodeProperties = builder.getNodeProperties(this); + + for (const childNode of Object.values(nodeProperties)) { + if (childNode && childNode.isNode === true) { + childNode.build(builder); + } + } + } + } + + generate(builder, output) { + const { outputNode } = builder.getNodeProperties(this); + + if (outputNode && outputNode.isNode === true) { + return outputNode.build(builder, output); + } + } + + updateBefore(/*frame*/) { + console.warn('Abstract function.'); + } + + updateAfter(/*frame*/) { + console.warn('Abstract function.'); + } + + update(/*frame*/) { + console.warn('Abstract function.'); + } + + build(builder, output = null) { + const refNode = this.getShared(builder); + + if (this !== refNode) { + return refNode.build(builder, output); + } + + builder.addNode(this); + builder.addChain(this); + + /* Build stages expected results: + - "setup" -> Node + - "analyze" -> null + - "generate" -> String + */ + let result = null; + + const buildStage = builder.getBuildStage(); + + if (buildStage === 'setup') { + this.updateReference(builder); + + const properties = builder.getNodeProperties(this); + + if (properties.initialized !== true) { + const stackNodesBeforeSetup = builder.stack.nodes.length; + + properties.initialized = true; + properties.outputNode = this.setup(builder); + + if (properties.outputNode !== null && builder.stack.nodes.length !== stackNodesBeforeSetup) { + // !! no outputNode !! + //properties.outputNode = builder.stack; + } + + for (const childNode of Object.values(properties)) { + if (childNode && childNode.isNode === true) { + childNode.build(builder); + } + } + } + } else if (buildStage === 'analyze') { + this.analyze(builder); + } else if (buildStage === 'generate') { + const isGenerateOnce = this.generate.length === 1; + + if (isGenerateOnce) { + const type = this.getNodeType(builder); + const nodeData = builder.getDataFromNode(this); + + result = nodeData.snippet; + + if (result === undefined) { + result = this.generate(builder) || ''; + + nodeData.snippet = result; + } else if (nodeData.flowCodes !== undefined && builder.context.nodeBlock !== undefined) { + builder.addFlowCodeHierarchy(this, builder.context.nodeBlock); + } + + result = builder.format(result, type, output); + } else { + result = this.generate(builder, output) || ''; + } + } + + builder.removeChain(this); + builder.addSequentialNode(this); + + return result; + } + + getSerializeChildren() { + return getNodeChildren(this); + } + + serialize(json) { + const nodeChildren = this.getSerializeChildren(); + + const inputNodes = {}; + + for (const { property, index, childNode } of nodeChildren) { + if (index !== undefined) { + if (inputNodes[property] === undefined) { + inputNodes[property] = Number.isInteger(index) ? [] : {}; + } + + inputNodes[property][index] = childNode.toJSON(json.meta).uuid; + } else { + inputNodes[property] = childNode.toJSON(json.meta).uuid; + } + } + + if (Object.keys(inputNodes).length > 0) { + json.inputNodes = inputNodes; + } + } + + deserialize(json) { + if (json.inputNodes !== undefined) { + const nodes = json.meta.nodes; + + for (const property in json.inputNodes) { + if (Array.isArray(json.inputNodes[property])) { + const inputArray = []; + + for (const uuid of json.inputNodes[property]) { + inputArray.push(nodes[uuid]); + } + + this[property] = inputArray; + } else if (typeof json.inputNodes[property] === 'object') { + const inputObject = {}; + + for (const subProperty in json.inputNodes[property]) { + const uuid = json.inputNodes[property][subProperty]; + + inputObject[subProperty] = nodes[uuid]; + } + + this[property] = inputObject; + } else { + const uuid = json.inputNodes[property]; + + this[property] = nodes[uuid]; + } + } + } + } + + toJSON(meta) { + const { uuid, type } = this; + const isRoot = meta === undefined || typeof meta === 'string'; + + if (isRoot) { + meta = { + textures: {}, + images: {}, + nodes: {}, + }; + } + + // serialize + + let data = meta.nodes[uuid]; + + if (data === undefined) { + data = { + uuid, + type, + meta, + metadata: { + version: 4.6, + type: 'Node', + generator: 'Node.toJSON', + }, + }; + + if (isRoot !== true) meta.nodes[data.uuid] = data; + + this.serialize(data); + + delete data.meta; + } + + // TODO: Copied from Object3D.toJSON + + function extractFromCache(cache) { + const values = []; + + for (const key in cache) { + const data = cache[key]; + delete data.metadata; + values.push(data); + } + + return values; + } + + if (isRoot) { + const textures = extractFromCache(meta.textures); + const images = extractFromCache(meta.images); + const nodes = extractFromCache(meta.nodes); + + if (textures.length > 0) data.textures = textures; + if (images.length > 0) data.images = images; + if (nodes.length > 0) data.nodes = nodes; + } + + return data; + } +} + +export default Node; diff --git a/src-testing/src/nodes/core/NodeAttribute.ts b/src-testing/src/nodes/core/NodeAttribute.ts new file mode 100644 index 000000000..190fe8c51 --- /dev/null +++ b/src-testing/src/nodes/core/NodeAttribute.ts @@ -0,0 +1,11 @@ +class NodeAttribute { + constructor(name, type, node = null) { + this.isNodeAttribute = true; + + this.name = name; + this.type = type; + this.node = node; + } +} + +export default NodeAttribute; diff --git a/src-testing/src/nodes/core/NodeBuilder.ts b/src-testing/src/nodes/core/NodeBuilder.ts new file mode 100644 index 000000000..3003d1680 --- /dev/null +++ b/src-testing/src/nodes/core/NodeBuilder.ts @@ -0,0 +1,1208 @@ +import NodeUniform from './NodeUniform.js'; +import NodeAttribute from './NodeAttribute.js'; +import NodeVarying from './NodeVarying.js'; +import NodeVar from './NodeVar.js'; +import NodeCode from './NodeCode.js'; +import NodeCache from './NodeCache.js'; +import ParameterNode from './ParameterNode.js'; +import FunctionNode from '../code/FunctionNode.js'; +import NodeMaterial from '../../materials/nodes/NodeMaterial.js'; +import { NodeUpdateType, defaultBuildStages, shaderStages } from './constants.js'; + +import { + NumberNodeUniform, + Vector2NodeUniform, + Vector3NodeUniform, + Vector4NodeUniform, + ColorNodeUniform, + Matrix3NodeUniform, + Matrix4NodeUniform, +} from '../../renderers/common/nodes/NodeUniform.js'; + +import { stack } from './StackNode.js'; +import { getCurrentStack, setCurrentStack } from '../tsl/TSLBase.js'; + +import CubeRenderTarget from '../../renderers/common/CubeRenderTarget.js'; +import ChainMap from '../../renderers/common/ChainMap.js'; + +import PMREMGenerator from '../../renderers/common/extras/PMREMGenerator.js'; + +import BindGroup from '../../renderers/common/BindGroup.js'; + +import { REVISION } from '../../constants.js'; +import { RenderTarget } from '../../core/RenderTarget.js'; +import { Color } from '../../math/Color.js'; +import { Vector2 } from '../../math/Vector2.js'; +import { Vector3 } from '../../math/Vector3.js'; +import { Vector4 } from '../../math/Vector4.js'; +import { Float16BufferAttribute } from '../../core/BufferAttribute.js'; +import { + IntType, + UnsignedIntType, + LinearFilter, + LinearMipmapNearestFilter, + NearestMipmapLinearFilter, + LinearMipmapLinearFilter, +} from '../../constants.js'; + +const rendererCache = new WeakMap(); + +const typeFromLength = new Map([ + [2, 'vec2'], + [3, 'vec3'], + [4, 'vec4'], + [9, 'mat3'], + [16, 'mat4'], +]); + +const typeFromArray = new Map([ + [Int8Array, 'int'], + [Int16Array, 'int'], + [Int32Array, 'int'], + [Uint8Array, 'uint'], + [Uint16Array, 'uint'], + [Uint32Array, 'uint'], + [Float32Array, 'float'], +]); + +const toFloat = value => { + if (/e/g.test(value)) { + return String(value).replace(/\+/g, ''); + } else { + value = Number(value); + + return value + (value % 1 ? '' : '.0'); + } +}; + +class NodeBuilder { + constructor(object, renderer, parser) { + this.object = object; + this.material = (object && object.material) || null; + this.geometry = (object && object.geometry) || null; + this.renderer = renderer; + this.parser = parser; + this.scene = null; + this.camera = null; + + this.nodes = []; + this.sequentialNodes = []; + this.updateNodes = []; + this.updateBeforeNodes = []; + this.updateAfterNodes = []; + this.hashNodes = {}; + + this.monitor = null; + + this.lightsNode = null; + this.environmentNode = null; + this.fogNode = null; + + this.clippingContext = null; + + this.vertexShader = null; + this.fragmentShader = null; + this.computeShader = null; + + this.flowNodes = { vertex: [], fragment: [], compute: [] }; + this.flowCode = { vertex: '', fragment: '', compute: '' }; + this.uniforms = { vertex: [], fragment: [], compute: [], index: 0 }; + this.structs = { vertex: [], fragment: [], compute: [], index: 0 }; + this.bindings = { vertex: {}, fragment: {}, compute: {} }; + this.bindingsIndexes = {}; + this.bindGroups = null; + this.attributes = []; + this.bufferAttributes = []; + this.varyings = []; + this.codes = {}; + this.vars = {}; + this.flow = { code: '' }; + this.chaining = []; + this.stack = stack(); + this.stacks = []; + this.tab = '\t'; + + this.currentFunctionNode = null; + + this.context = { + material: this.material, + }; + + this.cache = new NodeCache(); + this.globalCache = this.cache; + + this.flowsData = new WeakMap(); + + this.shaderStage = null; + this.buildStage = null; + + this.useComparisonMethod = false; + } + + getBindGroupsCache() { + let bindGroupsCache = rendererCache.get(this.renderer); + + if (bindGroupsCache === undefined) { + bindGroupsCache = new ChainMap(); + + rendererCache.set(this.renderer, bindGroupsCache); + } + + return bindGroupsCache; + } + + createRenderTarget(width, height, options) { + return new RenderTarget(width, height, options); + } + + createCubeRenderTarget(size, options) { + return new CubeRenderTarget(size, options); + } + + createPMREMGenerator() { + // TODO: Move Materials.js to outside of the Nodes.js in order to remove this function and improve tree-shaking support + + return new PMREMGenerator(this.renderer); + } + + includes(node) { + return this.nodes.includes(node); + } + + _getBindGroup(groupName, bindings) { + const bindGroupsCache = this.getBindGroupsCache(); + + // + + const bindingsArray = []; + + let sharedGroup = true; + + for (const binding of bindings) { + bindingsArray.push(binding); + + sharedGroup = sharedGroup && binding.groupNode.shared !== true; + } + + // + + let bindGroup; + + if (sharedGroup) { + bindGroup = bindGroupsCache.get(bindingsArray); + + if (bindGroup === undefined) { + bindGroup = new BindGroup( + groupName, + bindingsArray, + this.bindingsIndexes[groupName].group, + bindingsArray, + ); + + bindGroupsCache.set(bindingsArray, bindGroup); + } + } else { + bindGroup = new BindGroup(groupName, bindingsArray, this.bindingsIndexes[groupName].group, bindingsArray); + } + + return bindGroup; + } + + getBindGroupArray(groupName, shaderStage) { + const bindings = this.bindings[shaderStage]; + + let bindGroup = bindings[groupName]; + + if (bindGroup === undefined) { + if (this.bindingsIndexes[groupName] === undefined) { + this.bindingsIndexes[groupName] = { binding: 0, group: Object.keys(this.bindingsIndexes).length }; + } + + bindings[groupName] = bindGroup = []; + } + + return bindGroup; + } + + getBindings() { + let bindingsGroups = this.bindGroups; + + if (bindingsGroups === null) { + const groups = {}; + const bindings = this.bindings; + + for (const shaderStage of shaderStages) { + for (const groupName in bindings[shaderStage]) { + const uniforms = bindings[shaderStage][groupName]; + + const groupUniforms = groups[groupName] || (groups[groupName] = []); + groupUniforms.push(...uniforms); + } + } + + bindingsGroups = []; + + for (const groupName in groups) { + const group = groups[groupName]; + + const bindingsGroup = this._getBindGroup(groupName, group); + + bindingsGroups.push(bindingsGroup); + } + + this.bindGroups = bindingsGroups; + } + + return bindingsGroups; + } + + sortBindingGroups() { + const bindingsGroups = this.getBindings(); + + bindingsGroups.sort((a, b) => a.bindings[0].groupNode.order - b.bindings[0].groupNode.order); + + for (let i = 0; i < bindingsGroups.length; i++) { + const bindingGroup = bindingsGroups[i]; + this.bindingsIndexes[bindingGroup.name].group = i; + + bindingGroup.index = i; + } + } + + setHashNode(node, hash) { + this.hashNodes[hash] = node; + } + + addNode(node) { + if (this.nodes.includes(node) === false) { + this.nodes.push(node); + + this.setHashNode(node, node.getHash(this)); + } + } + + addSequentialNode(node) { + if (this.sequentialNodes.includes(node) === false) { + this.sequentialNodes.push(node); + } + } + + buildUpdateNodes() { + for (const node of this.nodes) { + const updateType = node.getUpdateType(); + + if (updateType !== NodeUpdateType.NONE) { + this.updateNodes.push(node.getSelf()); + } + } + + for (const node of this.sequentialNodes) { + const updateBeforeType = node.getUpdateBeforeType(); + const updateAfterType = node.getUpdateAfterType(); + + if (updateBeforeType !== NodeUpdateType.NONE) { + this.updateBeforeNodes.push(node.getSelf()); + } + + if (updateAfterType !== NodeUpdateType.NONE) { + this.updateAfterNodes.push(node.getSelf()); + } + } + } + + get currentNode() { + return this.chaining[this.chaining.length - 1]; + } + + isFilteredTexture(texture) { + return ( + texture.magFilter === LinearFilter || + texture.magFilter === LinearMipmapNearestFilter || + texture.magFilter === NearestMipmapLinearFilter || + texture.magFilter === LinearMipmapLinearFilter || + texture.minFilter === LinearFilter || + texture.minFilter === LinearMipmapNearestFilter || + texture.minFilter === NearestMipmapLinearFilter || + texture.minFilter === LinearMipmapLinearFilter + ); + } + + addChain(node) { + /* + if ( this.chaining.indexOf( node ) !== - 1 ) { + + console.warn( 'Recursive node: ', node ); + + } + */ + + this.chaining.push(node); + } + + removeChain(node) { + const lastChain = this.chaining.pop(); + + if (lastChain !== node) { + throw new Error('NodeBuilder: Invalid node chaining!'); + } + } + + getMethod(method) { + return method; + } + + getNodeFromHash(hash) { + return this.hashNodes[hash]; + } + + addFlow(shaderStage, node) { + this.flowNodes[shaderStage].push(node); + + return node; + } + + setContext(context) { + this.context = context; + } + + getContext() { + return this.context; + } + + getSharedContext() { + const context = { ...this.context }; + + delete context.material; + + return this.context; + } + + setCache(cache) { + this.cache = cache; + } + + getCache() { + return this.cache; + } + + getCacheFromNode(node, parent = true) { + const data = this.getDataFromNode(node); + if (data.cache === undefined) data.cache = new NodeCache(parent ? this.getCache() : null); + + return data.cache; + } + + isAvailable(/*name*/) { + return false; + } + + getVertexIndex() { + console.warn('Abstract function.'); + } + + getInstanceIndex() { + console.warn('Abstract function.'); + } + + getDrawIndex() { + console.warn('Abstract function.'); + } + + getFrontFacing() { + console.warn('Abstract function.'); + } + + getFragCoord() { + console.warn('Abstract function.'); + } + + isFlipY() { + return false; + } + + increaseUsage(node) { + const nodeData = this.getDataFromNode(node); + nodeData.usageCount = nodeData.usageCount === undefined ? 1 : nodeData.usageCount + 1; + + return nodeData.usageCount; + } + + generateTexture(/* texture, textureProperty, uvSnippet */) { + console.warn('Abstract function.'); + } + + generateTextureLod(/* texture, textureProperty, uvSnippet, levelSnippet */) { + console.warn('Abstract function.'); + } + + generateConst(type, value = null) { + if (value === null) { + if (type === 'float' || type === 'int' || type === 'uint') value = 0; + else if (type === 'bool') value = false; + else if (type === 'color') value = new Color(); + else if (type === 'vec2') value = new Vector2(); + else if (type === 'vec3') value = new Vector3(); + else if (type === 'vec4') value = new Vector4(); + } + + if (type === 'float') return toFloat(value); + if (type === 'int') return `${Math.round(value)}`; + if (type === 'uint') return value >= 0 ? `${Math.round(value)}u` : '0u'; + if (type === 'bool') return value ? 'true' : 'false'; + if (type === 'color') + return `${this.getType('vec3')}( ${toFloat(value.r)}, ${toFloat(value.g)}, ${toFloat(value.b)} )`; + + const typeLength = this.getTypeLength(type); + + const componentType = this.getComponentType(type); + + const generateConst = value => this.generateConst(componentType, value); + + if (typeLength === 2) { + return `${this.getType(type)}( ${generateConst(value.x)}, ${generateConst(value.y)} )`; + } else if (typeLength === 3) { + return `${this.getType(type)}( ${generateConst(value.x)}, ${generateConst(value.y)}, ${generateConst(value.z)} )`; + } else if (typeLength === 4) { + return `${this.getType(type)}( ${generateConst(value.x)}, ${generateConst(value.y)}, ${generateConst(value.z)}, ${generateConst(value.w)} )`; + } else if (typeLength > 4 && value && (value.isMatrix3 || value.isMatrix4)) { + return `${this.getType(type)}( ${value.elements.map(generateConst).join(', ')} )`; + } else if (typeLength > 4) { + return `${this.getType(type)}()`; + } + + throw new Error(`NodeBuilder: Type '${type}' not found in generate constant attempt.`); + } + + getType(type) { + if (type === 'color') return 'vec3'; + + return type; + } + + hasGeometryAttribute(name) { + return this.geometry && this.geometry.getAttribute(name) !== undefined; + } + + getAttribute(name, type) { + const attributes = this.attributes; + + // find attribute + + for (const attribute of attributes) { + if (attribute.name === name) { + return attribute; + } + } + + // create a new if no exist + + const attribute = new NodeAttribute(name, type); + + attributes.push(attribute); + + return attribute; + } + + getPropertyName(node /*, shaderStage*/) { + return node.name; + } + + isVector(type) { + return /vec\d/.test(type); + } + + isMatrix(type) { + return /mat\d/.test(type); + } + + isReference(type) { + return ( + type === 'void' || + type === 'property' || + type === 'sampler' || + type === 'texture' || + type === 'cubeTexture' || + type === 'storageTexture' || + type === 'depthTexture' || + type === 'texture3D' + ); + } + + needsToWorkingColorSpace(/*texture*/) { + return false; + } + + getComponentTypeFromTexture(texture) { + const type = texture.type; + + if (texture.isDataTexture) { + if (type === IntType) return 'int'; + if (type === UnsignedIntType) return 'uint'; + } + + return 'float'; + } + + getElementType(type) { + if (type === 'mat2') return 'vec2'; + if (type === 'mat3') return 'vec3'; + if (type === 'mat4') return 'vec4'; + + return this.getComponentType(type); + } + + getComponentType(type) { + type = this.getVectorType(type); + + if (type === 'float' || type === 'bool' || type === 'int' || type === 'uint') return type; + + const componentType = /(b|i|u|)(vec|mat)([2-4])/.exec(type); + + if (componentType === null) return null; + + if (componentType[1] === 'b') return 'bool'; + if (componentType[1] === 'i') return 'int'; + if (componentType[1] === 'u') return 'uint'; + + return 'float'; + } + + getVectorType(type) { + if (type === 'color') return 'vec3'; + if (type === 'texture' || type === 'cubeTexture' || type === 'storageTexture' || type === 'texture3D') + return 'vec4'; + + return type; + } + + getTypeFromLength(length, componentType = 'float') { + if (length === 1) return componentType; + + const baseType = typeFromLength.get(length); + const prefix = componentType === 'float' ? '' : componentType[0]; + + return prefix + baseType; + } + + getTypeFromArray(array) { + return typeFromArray.get(array.constructor); + } + + getTypeFromAttribute(attribute) { + let dataAttribute = attribute; + + if (attribute.isInterleavedBufferAttribute) dataAttribute = attribute.data; + + const array = dataAttribute.array; + const itemSize = attribute.itemSize; + const normalized = attribute.normalized; + + let arrayType; + + if (!(attribute instanceof Float16BufferAttribute) && normalized !== true) { + arrayType = this.getTypeFromArray(array); + } + + return this.getTypeFromLength(itemSize, arrayType); + } + + getTypeLength(type) { + const vecType = this.getVectorType(type); + const vecNum = /vec([2-4])/.exec(vecType); + + if (vecNum !== null) return Number(vecNum[1]); + if (vecType === 'float' || vecType === 'bool' || vecType === 'int' || vecType === 'uint') return 1; + if (/mat2/.test(type) === true) return 4; + if (/mat3/.test(type) === true) return 9; + if (/mat4/.test(type) === true) return 16; + + return 0; + } + + getVectorFromMatrix(type) { + return type.replace('mat', 'vec'); + } + + changeComponentType(type, newComponentType) { + return this.getTypeFromLength(this.getTypeLength(type), newComponentType); + } + + getIntegerType(type) { + const componentType = this.getComponentType(type); + + if (componentType === 'int' || componentType === 'uint') return type; + + return this.changeComponentType(type, 'int'); + } + + addStack() { + this.stack = stack(this.stack); + + this.stacks.push(getCurrentStack() || this.stack); + setCurrentStack(this.stack); + + return this.stack; + } + + removeStack() { + const lastStack = this.stack; + this.stack = lastStack.parent; + + setCurrentStack(this.stacks.pop()); + + return lastStack; + } + + getDataFromNode(node, shaderStage = this.shaderStage, cache = null) { + cache = cache === null ? (node.isGlobal(this) ? this.globalCache : this.cache) : cache; + + let nodeData = cache.getData(node); + + if (nodeData === undefined) { + nodeData = {}; + + cache.setData(node, nodeData); + } + + if (nodeData[shaderStage] === undefined) nodeData[shaderStage] = {}; + + return nodeData[shaderStage]; + } + + getNodeProperties(node, shaderStage = 'any') { + const nodeData = this.getDataFromNode(node, shaderStage); + + return nodeData.properties || (nodeData.properties = { outputNode: null }); + } + + getBufferAttributeFromNode(node, type) { + const nodeData = this.getDataFromNode(node); + + let bufferAttribute = nodeData.bufferAttribute; + + if (bufferAttribute === undefined) { + const index = this.uniforms.index++; + + bufferAttribute = new NodeAttribute('nodeAttribute' + index, type, node); + + this.bufferAttributes.push(bufferAttribute); + + nodeData.bufferAttribute = bufferAttribute; + } + + return bufferAttribute; + } + + getStructTypeFromNode(node, shaderStage = this.shaderStage) { + const nodeData = this.getDataFromNode(node, shaderStage); + + if (nodeData.structType === undefined) { + const index = this.structs.index++; + + node.name = `StructType${index}`; + this.structs[shaderStage].push(node); + + nodeData.structType = node; + } + + return node; + } + + getUniformFromNode(node, type, shaderStage = this.shaderStage, name = null) { + const nodeData = this.getDataFromNode(node, shaderStage, this.globalCache); + + let nodeUniform = nodeData.uniform; + + if (nodeUniform === undefined) { + const index = this.uniforms.index++; + + nodeUniform = new NodeUniform(name || 'nodeUniform' + index, type, node); + + this.uniforms[shaderStage].push(nodeUniform); + + nodeData.uniform = nodeUniform; + } + + return nodeUniform; + } + + getVarFromNode(node, name = null, type = node.getNodeType(this), shaderStage = this.shaderStage) { + const nodeData = this.getDataFromNode(node, shaderStage); + + let nodeVar = nodeData.variable; + + if (nodeVar === undefined) { + const vars = this.vars[shaderStage] || (this.vars[shaderStage] = []); + + if (name === null) name = 'nodeVar' + vars.length; + + nodeVar = new NodeVar(name, type); + + vars.push(nodeVar); + + nodeData.variable = nodeVar; + } + + return nodeVar; + } + + getVaryingFromNode(node, name = null, type = node.getNodeType(this)) { + const nodeData = this.getDataFromNode(node, 'any'); + + let nodeVarying = nodeData.varying; + + if (nodeVarying === undefined) { + const varyings = this.varyings; + const index = varyings.length; + + if (name === null) name = 'nodeVarying' + index; + + nodeVarying = new NodeVarying(name, type); + + varyings.push(nodeVarying); + + nodeData.varying = nodeVarying; + } + + return nodeVarying; + } + + getCodeFromNode(node, type, shaderStage = this.shaderStage) { + const nodeData = this.getDataFromNode(node); + + let nodeCode = nodeData.code; + + if (nodeCode === undefined) { + const codes = this.codes[shaderStage] || (this.codes[shaderStage] = []); + const index = codes.length; + + nodeCode = new NodeCode('nodeCode' + index, type); + + codes.push(nodeCode); + + nodeData.code = nodeCode; + } + + return nodeCode; + } + + addFlowCodeHierarchy(node, nodeBlock) { + const { flowCodes, flowCodeBlock } = this.getDataFromNode(node); + + let needsFlowCode = true; + let nodeBlockHierarchy = nodeBlock; + + while (nodeBlockHierarchy) { + if (flowCodeBlock.get(nodeBlockHierarchy) === true) { + needsFlowCode = false; + break; + } + + nodeBlockHierarchy = this.getDataFromNode(nodeBlockHierarchy).parentNodeBlock; + } + + if (needsFlowCode) { + for (const flowCode of flowCodes) { + this.addLineFlowCode(flowCode); + } + } + } + + addLineFlowCodeBlock(node, code, nodeBlock) { + const nodeData = this.getDataFromNode(node); + const flowCodes = nodeData.flowCodes || (nodeData.flowCodes = []); + const codeBlock = nodeData.flowCodeBlock || (nodeData.flowCodeBlock = new WeakMap()); + + flowCodes.push(code); + codeBlock.set(nodeBlock, true); + } + + addLineFlowCode(code, node = null) { + if (code === '') return this; + + if (node !== null && this.context.nodeBlock) { + this.addLineFlowCodeBlock(node, code, this.context.nodeBlock); + } + + code = this.tab + code; + + if (!/;\s*$/.test(code)) { + code = code + ';\n'; + } + + this.flow.code += code; + + return this; + } + + addFlowCode(code) { + this.flow.code += code; + + return this; + } + + addFlowTab() { + this.tab += '\t'; + + return this; + } + + removeFlowTab() { + this.tab = this.tab.slice(0, -1); + + return this; + } + + getFlowData(node /*, shaderStage*/) { + return this.flowsData.get(node); + } + + flowNode(node) { + const output = node.getNodeType(this); + + const flowData = this.flowChildNode(node, output); + + this.flowsData.set(node, flowData); + + return flowData; + } + + buildFunctionNode(shaderNode) { + const fn = new FunctionNode(); + + const previous = this.currentFunctionNode; + + this.currentFunctionNode = fn; + + fn.code = this.buildFunctionCode(shaderNode); + + this.currentFunctionNode = previous; + + return fn; + } + + flowShaderNode(shaderNode) { + const layout = shaderNode.layout; + + const inputs = { + [Symbol.iterator]() { + let index = 0; + const values = Object.values(this); + return { + next: () => ({ + value: values[index], + done: index++ >= values.length, + }), + }; + }, + }; + + for (const input of layout.inputs) { + inputs[input.name] = new ParameterNode(input.type, input.name); + } + + // + + shaderNode.layout = null; + + const callNode = shaderNode.call(inputs); + const flowData = this.flowStagesNode(callNode, layout.type); + + shaderNode.layout = layout; + + return flowData; + } + + flowStagesNode(node, output = null) { + const previousFlow = this.flow; + const previousVars = this.vars; + const previousCache = this.cache; + const previousBuildStage = this.buildStage; + const previousStack = this.stack; + + const flow = { + code: '', + }; + + this.flow = flow; + this.vars = {}; + this.cache = new NodeCache(); + this.stack = stack(); + + for (const buildStage of defaultBuildStages) { + this.setBuildStage(buildStage); + + flow.result = node.build(this, output); + } + + flow.vars = this.getVars(this.shaderStage); + + this.flow = previousFlow; + this.vars = previousVars; + this.cache = previousCache; + this.stack = previousStack; + + this.setBuildStage(previousBuildStage); + + return flow; + } + + getFunctionOperator() { + return null; + } + + flowChildNode(node, output = null) { + const previousFlow = this.flow; + + const flow = { + code: '', + }; + + this.flow = flow; + + flow.result = node.build(this, output); + + this.flow = previousFlow; + + return flow; + } + + flowNodeFromShaderStage(shaderStage, node, output = null, propertyName = null) { + const previousShaderStage = this.shaderStage; + + this.setShaderStage(shaderStage); + + const flowData = this.flowChildNode(node, output); + + if (propertyName !== null) { + flowData.code += `${this.tab + propertyName} = ${flowData.result};\n`; + } + + this.flowCode[shaderStage] = this.flowCode[shaderStage] + flowData.code; + + this.setShaderStage(previousShaderStage); + + return flowData; + } + + getAttributesArray() { + return this.attributes.concat(this.bufferAttributes); + } + + getAttributes(/*shaderStage*/) { + console.warn('Abstract function.'); + } + + getVaryings(/*shaderStage*/) { + console.warn('Abstract function.'); + } + + getVar(type, name) { + return `${this.getType(type)} ${name}`; + } + + getVars(shaderStage) { + let snippet = ''; + + const vars = this.vars[shaderStage]; + + if (vars !== undefined) { + for (const variable of vars) { + snippet += `${this.getVar(variable.type, variable.name)}; `; + } + } + + return snippet; + } + + getUniforms(/*shaderStage*/) { + console.warn('Abstract function.'); + } + + getCodes(shaderStage) { + const codes = this.codes[shaderStage]; + + let code = ''; + + if (codes !== undefined) { + for (const nodeCode of codes) { + code += nodeCode.code + '\n'; + } + } + + return code; + } + + getHash() { + return this.vertexShader + this.fragmentShader + this.computeShader; + } + + setShaderStage(shaderStage) { + this.shaderStage = shaderStage; + } + + getShaderStage() { + return this.shaderStage; + } + + setBuildStage(buildStage) { + this.buildStage = buildStage; + } + + getBuildStage() { + return this.buildStage; + } + + buildCode() { + console.warn('Abstract function.'); + } + + build() { + const { object, material, renderer } = this; + + if (material !== null) { + let nodeMaterial = renderer.library.fromMaterial(material); + + if (nodeMaterial === null) { + console.error(`NodeMaterial: Material "${material.type}" is not compatible.`); + + nodeMaterial = new NodeMaterial(); + } + + nodeMaterial.build(this); + } else { + this.addFlow('compute', object); + } + + // setup() -> stage 1: create possible new nodes and returns an output reference node + // analyze() -> stage 2: analyze nodes to possible optimization and validation + // generate() -> stage 3: generate shader + + for (const buildStage of defaultBuildStages) { + this.setBuildStage(buildStage); + + if (this.context.vertex && this.context.vertex.isNode) { + this.flowNodeFromShaderStage('vertex', this.context.vertex); + } + + for (const shaderStage of shaderStages) { + this.setShaderStage(shaderStage); + + const flowNodes = this.flowNodes[shaderStage]; + + for (const node of flowNodes) { + if (buildStage === 'generate') { + this.flowNode(node); + } else { + node.build(this); + } + } + } + } + + this.setBuildStage(null); + this.setShaderStage(null); + + // stage 4: build code for a specific output + + this.buildCode(); + this.buildUpdateNodes(); + + return this; + } + + getNodeUniform(uniformNode, type) { + if (type === 'float' || type === 'int' || type === 'uint') return new NumberNodeUniform(uniformNode); + if (type === 'vec2' || type === 'ivec2' || type === 'uvec2') return new Vector2NodeUniform(uniformNode); + if (type === 'vec3' || type === 'ivec3' || type === 'uvec3') return new Vector3NodeUniform(uniformNode); + if (type === 'vec4' || type === 'ivec4' || type === 'uvec4') return new Vector4NodeUniform(uniformNode); + if (type === 'color') return new ColorNodeUniform(uniformNode); + if (type === 'mat3') return new Matrix3NodeUniform(uniformNode); + if (type === 'mat4') return new Matrix4NodeUniform(uniformNode); + + throw new Error(`Uniform "${type}" not declared.`); + } + + createNodeMaterial(type = 'NodeMaterial') { + // @deprecated, r168 + + throw new Error(`THREE.NodeBuilder: createNodeMaterial() was deprecated. Use new ${type}() instead.`); + } + + format(snippet, fromType, toType) { + fromType = this.getVectorType(fromType); + toType = this.getVectorType(toType); + + if (fromType === toType || toType === null || this.isReference(toType)) { + return snippet; + } + + const fromTypeLength = this.getTypeLength(fromType); + const toTypeLength = this.getTypeLength(toType); + + if (fromTypeLength === 16 && toTypeLength === 9) { + return `${this.getType(toType)}(${snippet}[0].xyz, ${snippet}[1].xyz, ${snippet}[2].xyz)`; + } + + if (fromTypeLength === 9 && toTypeLength === 4) { + return `${this.getType(toType)}(${snippet}[0].xy, ${snippet}[1].xy)`; + } + + if (fromTypeLength > 4) { + // fromType is matrix-like + + // @TODO: ignore for now + + return snippet; + } + + if (toTypeLength > 4 || toTypeLength === 0) { + // toType is matrix-like or unknown + + // @TODO: ignore for now + + return snippet; + } + + if (fromTypeLength === toTypeLength) { + return `${this.getType(toType)}( ${snippet} )`; + } + + if (fromTypeLength > toTypeLength) { + return this.format( + `${snippet}.${'xyz'.slice(0, toTypeLength)}`, + this.getTypeFromLength(toTypeLength, this.getComponentType(fromType)), + toType, + ); + } + + if (toTypeLength === 4 && fromTypeLength > 1) { + // toType is vec4-like + + return `${this.getType(toType)}( ${this.format(snippet, fromType, 'vec3')}, 1.0 )`; + } + + if (fromTypeLength === 2) { + // fromType is vec2-like and toType is vec3-like + + return `${this.getType(toType)}( ${this.format(snippet, fromType, 'vec2')}, 0.0 )`; + } + + if (fromTypeLength === 1 && toTypeLength > 1 && fromType !== this.getComponentType(toType)) { + // fromType is float-like + + // convert a number value to vector type, e.g: + // vec3( 1u ) -> vec3( float( 1u ) ) + + snippet = `${this.getType(this.getComponentType(toType))}( ${snippet} )`; + } + + return `${this.getType(toType)}( ${snippet} )`; // fromType is float-like + } + + getSignature() { + return `// Three.js r${REVISION} - Node System\n`; + } +} + +export default NodeBuilder; diff --git a/src-testing/src/nodes/core/NodeCache.ts b/src-testing/src/nodes/core/NodeCache.ts new file mode 100644 index 000000000..ad72d50c5 --- /dev/null +++ b/src-testing/src/nodes/core/NodeCache.ts @@ -0,0 +1,26 @@ +let id = 0; + +class NodeCache { + constructor(parent = null) { + this.id = id++; + this.nodesData = new WeakMap(); + + this.parent = parent; + } + + getData(node) { + let data = this.nodesData.get(node); + + if (data === undefined && this.parent !== null) { + data = this.parent.getData(node); + } + + return data; + } + + setData(node, data) { + this.nodesData.set(node, data); + } +} + +export default NodeCache; diff --git a/src-testing/src/nodes/core/NodeCode.ts b/src-testing/src/nodes/core/NodeCode.ts new file mode 100644 index 000000000..2ee509037 --- /dev/null +++ b/src-testing/src/nodes/core/NodeCode.ts @@ -0,0 +1,11 @@ +class NodeCode { + constructor(name, type, code = '') { + this.name = name; + this.type = type; + this.code = code; + + Object.defineProperty(this, 'isNodeCode', { value: true }); + } +} + +export default NodeCode; diff --git a/src-testing/src/nodes/core/NodeFrame.ts b/src-testing/src/nodes/core/NodeFrame.ts new file mode 100644 index 000000000..ee64620ca --- /dev/null +++ b/src-testing/src/nodes/core/NodeFrame.ts @@ -0,0 +1,127 @@ +import { NodeUpdateType } from './constants.js'; + +class NodeFrame { + constructor() { + this.time = 0; + this.deltaTime = 0; + + this.frameId = 0; + this.renderId = 0; + + this.startTime = null; + + this.updateMap = new WeakMap(); + this.updateBeforeMap = new WeakMap(); + this.updateAfterMap = new WeakMap(); + + this.renderer = null; + this.material = null; + this.camera = null; + this.object = null; + this.scene = null; + } + + _getMaps(referenceMap, nodeRef) { + let maps = referenceMap.get(nodeRef); + + if (maps === undefined) { + maps = { + renderMap: new WeakMap(), + frameMap: new WeakMap(), + }; + + referenceMap.set(nodeRef, maps); + } + + return maps; + } + + updateBeforeNode(node) { + const updateType = node.getUpdateBeforeType(); + const reference = node.updateReference(this); + + if (updateType === NodeUpdateType.FRAME) { + const { frameMap } = this._getMaps(this.updateBeforeMap, reference); + + if (frameMap.get(reference) !== this.frameId) { + if (node.updateBefore(this) !== false) { + frameMap.set(reference, this.frameId); + } + } + } else if (updateType === NodeUpdateType.RENDER) { + const { renderMap } = this._getMaps(this.updateBeforeMap, reference); + + if (renderMap.get(reference) !== this.renderId) { + if (node.updateBefore(this) !== false) { + renderMap.set(reference, this.renderId); + } + } + } else if (updateType === NodeUpdateType.OBJECT) { + node.updateBefore(this); + } + } + + updateAfterNode(node) { + const updateType = node.getUpdateAfterType(); + const reference = node.updateReference(this); + + if (updateType === NodeUpdateType.FRAME) { + const { frameMap } = this._getMaps(this.updateAfterMap, reference); + + if (frameMap.get(reference) !== this.frameId) { + if (node.updateAfter(this) !== false) { + frameMap.set(reference, this.frameId); + } + } + } else if (updateType === NodeUpdateType.RENDER) { + const { renderMap } = this._getMaps(this.updateAfterMap, reference); + + if (renderMap.get(reference) !== this.renderId) { + if (node.updateAfter(this) !== false) { + renderMap.set(reference, this.renderId); + } + } + } else if (updateType === NodeUpdateType.OBJECT) { + node.updateAfter(this); + } + } + + updateNode(node) { + const updateType = node.getUpdateType(); + const reference = node.updateReference(this); + + if (updateType === NodeUpdateType.FRAME) { + const { frameMap } = this._getMaps(this.updateMap, reference); + + if (frameMap.get(reference) !== this.frameId) { + if (node.update(this) !== false) { + frameMap.set(reference, this.frameId); + } + } + } else if (updateType === NodeUpdateType.RENDER) { + const { renderMap } = this._getMaps(this.updateMap, reference); + + if (renderMap.get(reference) !== this.renderId) { + if (node.update(this) !== false) { + renderMap.set(reference, this.renderId); + } + } + } else if (updateType === NodeUpdateType.OBJECT) { + node.update(this); + } + } + + update() { + this.frameId++; + + if (this.lastTime === undefined) this.lastTime = performance.now(); + + this.deltaTime = (performance.now() - this.lastTime) / 1000; + + this.lastTime = performance.now(); + + this.time += this.deltaTime; + } +} + +export default NodeFrame; diff --git a/src-testing/src/nodes/core/NodeFunction.ts b/src-testing/src/nodes/core/NodeFunction.ts new file mode 100644 index 000000000..d05afb5e6 --- /dev/null +++ b/src-testing/src/nodes/core/NodeFunction.ts @@ -0,0 +1,16 @@ +class NodeFunction { + constructor(type, inputs, name = '', precision = '') { + this.type = type; + this.inputs = inputs; + this.name = name; + this.precision = precision; + } + + getCode(/*name = this.name*/) { + console.warn('Abstract function.'); + } +} + +NodeFunction.isNodeFunction = true; + +export default NodeFunction; diff --git a/src-testing/src/nodes/core/NodeFunctionInput.d.ts b/src-testing/src/nodes/core/NodeFunctionInput.d.ts new file mode 100644 index 000000000..a8231d126 --- /dev/null +++ b/src-testing/src/nodes/core/NodeFunctionInput.d.ts @@ -0,0 +1,7 @@ +export default class NodeFunctionInput { + isNodeFunctionInput: true; + count: null | number; + qualifier: string; + isConst: boolean; + constructor(type: string, name: string, count?: number, qualifier?: string, isConst?: boolean); +} diff --git a/src-testing/src/nodes/core/NodeParser.ts b/src-testing/src/nodes/core/NodeParser.ts new file mode 100644 index 000000000..9849452f1 --- /dev/null +++ b/src-testing/src/nodes/core/NodeParser.ts @@ -0,0 +1,7 @@ +class NodeParser { + parseFunction(/*source*/) { + console.warn('Abstract function.'); + } +} + +export default NodeParser; diff --git a/src-testing/src/nodes/core/NodeUniform.ts b/src-testing/src/nodes/core/NodeUniform.ts new file mode 100644 index 000000000..ca43958fc --- /dev/null +++ b/src-testing/src/nodes/core/NodeUniform.ts @@ -0,0 +1,27 @@ +class NodeUniform { + constructor(name, type, node) { + this.isNodeUniform = true; + + this.name = name; + this.type = type; + this.node = node.getSelf(); + } + + get value() { + return this.node.value; + } + + set value(val) { + this.node.value = val; + } + + get id() { + return this.node.id; + } + + get groupNode() { + return this.node.groupNode; + } +} + +export default NodeUniform; diff --git a/src-testing/src/nodes/core/NodeUtils.ts b/src-testing/src/nodes/core/NodeUtils.ts new file mode 100644 index 000000000..7ebac01f9 --- /dev/null +++ b/src-testing/src/nodes/core/NodeUtils.ts @@ -0,0 +1,171 @@ +import { Color } from '../../math/Color.js'; +import { Matrix3 } from '../../math/Matrix3.js'; +import { Matrix4 } from '../../math/Matrix4.js'; +import { Vector2 } from '../../math/Vector2.js'; +import { Vector3 } from '../../math/Vector3.js'; +import { Vector4 } from '../../math/Vector4.js'; + +// cyrb53 (c) 2018 bryc (github.com/bryc). License: Public domain. Attribution appreciated. +// A fast and simple 64-bit (or 53-bit) string hash function with decent collision resistance. +// Largely inspired by MurmurHash2/3, but with a focus on speed/simplicity. +// See https://stackoverflow.com/questions/7616461/generate-a-hash-from-string-in-javascript/52171480#52171480 +// https://github.com/bryc/code/blob/master/jshash/experimental/cyrb53.js +function cyrb53(value, seed = 0) { + let h1 = 0xdeadbeef ^ seed, + h2 = 0x41c6ce57 ^ seed; + + if (value instanceof Array) { + for (let i = 0, val; i < value.length; i++) { + val = value[i]; + h1 = Math.imul(h1 ^ val, 2654435761); + h2 = Math.imul(h2 ^ val, 1597334677); + } + } else { + for (let i = 0, ch; i < value.length; i++) { + ch = value.charCodeAt(i); + h1 = Math.imul(h1 ^ ch, 2654435761); + h2 = Math.imul(h2 ^ ch, 1597334677); + } + } + + h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507); + h1 ^= Math.imul(h2 ^ (h2 >>> 13), 3266489909); + h2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507); + h2 ^= Math.imul(h1 ^ (h1 >>> 13), 3266489909); + + return 4294967296 * (2097151 & h2) + (h1 >>> 0); +} + +export const hashString = str => cyrb53(str); +export const hashArray = array => cyrb53(array); +export const hash = (...params) => cyrb53(params); + +export function getCacheKey(object, force = false) { + const values = []; + + if (object.isNode === true) { + values.push(object.id); + object = object.getSelf(); + } + + for (const { property, childNode } of getNodeChildren(object)) { + values.push(values, cyrb53(property.slice(0, -4)), childNode.getCacheKey(force)); + } + + return cyrb53(values); +} + +export function* getNodeChildren(node, toJSON = false) { + for (const property in node) { + // Ignore private properties. + if (property.startsWith('_') === true) continue; + + const object = node[property]; + + if (Array.isArray(object) === true) { + for (let i = 0; i < object.length; i++) { + const child = object[i]; + + if (child && (child.isNode === true || (toJSON && typeof child.toJSON === 'function'))) { + yield { property, index: i, childNode: child }; + } + } + } else if (object && object.isNode === true) { + yield { property, childNode: object }; + } else if (typeof object === 'object') { + for (const subProperty in object) { + const child = object[subProperty]; + + if (child && (child.isNode === true || (toJSON && typeof child.toJSON === 'function'))) { + yield { property, index: subProperty, childNode: child }; + } + } + } + } +} + +export function getValueType(value) { + if (value === undefined || value === null) return null; + + const typeOf = typeof value; + + if (value.isNode === true) { + return 'node'; + } else if (typeOf === 'number') { + return 'float'; + } else if (typeOf === 'boolean') { + return 'bool'; + } else if (typeOf === 'string') { + return 'string'; + } else if (typeOf === 'function') { + return 'shader'; + } else if (value.isVector2 === true) { + return 'vec2'; + } else if (value.isVector3 === true) { + return 'vec3'; + } else if (value.isVector4 === true) { + return 'vec4'; + } else if (value.isMatrix3 === true) { + return 'mat3'; + } else if (value.isMatrix4 === true) { + return 'mat4'; + } else if (value.isColor === true) { + return 'color'; + } else if (value instanceof ArrayBuffer) { + return 'ArrayBuffer'; + } + + return null; +} + +export function getValueFromType(type, ...params) { + const last4 = type ? type.slice(-4) : undefined; + + if (params.length === 1) { + // ensure same behaviour as in NodeBuilder.format() + + if (last4 === 'vec2') params = [params[0], params[0]]; + else if (last4 === 'vec3') params = [params[0], params[0], params[0]]; + else if (last4 === 'vec4') params = [params[0], params[0], params[0], params[0]]; + } + + if (type === 'color') { + return new Color(...params); + } else if (last4 === 'vec2') { + return new Vector2(...params); + } else if (last4 === 'vec3') { + return new Vector3(...params); + } else if (last4 === 'vec4') { + return new Vector4(...params); + } else if (last4 === 'mat3') { + return new Matrix3(...params); + } else if (last4 === 'mat4') { + return new Matrix4(...params); + } else if (type === 'bool') { + return params[0] || false; + } else if (type === 'float' || type === 'int' || type === 'uint') { + return params[0] || 0; + } else if (type === 'string') { + return params[0] || ''; + } else if (type === 'ArrayBuffer') { + return base64ToArrayBuffer(params[0]); + } + + return null; +} + +export function arrayBufferToBase64(arrayBuffer) { + let chars = ''; + + const array = new Uint8Array(arrayBuffer); + + for (let i = 0; i < array.length; i++) { + chars += String.fromCharCode(array[i]); + } + + return btoa(chars); +} + +export function base64ToArrayBuffer(base64) { + return Uint8Array.from(atob(base64), c => c.charCodeAt(0)).buffer; +} diff --git a/src-testing/src/nodes/core/NodeVar.ts b/src-testing/src/nodes/core/NodeVar.ts new file mode 100644 index 000000000..e6e935b31 --- /dev/null +++ b/src-testing/src/nodes/core/NodeVar.ts @@ -0,0 +1,10 @@ +class NodeVar { + constructor(name, type) { + this.isNodeVar = true; + + this.name = name; + this.type = type; + } +} + +export default NodeVar; diff --git a/src-testing/src/nodes/core/NodeVarying.ts b/src-testing/src/nodes/core/NodeVarying.ts new file mode 100644 index 000000000..a14823628 --- /dev/null +++ b/src-testing/src/nodes/core/NodeVarying.ts @@ -0,0 +1,13 @@ +import NodeVar from './NodeVar.js'; + +class NodeVarying extends NodeVar { + constructor(name, type) { + super(name, type); + + this.needsInterpolation = false; + + this.isNodeVarying = true; + } +} + +export default NodeVarying; diff --git a/src-testing/src/nodes/core/OutputStructNode.d.ts b/src-testing/src/nodes/core/OutputStructNode.d.ts new file mode 100644 index 000000000..5a7fc6e7b --- /dev/null +++ b/src-testing/src/nodes/core/OutputStructNode.d.ts @@ -0,0 +1,12 @@ +import { ShaderNodeObject } from "../tsl/TSLCore.js"; +import Node from "./Node.js"; + +export default class OutputStructNode extends Node { + members: Node[]; + + readonly isOutputStructNode: true; + + constructor(...members: Node[]); +} + +export const outputStruct: (...members: Node[]) => ShaderNodeObject; diff --git a/src-testing/src/nodes/core/ParameterNode.d.ts b/src-testing/src/nodes/core/ParameterNode.d.ts new file mode 100644 index 000000000..02629dbf5 --- /dev/null +++ b/src-testing/src/nodes/core/ParameterNode.d.ts @@ -0,0 +1,12 @@ +import { ShaderNodeObject } from "../tsl/TSLCore.js"; +import PropertyNode from "./PropertyNode.js"; + +declare class ParameterNode extends PropertyNode { + readonly isParameterNode: true; + + constructor(nodeType: string, name?: string | null); +} + +export default ParameterNode; + +export const parameter: (type: string, name?: string | null) => ShaderNodeObject; diff --git a/src-testing/src/nodes/core/PropertyNode.d.ts b/src-testing/src/nodes/core/PropertyNode.d.ts new file mode 100644 index 000000000..b365d107b --- /dev/null +++ b/src-testing/src/nodes/core/PropertyNode.d.ts @@ -0,0 +1,43 @@ +import { ShaderNodeObject } from "../tsl/TSLCore.js"; +import Node from "./Node.js"; + +export default class PropertyNode extends Node { + name: string | null; + varying: boolean; + + readonly isPropertyNode: true; + + constructor(nodeType?: string | null, name?: string | null, varying?: boolean); +} + +export const property: (type?: string | null, name?: string | null) => ShaderNodeObject; +export const varyingProperty: (type?: string | null, name?: string | null) => ShaderNodeObject; + +export const diffuseColor: ShaderNodeObject; +export const emissive: ShaderNodeObject; +export const roughness: ShaderNodeObject; +export const metalness: ShaderNodeObject; +export const clearcoat: ShaderNodeObject; +export const clearcoatRoughness: ShaderNodeObject; +export const sheen: ShaderNodeObject; +export const sheenRoughness: ShaderNodeObject; +export const iridescence: ShaderNodeObject; +export const iridescenceIOR: ShaderNodeObject; +export const iridescenceThickness: ShaderNodeObject; +export const alphaT: ShaderNodeObject; +export const anisotropy: ShaderNodeObject; +export const anisotropyT: ShaderNodeObject; +export const anisotropyB: ShaderNodeObject; +export const specularColor: ShaderNodeObject; +export const specularF90: ShaderNodeObject; +export const shininess: ShaderNodeObject; +export const output: ShaderNodeObject; +export const dashSize: ShaderNodeObject; +export const gapSize: ShaderNodeObject; +export const pointWidth: ShaderNodeObject; +export const ior: ShaderNodeObject; +export const transmission: ShaderNodeObject; +export const thickness: ShaderNodeObject; +export const attenuationDistance: ShaderNodeObject; +export const attenuationColor: ShaderNodeObject; +export const dispersion: ShaderNodeObject; diff --git a/src-testing/src/nodes/core/StackNode.ts b/src-testing/src/nodes/core/StackNode.ts new file mode 100644 index 000000000..79313afad --- /dev/null +++ b/src-testing/src/nodes/core/StackNode.ts @@ -0,0 +1,89 @@ +import Node from './Node.js'; +import { select } from '../math/ConditionalNode.js'; +import { ShaderNode, nodeProxy, getCurrentStack, setCurrentStack } from '../tsl/TSLBase.js'; + +class StackNode extends Node { + static get type() { + return 'StackNode'; + } + + constructor(parent = null) { + super(); + + this.nodes = []; + this.outputNode = null; + + this.parent = parent; + + this._currentCond = null; + + this.isStackNode = true; + } + + getNodeType(builder) { + return this.outputNode ? this.outputNode.getNodeType(builder) : 'void'; + } + + add(node) { + this.nodes.push(node); + + return this; + } + + If(boolNode, method) { + const methodNode = new ShaderNode(method); + this._currentCond = select(boolNode, methodNode); + + return this.add(this._currentCond); + } + + ElseIf(boolNode, method) { + const methodNode = new ShaderNode(method); + const ifNode = select(boolNode, methodNode); + + this._currentCond.elseNode = ifNode; + this._currentCond = ifNode; + + return this; + } + + Else(method) { + this._currentCond.elseNode = new ShaderNode(method); + + return this; + } + + build(builder, ...params) { + const previousStack = getCurrentStack(); + + setCurrentStack(this); + + for (const node of this.nodes) { + node.build(builder, 'void'); + } + + setCurrentStack(previousStack); + + return this.outputNode ? this.outputNode.build(builder, ...params) : super.build(builder, ...params); + } + + // + + else(...params) { + // @deprecated, r168 + + console.warn('TSL.StackNode: .else() has been renamed to .Else().'); + return this.Else(...params); + } + + elseif(...params) { + // @deprecated, r168 + + console.warn('TSL.StackNode: .elseif() has been renamed to .ElseIf().'); + return this.ElseIf(...params); + } +} + +export default StackNode; + +export const stack = /*@__PURE__*/ nodeProxy(StackNode); diff --git a/src-testing/src/nodes/core/StructTypeNode.ts b/src-testing/src/nodes/core/StructTypeNode.ts new file mode 100644 index 000000000..acadb07e1 --- /dev/null +++ b/src-testing/src/nodes/core/StructTypeNode.ts @@ -0,0 +1,20 @@ +import Node from './Node.js'; + +class StructTypeNode extends Node { + static get type() { + return 'StructTypeNode'; + } + + constructor(types) { + super(); + + this.types = types; + this.isStructTypeNode = true; + } + + getMemberTypes() { + return this.types; + } +} + +export default StructTypeNode; diff --git a/src-testing/src/nodes/core/TempNode.d.ts b/src-testing/src/nodes/core/TempNode.d.ts new file mode 100644 index 000000000..367f5ade1 --- /dev/null +++ b/src-testing/src/nodes/core/TempNode.d.ts @@ -0,0 +1,10 @@ +import Node from "./Node.js"; +import NodeBuilder from "./NodeBuilder.js"; + +export default class TempNode extends Node { + isTempNode: true; + + constructor(type: string | null); + + hasDependencies(builder: NodeBuilder): boolean; +} diff --git a/src-testing/src/nodes/core/UniformGroup.d.ts b/src-testing/src/nodes/core/UniformGroup.d.ts new file mode 100644 index 000000000..60339877b --- /dev/null +++ b/src-testing/src/nodes/core/UniformGroup.d.ts @@ -0,0 +1,7 @@ +export default class UniformGroup { + name: string; + + readonly isUniformGroup: true; + + constructor(name: string); +} diff --git a/src-testing/src/nodes/core/UniformGroupNode.ts b/src-testing/src/nodes/core/UniformGroupNode.ts new file mode 100644 index 000000000..829fd3ee8 --- /dev/null +++ b/src-testing/src/nodes/core/UniformGroupNode.ts @@ -0,0 +1,47 @@ +import Node from './Node.js'; + +class UniformGroupNode extends Node { + static get type() { + return 'UniformGroupNode'; + } + + constructor(name, shared = false, order = 1) { + super('string'); + + this.name = name; + this.version = 0; + + this.shared = shared; + this.order = order; + this.isUniformGroup = true; + } + + set needsUpdate(value) { + if (value === true) this.version++; + } + + serialize(data) { + super.serialize(data); + + data.name = this.name; + data.version = this.version; + data.shared = this.shared; + } + + deserialize(data) { + super.deserialize(data); + + this.name = data.name; + this.version = data.version; + this.shared = data.shared; + } +} + +export default UniformGroupNode; + +export const uniformGroup = name => new UniformGroupNode(name); +export const sharedUniformGroup = (name, order = 0) => new UniformGroupNode(name, true, order); + +export const frameGroup = /*@__PURE__*/ sharedUniformGroup('frame'); +export const renderGroup = /*@__PURE__*/ sharedUniformGroup('render'); +export const objectGroup = /*@__PURE__*/ uniformGroup('object'); diff --git a/src-testing/src/nodes/core/UniformNode.ts b/src-testing/src/nodes/core/UniformNode.ts new file mode 100644 index 000000000..ec9fa9aee --- /dev/null +++ b/src-testing/src/nodes/core/UniformNode.ts @@ -0,0 +1,91 @@ +import InputNode from './InputNode.js'; +import { objectGroup } from './UniformGroupNode.js'; +import { nodeObject, getConstNodeType } from '../tsl/TSLCore.js'; + +class UniformNode extends InputNode { + static get type() { + return 'UniformNode'; + } + + constructor(value, nodeType = null) { + super(value, nodeType); + + this.isUniformNode = true; + + this.name = ''; + this.groupNode = objectGroup; + } + + label(name) { + this.name = name; + + return this; + } + + setGroup(group) { + this.groupNode = group; + + return this; + } + + getGroup() { + return this.groupNode; + } + + getUniformHash(builder) { + return this.getHash(builder); + } + + onUpdate(callback, updateType) { + const self = this.getSelf(); + + callback = callback.bind(self); + + return super.onUpdate(frame => { + const value = callback(frame, self); + + if (value !== undefined) { + this.value = value; + } + }, updateType); + } + + generate(builder, output) { + const type = this.getNodeType(builder); + + const hash = this.getUniformHash(builder); + + let sharedNode = builder.getNodeFromHash(hash); + + if (sharedNode === undefined) { + builder.setHashNode(this, hash); + + sharedNode = this; + } + + const sharedNodeType = sharedNode.getInputType(builder); + + const nodeUniform = builder.getUniformFromNode( + sharedNode, + sharedNodeType, + builder.shaderStage, + this.name || builder.context.label, + ); + const propertyName = builder.getPropertyName(nodeUniform); + + if (builder.context.label !== undefined) delete builder.context.label; + + return builder.format(propertyName, type, output); + } +} + +export default UniformNode; + +export const uniform = (arg1, arg2) => { + const nodeType = getConstNodeType(arg2 || arg1); + + // @TODO: get ConstNode from .traverse() in the future + const value = arg1 && arg1.isNode === true ? (arg1.node && arg1.node.value) || arg1.value : arg1; + + return nodeObject(new UniformNode(value, nodeType)); +}; diff --git a/src-testing/src/nodes/core/VarNode.d.ts b/src-testing/src/nodes/core/VarNode.d.ts new file mode 100644 index 000000000..327df482a --- /dev/null +++ b/src-testing/src/nodes/core/VarNode.d.ts @@ -0,0 +1,31 @@ +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; +import Node from "./Node.js"; + +export default class VarNode extends Node { + node: Node; + name: string | null; + + readonly isVarNode: true; + + constructor(node: Node, name?: string | null); +} + +declare module "../tsl/TSLCore.js" { + interface NodeElements { + toVar: (node: NodeRepresentation, name?: string | null) => ShaderNodeObject; + } +} + +/** + * @deprecated Use ".toVar()" instead. + */ +export const temp: (node: NodeRepresentation, name?: string | null) => ShaderNodeObject; + +declare module "../tsl/TSLCore.js" { + interface NodeElements { + /** + * @deprecated Use ".toVar()" instead. + */ + temp: typeof temp; + } +} diff --git a/src-testing/src/nodes/core/VaryingNode.d.ts b/src-testing/src/nodes/core/VaryingNode.d.ts new file mode 100644 index 000000000..f10077ce0 --- /dev/null +++ b/src-testing/src/nodes/core/VaryingNode.d.ts @@ -0,0 +1,21 @@ +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; +import Node from "./Node.js"; +import NodeBuilder from "./NodeBuilder.js"; +import NodeVarying from "./NodeVarying.js"; + +export default class VaryingNode extends Node { + node: Node; + name: string | null; + + constructor(node: Node, name?: string | null); + + setupVarying(builder: NodeBuilder): NodeVarying; +} + +export const varying: (node: NodeRepresentation, name?: string) => ShaderNodeObject; + +declare module "../tsl/TSLCore.js" { + interface NodeElements { + varying: typeof varying; + } +} diff --git a/src-testing/src/nodes/core/constants.ts b/src-testing/src/nodes/core/constants.ts new file mode 100644 index 000000000..3b01a9a6d --- /dev/null +++ b/src-testing/src/nodes/core/constants.ts @@ -0,0 +1,28 @@ +export const NodeShaderStage = { + VERTEX: 'vertex', + FRAGMENT: 'fragment', +}; + +export const NodeUpdateType = { + NONE: 'none', + FRAME: 'frame', + RENDER: 'render', + OBJECT: 'object', +}; + +export const NodeType = { + BOOLEAN: 'bool', + INTEGER: 'int', + FLOAT: 'float', + VECTOR2: 'vec2', + VECTOR3: 'vec3', + VECTOR4: 'vec4', + MATRIX2: 'mat2', + MATRIX3: 'mat3', + MATRIX4: 'mat4', +}; + +export const defaultShaderStages = ['fragment', 'vertex']; +export const defaultBuildStages = ['setup', 'analyze', 'generate']; +export const shaderStages = [...defaultShaderStages, 'compute']; +export const vectorComponents = ['x', 'y', 'z', 'w']; diff --git a/src-testing/src/nodes/display/BlendMode.d.ts b/src-testing/src/nodes/display/BlendMode.d.ts new file mode 100644 index 000000000..1f2d23991 --- /dev/null +++ b/src-testing/src/nodes/display/BlendMode.d.ts @@ -0,0 +1,10 @@ +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +export const burn: (base: NodeRepresentation, blend: NodeRepresentation) => ShaderNodeObject; + +export const dodge: (base: NodeRepresentation, blend: NodeRepresentation) => ShaderNodeObject; + +export const screen: (base: NodeRepresentation, blend: NodeRepresentation) => ShaderNodeObject; + +export const overlay: (base: NodeRepresentation, blend: NodeRepresentation) => ShaderNodeObject; diff --git a/src-testing/src/nodes/display/BumpMapNode.d.ts b/src-testing/src/nodes/display/BumpMapNode.d.ts new file mode 100644 index 000000000..726f55685 --- /dev/null +++ b/src-testing/src/nodes/display/BumpMapNode.d.ts @@ -0,0 +1,16 @@ +import TempNode from "../core/TempNode.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +declare class BumpMapNode extends TempNode { + textureNode: Node; + scaleNode: Node | null; + + constructor(textureNode: Node, scaleNode?: Node | null); +} + +export default BumpMapNode; + +export const bumpMap: ( + textureNode: NodeRepresentation, + scaleNode?: NodeRepresentation | null, +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/display/ColorAdjustment.d.ts b/src-testing/src/nodes/display/ColorAdjustment.d.ts new file mode 100644 index 000000000..4de024be7 --- /dev/null +++ b/src-testing/src/nodes/display/ColorAdjustment.d.ts @@ -0,0 +1,56 @@ +import Node from "../core/Node.js"; +import MathNode from "../math/MathNode.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +export const grayscale: (color: NodeRepresentation) => ShaderNodeObject; + +export const saturation: ( + color: NodeRepresentation, + adjustment?: NodeRepresentation, +) => ShaderNodeObject; + +export const vibrance: ( + color: NodeRepresentation, + adjustment?: NodeRepresentation, +) => ShaderNodeObject; + +export const hue: ( + color: NodeRepresentation, + adjustment?: NodeRepresentation, +) => ShaderNodeObject; + +export const luminance: ( + color: NodeRepresentation, + luminanceCoefficients?: NodeRepresentation, +) => ShaderNodeObject; + +export const threshold: (color: NodeRepresentation, thershold: NodeRepresentation) => ShaderNodeObject; + +/** + * Color Decision List (CDL) v1.2 + * + * Compact representation of color grading information, defined by slope, offset, power, and saturation. The CDL should + * be typically be given input in a log space (such as LogC, ACEScc, or AgX Log), and will return output in the same + * space. Output may require clamping >=0. + * + * References: + * - ASC CDL v1.2 + * - https://blender.stackexchange.com/a/55239/43930 + * - https://docs.acescentral.com/specifications/acescc/ + * + * @param color Input (-Infinity < input < +Infinity) + * @param slope Slope (0 ≤ slope < +Infinity) + * @param offset Offset (-Infinity < offset < +Infinity; typically -1 < offset < 1) + * @param power Power (0 < power < +Infinity) + * @param saturation Saturation (0 ≤ saturation < +Infinity; typically 0 ≤ saturation < 4) + * @param luminanceCoefficients Luminance coefficients for saturation term, typically Rec. 709 + * @return Output, -Infinity < output < +Infinity + */ +export const cdl: ( + color: NodeRepresentation, + slope?: NodeRepresentation, + offset?: NodeRepresentation, + power?: NodeRepresentation, + saturation?: NodeRepresentation, + luminanceCoefficients?: NodeRepresentation, +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/display/ColorSpaceFunctions.d.ts b/src-testing/src/nodes/display/ColorSpaceFunctions.d.ts new file mode 100644 index 000000000..a4bd01216 --- /dev/null +++ b/src-testing/src/nodes/display/ColorSpaceFunctions.d.ts @@ -0,0 +1,6 @@ +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +export const sRGBTransferEOTF: (color: NodeRepresentation) => ShaderNodeObject; + +export const sRGBTransferOETF: (color: NodeRepresentation) => ShaderNodeObject; diff --git a/src-testing/src/nodes/display/ColorSpaceNode.d.ts b/src-testing/src/nodes/display/ColorSpaceNode.d.ts new file mode 100644 index 000000000..c0de945da --- /dev/null +++ b/src-testing/src/nodes/display/ColorSpaceNode.d.ts @@ -0,0 +1,60 @@ +import { LinearSRGBColorSpace, SRGBColorSpace } from "../../constants.js"; +import Node from "../core/Node.js"; +import NodeBuilder from "../core/NodeBuilder.js"; +import TempNode from "../core/TempNode.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +export type WorkingOrOutputColorSpace = "WorkingColorSpace" | "OutputColorSpace"; + +export type ColorSpaceMethod = "LinearTosRGB" | "sRGBToLinear" | "LinearToLinear" | "sRGBTosRGB"; + +export function getColorSpaceMethod( + source: typeof LinearSRGBColorSpace | typeof SRGBColorSpace, + target: typeof LinearSRGBColorSpace | typeof SRGBColorSpace, +): ColorSpaceMethod; + +export default class ColorSpaceNode extends TempNode { + colorNode: Node; + source: string; + target: string; + + constructor( + colorNode: Node, + source: string, + target: string, + ); + + resolveColorSpace(nodeBuilder: NodeBuilder, colorSpace: WorkingOrOutputColorSpace): string; +} + +export const toOutputColorSpace: ( + node: NodeRepresentation, +) => ShaderNodeObject; +export const toWorkingColorSpace: ( + node: NodeRepresentation, +) => ShaderNodeObject; + +export const workingToColorSpace: ( + node: NodeRepresentation, + colorSpace: string, +) => ShaderNodeObject; +export const colorSpaceToWorking: ( + node: NodeRepresentation, + colorSpace: string, +) => ShaderNodeObject; + +export const convertColorSpace: ( + node: NodeRepresentation, + sourceColorSpace: string, + targetColorSpace: string, +) => ShaderNodeObject; + +declare module "../tsl/TSLCore.js" { + interface NodeElements { + toOutputColorSpace: typeof toOutputColorSpace; + toWorkingColorSpace: typeof toWorkingColorSpace; + + workingToColorSpace: typeof workingToColorSpace; + colorSpaceToWorking: typeof colorSpaceToWorking; + } +} diff --git a/src-testing/src/nodes/display/FrontFacingNode.d.ts b/src-testing/src/nodes/display/FrontFacingNode.d.ts new file mode 100644 index 000000000..f550ecacf --- /dev/null +++ b/src-testing/src/nodes/display/FrontFacingNode.d.ts @@ -0,0 +1,12 @@ +import Node from "../core/Node.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +declare class FrontFacingNode extends Node { + isFrontFacingNode: true; + constructor(); +} + +export default FrontFacingNode; + +export const frontFacing: ShaderNodeObject; +export const faceDirection: ShaderNodeObject; diff --git a/src-testing/src/nodes/display/NormalMapNode.d.ts b/src-testing/src/nodes/display/NormalMapNode.d.ts new file mode 100644 index 000000000..d06459502 --- /dev/null +++ b/src-testing/src/nodes/display/NormalMapNode.d.ts @@ -0,0 +1,17 @@ +import { NormalMapTypes } from "../../constants.js"; +import Node from "../core/Node.js"; +import TempNode from "../core/TempNode.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +declare class NormalMapNode extends TempNode { + node: Node; + scaleNode: Node | null; + + normalMapType: NormalMapTypes; + + constructor(node: Node, scaleNode?: Node | null); +} + +export default NormalMapNode; + +export const normalMap: (node: Node, scaleNode?: Node) => ShaderNodeObject; diff --git a/src-testing/src/nodes/display/PassNode.d.ts b/src-testing/src/nodes/display/PassNode.d.ts new file mode 100644 index 000000000..97bad417f --- /dev/null +++ b/src-testing/src/nodes/display/PassNode.d.ts @@ -0,0 +1,71 @@ +import { Camera } from "../../cameras/Camera.js"; +import { RenderTarget, RenderTargetOptions } from "../../core/RenderTarget.js"; +import { Scene } from "../../scenes/Scene.js"; +import { Texture } from "../../textures/Texture.js"; +import TextureNode from "../accessors/TextureNode.js"; +import MRTNode from "../core/MRTNode.js"; +import Node from "../core/Node.js"; +import TempNode from "../core/TempNode.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +declare class PassTextureNode extends TextureNode { + passNode: PassNode; + + constructor(passNode: PassNode, texture: Texture); +} + +declare class PassMultipleTextureNode extends PassTextureNode { + textureName: string; + previousTexture: boolean; + + constructor(passNode: PassNode, textureName: string, previousTexture?: boolean); + + updateTexture(): void; +} + +declare class PassNode extends TempNode { + scope: PassNodeScope; + scene: Scene; + camera: Camera; + + renderTarget: RenderTarget; + + readonly isPassNode: true; + + constructor(scope: PassNodeScope, scene: Scene, camera: Camera, options?: RenderTargetOptions); + + setMRT(mrt: MRTNode | null): this; + + getMRT(): MRTNode | null; + + getTexture(name: string): Texture; + + getPreviousTexture(name: string): Texture; + + toggleTexture(name: string): void; + + getTextureNode(name?: string): ShaderNodeObject; + + getPreviousTextureNode(name?: string): ShaderNodeObject; + + getViewZNode(name?: string): ShaderNodeObject; + + getLinearDepthNode(name?: string): ShaderNodeObject; + + setSize(width: number, height: number): void; + + setPixelRatio(pixelRatio: number): void; + + dispose(): void; + + static COLOR: "color"; + static DEPTH: "depth"; +} + +export type PassNodeScope = typeof PassNode.COLOR | typeof PassNode.DEPTH; + +export default PassNode; + +export const pass: (scene: Scene, camera: Camera, options?: RenderTargetOptions) => ShaderNodeObject; +export const passTexture: (pass: PassNode, texture: Texture) => ShaderNodeObject; +export const depthPass: (scene: Scene, camera: Camera) => ShaderNodeObject; diff --git a/src-testing/src/nodes/display/PosterizeNode.d.ts b/src-testing/src/nodes/display/PosterizeNode.d.ts new file mode 100644 index 000000000..17eb0fe52 --- /dev/null +++ b/src-testing/src/nodes/display/PosterizeNode.d.ts @@ -0,0 +1,14 @@ +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +export default class PosterizeNode extends Node { + sourceNode: Node; + stepsNode: Node; + + constructor(sourceNode: Node, stepsNode: Node); +} + +export const posterize: ( + sourceNode: NodeRepresentation, + stepsNode: NodeRepresentation, +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/display/RenderOutputNode.d.ts b/src-testing/src/nodes/display/RenderOutputNode.d.ts new file mode 100644 index 000000000..b7edad754 --- /dev/null +++ b/src-testing/src/nodes/display/RenderOutputNode.d.ts @@ -0,0 +1,28 @@ +import { ToneMapping } from "../../constants.js"; +import Node from "../core/Node.js"; +import TempNode from "../core/TempNode.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +declare class RenderOutputNode extends TempNode { + colorNode: Node; + toneMapping: ToneMapping | null; + outputColorSpace: string | null; + + readonly isRenderOutput: true; + + constructor(colorNode: Node, toneMapping?: ToneMapping | null, outputColorSpace?: string | null); +} + +export default RenderOutputNode; + +export const renderOutput: ( + color: NodeRepresentation, + toneMapping?: ToneMapping | null, + outputColorSpace?: string | null, +) => ShaderNodeObject; + +declare module "../tsl/TSLCore.js" { + interface NodeElements { + renderOutput: typeof renderOutput; + } +} diff --git a/src-testing/src/nodes/display/ScreenNode.d.ts b/src-testing/src/nodes/display/ScreenNode.d.ts new file mode 100644 index 000000000..f9ed102fc --- /dev/null +++ b/src-testing/src/nodes/display/ScreenNode.d.ts @@ -0,0 +1,48 @@ +import Node from "../core/Node.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +export type ScreenNodeScope = + | typeof ScreenNode.COORDINATE + | typeof ScreenNode.VIEWPORT + | typeof ScreenNode.SIZE + | typeof ScreenNode.UV; + +declare class ScreenNode extends Node { + scope: ScreenNodeScope; + + readonly isViewportNode: true; + + constructor(scope: ScreenNodeScope); + + static COORDINATE: "coordinate"; + static VIEWPORT: "viewport"; + static SIZE: "size"; + static UV: "uv"; +} + +export default ScreenNode; + +// Screen + +export const screenUV: ShaderNodeObject; +export const screenSize: ShaderNodeObject; +export const screenCoordinate: ShaderNodeObject; + +// Viewport + +export const viewport: ShaderNodeObject; +export const viewportSize: ShaderNodeObject; +export const viewportCoordinate: ShaderNodeObject; +export const viewportUV: ShaderNodeObject; + +// Deprecated + +/** + * @deprecated "viewportTopLeft" is deprecated. Use "viewportUV" instead. + */ +export const viewportTopLeft: ShaderNodeObject; + +/** + * @deprecated "viewportBottomLeft" is deprecated. Use "viewportUV.flipY()" instead. + */ +export const viewportBottomLeft: ShaderNodeObject; diff --git a/src-testing/src/nodes/display/ToneMappingFunctions.d.ts b/src-testing/src/nodes/display/ToneMappingFunctions.d.ts new file mode 100644 index 000000000..b972d6b6f --- /dev/null +++ b/src-testing/src/nodes/display/ToneMappingFunctions.d.ts @@ -0,0 +1,14 @@ +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +export const linearToneMapping: (color: NodeRepresentation, exposure: NodeRepresentation) => ShaderNodeObject; + +export const reinhardToneMapping: (color: NodeRepresentation, exposure: NodeRepresentation) => ShaderNodeObject; + +export const cineonToneMapping: (color: NodeRepresentation, exposure: NodeRepresentation) => ShaderNodeObject; + +export const acesFilmicToneMapping: (color: NodeRepresentation, exposure: NodeRepresentation) => ShaderNodeObject; + +export const agxToneMapping: (color: NodeRepresentation, exposure: NodeRepresentation) => ShaderNodeObject; + +export const neutralToneMapping: (color: NodeRepresentation, exposure: NodeRepresentation) => ShaderNodeObject; diff --git a/src-testing/src/nodes/display/ToneMappingNode.d.ts b/src-testing/src/nodes/display/ToneMappingNode.d.ts new file mode 100644 index 000000000..e4fdf9cf6 --- /dev/null +++ b/src-testing/src/nodes/display/ToneMappingNode.d.ts @@ -0,0 +1,32 @@ +import { ToneMapping } from "../../constants.js"; +import RendererReferenceNode from "../accessors/RendererReferenceNode.js"; +import Node from "../core/Node.js"; +import TempNode from "../core/TempNode.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +declare class ToneMappingNode extends TempNode { + toneMapping: ToneMapping; + exposureNode: Node; + colorNode: Node | null; + + constructor(toneMapping: ToneMapping, exposureNode?: Node, colorNode?: Node | null); +} + +export default ToneMappingNode; + +export const toneMapping: ( + mapping: ToneMapping, + exposure: NodeRepresentation, + color?: NodeRepresentation, +) => ShaderNodeObject; +export const toneMappingExposure: ShaderNodeObject; + +declare module "../tsl/TSLCore.js" { + interface NodeElements { + toneMapping: ( + color: NodeRepresentation, + mapping?: NodeRepresentation, + exposure?: NodeRepresentation, + ) => ShaderNodeObject; + } +} diff --git a/src-testing/src/nodes/display/ToonOutlinePassNode.d.ts b/src-testing/src/nodes/display/ToonOutlinePassNode.d.ts new file mode 100644 index 000000000..fe556b505 --- /dev/null +++ b/src-testing/src/nodes/display/ToonOutlinePassNode.d.ts @@ -0,0 +1,24 @@ +import { Camera } from "../../cameras/Camera.js"; +import { Color } from "../../math/Color.js"; +import { Scene } from "../../scenes/Scene.js"; +import Node from "../core/Node.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; +import PassNode from "./PassNode.js"; + +declare class ToonOutlinePassNode extends PassNode { + colorNode: Node; + thicknessNode: Node; + alphaNode: Node; + + constructor(scene: Scene, camera: Camera, colorNode: Node, thicknessNode: Node, alphaNode: Node); +} + +export default ToonOutlinePassNode; + +export const toonOutlinePass: ( + scene: Scene, + camera: Camera, + color?: Color, + thickness?: number, + alpha?: number, +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/display/ViewportDepthNode.d.ts b/src-testing/src/nodes/display/ViewportDepthNode.d.ts new file mode 100644 index 000000000..c741caba9 --- /dev/null +++ b/src-testing/src/nodes/display/ViewportDepthNode.d.ts @@ -0,0 +1,36 @@ +import Node from "../core/Node.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +declare class ViewportDepthNode extends Node { + scope: ViewportDepthNodeScope; + valueNode: Node; + + readonly isViewportDepthNode: true; + + constructor(scope: ViewportDepthNodeScope, valueNode?: Node | null); + + static DEPTH_BASE: "depthBase"; + static DEPTH: "depth"; + static LINEAR_DEPTH: "linearDepth"; +} + +export type ViewportDepthNodeScope = + | typeof ViewportDepthNode.DEPTH_BASE + | typeof ViewportDepthNode.DEPTH + | typeof ViewportDepthNode.LINEAR_DEPTH; + +export default ViewportDepthNode; + +export const viewZToOrthographicDepth: (viewZ: Node, near: Node, far: Node) => Node; + +export const orthographicDepthToViewZ: (depth: Node, near: Node, far: Node) => Node; + +export const viewZToPerspectiveDepth: (viewZ: Node, near: Node, far: Node) => Node; + +export const perspectiveDepthToViewZ: (depth: Node, near: Node, far: Node) => Node; + +export const perspectiveDepthToLogarithmicDepth: (perspectiveW: Node, near: Node, far: Node) => Node; + +export const depth: ShaderNodeObject; +export const linearDepth: (valueNode?: Node | null) => ShaderNodeObject; +export const viewportLinearDepth: ShaderNodeObject; diff --git a/src-testing/src/nodes/display/ViewportDepthTextureNode.d.ts b/src-testing/src/nodes/display/ViewportDepthTextureNode.d.ts new file mode 100644 index 000000000..7c1102e45 --- /dev/null +++ b/src-testing/src/nodes/display/ViewportDepthTextureNode.d.ts @@ -0,0 +1,14 @@ +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; +import ViewportTextureNode from "./ViewportTextureNode.js"; + +declare class ViewportDepthTextureNode extends ViewportTextureNode { + constructor(uvNode?: Node, levelNode?: Node | null); +} + +export default ViewportDepthTextureNode; + +export const viewportDepthTexture: ( + uvNode?: NodeRepresentation, + levelNode?: NodeRepresentation, +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/display/ViewportSharedTextureNode.d.ts b/src-testing/src/nodes/display/ViewportSharedTextureNode.d.ts new file mode 100644 index 000000000..307bfbde5 --- /dev/null +++ b/src-testing/src/nodes/display/ViewportSharedTextureNode.d.ts @@ -0,0 +1,14 @@ +import Node from "../core/Node.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; +import ViewportTextureNode from "./ViewportTextureNode.js"; + +declare class ViewportSharedTextureNode extends ViewportTextureNode { + constructor(uvNode?: Node, levelNode?: Node | null); +} + +export default ViewportSharedTextureNode; + +export const viewportSharedTexture: ( + uvNode?: Node, + levelNode?: Node | null, +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/display/ViewportTextureNode.d.ts b/src-testing/src/nodes/display/ViewportTextureNode.d.ts new file mode 100644 index 000000000..ade4ea51e --- /dev/null +++ b/src-testing/src/nodes/display/ViewportTextureNode.d.ts @@ -0,0 +1,28 @@ +import { FramebufferTexture } from "../../textures/FramebufferTexture.js"; +import TextureNode from "../accessors/TextureNode.js"; +import { NodeUpdateType } from "../core/constants.js"; +import Node from "../core/Node.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +declare class ViewportTextureNode extends TextureNode { + generateMipmaps: boolean; + + readonly isOutputTextureNode: true; + + updateBeforeType: NodeUpdateType; + + constructor(uvNode?: Node, levelNode?: Node | null, framebufferTexture?: FramebufferTexture | null); +} + +export default ViewportTextureNode; + +export const viewportTexture: ( + uvNode?: Node, + levelNode?: Node | null, + framebufferTexture?: FramebufferTexture | null, +) => ShaderNodeObject; +export const viewportMipTexture: ( + uvNode?: Node, + levelNode?: Node | null, + framebufferTexture?: FramebufferTexture | null, +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/fog/FogExp2Node.d.ts b/src-testing/src/nodes/fog/FogExp2Node.d.ts new file mode 100644 index 000000000..d129d2c72 --- /dev/null +++ b/src-testing/src/nodes/fog/FogExp2Node.d.ts @@ -0,0 +1,14 @@ +import Node from "../core/Node.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; +import FogNode from "./FogNode.js"; + +declare class FogExp2Node extends FogNode { + isFogExp2Node: true; + densityNode: Node; + + constructor(colorNode: Node, densityNode: Node); +} + +export default FogExp2Node; + +export const densityFog: (colorNode: Node, densityNode: Node) => ShaderNodeObject; diff --git a/src-testing/src/nodes/fog/FogNode.ts b/src-testing/src/nodes/fog/FogNode.ts new file mode 100644 index 000000000..f08efb700 --- /dev/null +++ b/src-testing/src/nodes/fog/FogNode.ts @@ -0,0 +1,38 @@ +import Node from '../core/Node.js'; +import { positionView } from '../accessors/Position.js'; +import { nodeProxy } from '../tsl/TSLBase.js'; + +class FogNode extends Node { + static get type() { + return 'FogNode'; + } + + constructor(colorNode, factorNode) { + super('float'); + + this.isFogNode = true; + + this.colorNode = colorNode; + this.factorNode = factorNode; + } + + getViewZNode(builder) { + let viewZ; + + const getViewZ = builder.context.getViewZ; + + if (getViewZ !== undefined) { + viewZ = getViewZ(this); + } + + return (viewZ || positionView.z).negate(); + } + + setup() { + return this.factorNode; + } +} + +export default FogNode; + +export const fog = /*@__PURE__*/ nodeProxy(FogNode); diff --git a/src-testing/src/nodes/fog/FogRangeNode.d.ts b/src-testing/src/nodes/fog/FogRangeNode.d.ts new file mode 100644 index 000000000..d0e1c7cf2 --- /dev/null +++ b/src-testing/src/nodes/fog/FogRangeNode.d.ts @@ -0,0 +1,19 @@ +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; +import FogNode from "./FogNode.js"; + +declare class FogRangeNode extends FogNode { + isFogRangeNode: true; + nearNode: Node | null; + farNode: Node | null; + + constructor(colorNode: Node | null, nearNode: Node | null, farNode: Node | null); +} + +export default FogRangeNode; + +export const rangeFog: ( + colorNode: NodeRepresentation | null, + nearNode: NodeRepresentation | null, + farNode: NodeRepresentation | null, +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/functions/BSDF/BRDF_GGX.d.ts b/src-testing/src/nodes/functions/BSDF/BRDF_GGX.d.ts new file mode 100644 index 000000000..a22bb480a --- /dev/null +++ b/src-testing/src/nodes/functions/BSDF/BRDF_GGX.d.ts @@ -0,0 +1,15 @@ +import Node from "../../core/Node.js"; +import OperatorNode from "../../math/OperatorNode.js"; +import { ShaderNodeObject } from "../../tsl/TSLCore.js"; + +declare const BRDF_GGX: (args: { + lightDirection: Node; + f0: Node; + f90: Node; + roughness: Node; + f?: Node; + USE_IRIDESCENCE?: Node; + USE_ANISOTROPY?: Node; +}) => ShaderNodeObject; + +export default BRDF_GGX; diff --git a/src-testing/src/nodes/functions/BSDF/BRDF_Lambert.d.ts b/src-testing/src/nodes/functions/BSDF/BRDF_Lambert.d.ts new file mode 100644 index 000000000..591fc262d --- /dev/null +++ b/src-testing/src/nodes/functions/BSDF/BRDF_Lambert.d.ts @@ -0,0 +1,7 @@ +import Node from "../../core/Node.js"; +import OperatorNode from "../../math/OperatorNode.js"; +import { ShaderNodeObject } from "../../tsl/TSLCore.js"; + +declare const BRDF_Lambert: (args: { diffuseColor: Node }) => ShaderNodeObject; + +export default BRDF_Lambert; diff --git a/src-testing/src/nodes/functions/BSDF/BRDF_Sheen.d.ts b/src-testing/src/nodes/functions/BSDF/BRDF_Sheen.d.ts new file mode 100644 index 000000000..3e5b218e8 --- /dev/null +++ b/src-testing/src/nodes/functions/BSDF/BRDF_Sheen.d.ts @@ -0,0 +1,7 @@ +import Node from "../../core/Node.js"; +import OperatorNode from "../../math/OperatorNode.js"; +import { ShaderNodeObject } from "../../tsl/TSLCore.js"; + +declare const BRDF_Sheen: (args: { lightDirection: Node }) => ShaderNodeObject; + +export default BRDF_Sheen; diff --git a/src-testing/src/nodes/functions/BSDF/DFGApprox.d.ts b/src-testing/src/nodes/functions/BSDF/DFGApprox.d.ts new file mode 100644 index 000000000..010b70ccc --- /dev/null +++ b/src-testing/src/nodes/functions/BSDF/DFGApprox.d.ts @@ -0,0 +1,11 @@ +import Node from "../../core/Node.js"; +import OperatorNode from "../../math/OperatorNode.js"; +import { ShaderNodeObject } from "../../tsl/TSLCore.js"; + +// Analytical approximation of the DFG LUT, one half of the +// split-sum approximation used in indirect specular lighting. +// via 'environmentBRDF' from "Physically Based Shading on Mobile" +// https://www.unrealengine.com/blog/physically-based-shading-on-mobile +declare const DFGApprox: (args: { roughness: Node; dotNV: Node }) => ShaderNodeObject; + +export default DFGApprox; diff --git a/src-testing/src/nodes/functions/BSDF/D_GGX.d.ts b/src-testing/src/nodes/functions/BSDF/D_GGX.d.ts new file mode 100644 index 000000000..71b673c6c --- /dev/null +++ b/src-testing/src/nodes/functions/BSDF/D_GGX.d.ts @@ -0,0 +1,10 @@ +import Node from "../../core/Node.js"; +import OperatorNode from "../../math/OperatorNode.js"; +import { ShaderNodeObject } from "../../tsl/TSLCore.js"; + +// Microfacet Models for Refraction through Rough Surfaces - equation (33) +// http://graphicrants.blogspot.com/2013/08/specular-brdf-reference.html +// alpha is "roughness squared" in Disney’s reparameterization +declare const D_GGX: (args: { alpha: Node; dotNH: Node }) => ShaderNodeObject; + +export default D_GGX; diff --git a/src-testing/src/nodes/functions/BSDF/D_GGX_Anisotropic.d.ts b/src-testing/src/nodes/functions/BSDF/D_GGX_Anisotropic.d.ts new file mode 100644 index 000000000..e296ea11d --- /dev/null +++ b/src-testing/src/nodes/functions/BSDF/D_GGX_Anisotropic.d.ts @@ -0,0 +1,10 @@ +import Node from "../../core/Node.js"; +import OperatorNode from "../../math/OperatorNode.js"; +import { ShaderNodeObject } from "../../tsl/TSLCore.js"; + +// https://google.github.io/filament/Filament.md.html#materialsystem/anisotropicmodel/anisotropicspecularbrdf +declare const D_GGX_Anisotropic: ( + args: { alphaT: Node; alphaB: Node; dotNH: Node; dotTH: Node; dotBH: Node }, +) => ShaderNodeObject; + +export default D_GGX_Anisotropic; diff --git a/src-testing/src/nodes/functions/BSDF/F_Schlick.d.ts b/src-testing/src/nodes/functions/BSDF/F_Schlick.d.ts new file mode 100644 index 000000000..46940e6a3 --- /dev/null +++ b/src-testing/src/nodes/functions/BSDF/F_Schlick.d.ts @@ -0,0 +1,7 @@ +import Node from "../../core/Node.js"; +import OperatorNode from "../../math/OperatorNode.js"; +import { ShaderNodeObject } from "../../tsl/TSLCore.js"; + +declare const F_Schlick: (args: { f0: Node; f90: Node; dotVH: Node }) => ShaderNodeObject; + +export default F_Schlick; diff --git a/src-testing/src/nodes/functions/BSDF/LTC.d.ts b/src-testing/src/nodes/functions/BSDF/LTC.d.ts new file mode 100644 index 000000000..4bd6d7f76 --- /dev/null +++ b/src-testing/src/nodes/functions/BSDF/LTC.d.ts @@ -0,0 +1,9 @@ +import Node from "../../core/Node.js"; + +declare const LTC_Uv: (args: { N: Node; V: Node; roughness: Node }) => Node; + +declare const LTC_Evaluate: ( + args: { N: Node; V: Node; P: Node; mInv: Node; p0: Node; p1: Node; p2: Node; p3: Node }, +) => Node; + +export { LTC_Evaluate, LTC_Uv }; diff --git a/src-testing/src/nodes/functions/BSDF/Schlick_to_F0.d.ts b/src-testing/src/nodes/functions/BSDF/Schlick_to_F0.d.ts new file mode 100644 index 000000000..d0554ba2c --- /dev/null +++ b/src-testing/src/nodes/functions/BSDF/Schlick_to_F0.d.ts @@ -0,0 +1,10 @@ +import Node from "../../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../../tsl/TSLCore.js"; + +declare const Schlick_to_F0: ( + f: NodeRepresentation, + f90: NodeRepresentation, + dotVH: NodeRepresentation, +) => ShaderNodeObject; + +export default Schlick_to_F0; diff --git a/src-testing/src/nodes/functions/BSDF/V_GGX_SmithCorrelated.d.ts b/src-testing/src/nodes/functions/BSDF/V_GGX_SmithCorrelated.d.ts new file mode 100644 index 000000000..b6c1ca80c --- /dev/null +++ b/src-testing/src/nodes/functions/BSDF/V_GGX_SmithCorrelated.d.ts @@ -0,0 +1,11 @@ +import Node from "../../core/Node.js"; +import OperatorNode from "../../math/OperatorNode.js"; +import { ShaderNodeObject } from "../../tsl/TSLCore.js"; + +declare const V_GGX_SmithCorrelated: (inputs: { + alpha: Node; + dotNL: Node; + dotNV: Node; +}) => ShaderNodeObject; + +export default V_GGX_SmithCorrelated; diff --git a/src-testing/src/nodes/functions/BSDF/V_GGX_SmithCorrelated_Anisotropic.d.ts b/src-testing/src/nodes/functions/BSDF/V_GGX_SmithCorrelated_Anisotropic.d.ts new file mode 100644 index 000000000..5150bf6b1 --- /dev/null +++ b/src-testing/src/nodes/functions/BSDF/V_GGX_SmithCorrelated_Anisotropic.d.ts @@ -0,0 +1,16 @@ +import Node from "../../core/Node.js"; +import MathNode from "../../math/MathNode.js"; +import { ShaderNodeObject } from "../../tsl/TSLCore.js"; + +declare const V_GGX_SmithCorrelated: (inputs: { + alphaT: Node; + alphaB: Node; + dotTV: Node; + dotBV: Node; + dotTL: Node; + dotBL: Node; + dotNV: Node; + dotNL: Node; +}) => ShaderNodeObject; + +export default V_GGX_SmithCorrelated; diff --git a/src-testing/src/nodes/functions/BasicLightingModel.d.ts b/src-testing/src/nodes/functions/BasicLightingModel.d.ts new file mode 100644 index 000000000..a64fafd44 --- /dev/null +++ b/src-testing/src/nodes/functions/BasicLightingModel.d.ts @@ -0,0 +1,7 @@ +import LightingModel from "../core/LightingModel.js"; + +declare class BasicLightingModel extends LightingModel { + constructor(); +} + +export default BasicLightingModel; diff --git a/src-testing/src/nodes/functions/PhongLightingModel.d.ts b/src-testing/src/nodes/functions/PhongLightingModel.d.ts new file mode 100644 index 000000000..5df595269 --- /dev/null +++ b/src-testing/src/nodes/functions/PhongLightingModel.d.ts @@ -0,0 +1,7 @@ +import BasicLightingModel from "./BasicLightingModel.js"; + +export default class PhongLightingModel extends BasicLightingModel { + specular: boolean; + + constructor(specular?: boolean); +} diff --git a/src-testing/src/nodes/functions/PhysicalLightingModel.d.ts b/src-testing/src/nodes/functions/PhysicalLightingModel.d.ts new file mode 100644 index 000000000..bec381051 --- /dev/null +++ b/src-testing/src/nodes/functions/PhysicalLightingModel.d.ts @@ -0,0 +1,30 @@ +import LightingModel from "../core/LightingModel.js"; +import Node from "../core/Node.js"; + +export default class PhysicalLightingModel extends LightingModel { + clearcoat: boolean; + sheen: boolean; + iridescence: boolean; + anisotropy: boolean; + transmission: boolean; + dispersion: boolean; + + clearcoatRadiance: Node | null; + clearcoatSpecularDirect: Node | null; + clearcoatSpecularIndirect: Node | null; + sheenSpecularDirect: Node | null; + sheenSpecularIndirect: Node | null; + iridescenceFresnel: Node | null; + iridescenceF0: Node | null; + + constructor( + clearcoat?: boolean, + sheen?: boolean, + iridescence?: boolean, + anisotropy?: boolean, + transmission?: boolean, + dispersion?: boolean, + ); + + computeMultiscattering(singleScatter: Node, multiScatter: Node, specularF90: Node): void; +} diff --git a/src-testing/src/nodes/functions/ShadowMaskModel.d.ts b/src-testing/src/nodes/functions/ShadowMaskModel.d.ts new file mode 100644 index 000000000..bcdee8b5c --- /dev/null +++ b/src-testing/src/nodes/functions/ShadowMaskModel.d.ts @@ -0,0 +1,9 @@ +import LightingModel from "../core/LightingModel.js"; +import VarNode from "../core/VarNode.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +export default class ShadowMaskModel extends LightingModel { + shadowNode: ShaderNodeObject; + + constructor(); +} diff --git a/src-testing/src/nodes/functions/ToonLightingModel.d.ts b/src-testing/src/nodes/functions/ToonLightingModel.d.ts new file mode 100644 index 000000000..d26db3457 --- /dev/null +++ b/src-testing/src/nodes/functions/ToonLightingModel.d.ts @@ -0,0 +1,4 @@ +import LightingModel from "../core/LightingModel.js"; + +export default class ToonLightingModel extends LightingModel { +} diff --git a/src-testing/src/nodes/functions/material/getGeometryRoughness.d.ts b/src-testing/src/nodes/functions/material/getGeometryRoughness.d.ts new file mode 100644 index 000000000..dd629cee0 --- /dev/null +++ b/src-testing/src/nodes/functions/material/getGeometryRoughness.d.ts @@ -0,0 +1,6 @@ +import MathNode from "../../math/MathNode.js"; +import { ShaderNodeObject } from "../../tsl/TSLCore.js"; + +declare const getGeometryRoughness: () => ShaderNodeObject; + +export default getGeometryRoughness; diff --git a/src-testing/src/nodes/functions/material/getRoughness.d.ts b/src-testing/src/nodes/functions/material/getRoughness.d.ts new file mode 100644 index 000000000..7022672b0 --- /dev/null +++ b/src-testing/src/nodes/functions/material/getRoughness.d.ts @@ -0,0 +1,7 @@ +import Node from "../../core/Node.js"; +import MathNode from "../../math/MathNode.js"; +import { ShaderNodeObject } from "../../tsl/TSLCore.js"; + +declare const getRoughness: (args: { roughness: Node }) => ShaderNodeObject; + +export default getRoughness; diff --git a/src-testing/src/nodes/functions/material/getShIrradianceAt.d.ts b/src-testing/src/nodes/functions/material/getShIrradianceAt.d.ts new file mode 100644 index 000000000..95c8d03c5 --- /dev/null +++ b/src-testing/src/nodes/functions/material/getShIrradianceAt.d.ts @@ -0,0 +1,6 @@ +import Node from "../../core/Node.js"; +import { ShaderNodeObject } from "../../tsl/TSLCore.js"; + +declare const getShIrradianceAt: (normal: Node, shCoefficients: Node) => ShaderNodeObject; + +export default getShIrradianceAt; diff --git a/src-testing/src/nodes/geometry/RangeNode.d.ts b/src-testing/src/nodes/geometry/RangeNode.d.ts new file mode 100644 index 000000000..c4c932486 --- /dev/null +++ b/src-testing/src/nodes/geometry/RangeNode.d.ts @@ -0,0 +1,19 @@ +import { Color } from "../../math/Color.js"; +import { Vector2 } from "../../math/Vector2.js"; +import { Vector3 } from "../../math/Vector3.js"; +import { Vector4 } from "../../math/Vector4.js"; +import Node from "../core/Node.js"; +import NodeBuilder from "../core/NodeBuilder.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +export type RangeModeBound = number | Color | Vector2 | Vector3 | Vector4; + +export default class RangeNode extends Node { + min: RangeModeBound; + max: RangeModeBound; + + constructor(min: RangeModeBound, max: RangeModeBound); + getVectorLength(builder: NodeBuilder): number; +} + +export const range: (min: RangeModeBound, max: RangeModeBound) => ShaderNodeObject; diff --git a/src-testing/src/nodes/gpgpu/ComputeNode.ts b/src-testing/src/nodes/gpgpu/ComputeNode.ts new file mode 100644 index 000000000..30d5be0b3 --- /dev/null +++ b/src-testing/src/nodes/gpgpu/ComputeNode.ts @@ -0,0 +1,75 @@ +import Node from '../core/Node.js'; +import { NodeUpdateType } from '../core/constants.js'; +import { addMethodChaining, nodeObject } from '../tsl/TSLCore.js'; + +class ComputeNode extends Node { + static get type() { + return 'ComputeNode'; + } + + constructor(computeNode, count, workgroupSize = [64]) { + super('void'); + + this.isComputeNode = true; + + this.computeNode = computeNode; + + this.count = count; + this.workgroupSize = workgroupSize; + this.dispatchCount = 0; + + this.version = 1; + this.updateBeforeType = NodeUpdateType.OBJECT; + + this.onInitFunction = null; + + this.updateDispatchCount(); + } + + dispose() { + this.dispatchEvent({ type: 'dispose' }); + } + + set needsUpdate(value) { + if (value === true) this.version++; + } + + updateDispatchCount() { + const { count, workgroupSize } = this; + + let size = workgroupSize[0]; + + for (let i = 1; i < workgroupSize.length; i++) size *= workgroupSize[i]; + + this.dispatchCount = Math.ceil(count / size); + } + + onInit(callback) { + this.onInitFunction = callback; + + return this; + } + + updateBefore({ renderer }) { + renderer.compute(this); + } + + generate(builder) { + const { shaderStage } = builder; + + if (shaderStage === 'compute') { + const snippet = this.computeNode.build(builder, 'void'); + + if (snippet !== '') { + builder.addLineFlowCode(snippet, this); + } + } + } +} + +export default ComputeNode; + +export const compute = (node, count, workgroupSize) => + nodeObject(new ComputeNode(nodeObject(node), count, workgroupSize)); + +addMethodChaining('compute', compute); diff --git a/src-testing/src/nodes/lighting/AONode.d.ts b/src-testing/src/nodes/lighting/AONode.d.ts new file mode 100644 index 000000000..998ec5236 --- /dev/null +++ b/src-testing/src/nodes/lighting/AONode.d.ts @@ -0,0 +1,8 @@ +import Node from "../core/Node.js"; +import LightingNode from "./LightingNode.js"; + +export default class AONode extends LightingNode { + aoNode: Node | null; + + constructor(aoNode?: Node | null); +} diff --git a/src-testing/src/nodes/lighting/AmbientLightNode.d.ts b/src-testing/src/nodes/lighting/AmbientLightNode.d.ts new file mode 100644 index 000000000..3b7cc6fb6 --- /dev/null +++ b/src-testing/src/nodes/lighting/AmbientLightNode.d.ts @@ -0,0 +1,8 @@ +import { AmbientLight } from "../../lights/AmbientLight.js"; +import AnalyticLightNode from "./AnalyticLightNode.js"; + +declare class AmbientLightNode extends AnalyticLightNode { + constructor(light?: AmbientLight | null); +} + +export default AmbientLightNode; diff --git a/src-testing/src/nodes/lighting/AnalyticLightNode.d.ts b/src-testing/src/nodes/lighting/AnalyticLightNode.d.ts new file mode 100644 index 000000000..d8cea32ef --- /dev/null +++ b/src-testing/src/nodes/lighting/AnalyticLightNode.d.ts @@ -0,0 +1,8 @@ +import { Light } from "../../lights/Light.js"; +import LightingNode from "./LightingNode.js"; + +export default class AnalyticLightNode extends LightingNode { + light: T | null; + + constructor(light?: T | null); +} diff --git a/src-testing/src/nodes/lighting/BasicEnvironmentNode.d.ts b/src-testing/src/nodes/lighting/BasicEnvironmentNode.d.ts new file mode 100644 index 000000000..de244562f --- /dev/null +++ b/src-testing/src/nodes/lighting/BasicEnvironmentNode.d.ts @@ -0,0 +1,10 @@ +import Node from "../core/Node.js"; +import LightingNode from "./LightingNode.js"; + +declare class BasicEnvironmentNode extends LightingNode { + envNode: Node | null; + + constructor(envNode?: Node | null); +} + +export default BasicEnvironmentNode; diff --git a/src-testing/src/nodes/lighting/BasicLightMapNode.d.ts b/src-testing/src/nodes/lighting/BasicLightMapNode.d.ts new file mode 100644 index 000000000..c759e8857 --- /dev/null +++ b/src-testing/src/nodes/lighting/BasicLightMapNode.d.ts @@ -0,0 +1,8 @@ +import Node from "../core/Node.js"; +import LightingNode from "./LightingNode.js"; + +declare class BasicLightMapNode extends LightingNode { + constructor(lightMapNode?: Node | null); +} + +export default BasicLightMapNode; diff --git a/src-testing/src/nodes/lighting/DirectionalLightNode.d.ts b/src-testing/src/nodes/lighting/DirectionalLightNode.d.ts new file mode 100644 index 000000000..41908abaf --- /dev/null +++ b/src-testing/src/nodes/lighting/DirectionalLightNode.d.ts @@ -0,0 +1,8 @@ +import { DirectionalLight } from "../../lights/DirectionalLight.js"; +import AnalyticLightNode from "./AnalyticLightNode.js"; + +declare class DirectionalLightNode extends AnalyticLightNode { + constructor(light?: DirectionalLight | null); +} + +export default DirectionalLightNode; diff --git a/src-testing/src/nodes/lighting/EnvironmentNode.ts b/src-testing/src/nodes/lighting/EnvironmentNode.ts new file mode 100644 index 000000000..eab24fba0 --- /dev/null +++ b/src-testing/src/nodes/lighting/EnvironmentNode.ts @@ -0,0 +1,114 @@ +import LightingNode from './LightingNode.js'; +import { cache } from '../core/CacheNode.js'; +import { roughness, clearcoatRoughness } from '../core/PropertyNode.js'; +import { cameraViewMatrix } from '../accessors/Camera.js'; +import { transformedClearcoatNormalView, transformedNormalView, transformedNormalWorld } from '../accessors/Normal.js'; +import { positionViewDirection } from '../accessors/Position.js'; +import { float } from '../tsl/TSLBase.js'; +import { reference } from '../accessors/ReferenceNode.js'; +import { transformedBentNormalView } from '../accessors/AccessorsUtils.js'; +import { pmremTexture } from '../pmrem/PMREMNode.js'; + +const _envNodeCache = new WeakMap(); + +class EnvironmentNode extends LightingNode { + static get type() { + return 'EnvironmentNode'; + } + + constructor(envNode = null) { + super(); + + this.envNode = envNode; + } + + setup(builder) { + const { material } = builder; + + let envNode = this.envNode; + + if (envNode.isTextureNode || envNode.isMaterialReferenceNode) { + const value = envNode.isTextureNode ? envNode.value : material[envNode.property]; + + let cacheEnvNode = _envNodeCache.get(value); + + if (cacheEnvNode === undefined) { + cacheEnvNode = pmremTexture(value); + + _envNodeCache.set(value, cacheEnvNode); + } + + envNode = cacheEnvNode; + } + + // + + const envMap = material.envMap; + const intensity = envMap + ? reference('envMapIntensity', 'float', builder.material) + : reference('environmentIntensity', 'float', builder.scene); // @TODO: Add materialEnvIntensity in MaterialNode + + const useAnisotropy = material.useAnisotropy === true || material.anisotropy > 0; + const radianceNormalView = useAnisotropy ? transformedBentNormalView : transformedNormalView; + + const radiance = envNode.context(createRadianceContext(roughness, radianceNormalView)).mul(intensity); + const irradiance = envNode.context(createIrradianceContext(transformedNormalWorld)).mul(Math.PI).mul(intensity); + + const isolateRadiance = cache(radiance); + const isolateIrradiance = cache(irradiance); + + // + + builder.context.radiance.addAssign(isolateRadiance); + + builder.context.iblIrradiance.addAssign(isolateIrradiance); + + // + + const clearcoatRadiance = builder.context.lightingModel.clearcoatRadiance; + + if (clearcoatRadiance) { + const clearcoatRadianceContext = envNode + .context(createRadianceContext(clearcoatRoughness, transformedClearcoatNormalView)) + .mul(intensity); + const isolateClearcoatRadiance = cache(clearcoatRadianceContext); + + clearcoatRadiance.addAssign(isolateClearcoatRadiance); + } + } +} + +export default EnvironmentNode; + +const createRadianceContext = (roughnessNode, normalViewNode) => { + let reflectVec = null; + + return { + getUV: () => { + if (reflectVec === null) { + reflectVec = positionViewDirection.negate().reflect(normalViewNode); + + // Mixing the reflection with the normal is more accurate and keeps rough objects from gathering light from behind their tangent plane. + reflectVec = roughnessNode.mul(roughnessNode).mix(reflectVec, normalViewNode).normalize(); + + reflectVec = reflectVec.transformDirection(cameraViewMatrix); + } + + return reflectVec; + }, + getTextureLevel: () => { + return roughnessNode; + }, + }; +}; + +const createIrradianceContext = normalWorldNode => { + return { + getUV: () => { + return normalWorldNode; + }, + getTextureLevel: () => { + return float(1.0); + }, + }; +}; diff --git a/src-testing/src/nodes/lighting/HemisphereLightNode.d.ts b/src-testing/src/nodes/lighting/HemisphereLightNode.d.ts new file mode 100644 index 000000000..7cf38dd79 --- /dev/null +++ b/src-testing/src/nodes/lighting/HemisphereLightNode.d.ts @@ -0,0 +1,13 @@ +import { HemisphereLight } from "../../lights/HemisphereLight.js"; +import Object3DNode from "../accessors/Object3DNode.js"; +import Node from "../core/Node.js"; +import AnalyticLightNode from "./AnalyticLightNode.js"; + +export default class HemisphereLightNode extends AnalyticLightNode { + lightPositionNode: Object3DNode; + lightDirectionNode: Node; + + groundColorNode: Node; + + constructor(light?: HemisphereLight | null); +} diff --git a/src-testing/src/nodes/lighting/IESSpotLightNode.d.ts b/src-testing/src/nodes/lighting/IESSpotLightNode.d.ts new file mode 100644 index 000000000..5906fe96d --- /dev/null +++ b/src-testing/src/nodes/lighting/IESSpotLightNode.d.ts @@ -0,0 +1,5 @@ +import SpotLightNode from "./SpotLightNode.js"; + +declare class IESSpotLightNode extends SpotLightNode {} + +export default IESSpotLightNode; diff --git a/src-testing/src/nodes/lighting/IrradianceNode.d.ts b/src-testing/src/nodes/lighting/IrradianceNode.d.ts new file mode 100644 index 000000000..a59838044 --- /dev/null +++ b/src-testing/src/nodes/lighting/IrradianceNode.d.ts @@ -0,0 +1,8 @@ +import Node from "../core/Node.js"; +import LightingNode from "./LightingNode.js"; + +export default class IrradianceNode extends LightingNode { + node: Node | null; + + constructor(node?: Node | null); +} diff --git a/src-testing/src/nodes/lighting/LightNode.d.ts b/src-testing/src/nodes/lighting/LightNode.d.ts new file mode 100644 index 000000000..de64bdb60 --- /dev/null +++ b/src-testing/src/nodes/lighting/LightNode.d.ts @@ -0,0 +1,18 @@ +import { Light } from "../../lights/Light.js"; +import Node from "../core/Node.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +export type LightNodeScope = typeof LightNode.TARGET_DIRECTION; + +declare class LightNode extends Node { + scope: LightNodeScope; + light: Light; + + constructor(scope?: LightNodeScope, light?: Light | null); + + static TARGET_DIRECTION: "targetDirection"; +} + +export default LightNode; + +export const lightTargetDirection: (light?: Light | null) => ShaderNodeObject; diff --git a/src-testing/src/nodes/lighting/LightProbeNode.d.ts b/src-testing/src/nodes/lighting/LightProbeNode.d.ts new file mode 100644 index 000000000..3a5b12963 --- /dev/null +++ b/src-testing/src/nodes/lighting/LightProbeNode.d.ts @@ -0,0 +1,11 @@ +import { LightProbe } from "../../lights/LightProbe.js"; +import UniformArrayNode from "../accessors/UniformArrayNode.js"; +import AnalyticLightNode from "./AnalyticLightNode.js"; + +declare class LightProbeNode extends AnalyticLightNode { + lightProbe: UniformArrayNode; + + constructor(light?: LightProbe | null); +} + +export default LightProbeNode; diff --git a/src-testing/src/nodes/lighting/LightUtils.d.ts b/src-testing/src/nodes/lighting/LightUtils.d.ts new file mode 100644 index 000000000..4fd41ea55 --- /dev/null +++ b/src-testing/src/nodes/lighting/LightUtils.d.ts @@ -0,0 +1,9 @@ +import Node from "../core/Node.js"; +import ConditionalNode from "../math/ConditionalNode.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +export const getDistanceAttenuation: (args: { + lightDistance: Node; + cutoffDistance: Node; + decayExponent: Node; +}) => ShaderNodeObject; diff --git a/src-testing/src/nodes/lighting/LightingContextNode.ts b/src-testing/src/nodes/lighting/LightingContextNode.ts new file mode 100644 index 000000000..f9dbf1a82 --- /dev/null +++ b/src-testing/src/nodes/lighting/LightingContextNode.ts @@ -0,0 +1,57 @@ +import ContextNode from '../core/ContextNode.js'; +import { nodeProxy, float, vec3 } from '../tsl/TSLBase.js'; + +class LightingContextNode extends ContextNode { + static get type() { + return 'LightingContextNode'; + } + + constructor(node, lightingModel = null, backdropNode = null, backdropAlphaNode = null) { + super(node); + + this.lightingModel = lightingModel; + this.backdropNode = backdropNode; + this.backdropAlphaNode = backdropAlphaNode; + + this._value = null; + } + + getContext() { + const { backdropNode, backdropAlphaNode } = this; + + const directDiffuse = vec3().toVar('directDiffuse'), + directSpecular = vec3().toVar('directSpecular'), + indirectDiffuse = vec3().toVar('indirectDiffuse'), + indirectSpecular = vec3().toVar('indirectSpecular'); + + const reflectedLight = { + directDiffuse, + directSpecular, + indirectDiffuse, + indirectSpecular, + }; + + const context = { + radiance: vec3().toVar('radiance'), + irradiance: vec3().toVar('irradiance'), + iblIrradiance: vec3().toVar('iblIrradiance'), + ambientOcclusion: float(1).toVar('ambientOcclusion'), + reflectedLight, + backdrop: backdropNode, + backdropAlpha: backdropAlphaNode, + }; + + return context; + } + + setup(builder) { + this.value = this._value || (this._value = this.getContext()); + this.value.lightingModel = this.lightingModel || builder.context.lightingModel; + + return super.setup(builder); + } +} + +export default LightingContextNode; + +export const lightingContext = /*@__PURE__*/ nodeProxy(LightingContextNode); diff --git a/src-testing/src/nodes/lighting/LightingNode.d.ts b/src-testing/src/nodes/lighting/LightingNode.d.ts new file mode 100644 index 000000000..3e8dd5424 --- /dev/null +++ b/src-testing/src/nodes/lighting/LightingNode.d.ts @@ -0,0 +1,7 @@ +import Node from "../core/Node.js"; + +export default abstract class LightingNode extends Node { + readonly isLightingNode: true; + + constructor(); +} diff --git a/src-testing/src/nodes/lighting/LightsNode.ts b/src-testing/src/nodes/lighting/LightsNode.ts new file mode 100644 index 000000000..1cf0b19ac --- /dev/null +++ b/src-testing/src/nodes/lighting/LightsNode.ts @@ -0,0 +1,200 @@ +import Node from '../core/Node.js'; +import { nodeObject, vec3 } from '../tsl/TSLBase.js'; + +const sortLights = lights => { + return lights.sort((a, b) => a.id - b.id); +}; + +const getLightNodeById = (id, lightNodes) => { + for (const lightNode of lightNodes) { + if (lightNode.isAnalyticLightNode && lightNode.light.id === id) { + return lightNode; + } + } + + return null; +}; + +const _lightsNodeRef = /*@__PURE__*/ new WeakMap(); + +class LightsNode extends Node { + static get type() { + return 'LightsNode'; + } + + constructor() { + super('vec3'); + + this.totalDiffuseNode = vec3().toVar('totalDiffuse'); + this.totalSpecularNode = vec3().toVar('totalSpecular'); + + this.outgoingLightNode = vec3().toVar('outgoingLight'); + + this._lights = []; + + this._lightNodes = null; + this._lightNodesHash = null; + + this.global = true; + } + + getHash(builder) { + if (this._lightNodesHash === null) { + if (this._lightNodes === null) this.setupLightsNode(builder); + + const hash = []; + + for (const lightNode of this._lightNodes) { + hash.push(lightNode.getSelf().getHash()); + } + + this._lightNodesHash = 'lights-' + hash.join(','); + } + + return this._lightNodesHash; + } + + analyze(builder) { + const properties = builder.getDataFromNode(this); + + for (const node of properties.nodes) { + node.build(builder); + } + } + + setupLightsNode(builder) { + const lightNodes = []; + + const previousLightNodes = this._lightNodes; + + const lights = sortLights(this._lights); + const nodeLibrary = builder.renderer.library; + + for (const light of lights) { + if (light.isNode) { + lightNodes.push(nodeObject(light)); + } else { + let lightNode = null; + + if (previousLightNodes !== null) { + lightNode = getLightNodeById(light.id, previousLightNodes); // resuse existing light node + } + + if (lightNode === null) { + const lightNodeClass = nodeLibrary.getLightNodeClass(light.constructor); + + if (lightNodeClass === null) { + console.warn(`LightsNode.setupNodeLights: Light node not found for ${light.constructor.name}`); + continue; + } + + let lightNode = null; + + if (!_lightsNodeRef.has(light)) { + lightNode = nodeObject(new lightNodeClass(light)); + _lightsNodeRef.set(light, lightNode); + } else { + lightNode = _lightsNodeRef.get(light); + } + + lightNodes.push(lightNode); + } + } + } + + this._lightNodes = lightNodes; + } + + setupLights(builder, lightNodes) { + for (const lightNode of lightNodes) { + lightNode.build(builder); + } + } + + setup(builder) { + if (this._lightNodes === null) this.setupLightsNode(builder); + + const context = builder.context; + const lightingModel = context.lightingModel; + + let outgoingLightNode = this.outgoingLightNode; + + if (lightingModel) { + const { _lightNodes, totalDiffuseNode, totalSpecularNode } = this; + + context.outgoingLight = outgoingLightNode; + + const stack = builder.addStack(); + + // + + const properties = builder.getDataFromNode(this); + properties.nodes = stack.nodes; + + // + + lightingModel.start(context, stack, builder); + + // lights + + this.setupLights(builder, _lightNodes); + + // + + lightingModel.indirect(context, stack, builder); + + // + + const { backdrop, backdropAlpha } = context; + const { directDiffuse, directSpecular, indirectDiffuse, indirectSpecular } = context.reflectedLight; + + let totalDiffuse = directDiffuse.add(indirectDiffuse); + + if (backdrop !== null) { + if (backdropAlpha !== null) { + totalDiffuse = vec3(backdropAlpha.mix(totalDiffuse, backdrop)); + } else { + totalDiffuse = vec3(backdrop); + } + + context.material.transparent = true; + } + + totalDiffuseNode.assign(totalDiffuse); + totalSpecularNode.assign(directSpecular.add(indirectSpecular)); + + outgoingLightNode.assign(totalDiffuseNode.add(totalSpecularNode)); + + // + + lightingModel.finish(context, stack, builder); + + // + + outgoingLightNode = outgoingLightNode.bypass(builder.removeStack()); + } + + return outgoingLightNode; + } + + setLights(lights) { + this._lights = lights; + + this._lightNodes = null; + this._lightNodesHash = null; + + return this; + } + + getLights() { + return this._lights; + } + + get hasLights() { + return this._lights.length > 0; + } +} + +export default LightsNode; + +export const lights = (lights = []) => nodeObject(new LightsNode()).setLights(lights); diff --git a/src-testing/src/nodes/lighting/PointLightNode.d.ts b/src-testing/src/nodes/lighting/PointLightNode.d.ts new file mode 100644 index 000000000..6ae10bc08 --- /dev/null +++ b/src-testing/src/nodes/lighting/PointLightNode.d.ts @@ -0,0 +1,20 @@ +import { PointLight } from "../../lights/PointLight.js"; +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; +import AnalyticLightNode from "./AnalyticLightNode.js"; + +export const directPointLight: ( + color: NodeRepresentation, + lightViewPosition: NodeRepresentation, + cutoffDistance: NodeRepresentation, + decayExponent: NodeRepresentation, +) => ShaderNodeObject; + +declare class PointLightNode extends AnalyticLightNode { + cutoffDistanceNode: Node; + decayExponentNode: Node; + + constructor(light?: PointLight | null); +} + +export default PointLightNode; diff --git a/src-testing/src/nodes/lighting/RectAreaLightNode.d.ts b/src-testing/src/nodes/lighting/RectAreaLightNode.d.ts new file mode 100644 index 000000000..db4d18b82 --- /dev/null +++ b/src-testing/src/nodes/lighting/RectAreaLightNode.d.ts @@ -0,0 +1,21 @@ +import { RectAreaLight } from "../../lights/RectAreaLight.js"; +import { DataTexture } from "../../textures/DataTexture.js"; +import Node from "../core/Node.js"; +import AnalyticLightNode from "./AnalyticLightNode.js"; + +export interface RectAreaLightTexturesLib { + LTC_HALF_1: DataTexture; + LTC_HALF_2: DataTexture; + + LTC_FLOAT_1: DataTexture; + LTC_FLOAT_2: DataTexture; +} + +export default class RectAreaLightNode extends AnalyticLightNode { + halfHeight: Node; + halfWidth: Node; + + constructor(light?: RectAreaLight | null); + + static setLTC(ltc: RectAreaLightTexturesLib): void; +} diff --git a/src-testing/src/nodes/lighting/ShadowNode.d.ts b/src-testing/src/nodes/lighting/ShadowNode.d.ts new file mode 100644 index 000000000..1b8d4fa9f --- /dev/null +++ b/src-testing/src/nodes/lighting/ShadowNode.d.ts @@ -0,0 +1,12 @@ +import { Light } from "../../lights/Light.js"; +import { LightShadow } from "../../lights/LightShadow.js"; +import Node from "../core/Node.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +declare class ShadowNode extends Node { + constructor(light: Light, shadow: LightShadow); +} + +export default ShadowNode; + +export const shadow: (light: Light, shadow: LightShadow) => ShaderNodeObject; diff --git a/src-testing/src/nodes/lighting/SpotLightNode.d.ts b/src-testing/src/nodes/lighting/SpotLightNode.d.ts new file mode 100644 index 000000000..0b1ae4b13 --- /dev/null +++ b/src-testing/src/nodes/lighting/SpotLightNode.d.ts @@ -0,0 +1,15 @@ +import { SpotLight } from "../../lights/SpotLight.js"; +import Node from "../core/Node.js"; +import AnalyticLightNode from "./AnalyticLightNode.js"; + +export default class PointLightNode extends AnalyticLightNode { + directionNode: Node; + + coneCosNode: Node; + penumbraCosNode: Node; + + cutoffDistanceNode: Node; + decayExponentNode: Node; + + constructor(light?: SpotLight | null); +} diff --git a/src-testing/src/nodes/materialx/MaterialXNodes.d.ts b/src-testing/src/nodes/materialx/MaterialXNodes.d.ts new file mode 100644 index 000000000..8007125a7 --- /dev/null +++ b/src-testing/src/nodes/materialx/MaterialXNodes.d.ts @@ -0,0 +1,107 @@ +import Node from "../core/Node.js"; +import MathNode from "../math/MathNode.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; +import { mx_hsvtorgb, mx_rgbtohsv } from "./lib/mx_hsv.js"; +import { mx_srgb_texture_to_lin_rec709 } from "./lib/mx_transform_color.js"; + +export function mx_aastep(threshold: NodeRepresentation, value: NodeRepresentation): ShaderNodeObject; + +export function mx_ramplr( + valuel: NodeRepresentation, + valuer: NodeRepresentation, + texcoord?: NodeRepresentation, +): ShaderNodeObject; +export function mx_ramptb( + valuet: NodeRepresentation, + valueb: NodeRepresentation, + texcoord?: NodeRepresentation, +): ShaderNodeObject; + +export function mx_splitlr( + valuel: NodeRepresentation, + valuer: NodeRepresentation, + center: NodeRepresentation, + texcoord?: NodeRepresentation, +): ShaderNodeObject; +export function mx_splittb( + valuet: NodeRepresentation, + valueb: NodeRepresentation, + center: NodeRepresentation, + texcoord?: NodeRepresentation, +): ShaderNodeObject; + +export function mx_transform_uv( + uv_scale?: NodeRepresentation, + uv_offset?: NodeRepresentation, + uv_geo?: NodeRepresentation, +): ShaderNodeObject; + +export function mx_safepower(in1: NodeRepresentation, in2?: NodeRepresentation): ShaderNodeObject; + +export function mx_contrast( + input: NodeRepresentation, + amount?: NodeRepresentation, + pivot?: NodeRepresentation, +): ShaderNodeObject; + +export function mx_noise_float( + texcoord?: NodeRepresentation, + amplitude?: NodeRepresentation, + pivot?: NodeRepresentation, +): ShaderNodeObject; +export function mx_noise_vec3( + texcoord?: NodeRepresentation, + amplitude?: NodeRepresentation, + pivot?: NodeRepresentation, +): ShaderNodeObject; +export function mx_noise_vec4( + texcoord?: NodeRepresentation, + amplitude?: NodeRepresentation, + pivot?: NodeRepresentation, +): ShaderNodeObject; + +export function mx_worley_noise_float( + texcoord?: NodeRepresentation, + jitter?: NodeRepresentation, +): ShaderNodeObject; +export function mx_worley_noise_vec2( + texcoord?: NodeRepresentation, + jitter?: NodeRepresentation, +): ShaderNodeObject; +export function mx_worley_noise_vec3( + texcoord?: NodeRepresentation, + jitter?: NodeRepresentation, +): ShaderNodeObject; + +export function mx_cell_noise_float(texcoord?: NodeRepresentation): ShaderNodeObject; + +export function mx_fractal_noise_float( + position?: NodeRepresentation, + octaves?: NodeRepresentation, + lacunarity?: NodeRepresentation, + diminish?: NodeRepresentation, + amplitude?: NodeRepresentation, +): ShaderNodeObject; +export function mx_fractal_noise_vec2( + position?: NodeRepresentation, + octaves?: NodeRepresentation, + lacunarity?: NodeRepresentation, + diminish?: NodeRepresentation, + amplitude?: NodeRepresentation, +): ShaderNodeObject; +export function mx_fractal_noise_vec3( + position?: NodeRepresentation, + octaves?: NodeRepresentation, + lacunarity?: NodeRepresentation, + diminish?: NodeRepresentation, + amplitude?: NodeRepresentation, +): ShaderNodeObject; +export function mx_fractal_noise_vec4( + position?: NodeRepresentation, + octaves?: NodeRepresentation, + lacunarity?: NodeRepresentation, + diminish?: NodeRepresentation, + amplitude?: NodeRepresentation, +): ShaderNodeObject; + +export { mx_hsvtorgb, mx_rgbtohsv, mx_srgb_texture_to_lin_rec709 }; diff --git a/src-testing/src/nodes/materialx/lib/mx_hsv.d.ts b/src-testing/src/nodes/materialx/lib/mx_hsv.d.ts new file mode 100644 index 000000000..ce11882e9 --- /dev/null +++ b/src-testing/src/nodes/materialx/lib/mx_hsv.d.ts @@ -0,0 +1,6 @@ +import Node from "../../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../../tsl/TSLCore.js"; + +export const mx_hsvtorgb: (hsv: NodeRepresentation) => ShaderNodeObject; + +export const mx_rgbtohsv: (c_immutable: NodeRepresentation) => ShaderNodeObject; diff --git a/src-testing/src/nodes/materialx/lib/mx_noise.d.ts b/src-testing/src/nodes/materialx/lib/mx_noise.d.ts new file mode 100644 index 000000000..2e5405f75 --- /dev/null +++ b/src-testing/src/nodes/materialx/lib/mx_noise.d.ts @@ -0,0 +1,359 @@ +import Node from "../../core/Node.js"; +import VarNode from "../../core/VarNode.js"; +import { NodeRepresentation, ShaderNodeObject } from "../../tsl/TSLCore.js"; + +export const mx_select: ( + b_immutable: NodeRepresentation, + t_immutable: NodeRepresentation, + f_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_negate_if: ( + val_immutable: NodeRepresentation, + b_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_floor: (x_immutable: NodeRepresentation) => ShaderNodeObject; + +export const mx_floorfrac: (x_immutable: NodeRepresentation, i: ShaderNodeObject) => ShaderNodeObject; + +export const mx_bilerp_0: ( + v0_immutable: NodeRepresentation, + v1_immutable: NodeRepresentation, + v2_immutable: NodeRepresentation, + v3_immutable: NodeRepresentation, + s_immutable: NodeRepresentation, + t_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_bilerp_1: ( + v0_immutable: NodeRepresentation, + v1_immutable: NodeRepresentation, + v2_immutable: NodeRepresentation, + v3_immutable: NodeRepresentation, + s_immutable: NodeRepresentation, + t_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_bilerp: ( + v0_immutable: NodeRepresentation, + v1_immutable: NodeRepresentation, + v2_immutable: NodeRepresentation, + v3_immutable: NodeRepresentation, + s_immutable: NodeRepresentation, + t_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_trilerp_0: ( + v0_immutable: NodeRepresentation, + v1_immutable: NodeRepresentation, + v2_immutable: NodeRepresentation, + v3_immutable: NodeRepresentation, + v4_immutable: NodeRepresentation, + v5_immutable: NodeRepresentation, + v6_immutable: NodeRepresentation, + v7_immutable: NodeRepresentation, + s_immutable: NodeRepresentation, + t_immutable: NodeRepresentation, + r_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_trilerp_1: ( + v0_immutable: NodeRepresentation, + v1_immutable: NodeRepresentation, + v2_immutable: NodeRepresentation, + v3_immutable: NodeRepresentation, + v4_immutable: NodeRepresentation, + v5_immutable: NodeRepresentation, + v6_immutable: NodeRepresentation, + v7_immutable: NodeRepresentation, + s_immutable: NodeRepresentation, + t_immutable: NodeRepresentation, + r_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_trilerp: ( + v0_immutable: NodeRepresentation, + v1_immutable: NodeRepresentation, + v2_immutable: NodeRepresentation, + v3_immutable: NodeRepresentation, + v4_immutable: NodeRepresentation, + v5_immutable: NodeRepresentation, + v6_immutable: NodeRepresentation, + v7_immutable: NodeRepresentation, + s_immutable: NodeRepresentation, + t_immutable: NodeRepresentation, + r_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_gradient_float_0: ( + hash_immutable: NodeRepresentation, + x_immutable: NodeRepresentation, + y_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_gradient_float_1: ( + hash_immutable: NodeRepresentation, + x_immutable: NodeRepresentation, + y_immutable: NodeRepresentation, + z_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_gradient_float: ( + hash_immutable: NodeRepresentation, + x_immutable: NodeRepresentation, + y_immutable: NodeRepresentation, + z_immutable?: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_gradient_vec3_0: ( + hash_immutable: NodeRepresentation, + x_immutable: NodeRepresentation, + y_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_gradient_vec3_1: ( + hash_immutable: NodeRepresentation, + x_immutable: NodeRepresentation, + y_immutable: NodeRepresentation, + z_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_gradient_vec3: ( + hash_immutable: NodeRepresentation, + x_immutable: NodeRepresentation, + y_immutable: NodeRepresentation, + z_immutable?: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_gradient_scale2d_0: (v_immutable: NodeRepresentation) => ShaderNodeObject; + +export const mx_gradient_scale3d_0: (v_immutable: NodeRepresentation) => ShaderNodeObject; + +export const mx_gradient_scale2d_1: (v_immutable: NodeRepresentation) => ShaderNodeObject; + +export const mx_gradient_scale2d: (v_immutable: NodeRepresentation) => ShaderNodeObject; + +export const mx_gradient_scale3d_1: (v_immutable: NodeRepresentation) => ShaderNodeObject; + +export const mx_gradient_scale3d: (v_immutable: NodeRepresentation) => ShaderNodeObject; + +export const mx_rotl32: (x_immutable: NodeRepresentation, k_immutable: NodeRepresentation) => ShaderNodeObject; + +export const mx_bjmix: ( + a: ShaderNodeObject, + b: ShaderNodeObject, + c: ShaderNodeObject, +) => ShaderNodeObject; + +export const mx_bjfinal: ( + a_immutable: NodeRepresentation, + b_immutable: NodeRepresentation, + c_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_bits_to_01: (bits_immutable: NodeRepresentation) => ShaderNodeObject; + +export const mx_fade: (t_immutable: NodeRepresentation) => ShaderNodeObject; + +export const mx_hash_int_0: (x_immutable: NodeRepresentation) => ShaderNodeObject; + +export const mx_hash_int_1: ( + x_immutable: NodeRepresentation, + y_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_hash_int_2: ( + x_immutable: NodeRepresentation, + y_immutable: NodeRepresentation, + z_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_hash_int_3: ( + x_immutable: NodeRepresentation, + y_immutable: NodeRepresentation, + z_immutable: NodeRepresentation, + xx_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_hash_int_4: ( + x_immutable: NodeRepresentation, + y_immutable: NodeRepresentation, + z_immutable: NodeRepresentation, + xx_immutable: NodeRepresentation, + yy_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_hash_int: ( + x_immutable: NodeRepresentation, + y_immutable?: NodeRepresentation, + z_immutable?: NodeRepresentation, + xx_immutable?: NodeRepresentation, + yy_immutable?: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_hash_vec3_0: ( + x_immutable: NodeRepresentation, + y_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_hash_vec3_1: ( + x_immutable: NodeRepresentation, + y_immutable: NodeRepresentation, + z_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_hash_vec3: ( + x_immutable: NodeRepresentation, + y_immutable: NodeRepresentation, + z_immutable?: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_perlin_noise_float_0: (p_immutable: NodeRepresentation) => ShaderNodeObject; + +export const mx_perlin_noise_float_1: (p_immutable: NodeRepresentation) => ShaderNodeObject; + +export const mx_perlin_noise_float: (p_immutable: NodeRepresentation) => ShaderNodeObject; + +export const mx_perlin_noise_vec3_0: (p_immutable: NodeRepresentation) => ShaderNodeObject; + +export const mx_perlin_noise_vec3_1: (p_immutable: NodeRepresentation) => ShaderNodeObject; + +export const mx_perlin_noise_vec3: (p_immutable: NodeRepresentation) => ShaderNodeObject; + +export const mx_cell_noise_float_0: (p_immutable: NodeRepresentation) => ShaderNodeObject; + +export const mx_cell_noise_float_1: (p_immutable: NodeRepresentation) => ShaderNodeObject; + +export const mx_cell_noise_float_2: (p_immutable: NodeRepresentation) => ShaderNodeObject; + +export const mx_cell_noise_float_3: (p_immutable: NodeRepresentation) => ShaderNodeObject; + +export const mx_cell_noise_float: (p_immutable: NodeRepresentation) => ShaderNodeObject; + +export const mx_cell_noise_vec3_0: (p_immutable: NodeRepresentation) => ShaderNodeObject; + +export const mx_cell_noise_vec3_1: (p_immutable: NodeRepresentation) => ShaderNodeObject; + +export const mx_cell_noise_vec3_2: (p_immutable: NodeRepresentation) => ShaderNodeObject; + +export const mx_cell_noise_vec3_3: (p_immutable: NodeRepresentation) => ShaderNodeObject; + +export const mx_cell_noise_vec3: (p_immutable: NodeRepresentation) => ShaderNodeObject; + +export const mx_fractal_noise_float: ( + p_immutable: NodeRepresentation, + octaves_immutable: NodeRepresentation, + lacunarity_immutable: NodeRepresentation, + diminish_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_fractal_noise_vec3: ( + p_immutable: NodeRepresentation, + octaves_immutable: NodeRepresentation, + lacunarity_immutable: NodeRepresentation, + diminish_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_fractal_noise_vec2: ( + p_immutable: NodeRepresentation, + octaves_immutable: NodeRepresentation, + lacunarity_immutable: NodeRepresentation, + diminish_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_fractal_noise_vec4: ( + p_immutable: NodeRepresentation, + octaves_immutable: NodeRepresentation, + lacunarity_immutable: NodeRepresentation, + diminish_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_worley_distance_0: ( + p_immutable: NodeRepresentation, + x_immutable: NodeRepresentation, + y_immutable: NodeRepresentation, + z_immutable: NodeRepresentation, + xoff_immutable: NodeRepresentation, + yoff_immutable: NodeRepresentation, + jitter_immutable: NodeRepresentation, + metric_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_worley_distance_1: ( + p_immutable: NodeRepresentation, + x_immutable: NodeRepresentation, + y_immutable: NodeRepresentation, + z_immutable: NodeRepresentation, + xoff_immutable: NodeRepresentation, + yoff_immutable: NodeRepresentation, + zoff_immutable: NodeRepresentation, + jitter_immutable: NodeRepresentation, + metric_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_worley_distance: ( + p_immutable: NodeRepresentation, + x_immutable: NodeRepresentation, + y_immutable: NodeRepresentation, + z_immutable: NodeRepresentation, + xoff_immutable: NodeRepresentation, + yoff_immutable: NodeRepresentation, + zoff_immutable: NodeRepresentation, + jitter_immutable: NodeRepresentation, + metric_immutable?: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_worley_noise_float_0: ( + p_immutable: NodeRepresentation, + jitter_immutable: NodeRepresentation, + metric_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_worley_noise_vec2_0: ( + p_immutable: NodeRepresentation, + jitter_immutable: NodeRepresentation, + metric_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_worley_noise_vec3_0: ( + p_immutable: NodeRepresentation, + jitter_immutable: NodeRepresentation, + metric_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_worley_noise_float_1: ( + p_immutable: NodeRepresentation, + jitter_immutable: NodeRepresentation, + metric_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_worley_noise_float: ( + p_immutable: NodeRepresentation, + jitter_immutable: NodeRepresentation, + metric_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_worley_noise_vec2_1: ( + p_immutable: NodeRepresentation, + jitter_immutable: NodeRepresentation, + metric_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_worley_noise_vec2: ( + p_immutable: NodeRepresentation, + jitter_immutable: NodeRepresentation, + metric_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_worley_noise_vec3_1: ( + p_immutable: NodeRepresentation, + jitter_immutable: NodeRepresentation, + metric_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_worley_noise_vec3: ( + p_immutable: NodeRepresentation, + jitter_immutable: NodeRepresentation, + metric_immutable: NodeRepresentation, +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/materialx/lib/mx_transform_color.d.ts b/src-testing/src/nodes/materialx/lib/mx_transform_color.d.ts new file mode 100644 index 000000000..418818d0e --- /dev/null +++ b/src-testing/src/nodes/materialx/lib/mx_transform_color.d.ts @@ -0,0 +1,4 @@ +import Node from "../../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../../tsl/TSLCore.js"; + +export const mx_srgb_texture_to_lin_rec709: (color_immutable: NodeRepresentation) => ShaderNodeObject; diff --git a/src-testing/src/nodes/math/ConditionalNode.d.ts b/src-testing/src/nodes/math/ConditionalNode.d.ts new file mode 100644 index 000000000..5313a9836 --- /dev/null +++ b/src-testing/src/nodes/math/ConditionalNode.d.ts @@ -0,0 +1,39 @@ +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +declare class ConditionalNode extends Node { + condNode: Node; + ifNode: Node; + elseNode: Node; + + constructor(condNode: Node, ifNode: Node, elseNode: Node); +} + +export default ConditionalNode; + +export const select: ( + condNode: NodeRepresentation, + ifNode: NodeRepresentation, + elseNode: NodeRepresentation, +) => ShaderNodeObject; + +declare module "../tsl/TSLCore.js" { + interface NodeElements { + select: typeof select; + } +} + +/** + * @deprecated cond() has been renamed to select() + */ +export const cond: ( + condNode: NodeRepresentation, + ifNode: NodeRepresentation, + elseNode: NodeRepresentation, +) => ShaderNodeObject; + +declare module "../tsl/TSLCore.js" { + interface NodeElements { + cond: typeof cond; + } +} diff --git a/src-testing/src/nodes/math/Hash.d.ts b/src-testing/src/nodes/math/Hash.d.ts new file mode 100644 index 000000000..df9e81997 --- /dev/null +++ b/src-testing/src/nodes/math/Hash.d.ts @@ -0,0 +1,4 @@ +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +export const hash: (seed: NodeRepresentation) => ShaderNodeObject; diff --git a/src-testing/src/nodes/math/MathNode.d.ts b/src-testing/src/nodes/math/MathNode.d.ts new file mode 100644 index 000000000..f65546d75 --- /dev/null +++ b/src-testing/src/nodes/math/MathNode.d.ts @@ -0,0 +1,273 @@ +import Node from "../core/Node.js"; +import TempNode from "../core/TempNode.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; +import OperatorNode from "./OperatorNode.js"; + +export type MathNodeMethod1 = + | typeof MathNode.RADIANS + | typeof MathNode.DEGREES + | typeof MathNode.EXP + | typeof MathNode.EXP2 + | typeof MathNode.LOG + | typeof MathNode.LOG2 + | typeof MathNode.SQRT + | typeof MathNode.INVERSE_SQRT + | typeof MathNode.FLOOR + | typeof MathNode.CEIL + | typeof MathNode.NORMALIZE + | typeof MathNode.FRACT + | typeof MathNode.SIN + | typeof MathNode.COS + | typeof MathNode.TAN + | typeof MathNode.ASIN + | typeof MathNode.ACOS + | typeof MathNode.ATAN + | typeof MathNode.ABS + | typeof MathNode.SIGN + | typeof MathNode.LENGTH + | typeof MathNode.NEGATE + | typeof MathNode.ONE_MINUS + | typeof MathNode.DFDX + | typeof MathNode.DFDY + | typeof MathNode.ROUND + | typeof MathNode.RECIPROCAL + | typeof MathNode.TRUNC + | typeof MathNode.FWIDTH + | typeof MathNode.BITCAST + | typeof MathNode.TRANSPOSE; + +export type MathNodeMethod2 = + | typeof MathNode.ATAN2 + | typeof MathNode.MIN + | typeof MathNode.MAX + | typeof MathNode.MOD + | typeof MathNode.STEP + | typeof MathNode.REFLECT + | typeof MathNode.DISTANCE + | typeof MathNode.DOT + | typeof MathNode.CROSS + | typeof MathNode.POW + | typeof MathNode.TRANSFORM_DIRECTION; + +export type MathNodeMethod3 = + | typeof MathNode.MIX + | typeof MathNode.CLAMP + | typeof MathNode.REFRACT + | typeof MathNode.SMOOTHSTEP + | typeof MathNode.FACEFORWARD; + +export type MathNodeMethod = MathNodeMethod1 | MathNodeMethod2 | MathNodeMethod3; + +export default class MathNode extends TempNode { + // 1 input + + static ALL: "all"; + static ANY: "any"; + static EQUALS: "equals"; + + static RADIANS: "radians"; + static DEGREES: "degrees"; + static EXP: "exp"; + static EXP2: "exp2"; + static LOG: "log"; + static LOG2: "log2"; + static SQRT: "sqrt"; + static INVERSE_SQRT: "inversesqrt"; + static FLOOR: "floor"; + static CEIL: "ceil"; + static NORMALIZE: "normalize"; + static FRACT: "fract"; + static SIN: "sin"; + static COS: "cos"; + static TAN: "tan"; + static ASIN: "asin"; + static ACOS: "acos"; + static ATAN: "atan"; + static ABS: "abs"; + static SIGN: "sign"; + static LENGTH: "length"; + static NEGATE: "negate"; + static ONE_MINUS: "oneMinus"; + static DFDX: "dFdx"; + static DFDY: "dFdy"; + static ROUND: "round"; + static RECIPROCAL: "reciprocal"; + static TRUNC: "trunc"; + static FWIDTH: "fwidth"; + static BITCAST: "bitcast"; + static TRANSPOSE: "transpose"; + + // 2 inputs + + static ATAN2: "atan2"; + static MIN: "min"; + static MAX: "max"; + static MOD: "mod"; + static STEP: "step"; + static REFLECT: "reflect"; + static DISTANCE: "distance"; + static DOT: "dot"; + static CROSS: "cross"; + static POW: "pow"; + static TRANSFORM_DIRECTION: "transformDirection"; + + // 3 inputs + + static MIX: "mix"; + static CLAMP: "clamp"; + static REFRACT: "refract"; + static SMOOTHSTEP: "smoothstep"; + static FACEFORWARD: "faceforward"; + + method: MathNodeMethod; + aNode: Node; + bNode: Node | null; + cNode: Node | null; + + constructor(method: MathNodeMethod1, aNode: Node); + constructor(method: MathNodeMethod2, aNode: Node, bNode: Node); + constructor(method: MathNodeMethod3, aNode: Node, bNode: Node, cNode: Node); +} + +export const EPSILON: ShaderNodeObject; +export const INFINITY: ShaderNodeObject; +export const PI: ShaderNodeObject; +export const PI2: ShaderNodeObject; + +type Unary = (a: NodeRepresentation) => ShaderNodeObject; + +export const all: Unary; +export const any: Unary; +export const equals: Unary; + +export const radians: Unary; +export const degrees: Unary; +export const exp: Unary; +export const exp2: Unary; +export const log: Unary; +export const log2: Unary; +export const sqrt: Unary; +export const inverseSqrt: Unary; +export const floor: Unary; +export const ceil: Unary; +export const normalize: Unary; +export const fract: Unary; +export const sin: Unary; +export const cos: Unary; +export const tan: Unary; +export const asin: Unary; +export const acos: Unary; +export const atan: Unary; +export const abs: Unary; +export const sign: Unary; +export const length: Unary; +export const negate: Unary; +export const oneMinus: Unary; +export const dFdx: Unary; +export const dFdy: Unary; +export const round: Unary; +export const reciprocal: Unary; +export const trunc: Unary; +export const fwidth: Unary; +export const bitcast: Unary; +export const transpose: Unary; + +type Binary = (a: NodeRepresentation, b: NodeRepresentation) => ShaderNodeObject; + +export const atan2: Binary; +export const min: Binary; +export const max: Binary; +export const mod: Binary; +export const step: Binary; +export const reflect: Binary; +export const distance: Binary; +export const difference: Binary; +export const dot: Binary; +export const cross: Binary; +export const pow: Binary; +export const pow2: Binary; +export const pow3: Binary; +export const pow4: Binary; +export const transformDirection: Binary; + +type Ternary = (a: NodeRepresentation, b: NodeRepresentation, c: NodeRepresentation) => ShaderNodeObject; + +export const cbrt: Unary; +export const lengthSq: Unary; +export const mix: Ternary; +export const clamp: ( + a: NodeRepresentation, + b?: NodeRepresentation, + c?: NodeRepresentation, +) => ShaderNodeObject; +export const saturate: Unary; +export const refract: Ternary; +export const smoothstep: Ternary; +export const faceForward: Ternary; + +export const rand: (uv: NodeRepresentation) => ShaderNodeObject; + +export const mixElement: Ternary; +export const smoothstepElement: Ternary; + +declare module "../tsl/TSLCore.js" { + interface NodeElements { + all: typeof all; + any: typeof any; + equals: typeof equals; + radians: typeof radians; + degrees: typeof degrees; + exp: typeof exp; + exp2: typeof exp2; + log: typeof log; + log2: typeof log2; + sqrt: typeof sqrt; + inverseSqrt: typeof inverseSqrt; + floor: typeof floor; + ceil: typeof ceil; + normalize: typeof normalize; + fract: typeof fract; + sin: typeof sin; + cos: typeof cos; + tan: typeof tan; + asin: typeof asin; + acos: typeof acos; + atan: typeof atan; + abs: typeof abs; + sign: typeof sign; + length: typeof length; + lengthSq: typeof lengthSq; + negate: typeof negate; + oneMinus: typeof oneMinus; + dFdx: typeof dFdx; + dFdy: typeof dFdy; + round: typeof round; + reciprocal: typeof reciprocal; + trunc: typeof trunc; + fwidth: typeof fwidth; + atan2: typeof atan2; + min: typeof min; + max: typeof max; + mod: typeof mod; + step: typeof step; + reflect: typeof reflect; + distance: typeof distance; + dot: typeof dot; + cross: typeof cross; + pow: typeof pow; + pow2: typeof pow2; + pow3: typeof pow3; + pow4: typeof pow4; + transformDirection: typeof transformDirection; + mix: typeof mixElement; + clamp: typeof clamp; + refract: typeof refract; + smoothstep: typeof smoothstepElement; + faceForward: typeof faceForward; + difference: typeof difference; + saturate: typeof saturate; + cbrt: typeof cbrt; + transpose: typeof transpose; + rand: typeof rand; + } +} diff --git a/src-testing/src/nodes/math/MathUtils.d.ts b/src-testing/src/nodes/math/MathUtils.d.ts new file mode 100644 index 000000000..572d9eef5 --- /dev/null +++ b/src-testing/src/nodes/math/MathUtils.d.ts @@ -0,0 +1,6 @@ +import { Binary, Ternary } from "./MathNode.js"; + +export const parabola: Binary; +export const gain: Binary; +export const pcurve: Ternary; +export const sinc: Binary; diff --git a/src-testing/src/nodes/math/OperatorNode.d.ts b/src-testing/src/nodes/math/OperatorNode.d.ts new file mode 100644 index 000000000..77157ea73 --- /dev/null +++ b/src-testing/src/nodes/math/OperatorNode.d.ts @@ -0,0 +1,97 @@ +import Node from "../core/Node.js"; +import TempNode from "../core/TempNode.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +export type OperatorNodeOp = + | "%" + | "&" + | "|" + | "^" + | ">>" + | "<<" + | "==" + | "&&" + | "||" + | "^^" + | "<" + | ">" + | "<=" + | ">=" + | "+" + | "-" + | "*" + | "/"; + +export default class OperatorNode extends TempNode { + aNode: Node; + bNode: Node; + op: OperatorNodeOp; + + constructor(op: OperatorNodeOp, ...params: [Node, Node, ...Node[]]); +} + +type Operator = ( + a: NodeRepresentation, + b: NodeRepresentation, + ...others: NodeRepresentation[] +) => ShaderNodeObject; + +export const add: Operator; +export const sub: Operator; +export const mul: Operator; +export const div: Operator; +export const modInt: Operator; +export const equal: Operator; +export const lessThan: Operator; +export const greaterThan: Operator; +export const lessThanEqual: Operator; +export const greaterThanEqual: Operator; +export const and: Operator; +export const or: Operator; +export const not: (a: NodeRepresentation) => ShaderNodeObject; +export const xor: Operator; +export const bitAnd: Operator; +export const bitNot: (a: NodeRepresentation) => ShaderNodeObject; +export const bitOr: Operator; +export const bitXor: Operator; +export const shiftLeft: Operator; +export const shiftRight: Operator; + +declare module "../tsl/TSLCore.js" { + interface NodeElements { + add: typeof add; + sub: typeof sub; + mul: typeof mul; + div: typeof div; + modInt: typeof modInt; + equal: typeof equal; + lessThan: typeof lessThan; + greaterThan: typeof greaterThan; + lessThanEqual: typeof lessThanEqual; + greaterThanEqual: typeof greaterThanEqual; + and: typeof and; + or: typeof or; + not: typeof not; + xor: typeof xor; + bitAnd: typeof bitAnd; + bitNot: typeof bitNot; + bitOr: typeof bitOr; + bitXor: typeof bitXor; + shiftLeft: typeof shiftLeft; + shiftRight: typeof shiftRight; + } +} + +/** + * @deprecated .remainder() has been renamed to .modInt(). + */ +export const remainder: Operator; + +declare module "../tsl/TSLCore.js" { + interface NodeElements { + /** + * @deprecated .remainder() has been renamed to .modInt(). + */ + remainder: typeof remainder; + } +} diff --git a/src-testing/src/nodes/math/TriNoise3D.d.ts b/src-testing/src/nodes/math/TriNoise3D.d.ts new file mode 100644 index 000000000..f5220dbe6 --- /dev/null +++ b/src-testing/src/nodes/math/TriNoise3D.d.ts @@ -0,0 +1,12 @@ +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +export const tri: (x: NodeRepresentation) => ShaderNodeObject; + +export const tri3: (p: NodeRepresentation) => ShaderNodeObject; + +export const triNoise3D: ( + p_immutable: NodeRepresentation, + spd: NodeRepresentation, + time: NodeRepresentation, +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/parsers/GLSLNodeFunction.d.ts b/src-testing/src/nodes/parsers/GLSLNodeFunction.d.ts new file mode 100644 index 000000000..ec2396423 --- /dev/null +++ b/src-testing/src/nodes/parsers/GLSLNodeFunction.d.ts @@ -0,0 +1,9 @@ +import NodeFunction from "../core/NodeFunction.js"; + +declare class GLSLNodeFunction extends NodeFunction { + constructor(source: string); + + getCode(name?: string): string; +} + +export default GLSLNodeFunction; diff --git a/src-testing/src/nodes/parsers/GLSLNodeParser.d.ts b/src-testing/src/nodes/parsers/GLSLNodeParser.d.ts new file mode 100644 index 000000000..f6b663d4b --- /dev/null +++ b/src-testing/src/nodes/parsers/GLSLNodeParser.d.ts @@ -0,0 +1,8 @@ +import NodeParser from "../core/NodeParser.js"; +import GLSLNodeFunction from "./GLSLNodeFunction.js"; + +declare class GLSLNodeParser extends NodeParser { + parseFunction(source: string): GLSLNodeFunction; +} + +export default GLSLNodeParser; diff --git a/src-testing/src/nodes/pmrem/PMREMNode.d.ts b/src-testing/src/nodes/pmrem/PMREMNode.d.ts new file mode 100644 index 000000000..2a957c8e6 --- /dev/null +++ b/src-testing/src/nodes/pmrem/PMREMNode.d.ts @@ -0,0 +1,22 @@ +import { Texture } from "../../textures/Texture.js"; +import Node from "../core/Node.js"; +import TempNode from "../core/TempNode.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +declare class PMREMNode extends TempNode { + uvNode: Node | null; + levelNode: Node | null; + + constructor(value: Texture, uvNode?: Node | null, levelNode?: Node | null); + + set value(value: Texture); + get value(): Texture; +} + +export default PMREMNode; + +export const pmremTexture: ( + value: Texture, + uvNode?: NodeRepresentation, + levelNode?: NodeRepresentation, +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/pmrem/PMREMUtils.d.ts b/src-testing/src/nodes/pmrem/PMREMUtils.d.ts new file mode 100644 index 000000000..947e7fe25 --- /dev/null +++ b/src-testing/src/nodes/pmrem/PMREMUtils.d.ts @@ -0,0 +1,28 @@ +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +export const getDirection: (uv_immutable: NodeRepresentation, face: NodeRepresentation) => ShaderNodeObject; + +export const textureCubeUV: ( + envMap: NodeRepresentation, + sampleDir_immutable: NodeRepresentation, + roughness_immutable: NodeRepresentation, + CUBEUV_TEXEL_WIDTH: NodeRepresentation, + CUBEUV_TEXEL_HEIGHT: NodeRepresentation, + CUBEUV_MAX_MIP: NodeRepresentation, +) => ShaderNodeObject; + +export const blur: ( + n: NodeRepresentation, + latitudinal: NodeRepresentation, + poleAxis: NodeRepresentation, + outputDirection: NodeRepresentation, + weights: NodeRepresentation, + samples: NodeRepresentation, + dTheta: NodeRepresentation, + mipInt: NodeRepresentation, + envMap: NodeRepresentation, + CUBEUV_TEXEL_WIDTH: NodeRepresentation, + CUBEUV_TEXEL_HEIGHT: NodeRepresentation, + CUBEUV_MAX_MIP: NodeRepresentation, +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/procedural/Checker.d.ts b/src-testing/src/nodes/procedural/Checker.d.ts new file mode 100644 index 000000000..af7cce3a7 --- /dev/null +++ b/src-testing/src/nodes/procedural/Checker.d.ts @@ -0,0 +1,4 @@ +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +export const checker: (coord?: NodeRepresentation) => ShaderNodeObject; diff --git a/src-testing/src/nodes/tsl/TSLBase.d.ts b/src-testing/src/nodes/tsl/TSLBase.d.ts new file mode 100644 index 000000000..297b9a483 --- /dev/null +++ b/src-testing/src/nodes/tsl/TSLBase.d.ts @@ -0,0 +1,21 @@ +export * from "../accessors/BufferAttributeNode.js"; +export * from "../code/ExpressionNode.js"; +export * from "../code/FunctionCallNode.js"; +export * from "../core/AssignNode.js"; +export * from "../core/BypassNode.js"; +export * from "../core/CacheNode.js"; +export * from "../core/ContextNode.js"; +export * from "../core/PropertyNode.js"; +export * from "../core/UniformNode.js"; +export * from "../core/VarNode.js"; +export * from "../core/VaryingNode.js"; +export * from "../display/ColorSpaceNode.js"; +export * from "../display/RenderOutputNode.js"; +export * from "../display/ToneMappingNode.js"; +export * from "../gpgpu/ComputeNode.js"; +export * from "../math/ConditionalNode.js"; +export * from "../math/MathNode.js"; +export * from "../math/OperatorNode.js"; +export * from "../utils/Discard.js"; +export * from "../utils/RemapNode.js"; +export * from "./TSLCore.js"; diff --git a/src-testing/src/nodes/tsl/TSLCore.ts b/src-testing/src/nodes/tsl/TSLCore.ts new file mode 100644 index 000000000..4ac059f08 --- /dev/null +++ b/src-testing/src/nodes/tsl/TSLCore.ts @@ -0,0 +1,533 @@ +import Node from '../core/Node.js'; +import ArrayElementNode from '../utils/ArrayElementNode.js'; +import ConvertNode from '../utils/ConvertNode.js'; +import JoinNode from '../utils/JoinNode.js'; +import SplitNode from '../utils/SplitNode.js'; +import SetNode from '../utils/SetNode.js'; +import FlipNode from '../utils/FlipNode.js'; +import ConstNode from '../core/ConstNode.js'; +import { getValueFromType, getValueType } from '../core/NodeUtils.js'; + +// + +let currentStack = null; + +const NodeElements = new Map(); + +export function addMethodChaining(name, nodeElement) { + if (NodeElements.has(name)) { + console.warn(`Redefinition of method chaining ${name}`); + return; + } + + if (typeof nodeElement !== 'function') throw new Error(`Node element ${name} is not a function`); + + NodeElements.set(name, nodeElement); +} + +const parseSwizzle = props => props.replace(/r|s/g, 'x').replace(/g|t/g, 'y').replace(/b|p/g, 'z').replace(/a|q/g, 'w'); +const parseSwizzleAndSort = props => parseSwizzle(props).split('').sort().join(''); + +const shaderNodeHandler = { + setup(NodeClosure, params) { + const inputs = params.shift(); + + return NodeClosure(nodeObjects(inputs), ...params); + }, + + get(node, prop, nodeObj) { + if (typeof prop === 'string' && node[prop] === undefined) { + if (node.isStackNode !== true && prop === 'assign') { + return (...params) => { + currentStack.assign(nodeObj, ...params); + + return nodeObj; + }; + } else if (NodeElements.has(prop)) { + const nodeElement = NodeElements.get(prop); + + return node.isStackNode + ? (...params) => nodeObj.add(nodeElement(...params)) + : (...params) => nodeElement(nodeObj, ...params); + } else if (prop === 'self') { + return node; + } else if (prop.endsWith('Assign') && NodeElements.has(prop.slice(0, prop.length - 'Assign'.length))) { + const nodeElement = NodeElements.get(prop.slice(0, prop.length - 'Assign'.length)); + + return node.isStackNode + ? (...params) => nodeObj.assign(params[0], nodeElement(...params)) + : (...params) => nodeObj.assign(nodeElement(nodeObj, ...params)); + } else if (/^[xyzwrgbastpq]{1,4}$/.test(prop) === true) { + // accessing properties ( swizzle ) + + prop = parseSwizzle(prop); + + return nodeObject(new SplitNode(nodeObj, prop)); + } else if (/^set[XYZWRGBASTPQ]{1,4}$/.test(prop) === true) { + // set properties ( swizzle ) and sort to xyzw sequence + + prop = parseSwizzleAndSort(prop.slice(3).toLowerCase()); + + return value => nodeObject(new SetNode(node, prop, value)); + } else if (/^flip[XYZWRGBASTPQ]{1,4}$/.test(prop) === true) { + // set properties ( swizzle ) and sort to xyzw sequence + + prop = parseSwizzleAndSort(prop.slice(4).toLowerCase()); + + return () => nodeObject(new FlipNode(nodeObject(node), prop)); + } else if (prop === 'width' || prop === 'height' || prop === 'depth') { + // accessing property + + if (prop === 'width') prop = 'x'; + else if (prop === 'height') prop = 'y'; + else if (prop === 'depth') prop = 'z'; + + return nodeObject(new SplitNode(node, prop)); + } else if (/^\d+$/.test(prop) === true) { + // accessing array + + return nodeObject(new ArrayElementNode(nodeObj, new ConstNode(Number(prop), 'uint'))); + } + } + + return Reflect.get(node, prop, nodeObj); + }, + + set(node, prop, value, nodeObj) { + if (typeof prop === 'string' && node[prop] === undefined) { + // setting properties + + if ( + /^[xyzwrgbastpq]{1,4}$/.test(prop) === true || + prop === 'width' || + prop === 'height' || + prop === 'depth' || + /^\d+$/.test(prop) === true + ) { + nodeObj[prop].assign(value); + + return true; + } + } + + return Reflect.set(node, prop, value, nodeObj); + }, +}; + +const nodeObjectsCacheMap = new WeakMap(); +const nodeBuilderFunctionsCacheMap = new WeakMap(); + +const ShaderNodeObject = function (obj, altType = null) { + const type = getValueType(obj); + + if (type === 'node') { + let nodeObject = nodeObjectsCacheMap.get(obj); + + if (nodeObject === undefined) { + nodeObject = new Proxy(obj, shaderNodeHandler); + + nodeObjectsCacheMap.set(obj, nodeObject); + nodeObjectsCacheMap.set(nodeObject, nodeObject); + } + + return nodeObject; + } else if ( + (altType === null && (type === 'float' || type === 'boolean')) || + (type && type !== 'shader' && type !== 'string') + ) { + return nodeObject(getConstNode(obj, altType)); + } else if (type === 'shader') { + return Fn(obj); + } + + return obj; +}; + +const ShaderNodeObjects = function (objects, altType = null) { + for (const name in objects) { + objects[name] = nodeObject(objects[name], altType); + } + + return objects; +}; + +const ShaderNodeArray = function (array, altType = null) { + const len = array.length; + + for (let i = 0; i < len; i++) { + array[i] = nodeObject(array[i], altType); + } + + return array; +}; + +const ShaderNodeProxy = function (NodeClass, scope = null, factor = null, settings = null) { + const assignNode = node => nodeObject(settings !== null ? Object.assign(node, settings) : node); + + if (scope === null) { + return (...params) => { + return assignNode(new NodeClass(...nodeArray(params))); + }; + } else if (factor !== null) { + factor = nodeObject(factor); + + return (...params) => { + return assignNode(new NodeClass(scope, ...nodeArray(params), factor)); + }; + } else { + return (...params) => { + return assignNode(new NodeClass(scope, ...nodeArray(params))); + }; + } +}; + +const ShaderNodeImmutable = function (NodeClass, ...params) { + return nodeObject(new NodeClass(...nodeArray(params))); +}; + +class ShaderCallNodeInternal extends Node { + constructor(shaderNode, inputNodes) { + super(); + + this.shaderNode = shaderNode; + this.inputNodes = inputNodes; + } + + getNodeType(builder) { + return this.shaderNode.nodeType || this.getOutputNode(builder).getNodeType(builder); + } + + call(builder) { + const { shaderNode, inputNodes } = this; + + const properties = builder.getNodeProperties(shaderNode); + if (properties.onceOutput) return properties.onceOutput; + + // + + let result = null; + + if (shaderNode.layout) { + let functionNodesCacheMap = nodeBuilderFunctionsCacheMap.get(builder.constructor); + + if (functionNodesCacheMap === undefined) { + functionNodesCacheMap = new WeakMap(); + + nodeBuilderFunctionsCacheMap.set(builder.constructor, functionNodesCacheMap); + } + + let functionNode = functionNodesCacheMap.get(shaderNode); + + if (functionNode === undefined) { + functionNode = nodeObject(builder.buildFunctionNode(shaderNode)); + + functionNodesCacheMap.set(shaderNode, functionNode); + } + + if (builder.currentFunctionNode !== null) { + builder.currentFunctionNode.includes.push(functionNode); + } + + result = nodeObject(functionNode.call(inputNodes)); + } else { + const jsFunc = shaderNode.jsFunc; + const outputNode = inputNodes !== null ? jsFunc(inputNodes, builder) : jsFunc(builder); + + result = nodeObject(outputNode); + } + + if (shaderNode.once) { + properties.onceOutput = result; + } + + return result; + } + + getOutputNode(builder) { + const properties = builder.getNodeProperties(this); + + if (properties.outputNode === null) { + properties.outputNode = this.setupOutput(builder); + } + + return properties.outputNode; + } + + setup(builder) { + return this.getOutputNode(builder); + } + + setupOutput(builder) { + builder.addStack(); + + builder.stack.outputNode = this.call(builder); + + return builder.removeStack(); + } + + generate(builder, output) { + const outputNode = this.getOutputNode(builder); + + return outputNode.build(builder, output); + } +} + +class ShaderNodeInternal extends Node { + constructor(jsFunc, nodeType) { + super(nodeType); + + this.jsFunc = jsFunc; + this.layout = null; + + this.global = true; + + this.once = false; + } + + setLayout(layout) { + this.layout = layout; + + return this; + } + + call(inputs = null) { + nodeObjects(inputs); + + return nodeObject(new ShaderCallNodeInternal(this, inputs)); + } + + setup() { + return this.call(); + } +} + +const bools = [false, true]; +const uints = [0, 1, 2, 3]; +const ints = [-1, -2]; +const floats = [ + 0.5, + 1.5, + 1 / 3, + 1e-6, + 1e6, + Math.PI, + Math.PI * 2, + 1 / Math.PI, + 2 / Math.PI, + 1 / (Math.PI * 2), + Math.PI / 2, +]; + +const boolsCacheMap = new Map(); +for (const bool of bools) boolsCacheMap.set(bool, new ConstNode(bool)); + +const uintsCacheMap = new Map(); +for (const uint of uints) uintsCacheMap.set(uint, new ConstNode(uint, 'uint')); + +const intsCacheMap = new Map([...uintsCacheMap].map(el => new ConstNode(el.value, 'int'))); +for (const int of ints) intsCacheMap.set(int, new ConstNode(int, 'int')); + +const floatsCacheMap = new Map([...intsCacheMap].map(el => new ConstNode(el.value))); +for (const float of floats) floatsCacheMap.set(float, new ConstNode(float)); +for (const float of floats) floatsCacheMap.set(-float, new ConstNode(-float)); + +const cacheMaps = { bool: boolsCacheMap, uint: uintsCacheMap, ints: intsCacheMap, float: floatsCacheMap }; + +const constNodesCacheMap = new Map([...boolsCacheMap, ...floatsCacheMap]); + +const getConstNode = (value, type) => { + if (constNodesCacheMap.has(value)) { + return constNodesCacheMap.get(value); + } else if (value.isNode === true) { + return value; + } else { + return new ConstNode(value, type); + } +}; + +const safeGetNodeType = node => { + try { + return node.getNodeType(); + } catch (_) { + return undefined; + } +}; + +const ConvertType = function (type, cacheMap = null) { + return (...params) => { + if ( + params.length === 0 || + (!['bool', 'float', 'int', 'uint'].includes(type) && params.every(param => typeof param !== 'object')) + ) { + params = [getValueFromType(type, ...params)]; + } + + if (params.length === 1 && cacheMap !== null && cacheMap.has(params[0])) { + return nodeObject(cacheMap.get(params[0])); + } + + if (params.length === 1) { + const node = getConstNode(params[0], type); + if (safeGetNodeType(node) === type) return nodeObject(node); + return nodeObject(new ConvertNode(node, type)); + } + + const nodes = params.map(param => getConstNode(param)); + return nodeObject(new JoinNode(nodes, type)); + }; +}; + +// exports + +export const defined = v => (typeof v === 'object' && v !== null ? v.value : v); // TODO: remove boolean conversion and defined function + +// utils + +export const getConstNodeType = value => + value !== undefined && value !== null + ? value.nodeType || value.convertTo || (typeof value === 'string' ? value : null) + : null; + +// shader node base + +export function ShaderNode(jsFunc, nodeType) { + return new Proxy(new ShaderNodeInternal(jsFunc, nodeType), shaderNodeHandler); +} + +export const nodeObject = (val, altType = null) => /* new */ ShaderNodeObject(val, altType); +export const nodeObjects = (val, altType = null) => new ShaderNodeObjects(val, altType); +export const nodeArray = (val, altType = null) => new ShaderNodeArray(val, altType); +export const nodeProxy = (...params) => new ShaderNodeProxy(...params); +export const nodeImmutable = (...params) => new ShaderNodeImmutable(...params); + +export const Fn = (jsFunc, nodeType) => { + const shaderNode = new ShaderNode(jsFunc, nodeType); + + const fn = (...params) => { + let inputs; + + nodeObjects(params); + + if (params[0] && params[0].isNode) { + inputs = [...params]; + } else { + inputs = params[0]; + } + + return shaderNode.call(inputs); + }; + + fn.shaderNode = shaderNode; + + fn.setLayout = layout => { + shaderNode.setLayout(layout); + + return fn; + }; + + fn.once = () => { + shaderNode.once = true; + + return fn; + }; + + return fn; +}; + +export const tslFn = (...params) => { + // @deprecated, r168 + + console.warn('TSL.ShaderNode: tslFn() has been renamed to Fn().'); + return Fn(...params); +}; + +// + +addMethodChaining('toGlobal', node => { + node.global = true; + + return node; +}); + +// + +export const setCurrentStack = stack => { + if (currentStack === stack) { + //throw new Error( 'Stack already defined.' ); + } + + currentStack = stack; +}; + +export const getCurrentStack = () => currentStack; + +export const If = (...params) => currentStack.If(...params); + +export function append(node) { + if (currentStack) currentStack.add(node); + + return node; +} + +addMethodChaining('append', append); + +// types + +export const color = new ConvertType('color'); + +export const float = new ConvertType('float', cacheMaps.float); +export const int = new ConvertType('int', cacheMaps.ints); +export const uint = new ConvertType('uint', cacheMaps.uint); +export const bool = new ConvertType('bool', cacheMaps.bool); + +export const vec2 = new ConvertType('vec2'); +export const ivec2 = new ConvertType('ivec2'); +export const uvec2 = new ConvertType('uvec2'); +export const bvec2 = new ConvertType('bvec2'); + +export const vec3 = new ConvertType('vec3'); +export const ivec3 = new ConvertType('ivec3'); +export const uvec3 = new ConvertType('uvec3'); +export const bvec3 = new ConvertType('bvec3'); + +export const vec4 = new ConvertType('vec4'); +export const ivec4 = new ConvertType('ivec4'); +export const uvec4 = new ConvertType('uvec4'); +export const bvec4 = new ConvertType('bvec4'); + +export const mat2 = new ConvertType('mat2'); +export const mat3 = new ConvertType('mat3'); +export const mat4 = new ConvertType('mat4'); + +export const string = (value = '') => nodeObject(new ConstNode(value, 'string')); +export const arrayBuffer = value => nodeObject(new ConstNode(value, 'ArrayBuffer')); + +addMethodChaining('toColor', color); +addMethodChaining('toFloat', float); +addMethodChaining('toInt', int); +addMethodChaining('toUint', uint); +addMethodChaining('toBool', bool); +addMethodChaining('toVec2', vec2); +addMethodChaining('toIVec2', ivec2); +addMethodChaining('toUVec2', uvec2); +addMethodChaining('toBVec2', bvec2); +addMethodChaining('toVec3', vec3); +addMethodChaining('toIVec3', ivec3); +addMethodChaining('toUVec3', uvec3); +addMethodChaining('toBVec3', bvec3); +addMethodChaining('toVec4', vec4); +addMethodChaining('toIVec4', ivec4); +addMethodChaining('toUVec4', uvec4); +addMethodChaining('toBVec4', bvec4); +addMethodChaining('toMat2', mat2); +addMethodChaining('toMat3', mat3); +addMethodChaining('toMat4', mat4); + +// basic nodes + +export const element = /*@__PURE__*/ nodeProxy(ArrayElementNode); +export const convert = (node, types) => nodeObject(new ConvertNode(nodeObject(node), types)); +export const split = (node, channels) => nodeObject(new SplitNode(nodeObject(node), channels)); + +addMethodChaining('element', element); +addMethodChaining('convert', convert); diff --git a/src-testing/src/nodes/utils/ArrayElementNode.d.ts b/src-testing/src/nodes/utils/ArrayElementNode.d.ts new file mode 100644 index 000000000..650f04047 --- /dev/null +++ b/src-testing/src/nodes/utils/ArrayElementNode.d.ts @@ -0,0 +1,9 @@ +import Node from "../core/Node.js"; +import { TempNode } from "../Nodes.js"; + +export default class ArrayElementNode extends TempNode { + node: Node; + indexNode: Node; + + constructor(node: Node, indexNode: Node); +} diff --git a/src-testing/src/nodes/utils/ConvertNode.d.ts b/src-testing/src/nodes/utils/ConvertNode.d.ts new file mode 100644 index 000000000..7972df608 --- /dev/null +++ b/src-testing/src/nodes/utils/ConvertNode.d.ts @@ -0,0 +1,7 @@ +import Node from "../core/Node.js"; + +export default class ConvertNode extends Node { + node: Node; + convertTo: string; + constructor(node: Node, convertTo: string); +} diff --git a/src-testing/src/nodes/utils/CubeMapNode.d.ts b/src-testing/src/nodes/utils/CubeMapNode.d.ts new file mode 100644 index 000000000..6a5c47371 --- /dev/null +++ b/src-testing/src/nodes/utils/CubeMapNode.d.ts @@ -0,0 +1,13 @@ +import Node from "../core/Node.js"; +import TempNode from "../core/TempNode.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +declare class CubeMapNode extends TempNode { + envNode: Node; + + constructor(envNode: Node); +} + +export default CubeMapNode; + +export const cubeMapNode: (envNode: NodeRepresentation) => ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/Discard.d.ts b/src-testing/src/nodes/utils/Discard.d.ts new file mode 100644 index 000000000..819c009b1 --- /dev/null +++ b/src-testing/src/nodes/utils/Discard.d.ts @@ -0,0 +1,11 @@ +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +export const Discard: (conditional?: NodeRepresentation) => ShaderNodeObject; +export const Return: () => ShaderNodeObject; + +declare module "../tsl/TSLCore.js" { + interface NodeElements { + discard: typeof Discard; + } +} diff --git a/src-testing/src/nodes/utils/EquirectUVNode.d.ts b/src-testing/src/nodes/utils/EquirectUVNode.d.ts new file mode 100644 index 000000000..4e85dc40e --- /dev/null +++ b/src-testing/src/nodes/utils/EquirectUVNode.d.ts @@ -0,0 +1,8 @@ +import { Node, TempNode } from "../Nodes.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +export default class EquirectUVNode extends TempNode { + constructor(dirNode?: ShaderNodeObject); +} + +export const equirectUV: ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/FunctionOverloadingNode.d.ts b/src-testing/src/nodes/utils/FunctionOverloadingNode.d.ts new file mode 100644 index 000000000..d7c3febb4 --- /dev/null +++ b/src-testing/src/nodes/utils/FunctionOverloadingNode.d.ts @@ -0,0 +1,13 @@ +import Node from "../core/Node.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +declare class FunctionOverloadingNode extends Node { + functionNodes: Node[]; + parameterNodes: Node[]; + + constructor(functionNodes?: Node[], ...parameterNodes: Node[]); +} + +export default FunctionOverloadingNode; + +export const overloadingFn: (functionNodes: Node[]) => (...params: Node[]) => ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/JoinNode.d.ts b/src-testing/src/nodes/utils/JoinNode.d.ts new file mode 100644 index 000000000..7f456bafa --- /dev/null +++ b/src-testing/src/nodes/utils/JoinNode.d.ts @@ -0,0 +1,10 @@ +import Node from "../core/Node.js"; +import { TempNode } from "../Nodes.js"; + +/** + * This node constructs given type from elements, like vec3(a,b,c) + */ +export default class JoinNode extends TempNode { + nodes: Node[]; + constructor(nodes: Node[]); +} diff --git a/src-testing/src/nodes/utils/LoopNode.d.ts b/src-testing/src/nodes/utils/LoopNode.d.ts new file mode 100644 index 000000000..d59518588 --- /dev/null +++ b/src-testing/src/nodes/utils/LoopNode.d.ts @@ -0,0 +1,22 @@ +import Node from "../core/Node.js"; +import NodeBuilder from "../core/NodeBuilder.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +declare class LoopNode extends Node { + params: unknown[]; + + constructor(params?: unknown[]); + + getProperties(builder: NodeBuilder): unknown; +} + +export default LoopNode; + +export const Loop: (...params: unknown[]) => ShaderNodeObject; +export const Continue: () => ShaderNodeObject; +export const Break: () => ShaderNodeObject; + +/** + * @deprecated loop() has been renamed to Loop() + */ +export const loop: (...params: unknown[]) => ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/MatcapUVNode.d.ts b/src-testing/src/nodes/utils/MatcapUVNode.d.ts new file mode 100644 index 000000000..7f56667b3 --- /dev/null +++ b/src-testing/src/nodes/utils/MatcapUVNode.d.ts @@ -0,0 +1,8 @@ +import TempNode from "../core/TempNode.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +export default class MatcapUVNode extends TempNode { + constructor(); +} + +export const matcapUV: ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/MaxMipLevelNode.d.ts b/src-testing/src/nodes/utils/MaxMipLevelNode.d.ts new file mode 100644 index 000000000..455cb77a5 --- /dev/null +++ b/src-testing/src/nodes/utils/MaxMipLevelNode.d.ts @@ -0,0 +1,14 @@ +import { Texture } from "../../textures/Texture.js"; +import TextureNode from "../accessors/TextureNode.js"; +import UniformNode from "../core/UniformNode.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +export default class MaxMipLevelNode extends UniformNode<0> { + constructor(textureNode: TextureNode); + + get textureNode(): TextureNode; + + get texture(): Texture; +} + +export const maxMipLevel: (texture: Texture) => ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/Oscillators.d.ts b/src-testing/src/nodes/utils/Oscillators.d.ts new file mode 100644 index 000000000..b1a196d43 --- /dev/null +++ b/src-testing/src/nodes/utils/Oscillators.d.ts @@ -0,0 +1,7 @@ +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +export const oscSine: (timeNode?: NodeRepresentation) => ShaderNodeObject; +export const oscSquare: (timeNode?: NodeRepresentation) => ShaderNodeObject; +export const oscTriangle: (timeNode?: NodeRepresentation) => ShaderNodeObject; +export const oscSawtooth: (timeNode?: NodeRepresentation) => ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/Packing.d.ts b/src-testing/src/nodes/utils/Packing.d.ts new file mode 100644 index 000000000..61d0d039e --- /dev/null +++ b/src-testing/src/nodes/utils/Packing.d.ts @@ -0,0 +1,5 @@ +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +export const directionToColor: (node: NodeRepresentation) => ShaderNodeObject; +export const colorToDirection: (node: NodeRepresentation) => ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/PostProcessingUtils.d.ts b/src-testing/src/nodes/utils/PostProcessingUtils.d.ts new file mode 100644 index 000000000..0406e4d77 --- /dev/null +++ b/src-testing/src/nodes/utils/PostProcessingUtils.d.ts @@ -0,0 +1,45 @@ +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +/** + * Computes a position in view space based on a fragment's screen position expressed as uv coordinates, the fragments + * depth value and the camera's inverse projection matrix. + * + * @param {vec2} screenPosition - The fragment's screen position expressed as uv coordinates. + * @param {float} depth - The fragment's depth value. + * @param {mat4} projectionMatrixInverse - The camera's inverse projection matrix. + * @return {vec3} The fragments position in view space. + */ +export const getViewPosition: ( + screenPosition: NodeRepresentation, + depth: NodeRepresentation, + projectionMatrixInverse: NodeRepresentation, +) => ShaderNodeObject; + +/** + * Computes a screen position expressed as uv coordinates based on a fragment's position in view space and the camera's + * projection matrix + * + * @param {vec3} viewPosition - The fragments position in view space. + * @param {mat4} projectionMatrix - The camera's projection matrix. + * @return {vec2} The fragment's screen position expressed as uv coordinates. + */ +export const getScreenPosition: ( + viewPosition: NodeRepresentation, + projectionMatrix: NodeRepresentation, +) => ShaderNodeObject; + +/** + * Computes a normal vector based on depth data. Can be used as a fallback when no normal render target is available or + * if flat surface normals are required. + * + * @param {vec2} uv - The texture coordinate. + * @param {DepthTexture} depthTexture - The depth texture. + * @param {mat4} projectionMatrixInverse - The camera's inverse projection matrix. + * @return {vec3} The computed normal vector. + */ +export const getNormalFromDepth: ( + uv: NodeRepresentation, + depthTexture: NodeRepresentation, + projectionMatrixInverse: NodeRepresentation, +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/RTTNode.d.ts b/src-testing/src/nodes/utils/RTTNode.d.ts new file mode 100644 index 000000000..9f0d3e46e --- /dev/null +++ b/src-testing/src/nodes/utils/RTTNode.d.ts @@ -0,0 +1,45 @@ +import { TextureDataType } from "../../constants.js"; +import { RenderTarget } from "../../core/RenderTarget.js"; +import TextureNode from "../accessors/TextureNode.js"; +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +export interface RTTNodeOptions { + type: TextureDataType; +} + +declare class RTTNode extends TextureNode { + node: Node; + width: number | null; + height: number | null; + + renderTarget: RenderTarget | null; + + textureNeedsUpdate: boolean; + autoUpdate: boolean; + + pixelRatio?: number; + + constructor(node: Node, width?: number | null, height?: number | null, options?: RTTNodeOptions); + + get autoSize(): boolean; + + setSize(width: number | null, height: number | null): void; + + setPixelRatio(pixelRatio: number): void; +} + +export default RTTNode; + +export const rtt: ( + node: NodeRepresentation, + width?: number | null, + height?: number | null, + options?: RTTNodeOptions, +) => ShaderNodeObject; +export const convertToTexture: ( + node: Node, + width?: number | null, + height?: number | null, + options?: RTTNodeOptions, +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/ReflectorNode.d.ts b/src-testing/src/nodes/utils/ReflectorNode.d.ts new file mode 100644 index 000000000..54cd9abfc --- /dev/null +++ b/src-testing/src/nodes/utils/ReflectorNode.d.ts @@ -0,0 +1,45 @@ +import { Camera } from "../../cameras/Camera.js"; +import { Object3D } from "../../core/Object3D.js"; +import { RenderTarget } from "../../core/RenderTarget.js"; +import TextureNode from "../accessors/TextureNode.js"; +import Node from "../core/Node.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +export interface ReflectorNodeParameters { + target?: Object3D | undefined; + resolution?: number | undefined; + generateMipmaps?: boolean | undefined; + bounces?: boolean | undefined; +} + +declare class ReflectorNode extends TextureNode { + constructor(parameters?: ReflectorNodeParameters); + + get reflector(): ReflectorBaseNode; + + get target(): Object3D; + + getDepthNode(): ShaderNodeObject; +} + +declare class ReflectorBaseNode extends Node { + textureNode: TextureNode; + + target: Object3D; + resolution: number; + generateMipmaps: boolean; + bounces: boolean; + + virtualCameras: WeakMap; + renderTargets: WeakMap; + + constructor(textureNode: TextureNode, parameters?: ReflectorNodeParameters); + + getVirtualCamera(camera: Camera): Camera; + + getRenderTarget(camera: Camera): RenderTarget; +} + +export const reflector: (parameters?: ReflectorNodeParameters) => ShaderNodeObject; + +export default ReflectorNode; diff --git a/src-testing/src/nodes/utils/RemapNode.d.ts b/src-testing/src/nodes/utils/RemapNode.d.ts new file mode 100644 index 000000000..e50456d0a --- /dev/null +++ b/src-testing/src/nodes/utils/RemapNode.d.ts @@ -0,0 +1,36 @@ +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +export default class RemapNode extends Node { + node: Node; + inLowNode: Node; + inHighNode: Node; + outLowNode: Node; + outHighNode: Node; + + doClamp: boolean; + + constructor(node: Node, inLowNode: Node, inHighNode: Node, outLowNode?: Node, outHighNode?: Node); +} + +export const remap: ( + node: Node, + inLowNode: NodeRepresentation, + inHighNode: NodeRepresentation, + outLowNode?: NodeRepresentation, + outHighNode?: NodeRepresentation, +) => ShaderNodeObject; +export const remapClamp: ( + node: Node, + inLowNode: NodeRepresentation, + inHighNode: NodeRepresentation, + outLowNode?: NodeRepresentation, + outHighNode?: NodeRepresentation, +) => ShaderNodeObject; + +declare module "../tsl/TSLCore.js" { + interface NodeElements { + remap: typeof remap; + remapClamp: typeof remapClamp; + } +} diff --git a/src-testing/src/nodes/utils/RotateNode.d.ts b/src-testing/src/nodes/utils/RotateNode.d.ts new file mode 100644 index 000000000..8f6df796a --- /dev/null +++ b/src-testing/src/nodes/utils/RotateNode.d.ts @@ -0,0 +1,15 @@ +import Node from "../core/Node.js"; +import TempNode from "../core/TempNode.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +export default class RotateNode extends TempNode { + positionNode: Node; + rotationNode: Node; + + constructor(positionNode: Node, rotationNode: Node); +} + +export const rotate: ( + positionNode: NodeRepresentation, + rotationNode: NodeRepresentation, +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/SetNode.d.ts b/src-testing/src/nodes/utils/SetNode.d.ts new file mode 100644 index 000000000..7124d46c3 --- /dev/null +++ b/src-testing/src/nodes/utils/SetNode.d.ts @@ -0,0 +1,11 @@ +import TempNode from "../core/TempNode.js"; + +declare class SetNode extends TempNode { + sourceNode: Node; + components: string[]; + targetNode: Node; + + constructor(sourceNode: Node, components: string[], targetNode: Node); +} + +export default SetNode; diff --git a/src-testing/src/nodes/utils/SplitNode.d.ts b/src-testing/src/nodes/utils/SplitNode.d.ts new file mode 100644 index 000000000..f3aa50f41 --- /dev/null +++ b/src-testing/src/nodes/utils/SplitNode.d.ts @@ -0,0 +1,15 @@ +import Node from "../core/Node.js"; +import { SwizzleOption } from "../tsl/TSLCore.js"; + +/** swizzle node */ +export default class SplitNode extends Node { + node: Node; + components: string; + + /** + * @param node the input node + * @param components swizzle like string, default = "x" + */ + constructor(node: Node, components?: SwizzleOption); + getVectorLength(): number; +} diff --git a/src-testing/src/nodes/utils/SpriteSheetUVNode.d.ts b/src-testing/src/nodes/utils/SpriteSheetUVNode.d.ts new file mode 100644 index 000000000..9e191a390 --- /dev/null +++ b/src-testing/src/nodes/utils/SpriteSheetUVNode.d.ts @@ -0,0 +1,16 @@ +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +export default class SpriteSheetUVNode extends Node { + countNode: Node; + uvNode: Node; + frameNode: Node; + + constructor(countNode: Node, uvNode?: Node, frameNode?: Node); +} + +export const spritesheetUV: ( + countNode: NodeRepresentation, + uvNode?: NodeRepresentation, + frameNode?: NodeRepresentation, +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/SpriteUtils.d.ts b/src-testing/src/nodes/utils/SpriteUtils.d.ts new file mode 100644 index 000000000..85884df7b --- /dev/null +++ b/src-testing/src/nodes/utils/SpriteUtils.d.ts @@ -0,0 +1,6 @@ +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +export const billboarding: ( + args?: { position?: NodeRepresentation | null; horizontal?: boolean; vertical?: boolean }, +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/StorageArrayElementNode.d.ts b/src-testing/src/nodes/utils/StorageArrayElementNode.d.ts new file mode 100644 index 000000000..53ff9a79a --- /dev/null +++ b/src-testing/src/nodes/utils/StorageArrayElementNode.d.ts @@ -0,0 +1,19 @@ +import StorageBufferNode from "../accessors/StorageBufferNode.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; +import ArrayElementNode from "./ArrayElementNode.js"; + +export default class StorageArrayElementNode extends ArrayElementNode { + node: StorageBufferNode; + + readonly isStorageArrayElementNode: true; + + constructor(storageBufferNode: StorageBufferNode, indexNode: Node); + + get storageBufferNode(): StorageBufferNode; + set storageBufferNode(value: StorageBufferNode); +} + +export const storageElement: ( + storageBufferNode: NodeRepresentation, + indexNode: NodeRepresentation, +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/Timer.d.ts b/src-testing/src/nodes/utils/Timer.d.ts new file mode 100644 index 000000000..ffad3ed7f --- /dev/null +++ b/src-testing/src/nodes/utils/Timer.d.ts @@ -0,0 +1,21 @@ +import Node from "../core/Node.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +export const time: ShaderNodeObject; +export const deltaTime: ShaderNodeObject; +export const frameId: ShaderNodeObject; + +/** + * @deprecated Use "time" instead. + */ +export const timerLocal: (timeScale?: number) => ShaderNodeObject; + +/** + * @deprecated Use "time" instead. + */ +export const timerGlobal: (timeScale?: number) => ShaderNodeObject; + +/** + * @deprecated Use "deltaTime" instead. + */ +export const timerDelta: (timeScale?: number) => ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/TriplanarTexturesNode.d.ts b/src-testing/src/nodes/utils/TriplanarTexturesNode.d.ts new file mode 100644 index 000000000..1f2875c26 --- /dev/null +++ b/src-testing/src/nodes/utils/TriplanarTexturesNode.d.ts @@ -0,0 +1,36 @@ +import TextureNode from "../accessors/TextureNode.js"; +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +export default class TriplanarTexturesNode extends Node { + textureXNode: TextureNode; + textureYNode: TextureNode | null; + textureZNode: TextureNode | null; + + scaleNode: ShaderNodeObject; + + positionNode: ShaderNodeObject; + normalNode: ShaderNodeObject; + + constructor( + textureXNode: Node, + textureYNode?: TextureNode | null, + textureZNode?: TextureNode | null, + scaleNode?: ShaderNodeObject, + positionNode?: ShaderNodeObject, + normalNode?: ShaderNodeObject, + ); +} + +export const triplanarTextures: ( + textureXNode: NodeRepresentation, + textureYNode?: NodeRepresentation, + textureZNode?: NodeRepresentation, + scaleNode?: NodeRepresentation, + positionNode?: NodeRepresentation, + normalNode?: NodeRepresentation, +) => ShaderNodeObject; +export const triplanarTexture: ( + texture: NodeRepresentation, + ...params: NodeRepresentation[] +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/UVUtils.d.ts b/src-testing/src/nodes/utils/UVUtils.d.ts new file mode 100644 index 000000000..d375e1e11 --- /dev/null +++ b/src-testing/src/nodes/utils/UVUtils.d.ts @@ -0,0 +1,14 @@ +import OperatorNode from "../math/OperatorNode.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +export const rotateUV: ( + uv: NodeRepresentation, + rotation: NodeRepresentation, + center?: NodeRepresentation, +) => ShaderNodeObject; + +export const spherizeUV: ( + uv: NodeRepresentation, + strength: NodeRepresentation, + center?: NodeRepresentation, +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/ViewportUtils.d.ts b/src-testing/src/nodes/utils/ViewportUtils.d.ts new file mode 100644 index 000000000..e77e7f350 --- /dev/null +++ b/src-testing/src/nodes/utils/ViewportUtils.d.ts @@ -0,0 +1,4 @@ +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +export const viewportSafeUV: (uv?: NodeRepresentation | null) => ShaderNodeObject; diff --git a/src-testing/src/objects/BatchedMesh.d.ts b/src-testing/src/objects/BatchedMesh.d.ts new file mode 100644 index 000000000..84044f00b --- /dev/null +++ b/src-testing/src/objects/BatchedMesh.d.ts @@ -0,0 +1,275 @@ +import { Camera } from "../cameras/Camera.js"; +import { BufferGeometry } from "../core/BufferGeometry.js"; +import { Material } from "../materials/Material.js"; +import { Box3 } from "../math/Box3.js"; +import { Color } from "../math/Color.js"; +import { Matrix4 } from "../math/Matrix4.js"; +import { Sphere } from "../math/Sphere.js"; +import { Mesh } from "./Mesh.js"; + +export interface BatchedMeshGeometryRange { + vertexStart: number; + vertexCount: number; + reservedVertexCount: number; + indexStart: number; + indexCount: number; + reservedIndexCount: number; + start: number; + count: number; +} + +/** + * A special version of {@link Mesh} with multi draw batch rendering support. Use {@link BatchedMesh} if you have to + * render a large number of objects with the same material but with different world transformations. The usage of + * {@link BatchedMesh} will help you to reduce the number of draw calls and thus improve the overall rendering + * performance in your application. + * + * If the {@link https://developer.mozilla.org/en-US/docs/Web/API/WEBGL_multi_draw WEBGL_multi_draw extension} is not + * supported then a less performant fallback is used. + * + * @example + * const box = new THREE.BoxGeometry( 1, 1, 1 ); + * const sphere = new THREE.SphereGeometry( 1, 12, 12 ); + * const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } ); + * + * // initialize and add geometries into the batched mesh + * const batchedMesh = new BatchedMesh( 10, 5000, 10000, material ); + * const boxGeometryId = batchedMesh.addGeometry( box ); + * const sphereGeometryId = batchedMesh.addGeometry( sphere ); + * + * // create instances of those geometries + * const boxInstancedId1 = batchedMesh.addInstance( boxGeometryId ); + * const boxInstancedId2 = batchedMesh.addInstance( boxGeometryId ); + * + * const sphereInstancedId1 = batchedMesh.addInstance( sphereGeometryId ); + * const sphereInstancedId2 = batchedMesh.addInstance( sphereGeometryId ); + * + * // position the geometries + * batchedMesh.setMatrixAt( boxInstancedId1, boxMatrix1 ); + * batchedMesh.setMatrixAt( boxInstancedId2, boxMatrix2 ); + * + * batchedMesh.setMatrixAt( sphereInstancedId1, sphereMatrix1 ); + * batchedMesh.setMatrixAt( sphereInstancedId2, sphereMatrix2 ); + * + * scene.add( batchedMesh ); + * + * @also Example: {@link https://threejs.org/examples/#webgl_mesh_batch WebGL / mesh / batch} + */ +declare class BatchedMesh extends Mesh { + /** + * This bounding box encloses all instances of the {@link BatchedMesh}. Can be calculated with + * {@link .computeBoundingBox()}. + * @default null + */ + boundingBox: Box3 | null; + + /** + * This bounding sphere encloses all instances of the {@link BatchedMesh}. Can be calculated with + * {@link .computeBoundingSphere()}. + * @default null + */ + boundingSphere: Sphere | null; + + customSort: ((this: this, list: Array<{ start: number; count: number; z: number }>, camera: Camera) => void) | null; + + /** + * If true then the individual objects within the {@link BatchedMesh} are frustum culled. + * @default true + */ + perObjectFrustumCulled: boolean; + + /** + * If true then the individual objects within the {@link BatchedMesh} are sorted to improve overdraw-related + * artifacts. If the material is marked as "transparent" objects are rendered back to front and if not then they are + * rendered front to back. + * @default true + */ + sortObjects: boolean; + + /** + * The maximum number of individual geometries that can be stored in the {@link BatchedMesh}. Read only. + */ + get maxInstanceCount(): number; + + get instanceCount(): number; + + get unusedVertexCount(): number; + + get unusedIndexCount(): number; + + /** + * Read-only flag to check if a given object is of type {@link BatchedMesh}. + */ + readonly isBatchedMesh: true; + + /** + * @param maxInstanceCount the max number of individual geometries planned to be added. + * @param maxVertexCount the max number of vertices to be used by all geometries. + * @param maxIndexCount the max number of indices to be used by all geometries. + * @param material an instance of {@link Material}. Default is a new {@link MeshBasicMaterial}. + */ + constructor(maxInstanceCount: number, maxVertexCount: number, maxIndexCount?: number, material?: Material); + + /** + * Computes the bounding box, updating {@link .boundingBox} attribute. + * Bounding boxes aren't computed by default. They need to be explicitly computed, otherwise they are `null`. + */ + computeBoundingBox(): void; + + /** + * Computes the bounding sphere, updating {@link .boundingSphere} attribute. + * Bounding spheres aren't computed by default. They need to be explicitly computed, otherwise they are `null`. + */ + computeBoundingSphere(): void; + + /** + * Frees the GPU-related resources allocated by this instance. Call this method whenever this instance is no longer + * used in your app. + */ + dispose(): this; + + /** + * Takes a sort a function that is run before render. The function takes a list of instances to sort and a camera. + * The objects in the list include a "z" field to perform a depth-ordered sort with. + */ + setCustomSort( + sortFunction: + | ((this: this, list: Array<{ start: number; count: number; z: number }>, camera: Camera) => void) + | null, + ): this; + + /** + * Get the color of the defined geometry. + * @param instanceId The id of an instance to get the color of. + * @param target The target object to copy the color in to. + */ + getColorAt(instanceId: number, target: Color): void; + + /** + * Get the local transformation matrix of the defined instance. + * @param instanceId The id of an instance to get the matrix of. + * @param target This 4x4 matrix will be set to the local transformation matrix of the defined instance. + */ + getMatrixAt(instanceId: number, target: Matrix4): Matrix4; + + /** + * Get whether the given instance is marked as "visible" or not. + * @param instanceId The id of an instance to get the visibility state of. + */ + getVisibleAt(instanceId: number): boolean; + + /** + * Get the range representing the subset of triangles related to the attached geometry, indicating the starting + * offset and count, or `null` if invalid. + * + * Return an object of the form: { start: Integer, count: Integer } + * @param geometryId The id of the geometry to get the range of. + * @param target Optional target object to copy the range in to. + */ + getGeometryRangeAt( + geometryId: number, + target?: BatchedMeshGeometryRange, + ): BatchedMeshGeometryRange | null; + + /** + * Get the geometryIndex of the defined instance. + * @param instanceId The id of an instance to get the geometryIndex of. + */ + getGeometryIdAt(instanceId: number): number; + + /** + * Sets the given color to the defined geometry instance. + * @param instanceId The id of the instance to set the color of. + * @param color The color to set the instance to. + */ + setColorAt(instanceId: number, color: Color): void; + + /** + * Sets the given local transformation matrix to the defined instance. + * @param instanceId The id of an instance to set the matrix of. + * @param matrix A 4x4 matrix representing the local transformation of a single instance. + */ + setMatrixAt(instanceId: number, matrix: Matrix4): this; + + /** + * Sets the visibility of the instance at the given index. + * @param instanceId The id of the instance to set the visibility of. + * @param visible A boolean value indicating the visibility state. + */ + setVisibleAt(instanceId: number, visible: boolean): this; + + /** + * Sets the geometryIndex of the instance at the given index. + * @param instanceId The id of the instance to set the geometryIndex of. + * @param geometryId The geometryIndex to be use by the instance. + */ + setGeometryIdAt(instanceId: number, geometryId: number): this; + + /** + * Adds the given geometry to the {@link BatchedMesh} and returns the associated index referring to it. + * @param geometry The geometry to add into the {@link BatchedMesh}. + * @param reservedVertexRange Optional parameter specifying the amount of vertex buffer space to reserve for the + * added geometry. This is necessary if it is planned to set a new geometry at this index at a later time that is + * larger than the original geometry. Defaults to the length of the given geometry vertex buffer. + * @param reservedIndexRange Optional parameter specifying the amount of index buffer space to reserve for the added + * geometry. This is necessary if it is planned to set a new geometry at this index at a later time that is larger + * than the original geometry. Defaults to the length of the given geometry index buffer. + */ + addGeometry(geometry: BufferGeometry, reservedVertexRange?: number, reservedIndexRange?: number): number; + + /** + * Adds a new instance to the {@link BatchedMesh} using the geometry of the given geometryId and returns a new id + * referring to the new instance to be used by other functions. + * @param geometryId The id of a previously added geometry via "addGeometry" to add into the {@link BatchedMesh} to + * render. + */ + addInstance(geometryId: number): number; + + /** + * @param geometryId The id of a geometry to remove from the [name] that was previously added via "addGeometry". Any + * instances referencing this geometry will also be removed as a side effect. + */ + deleteGeometry(geometryId: number): this; + + /** + * Removes an existing instance from the BatchedMesh using the given instanceId. + * @param instanceId The id of an instance to remove from the BatchedMesh that was previously added via + * "addInstance". + */ + deleteInstance(instanceId: number): this; + + /** + * Replaces the geometry at `geometryId` with the provided geometry. Throws an error if there is not enough space + * reserved for geometry. Calling this will change all instances that are rendering that geometry. + * @param geometryId Which geometry id to replace with this geometry. + * @param geometry The geometry to substitute at the given geometry id. + */ + setGeometryAt(geometryId: number, geometry: BufferGeometry): number; + + /** + * Repacks the sub geometries in [name] to remove any unused space remaining from previously deleted geometry, + * freeing up space to add new geometry. + */ + optimize(): this; + + /** + * Resizes the available space in BatchedMesh's vertex and index buffer attributes to the provided sizes. If the + * provided arguments shrink the geometry buffers but there is not enough unused space at the end of the geometry + * attributes then an error is thrown. + * @param maxVertexCount the max number of vertices to be used by all unique geometries to resize to. + * @param maxIndexCount the max number of indices to be used by all unique geometries to resize to. + */ + setGeometrySize(maxVertexCount: number, maxIndexCount: number): void; + + /** + * Resizes the necessary buffers to support the provided number of instances. If the provided arguments shrink the + * number of instances but there are not enough unused ids at the end of the list then an error is thrown. + * @param maxInstanceCount the max number of individual instances that can be added and rendered by the BatchedMesh. + */ + setInstanceCount(maxInstanceCount: number): void; + + getBoundingBoxAt(geometryId: number, target: Box3): Box3 | null; + getBoundingSphereAt(geometryId: number, target: Sphere): Sphere | null; +} + +export { BatchedMesh }; diff --git a/src-testing/src/objects/Bone.d.ts b/src-testing/src/objects/Bone.d.ts new file mode 100644 index 000000000..3400ea1b6 --- /dev/null +++ b/src-testing/src/objects/Bone.d.ts @@ -0,0 +1,36 @@ +import { Object3D, Object3DEventMap } from "../core/Object3D.js"; + +/** + * A {@link Bone} which is part of a {@link THREE.Skeleton | Skeleton} + * @remarks + * The skeleton in turn is used by the {@link THREE.SkinnedMesh | SkinnedMesh} + * Bones are almost identical to a blank {@link THREE.Object3D | Object3D}. + * @example + * ```typescript + * const root = new THREE.Bone(); + * const child = new THREE.Bone(); + * root.add(child); + * child.position.y = 5; + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/objects/Bone | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/objects/Bone.js | Source} + */ +export class Bone extends Object3D { + /** + * Creates a new {@link Bone}. + */ + constructor(); + + /** + * Read-only flag to check if a given object is of type {@link Bone}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isBone: true; + + /** + * @override + * @defaultValue `Bone` + */ + override readonly type: string | "Bone"; +} diff --git a/src-testing/src/objects/Group.d.ts b/src-testing/src/objects/Group.d.ts new file mode 100644 index 000000000..4b882d2e9 --- /dev/null +++ b/src-testing/src/objects/Group.d.ts @@ -0,0 +1,37 @@ +import { Object3D, Object3DEventMap } from "../core/Object3D.js"; + +/** + * Its purpose is to make working with groups of objects syntactically clearer. + * @remarks This is almost identical to an {@link Object3D | Object3D} + * @example + * ```typescript + * const geometry = new THREE.BoxGeometry(1, 1, 1); + * const material = new THREE.MeshBasicMaterial({ + * color: 0x00ff00 + * }); + * const cubeA = new THREE.Mesh(geometry, material); + * cubeA.position.set(100, 100, 0); + * const cubeB = new THREE.Mesh(geometry, material); + * cubeB.position.set(-100, -100, 0); + * //create a {@link Group} and add the two cubes + * //These cubes can now be rotated / scaled etc as a {@link Group} * const {@link Group} = new THREE.Group(); + * group.add(cubeA); + * group.add(cubeB); + * scene.add(group); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/objects/Group | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/objects/Group.js | Source} + */ +export class Group extends Object3D { + /** + * Creates a new {@link Group}. + */ + constructor(); + + /** + * Read-only flag to check if a given object is of type {@link Group}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isGroup: true; +} diff --git a/src-testing/src/objects/InstancedMesh.d.ts b/src-testing/src/objects/InstancedMesh.d.ts new file mode 100644 index 000000000..b239afb7a --- /dev/null +++ b/src-testing/src/objects/InstancedMesh.d.ts @@ -0,0 +1,179 @@ +import { BufferAttributeJSON } from "./../core/BufferAttribute.js"; +import { BufferGeometry } from "../core/BufferGeometry.js"; +import { InstancedBufferAttribute } from "../core/InstancedBufferAttribute.js"; +import { JSONMeta, Object3DEventMap } from "../core/Object3D.js"; +import { Material } from "../materials/Material.js"; +import { Box3 } from "../math/Box3.js"; +import { Color } from "../math/Color.js"; +import { Matrix4 } from "../math/Matrix4.js"; +import { Sphere } from "../math/Sphere.js"; +import { DataTexture } from "../textures/DataTexture.js"; +import { Mesh, MeshJSONObject } from "./Mesh.js"; + +export interface InstancedMeshJSONObject extends MeshJSONObject { + count: number; + instanceMatrix: BufferAttributeJSON; + instanceColor?: BufferAttributeJSON; +} + +export interface InstancedMeshJSON extends MeshJSONObject { + object: InstancedMeshJSONObject; +} + +export interface InstancedMeshEventMap extends Object3DEventMap { + dispose: {}; +} + +/** + * A special version of {@link THREE.Mesh | Mesh} with instanced rendering support + * @remarks + * Use {@link InstancedMesh} if you have to render a large number of objects with the same geometry and material(s) but with different world transformations + * @remarks + * The usage of {@link InstancedMesh} will help you to reduce the number of draw calls and thus improve the overall rendering performance in your application. + * @see Example: {@link https://threejs.org/examples/#webgl_instancing_dynamic | WebGL / instancing / dynamic} + * @see Example: {@link https://threejs.org/examples/#webgl_instancing_performance | WebGL / instancing / performance} + * @see Example: {@link https://threejs.org/examples/#webgl_instancing_scatter | WebGL / instancing / scatter} + * @see Example: {@link https://threejs.org/examples/#webgl_instancing_raycast | WebGL / instancing / raycast} + * @see {@link https://threejs.org/docs/index.html#api/en/objects/InstancedMesh | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/objects/InstancedMesh.js | Source} + */ +export class InstancedMesh< + TGeometry extends BufferGeometry = BufferGeometry, + TMaterial extends Material | Material[] = Material | Material[], + TEventMap extends InstancedMeshEventMap = InstancedMeshEventMap, +> extends Mesh { + /** + * Create a new instance of {@link InstancedMesh} + * @param geometry An instance of {@link BufferGeometry}. + * @param material A single or an array of {@link Material}. Default is a new {@link MeshBasicMaterial}. + * @param count The **maximum** number of instances of this Mesh. Expects a `Integer` + */ + constructor(geometry: TGeometry | undefined, material: TMaterial | undefined, count: number); + + /** + * Read-only flag to check if a given object is of type {@link InstancedMesh}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isInstancedMesh: true; + + /** + * This bounding box encloses all instances of the {@link InstancedMesh},, which can be calculated with {@link computeBoundingBox | .computeBoundingBox()}. + * @remarks Bounding boxes aren't computed by default. They need to be explicitly computed, otherwise they are `null`. + * @defaultValue `null` + */ + boundingBox: Box3 | null; + + /** + * This bounding sphere encloses all instances of the {@link InstancedMesh}, which can be calculated with {@link computeBoundingSphere | .computeBoundingSphere()}. + * @remarks bounding spheres aren't computed by default. They need to be explicitly computed, otherwise they are `null`. + * @defaultValue `null` + */ + boundingSphere: Sphere | null; + + /** + * The number of instances. + * @remarks + * The `count` value passed into the {@link InstancedMesh | constructor} represents the **maximum** number of instances of this mesh. + * You can change the number of instances at runtime to an integer value in the range `[0, count]`. + * @remarks If you need more instances than the original `count` value, you have to create a new InstancedMesh. + * @remarks Expects a `Integer` + */ + count: number; + + /** + * Represents the colors of all instances. + * You have to set {@link InstancedBufferAttribute.needsUpdate | .instanceColor.needsUpdate()} flag to `true` if you modify instanced data via {@link setColorAt | .setColorAt()}. + * @defaultValue `null` + */ + instanceColor: InstancedBufferAttribute | null; + + /** + * Represents the local transformation of all instances. + * You have to set {@link InstancedBufferAttribute.needsUpdate | .instanceMatrix.needsUpdate()} flag to `true` if you modify instanced data via {@link setMatrixAt | .setMatrixAt()}. + */ + instanceMatrix: InstancedBufferAttribute; + + /** + * Represents the morph target weights of all instances. You have to set its {@link .needsUpdate} flag to true if + * you modify instanced data via {@link .setMorphAt}. + */ + morphTexture: DataTexture | null; + + /** + * Computes the bounding box of the instanced mesh, and updates the {@link .boundingBox} attribute. The bounding box + * is not computed by the engine; it must be computed by your app. You may need to recompute the bounding box if an + * instance is transformed via {@link .setMatrixAt()}. + */ + computeBoundingBox(): void; + + /** + * Computes the bounding sphere of the instanced mesh, and updates the {@link .boundingSphere} attribute. The engine + * automatically computes the bounding sphere when it is needed, e.g., for ray casting or view frustum culling. You + * may need to recompute the bounding sphere if an instance is transformed via [page:.setMatrixAt](). + */ + computeBoundingSphere(): void; + + /** + * Get the color of the defined instance. + * @param index The index of an instance. Values have to be in the range `[0, count]`. Expects a `Integer` + * @param color This color object will be set to the color of the defined instance. + */ + getColorAt(index: number, color: Color): void; + + /** + * Sets the given color to the defined instance + * @remarks + * Make sure you set {@link InstancedBufferAttribute.needsUpdate | .instanceColor.needsUpdate()} to `true` after updating all the colors. + * @param index The index of an instance. Values have to be in the range `[0, count]`. Expects a `Integer` + * @param color The color of a single instance. + */ + setColorAt(index: number, color: Color): void; + + /** + * Get the local transformation matrix of the defined instance. + * @param index The index of an instance Values have to be in the range `[0, count]`. Expects a `Integer` + * @param matrix This 4x4 matrix will be set to the local transformation matrix of the defined instance. + */ + getMatrixAt(index: number, matrix: Matrix4): void; + + /** + * Get the morph target weights of the defined instance. + * @param index The index of an instance. Values have to be in the range [0, count]. + * @param mesh The {@link .morphTargetInfluences} property of this mesh will be filled with the morph target weights of the defined instance. + */ + getMorphAt(index: number, mesh: Mesh): void; + + /** + * Sets the given local transformation matrix to the defined instance. + * @remarks + * Make sure you set {@link InstancedBufferAttribute.needsUpdate | .instanceMatrix.needsUpdate()} flag to `true` after updating all the matrices. + * @param index The index of an instance. Values have to be in the range `[0, count]`. Expects a `Integer` + * @param matrix A 4x4 matrix representing the local transformation of a single instance. + */ + setMatrixAt(index: number, matrix: Matrix4): void; + + /** + * Sets the morph target weights to the defined instance. Make sure you set {@link .morphTexture}{@link .needsUpdate} + * to true after updating all the influences. + * @param index The index of an instance. Values have to be in the range [0, count]. + * @param mesh A mesh with {@link .morphTargetInfluences} property containing the morph target weights of a single instance. + */ + setMorphAt(index: number, mesh: Mesh): void; + + /** + * No effect in {@link InstancedMesh}. + * @ignore + * @hidden + */ + override updateMorphTargets(): void; + + /** + * Frees the GPU-related resources allocated by this instance + * @remarks + * Call this method whenever this instance is no longer used in your app. + */ + dispose(): this; + + toJSON(meta?: JSONMeta): InstancedMeshJSON; +} diff --git a/src-testing/src/objects/LOD.d.ts b/src-testing/src/objects/LOD.d.ts new file mode 100644 index 000000000..2440b8503 --- /dev/null +++ b/src-testing/src/objects/LOD.d.ts @@ -0,0 +1,111 @@ +import { Camera } from "../cameras/Camera.js"; +import { JSONMeta, Object3D, Object3DEventMap, Object3DJSON, Object3DJSONObject } from "../core/Object3D.js"; + +export interface LODJSONObject extends Object3DJSONObject { + autoUpdate?: boolean; + + levels: Array<{ + object: string; + distance: number; + hysteresis: number; + }>; +} + +export interface LODJSON extends Object3DJSON { + object: LODJSONObject; +} + +/** + * Every level is associated with an object, and rendering can be switched between them at the distances specified + * @remarks + * Typically you would create, say, three meshes, one for far away (low detail), one for mid range (medium detail) and one for close up (high detail). + * @example + * ```typescript + * const {@link LOD} = new THREE.LOD(); + * //Create spheres with 3 levels of detail and create new {@link LOD} levels for them + * for (let i = 0; i & lt; 3; i++) { + * const geometry = new THREE.IcosahedronGeometry(10, 3 - i) + * const mesh = new THREE.Mesh(geometry, material); + * lod.addLevel(mesh, i * 75); + * } + * scene.add(lod); + * ``` + * @see Example: {@link https://threejs.org/examples/#webgl_lod | webgl / {@link LOD} } + * @see {@link https://threejs.org/docs/index.html#api/en/objects/LOD | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/objects/LOD.js | Source} + */ +export class LOD extends Object3D { + /** + * Creates a new {@link LOD}. + */ + constructor(); + + /** + * Read-only flag to check if a given object is of type {@link LOD}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isLOD: true; + + /** + * @override + * @defaultValue `LOD` + */ + override readonly type: string | "LOD"; + + /** + * An array of level objects + */ + levels: Array<{ + /** The Object3D to display at this level. */ + object: Object3D; + /** The distance at which to display this level of detail. Expects a `Float`. */ + distance: number; + /** Threshold used to avoid flickering at LOD boundaries, as a fraction of distance. Expects a `Float`. */ + hysteresis: number; + }>; + + /** + * Whether the {@link LOD} object is updated automatically by the renderer per frame or not. + * If set to `false`, you have to call {@link update | .update()} in the render loop by yourself. + * @defaultValue `true` + */ + autoUpdate: boolean; + + /** + * Adds a mesh that will display at a certain distance and greater. Typically the further away the distance, the lower the detail on the mesh. + * + * @param object The Object3D to display at this level. + * @param distance The distance at which to display this level of detail. Expects a `Float`. Default `0.0`. + * @param hysteresis Threshold used to avoid flickering at LOD boundaries, as a fraction of distance. Expects a `Float`. Default `0.0`. + */ + addLevel(object: Object3D, distance?: number, hysteresis?: number): this; + + /** + * Removes an existing level, based on the distance from the camera. Returns `true` when the level has been removed. + * Otherwise `false`. + * @param distance Distance of the level to delete. + */ + removeLabel(distance: number): boolean; + + /** + * Get the currently active {@link LOD} level + * @remarks + * As index of the levels array. + */ + getCurrentLevel(): number; + + /** + * Get a reference to the first {@link THREE.Object3D | Object3D} (mesh) that is greater than {@link distance}. + * @param distance Expects a `Float` + */ + getObjectForDistance(distance: number): Object3D | null; + + /** + * Set the visibility of each {@link levels | level}'s {@link THREE.Object3D | object} based on distance from the {@link THREE.Camera | camera}. + * @param camera + */ + update(camera: Camera): void; + + toJSON(meta?: JSONMeta): LODJSON; +} diff --git a/src-testing/src/objects/Line.d.ts b/src-testing/src/objects/Line.d.ts new file mode 100644 index 000000000..2d76dec69 --- /dev/null +++ b/src-testing/src/objects/Line.d.ts @@ -0,0 +1,87 @@ +import { BufferGeometry } from "../core/BufferGeometry.js"; +import { Object3D, Object3DEventMap } from "../core/Object3D.js"; +import { Material } from "../materials/Material.js"; + +/** + * A continuous line. + * @remarks + * This is nearly the same as {@link THREE.LineSegments | LineSegments}, + * the only difference is that it is rendered using {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/drawElements | gl.LINE_STRIP} + * instead of {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/drawElements | gl.LINES} + * @example + * ```typescript + * const material = new THREE.LineBasicMaterial({ + * color: 0x0000ff + * }); + * const points = []; + * points.push(new THREE.Vector3(-10, 0, 0)); + * points.push(new THREE.Vector3(0, 10, 0)); + * points.push(new THREE.Vector3(10, 0, 0)); + * const geometry = new THREE.BufferGeometry().setFromPoints(points); + * const {@link Line} = new THREE.Line(geometry, material); + * scene.add(line); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/objects/Line | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/objects/Line.js | Source} + */ +export class Line< + TGeometry extends BufferGeometry = BufferGeometry, + TMaterial extends Material | Material[] = Material | Material[], + TEventMap extends Object3DEventMap = Object3DEventMap, +> extends Object3D { + /** + * Create a new instance of {@link Line} + * @param geometry Vertices representing the {@link Line} segment(s). Default {@link THREE.BufferGeometry | `new THREE.BufferGeometry()`}. + * @param material Material for the line. Default {@link THREE.LineBasicMaterial | `new THREE.LineBasicMaterial()`}. + */ + constructor(geometry?: TGeometry, material?: TMaterial); + + /** + * Read-only flag to check if a given object is of type {@link Line}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isLine: true; + + /** + * @override + * @defaultValue `Line` + */ + override readonly type: string | "Line"; + + /** + * Vertices representing the {@link Line} segment(s). + */ + geometry: TGeometry; + + /** + * Material for the line. + */ + material: TMaterial; + + /** + * An array of weights typically from `0-1` that specify how much of the morph is applied. + * @defaultValue `undefined`, but reset to a blank array by {@link updateMorphTargets | .updateMorphTargets()}. + */ + morphTargetInfluences?: number[] | undefined; + + /** + * A dictionary of morphTargets based on the `morphTarget.name` property. + * @defaultValue `undefined`, but reset to a blank array by {@link updateMorphTargets | .updateMorphTargets()}. + */ + morphTargetDictionary?: { [key: string]: number } | undefined; + + /** + * Computes an array of distance values which are necessary for {@link THREE.LineDashedMaterial | LineDashedMaterial} + * @remarks + * For each vertex in the geometry, the method calculates the cumulative length from the current point to the very beginning of the line. + */ + computeLineDistances(): this; + + /** + * Updates the morphTargets to have no influence on the object + * @remarks + * Resets the {@link morphTargetInfluences | .morphTargetInfluences} and {@link morphTargetDictionary | .morphTargetDictionary} properties. + */ + updateMorphTargets(): void; +} diff --git a/src-testing/src/objects/LineLoop.d.ts b/src-testing/src/objects/LineLoop.d.ts new file mode 100644 index 000000000..0a070a838 --- /dev/null +++ b/src-testing/src/objects/LineLoop.d.ts @@ -0,0 +1,40 @@ +import { BufferGeometry } from "../core/BufferGeometry.js"; +import { Object3DEventMap } from "../core/Object3D.js"; +import { Material } from "../materials/Material.js"; +import { Line } from "./Line.js"; + +/** + * A continuous line that connects back to the start. + * @remarks + * This is nearly the same as {@link THREE.Line | Line}, + * the only difference is that it is rendered using {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/drawElements | gl.LINE_LOOP} + * instead of {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/drawElements | gl.LINE_STRIP}, + * which draws a straight line to the next vertex, and connects the last vertex back to the first. + * @see {@link https://threejs.org/docs/index.html#api/en/objects/LineLoop | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/objects/LineLoop.js | Source} + */ +export class LineLoop< + TGeometry extends BufferGeometry = BufferGeometry, + TMaterial extends Material | Material[] = Material | Material[], + TEventMap extends Object3DEventMap = Object3DEventMap, +> extends Line { + /** + * Create a new instance of {@link LineLoop} + * @param geometry List of vertices representing points on the line loop. Default {@link THREE.BufferGeometry | `new THREE.BufferGeometry()`}. + * @param material Material for the line. Default {@link THREE.LineBasicMaterial | `new THREE.LineBasicMaterial()`}. + */ + constructor(geometry?: TGeometry, material?: TMaterial); + + /** + * Read-only flag to check if a given object is of type {@link LineLoop}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isLineLoop: true; + + /** + * @override + * @defaultValue `LineLoop` + */ + override readonly type: string | "LineLoop"; +} diff --git a/src-testing/src/objects/LineSegments.d.ts b/src-testing/src/objects/LineSegments.d.ts new file mode 100644 index 000000000..9a8199bdc --- /dev/null +++ b/src-testing/src/objects/LineSegments.d.ts @@ -0,0 +1,41 @@ +import { BufferGeometry } from "../core/BufferGeometry.js"; +import { Object3DEventMap } from "../core/Object3D.js"; +import { Material } from "../materials/Material.js"; +import { Line } from "./Line.js"; + +/** + * A series of lines drawn between pairs of vertices. + * @remarks + * This is nearly the same as {@link THREE.Line | Line}, + * the only difference is that it is rendered using {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/drawElements | gl.LINES} + * instead of {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/drawElements | gl.LINE_STRIP}. + * @see {@link https://threejs.org/docs/index.html#api/en/objects/LineSegments | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/objects/LineSegments.js | Source} + */ +export class LineSegments< + TGeometry extends BufferGeometry = BufferGeometry, + TMaterial extends Material | Material[] = Material | Material[], + TEventMap extends Object3DEventMap = Object3DEventMap, +> extends Line { + /** + * Create a new instance of {@link LineSegments} + * @param geometry Pair(s) of vertices representing each line segment(s). Default {@link THREE.BufferGeometry | `new THREE.BufferGeometry()`}. + * @param material Material for the line. Default {@link THREE.LineBasicMaterial | `new THREE.LineBasicMaterial()`}. + */ + constructor(geometry?: TGeometry, material?: TMaterial); + + /** + * Read-only flag to check if a given object is of type {@link LineSegments}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isLineSegments: true; + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @override + * @defaultValue `LineSegments` + */ + override readonly type: string | "LineSegments"; +} diff --git a/src-testing/src/objects/Mesh.d.ts b/src-testing/src/objects/Mesh.d.ts new file mode 100644 index 000000000..38dad1c73 --- /dev/null +++ b/src-testing/src/objects/Mesh.d.ts @@ -0,0 +1,94 @@ +import { BufferGeometry } from "../core/BufferGeometry.js"; +import { JSONMeta, Object3D, Object3DEventMap, Object3DJSON, Object3DJSONObject } from "../core/Object3D.js"; +import { Material } from "../materials/Material.js"; +import { Vector3 } from "../math/Vector3.js"; + +export interface MeshJSONObject extends Object3DJSONObject { + geometry: string; +} + +export interface MeshJSON extends Object3DJSON { + object: MeshJSONObject; +} + +/** + * Class representing triangular {@link https://en.wikipedia.org/wiki/Polygon_mesh | polygon mesh} based objects. + * @remarks + * Also serves as a base for other classes such as {@link THREE.SkinnedMesh | SkinnedMesh}, {@link THREE.InstancedMesh | InstancedMesh}. + * @example + * ```typescript + * const geometry = new THREE.BoxGeometry(1, 1, 1); + * const material = new THREE.MeshBasicMaterial({ + * color: 0xffff00 + * }); + * const {@link Mesh} = new THREE.Mesh(geometry, material); + * scene.add(mesh); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/objects/Mesh | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/objects/Mesh.js | Source} + */ +export class Mesh< + TGeometry extends BufferGeometry = BufferGeometry, + TMaterial extends Material | Material[] = Material | Material[], + TEventMap extends Object3DEventMap = Object3DEventMap, +> extends Object3D { + /** + * Create a new instance of {@link Mesh} + * @param geometry An instance of {@link THREE.BufferGeometry | BufferGeometry}. Default {@link THREE.BufferGeometry | `new THREE.BufferGeometry()`}. + * @param material A single or an array of {@link THREE.Material | Material}. Default {@link THREE.MeshBasicMaterial | `new THREE.MeshBasicMaterial()`}. + */ + constructor(geometry?: TGeometry, material?: TMaterial); + + /** + * Read-only flag to check if a given object is of type {@link Mesh}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isMesh: true; + + /** + * @override + * @defaultValue `Mesh` + */ + override readonly type: string | "Mesh"; + + /** + * An instance of {@link THREE.BufferGeometry | BufferGeometry} (or derived classes), defining the object's structure. + * @defaultValue {@link THREE.BufferGeometry | `new THREE.BufferGeometry()`}. + */ + geometry: TGeometry; + + /** + * An instance of material derived from the {@link THREE.Material | Material} base class or an array of materials, defining the object's appearance. + * @defaultValue {@link THREE.MeshBasicMaterial | `new THREE.MeshBasicMaterial()`}. + */ + material: TMaterial; + + /** + * An array of weights typically from `0-1` that specify how much of the morph is applied. + * @defaultValue `undefined`, _but reset to a blank array by {@link updateMorphTargets | .updateMorphTargets()}._ + */ + morphTargetInfluences?: number[] | undefined; + + /** + * A dictionary of morphTargets based on the `morphTarget.name` property. + * @defaultValue `undefined`, _but rebuilt by {@link updateMorphTargets | .updateMorphTargets()}._ + */ + morphTargetDictionary?: { [key: string]: number } | undefined; + + /** + * Updates the morphTargets to have no influence on the object + * @remarks Resets the {@link morphTargetInfluences} and {@link morphTargetDictionary} properties. + */ + updateMorphTargets(): void; + + /** + * Get the local-space position of the vertex at the given index, + * taking into account the current animation state of both morph targets and skinning. + * @param index Expects a `Integer` + * @param target + */ + getVertexPosition(index: number, target: Vector3): Vector3; + + toJSON(meta?: JSONMeta): MeshJSON; +} diff --git a/src-testing/src/objects/Points.d.ts b/src-testing/src/objects/Points.d.ts new file mode 100644 index 000000000..3cba2c74b --- /dev/null +++ b/src-testing/src/objects/Points.d.ts @@ -0,0 +1,66 @@ +import { BufferGeometry, NormalOrGLBufferAttributes } from "../core/BufferGeometry.js"; +import { Object3D, Object3DEventMap } from "../core/Object3D.js"; +import { Material } from "../materials/Material.js"; + +/** + * A class for displaying {@link Points} + * @remarks + * The {@link Points} are rendered by the {@link THREE.WebGLRenderer | WebGLRenderer} using {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/drawElements | gl.POINTS}. + * @see {@link https://threejs.org/docs/index.html#api/en/objects/Points | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/objects/Points.js | Source} + */ +export class Points< + TGeometry extends BufferGeometry = BufferGeometry, + TMaterial extends Material | Material[] = Material | Material[], + TEventMap extends Object3DEventMap = Object3DEventMap, +> extends Object3D { + /** + * Create a new instance of {@link Points} + * @param geometry An instance of {@link THREE.BufferGeometry | BufferGeometry}. Default {@link THREE.BufferGeometry | `new THREE.BufferGeometry()`}. + * @param material A single or an array of {@link THREE.Material | Material}. Default {@link THREE.PointsMaterial | `new THREE.PointsMaterial()`}. + */ + constructor(geometry?: TGeometry, material?: TMaterial); + + /** + * Read-only flag to check if a given object is of type {@link Points}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isPoints: true; + + /** + * @override + * @defaultValue `Points` + */ + override readonly type: string | "Points"; + + /** + * An array of weights typically from `0-1` that specify how much of the morph is applied. + * @defaultValue `undefined`, _but reset to a blank array by {@link updateMorphTargets | .updateMorphTargets()}._ + */ + morphTargetInfluences?: number[] | undefined; + + /** + * A dictionary of morphTargets based on the `morphTarget.name` property. + * @defaultValue `undefined`, _but rebuilt by {@link updateMorphTargets | .updateMorphTargets()}._ + */ + morphTargetDictionary?: { [key: string]: number } | undefined; + + /** + * An instance of {@link THREE.BufferGeometry | BufferGeometry} (or derived classes), defining the object's structure. + * @remarks each vertex designates the position of a particle in the system. + */ + geometry: TGeometry; + + /** + * An instance of {@link THREE.Material | Material}, defining the object's appearance. + * @defaultValue {@link THREE.PointsMaterial | `new THREE.PointsMaterial()`}, _with randomised colour_. + */ + material: TMaterial; + + /** + * Updates the morphTargets to have no influence on the object + * @remarks Resets the {@link morphTargetInfluences} and {@link morphTargetDictionary} properties. + */ + updateMorphTargets(): void; +} diff --git a/src-testing/src/objects/Skeleton.d.ts b/src-testing/src/objects/Skeleton.d.ts new file mode 100644 index 000000000..aaeb3198b --- /dev/null +++ b/src-testing/src/objects/Skeleton.d.ts @@ -0,0 +1,120 @@ +import { Matrix4, Matrix4Tuple } from "../math/Matrix4.js"; +import { DataTexture } from "../textures/DataTexture.js"; +import { Bone } from "./Bone.js"; + +export interface SkeletonJSON { + metadata: { version: number; type: string; generator: string }; + bones: string[]; + boneInverses: Matrix4Tuple[]; + uuid: string; +} + +/** + * Use an array of {@link Bone | bones} to create a {@link Skeleton} that can be used by a {@link THREE.SkinnedMesh | SkinnedMesh}. + * @example + * ```typescript + * // Create a simple "arm" + * const bones = []; + * const shoulder = new THREE.Bone(); + * const elbow = new THREE.Bone(); + * const hand = new THREE.Bone(); + * shoulder.add(elbow); + * elbow.add(hand); + * bones.push(shoulder); + * bones.push(elbow); + * bones.push(hand); + * shoulder.position.y = -5; + * elbow.position.y = 0; + * hand.position.y = 5; + * const armSkeleton = new THREE.Skeleton(bones); + * See the[page: SkinnedMesh] page + * for an example of usage with standard[page: BufferGeometry]. + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/objects/Skeleton | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/objects/Skeleton.js | Source} + */ +export class Skeleton { + /** + * Creates a new Skeleton. + * @param bones The array of {@link THREE.Bone | bones}. Default `[]`. + * @param boneInverses An array of {@link THREE.Matrix4 | Matrix4s}. Default `[]`. + */ + constructor(bones?: Bone[], boneInverses?: Matrix4[]); + + /** + * {@link http://en.wikipedia.org/wiki/Universally_unique_identifier | UUID} of this object instance. + * @remarks This gets automatically assigned and shouldn't be edited. + */ + uuid: string; + + /** + * The array of {@link THREE.Bone | Bones}. + * @remarks Note this is a copy of the original array, not a reference, so you can modify the original array without effecting this one. + */ + bones: Bone[]; + + /** + * An array of {@link Matrix4 | Matrix4s} that represent the inverse of the {@link THREE.Matrix4 | matrixWorld} of the individual bones. + */ + boneInverses: Matrix4[]; + + /** + * The array buffer holding the bone data when using a vertex texture. + */ + boneMatrices: Float32Array; + + /** + * The {@link THREE.DataTexture | DataTexture} holding the bone data when using a vertex texture. + */ + boneTexture: null | DataTexture; + + frame: number; + + init(): void; + + /** + * Generates the {@link boneInverses} array if not provided in the constructor. + */ + calculateInverses(): void; + + /** + * Computes an instance of {@link THREE.DataTexture | DataTexture} in order to pass the bone data more efficiently to the shader + * @remarks + * The texture is assigned to {@link boneTexture}. + */ + computeBoneTexture(): this; + + /** + * Returns the skeleton to the base pose. + */ + pose(): void; + + /** + * Updates the {@link boneMatrices} and {@link boneTexture} after changing the bones + * @remarks + * This is called automatically by the {@link THREE.WebGLRenderer | WebGLRenderer} if the {@link Skeleton} is used with a {@link THREE.SkinnedMesh | SkinnedMesh}. + */ + update(): void; + + /** + * Returns a clone of this {@link Skeleton} object. + */ + clone(): Skeleton; + + /** + * Searches through the skeleton's bone array and returns the first with a matching name. + * @param name String to match to the Bone's {@link THREE.Bone.name | .name} property. + */ + getBoneByName(name: string): undefined | Bone; + + /** + * Frees the GPU-related resources allocated by this instance + * @remarks + * Call this method whenever this instance is no longer used in your app. + */ + dispose(): void; + + toJSON(): SkeletonJSON; + + fromJSON(json: SkeletonJSON, bones: Record): void; +} diff --git a/src-testing/src/objects/SkinnedMesh.d.ts b/src-testing/src/objects/SkinnedMesh.d.ts new file mode 100644 index 000000000..35149c5d1 --- /dev/null +++ b/src-testing/src/objects/SkinnedMesh.d.ts @@ -0,0 +1,160 @@ +import { BindMode } from "../constants.js"; +import { BufferGeometry } from "../core/BufferGeometry.js"; +import { JSONMeta, Object3DEventMap } from "../core/Object3D.js"; +import { Material } from "../materials/Material.js"; +import { Box3 } from "../math/Box3.js"; +import { Matrix4, Matrix4Tuple } from "../math/Matrix4.js"; +import { Sphere } from "../math/Sphere.js"; +import { Vector3 } from "../math/Vector3.js"; +import { Mesh, MeshJSON, MeshJSONObject } from "./Mesh.js"; +import { Skeleton } from "./Skeleton.js"; + +export interface SkinnedMeshJSONObject extends MeshJSONObject { + bindMode: BindMode; + bindMatrix: Matrix4Tuple; + skeleton?: string; +} + +export interface SkinnedMeshJSON extends MeshJSON { + object: SkinnedMeshJSONObject; +} + +/** + * A mesh that has a {@link THREE.Skeleton | Skeleton} with {@link Bone | bones} that can then be used to animate the vertices of the geometry. + * @example + * ```typescript + * const geometry = new THREE.CylinderGeometry(5, 5, 5, 5, 15, 5, 30); + * // create the skin indices and skin weights manually + * // (typically a loader would read this data from a 3D model for you) + * const position = geometry.attributes.position; + * const vertex = new THREE.Vector3(); + * const skinIndices = []; + * const skinWeights = []; + * for (let i = 0; i & lt; position.count; i++) { + * vertex.fromBufferAttribute(position, i); + * // compute skinIndex and skinWeight based on some configuration data + * const y = (vertex.y + sizing.halfHeight); + * const skinIndex = Math.floor(y / sizing.segmentHeight); + * const skinWeight = (y % sizing.segmentHeight) / sizing.segmentHeight; + * skinIndices.push(skinIndex, skinIndex + 1, 0, 0); + * skinWeights.push(1 - skinWeight, skinWeight, 0, 0); + * } + * geometry.setAttribute('skinIndex', new THREE.Uint16BufferAttribute(skinIndices, 4)); + * geometry.setAttribute('skinWeight', new THREE.Float32BufferAttribute(skinWeights, 4)); + * // create skinned mesh and skeleton + * const mesh = new THREE.SkinnedMesh(geometry, material); + * const skeleton = new THREE.Skeleton(bones); + * // see example from THREE.Skeleton + * const rootBone = skeleton.bones[0]; + * mesh.add(rootBone); + * // bind the skeleton to the mesh + * mesh.bind(skeleton); + * // move the bones and manipulate the model + * skeleton.bones[0].rotation.x = -0.1; + * skeleton.bones[1].rotation.x = 0.2; + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/objects/SkinnedMesh | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/objects/SkinnedMesh.js | Source} + */ +export class SkinnedMesh< + TGeometry extends BufferGeometry = BufferGeometry, + TMaterial extends Material | Material[] = Material | Material[], + TEventMap extends Object3DEventMap = Object3DEventMap, +> extends Mesh { + /** + * Create a new instance of {@link SkinnedMesh} + * @param geometry An instance of {@link THREE.BufferGeometry | BufferGeometry}. Default {@link THREE.BufferGeometry | `new THREE.BufferGeometry()`}. + * @param material A single or an array of {@link THREE.Material | Material}. Default {@link THREE.MeshBasicMaterial | `new THREE.MeshBasicMaterial()`}. + */ + constructor(geometry?: TGeometry, material?: TMaterial, useVertexTexture?: boolean); + + /** + * Read-only flag to check if a given object is of type {@link SkinnedMesh}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isSkinnedMesh: true; + + /** + * @override + * @defaultValue `SkinnedMesh` + */ + override readonly type: string | "SkinnedMesh"; + + /** + * Either {@link AttachedBindMode} or {@link DetachedBindMode}. {@link AttachedBindMode} means the skinned mesh + * shares the same world space as the skeleton. This is not true when using {@link DetachedBindMode} which is useful + * when sharing a skeleton across multiple skinned meshes. + * @defaultValue `AttachedBindMode` + */ + bindMode: BindMode; + + /** + * The base matrix that is used for the bound bone transforms. + */ + bindMatrix: Matrix4; + /** + * The base matrix that is used for resetting the bound bone transforms. + */ + bindMatrixInverse: Matrix4; + + /** + * The bounding box of the SkinnedMesh. Can be calculated with {@link computeBoundingBox | .computeBoundingBox()}. + * @default `null` + */ + boundingBox: Box3; + + /** + * The bounding box of the SkinnedMesh. Can be calculated with {@link computeBoundingSphere | .computeBoundingSphere()}. + * @default `null` + */ + boundingSphere: Sphere; + + /** + * {@link THREE.Skeleton | Skeleton} representing the bone hierarchy of the skinned mesh. + */ + skeleton: Skeleton; + + /** + * Bind a skeleton to the skinned mesh + * @remarks + * The bindMatrix gets saved to .bindMatrix property and the .bindMatrixInverse gets calculated. + * @param skeleton {@link THREE.Skeleton | Skeleton} created from a {@link Bone | Bones} tree. + * @param bindMatrix {@link THREE.Matrix4 | Matrix4} that represents the base transform of the skeleton. + */ + bind(skeleton: Skeleton, bindMatrix?: Matrix4): void; + + /** + * Computes the bounding box of the skinned mesh, and updates the {@link .boundingBox} attribute. The bounding box + * is not computed by the engine; it must be computed by your app. If the skinned mesh is animated, the bounding box + * should be recomputed per frame. + */ + computeBoundingBox(): void; + + /** + * Computes the bounding sphere of the skinned mesh, and updates the {@link .boundingSphere} attribute. The bounding + * sphere is automatically computed by the engine when it is needed, e.g., for ray casting and view frustum culling. + * If the skinned mesh is animated, the bounding sphere should be recomputed per frame. + */ + computeBoundingSphere(): void; + + /** + * This method sets the skinned mesh in the rest pose (resets the pose). + */ + pose(): void; + + /** + * Normalizes the skin weights. + */ + normalizeSkinWeights(): void; + + /** + * Applies the bone transform associated with the given index to the given position vector + * @remarks Returns the updated vector. + * @param index Expects a `Integer` + * @param vector + */ + applyBoneTransform(index: number, vector: Vector3): Vector3; + + toJSON(meta?: JSONMeta): SkinnedMeshJSON; +} diff --git a/src-testing/src/objects/Sprite.d.ts b/src-testing/src/objects/Sprite.d.ts new file mode 100644 index 000000000..427b8b414 --- /dev/null +++ b/src-testing/src/objects/Sprite.d.ts @@ -0,0 +1,65 @@ +import { BufferGeometry } from "../core/BufferGeometry.js"; +import { Object3D, Object3DEventMap } from "../core/Object3D.js"; +import { SpriteMaterial } from "../materials/Materials.js"; +import { Vector2 } from "../math/Vector2.js"; + +/** + * A {@link Sprite} is a plane that always faces towards the camera, generally with a partially transparent texture applied. + * @remarks Sprites do not cast shadows, setting `castShadow = true` will have no effect. + * @example + * ```typescript + * const map = new THREE.TextureLoader().load('sprite.png'); + * const material = new THREE.SpriteMaterial({ + * map: map + * }); + * const {@link Sprite} = new THREE.Sprite(material); + * scene.add(sprite); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/objects/Sprite | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/objects/Sprite.js | Source} + */ +export class Sprite extends Object3D { + /** + * Creates a new Sprite. + * @param material An instance of {@link THREE.SpriteMaterial | SpriteMaterial}. Default {@link THREE.SpriteMaterial | `new SpriteMaterial()`}, _with white color_. + */ + constructor(material?: SpriteMaterial); + + /** + * Read-only flag to check if a given object is of type {@link Sprite}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isSprite: true; + + /** + * @override + * @defaultValue `Sprite` + */ + override readonly type: string | "Sprite"; + + /** + * Whether the object gets rendered into shadow map. + * No effect in {@link Sprite}. + * @ignore + * @hidden + * @defaultValue `false` + */ + override castShadow: false; + + geometry: BufferGeometry; + + /** + * An instance of {@link THREE.SpriteMaterial | SpriteMaterial}, defining the object's appearance. + * @defaultValue {@link THREE.SpriteMaterial | `new SpriteMaterial()`}, _with white color_. + */ + material: SpriteMaterial; + + /** + * The sprite's anchor point, and the point around which the {@link Sprite} rotates. + * A value of (0.5, 0.5) corresponds to the midpoint of the sprite. + * A value of (0, 0) corresponds to the lower left corner of the sprite. + * @defaultValue {@link THREE.Vector2 | `new Vector2(0.5, 0.5)`}. + */ + center: Vector2; +} diff --git a/src-testing/src/renderers/WebGL3DRenderTarget.d.ts b/src-testing/src/renderers/WebGL3DRenderTarget.d.ts new file mode 100644 index 000000000..420caa97e --- /dev/null +++ b/src-testing/src/renderers/WebGL3DRenderTarget.d.ts @@ -0,0 +1,29 @@ +import { RenderTargetOptions } from "../core/RenderTarget.js"; +import { Data3DTexture } from "../textures/Data3DTexture.js"; +import { WebGLRenderTarget } from "./WebGLRenderTarget.js"; + +/** + * Represents a three-dimensional render target. + */ +export class WebGL3DRenderTarget extends WebGLRenderTarget { + /** + * Creates a new WebGL3DRenderTarget. + * + * @param width the width of the render target, in pixels. Default is `1`. + * @param height the height of the render target, in pixels. Default is `1`. + * @param depth the depth of the render target. Default is `1`. + * @param options optional object that holds texture parameters for an auto-generated target texture and + * depthBuffer/stencilBuffer booleans. See {@link WebGLRenderTarget} for details. + */ + constructor(width?: number, height?: number, depth?: number, options?: RenderTargetOptions); + + textures: Data3DTexture[]; + + /** + * The texture property is overwritten with an instance of {@link Data3DTexture}. + */ + get texture(): Data3DTexture; + set texture(value: Data3DTexture); + + readonly isWebGL3DRenderTarget: true; +} diff --git a/src-testing/src/renderers/WebGLArrayRenderTarget.d.ts b/src-testing/src/renderers/WebGLArrayRenderTarget.d.ts new file mode 100644 index 000000000..1ac617889 --- /dev/null +++ b/src-testing/src/renderers/WebGLArrayRenderTarget.d.ts @@ -0,0 +1,29 @@ +import { RenderTargetOptions } from "../core/RenderTarget.js"; +import { DataArrayTexture } from "../textures/DataArrayTexture.js"; +import { WebGLRenderTarget } from "./WebGLRenderTarget.js"; + +/** + * This type of render target represents an array of textures. + */ +export class WebGLArrayRenderTarget extends WebGLRenderTarget { + /** + * Creates a new WebGLArrayRenderTarget. + * + * @param width the width of the render target, in pixels. Default is `1`. + * @param height the height of the render target, in pixels. Default is `1`. + * @param depth the depth/layer count of the render target. Default is `1`. + * @param options optional object that holds texture parameters for an auto-generated target texture and + * depthBuffer/stencilBuffer booleans. See {@link WebGLRenderTarget} for details. + */ + constructor(width?: number, height?: number, depth?: number, options?: RenderTargetOptions); + + textures: DataArrayTexture[]; + + /** + * The texture property is overwritten with an instance of {@link DataArrayTexture}. + */ + get texture(): DataArrayTexture; + set texture(value: DataArrayTexture); + + readonly isWebGLArrayRenderTarget: true; +} diff --git a/src-testing/src/renderers/WebGLCubeRenderTarget.d.ts b/src-testing/src/renderers/WebGLCubeRenderTarget.d.ts new file mode 100644 index 000000000..c390adb67 --- /dev/null +++ b/src-testing/src/renderers/WebGLCubeRenderTarget.d.ts @@ -0,0 +1,18 @@ +import { RenderTargetOptions } from "../core/RenderTarget.js"; +import { CubeTexture } from "../textures/CubeTexture.js"; +import { Texture } from "../textures/Texture.js"; +import { WebGLRenderer } from "./WebGLRenderer.js"; +import { WebGLRenderTarget } from "./WebGLRenderTarget.js"; + +export class WebGLCubeRenderTarget extends WebGLRenderTarget { + constructor(size?: number, options?: RenderTargetOptions); + + textures: CubeTexture[]; + + get texture(): CubeTexture; + set texture(value: CubeTexture); + + fromEquirectangularTexture(renderer: WebGLRenderer, texture: Texture): this; + + clear(renderer: WebGLRenderer, color: boolean, depth: boolean, stencil: boolean): void; +} diff --git a/src-testing/src/renderers/WebGLRenderTarget.d.ts b/src-testing/src/renderers/WebGLRenderTarget.d.ts new file mode 100644 index 000000000..fdff12e78 --- /dev/null +++ b/src-testing/src/renderers/WebGLRenderTarget.d.ts @@ -0,0 +1,8 @@ +import { RenderTarget, RenderTargetOptions } from "../core/RenderTarget.js"; +import { Texture } from "../textures/Texture.js"; + +export class WebGLRenderTarget extends RenderTarget { + constructor(width?: number, height?: number, options?: RenderTargetOptions); + + readonly isWebGLRenderTarget: true; +} diff --git a/src-testing/src/renderers/WebGLRenderer.d.ts b/src-testing/src/renderers/WebGLRenderer.d.ts new file mode 100644 index 000000000..963fd850a --- /dev/null +++ b/src-testing/src/renderers/WebGLRenderer.d.ts @@ -0,0 +1,558 @@ +import { Camera } from "../cameras/Camera.js"; +import { CullFace, ShadowMapType, ToneMapping, WebGLCoordinateSystem } from "../constants.js"; +import { TypedArray } from "../core/BufferAttribute.js"; +import { BufferGeometry } from "../core/BufferGeometry.js"; +import { Object3D } from "../core/Object3D.js"; +import { Material } from "../materials/Material.js"; +import { Box2 } from "../math/Box2.js"; +import { Box3 } from "../math/Box3.js"; +import { Color, ColorRepresentation } from "../math/Color.js"; +import { Plane } from "../math/Plane.js"; +import { Vector2 } from "../math/Vector2.js"; +import { Vector3 } from "../math/Vector3.js"; +import { Vector4 } from "../math/Vector4.js"; +import { Scene } from "../scenes/Scene.js"; +import { Data3DTexture } from "../textures/Data3DTexture.js"; +import { DataArrayTexture } from "../textures/DataArrayTexture.js"; +import { OffscreenCanvas, Texture } from "../textures/Texture.js"; +import { WebGLCapabilities, WebGLCapabilitiesParameters } from "./webgl/WebGLCapabilities.js"; +import { WebGLExtensions } from "./webgl/WebGLExtensions.js"; +import { WebGLInfo } from "./webgl/WebGLInfo.js"; +import { WebGLProgram } from "./webgl/WebGLProgram.js"; +import { WebGLProperties } from "./webgl/WebGLProperties.js"; +import { WebGLRenderLists } from "./webgl/WebGLRenderLists.js"; +import { WebGLShadowMap } from "./webgl/WebGLShadowMap.js"; +import { WebGLState } from "./webgl/WebGLState.js"; +import { WebGLRenderTarget } from "./WebGLRenderTarget.js"; +import { WebXRManager } from "./webxr/WebXRManager.js"; + +export interface Renderer { + domElement: HTMLCanvasElement; + + render(scene: Object3D, camera: Camera): void; + setSize(width: number, height: number, updateStyle?: boolean): void; +} + +export interface WebGLRendererParameters extends WebGLCapabilitiesParameters { + /** + * A Canvas where the renderer draws its output. + */ + canvas?: HTMLCanvasElement | OffscreenCanvas | undefined; + + /** + * A WebGL Rendering Context. + * (https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext) + * Default is null + */ + context?: WebGLRenderingContext | undefined; + + /** + * default is false. + */ + alpha?: boolean | undefined; + + /** + * default is true. + */ + premultipliedAlpha?: boolean | undefined; + + /** + * default is false. + */ + antialias?: boolean | undefined; + + /** + * default is false. + */ + stencil?: boolean | undefined; + + /** + * default is false. + */ + preserveDrawingBuffer?: boolean | undefined; + + /** + * Can be "high-performance", "low-power" or "default" + */ + powerPreference?: WebGLPowerPreference | undefined; + + /** + * default is true. + */ + depth?: boolean | undefined; + + /** + * default is false. + */ + failIfMajorPerformanceCaveat?: boolean | undefined; +} + +export interface WebGLDebug { + /** + * Enables error checking and reporting when shader programs are being compiled. + */ + checkShaderErrors: boolean; + + /** + * A callback function that can be used for custom error reporting. The callback receives the WebGL context, an + * instance of WebGLProgram as well two instances of WebGLShader representing the vertex and fragment shader. + * Assigning a custom function disables the default error reporting. + * @default `null` + */ + onShaderError: + | (( + gl: WebGLRenderingContext, + program: WebGLProgram, + glVertexShader: WebGLShader, + glFragmentShader: WebGLShader, + ) => void) + | null; +} + +/** + * The WebGL renderer displays your beautifully crafted scenes using WebGL, if your device supports it. + * This renderer has way better performance than CanvasRenderer. + * + * see {@link https://github.com/mrdoob/three.js/blob/master/src/renderers/WebGLRenderer.js|src/renderers/WebGLRenderer.js} + */ +export class WebGLRenderer implements Renderer { + /** + * parameters is an optional object with properties defining the renderer's behavior. + * The constructor also accepts no parameters at all. + * In all cases, it will assume sane defaults when parameters are missing. + */ + constructor(parameters?: WebGLRendererParameters); + + /** + * A Canvas where the renderer draws its output. + * This is automatically created by the renderer in the constructor (if not provided already); you just need to add it to your page. + * @default document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' ) + */ + domElement: HTMLCanvasElement; + + /** + * Defines whether the renderer should automatically clear its output before rendering. + * @default true + */ + autoClear: boolean; + + /** + * If autoClear is true, defines whether the renderer should clear the color buffer. Default is true. + * @default true + */ + autoClearColor: boolean; + + /** + * If autoClear is true, defines whether the renderer should clear the depth buffer. Default is true. + * @default true + */ + autoClearDepth: boolean; + + /** + * If autoClear is true, defines whether the renderer should clear the stencil buffer. Default is true. + * @default true + */ + autoClearStencil: boolean; + + /** + * Debug configurations. + * @default { checkShaderErrors: true } + */ + debug: WebGLDebug; + + /** + * Defines whether the renderer should sort objects. Default is true. + * @default true + */ + sortObjects: boolean; + + /** + * @default [] + */ + clippingPlanes: Plane[]; + + /** + * @default false + */ + localClippingEnabled: boolean; + + extensions: WebGLExtensions; + + /** + * Color space used for output to HTMLCanvasElement. Supported values are + * {@link SRGBColorSpace} and {@link LinearSRGBColorSpace}. + * @default THREE.SRGBColorSpace. + */ + get outputColorSpace(): string; + set outputColorSpace(colorSpace: string); + + get coordinateSystem(): typeof WebGLCoordinateSystem; + + /** + * @default THREE.NoToneMapping + */ + toneMapping: ToneMapping; + + /** + * @default 1 + */ + toneMappingExposure: number; + + info: WebGLInfo; + + shadowMap: WebGLShadowMap; + + pixelRatio: number; + + capabilities: WebGLCapabilities; + properties: WebGLProperties; + renderLists: WebGLRenderLists; + state: WebGLState; + + xr: WebXRManager; + + /** + * Return the WebGL context. + */ + getContext(): WebGLRenderingContext | WebGL2RenderingContext; + getContextAttributes(): any; + forceContextLoss(): void; + forceContextRestore(): void; + + /** + * @deprecated Use {@link WebGLCapabilities#getMaxAnisotropy .capabilities.getMaxAnisotropy()} instead. + */ + getMaxAnisotropy(): number; + + /** + * @deprecated Use {@link WebGLCapabilities#precision .capabilities.precision} instead. + */ + getPrecision(): string; + + getPixelRatio(): number; + setPixelRatio(value: number): void; + + getDrawingBufferSize(target: Vector2): Vector2; + setDrawingBufferSize(width: number, height: number, pixelRatio: number): void; + + getSize(target: Vector2): Vector2; + + /** + * Resizes the output canvas to (width, height), and also sets the viewport to fit that size, starting in (0, 0). + */ + setSize(width: number, height: number, updateStyle?: boolean): void; + + getCurrentViewport(target: Vector4): Vector4; + + /** + * Copies the viewport into target. + */ + getViewport(target: Vector4): Vector4; + + /** + * Sets the viewport to render from (x, y) to (x + width, y + height). + * (x, y) is the lower-left corner of the region. + */ + setViewport(x: Vector4 | number, y?: number, width?: number, height?: number): void; + + /** + * Copies the scissor area into target. + */ + getScissor(target: Vector4): Vector4; + + /** + * Sets the scissor area from (x, y) to (x + width, y + height). + */ + setScissor(x: Vector4 | number, y?: number, width?: number, height?: number): void; + + /** + * Returns true if scissor test is enabled; returns false otherwise. + */ + getScissorTest(): boolean; + + /** + * Enable the scissor test. When this is enabled, only the pixels within the defined scissor area will be affected by further renderer actions. + */ + setScissorTest(enable: boolean): void; + + /** + * Sets the custom opaque sort function for the WebGLRenderLists. Pass null to use the default painterSortStable function. + */ + setOpaqueSort(method: (a: any, b: any) => number): void; + + /** + * Sets the custom transparent sort function for the WebGLRenderLists. Pass null to use the default reversePainterSortStable function. + */ + setTransparentSort(method: (a: any, b: any) => number): void; + + /** + * Returns a THREE.Color instance with the current clear color. + */ + getClearColor(target: Color): Color; + + /** + * Sets the clear color, using color for the color and alpha for the opacity. + */ + setClearColor(color: ColorRepresentation, alpha?: number): void; + + /** + * Returns a float with the current clear alpha. Ranges from 0 to 1. + */ + getClearAlpha(): number; + + setClearAlpha(alpha: number): void; + + /** + * Tells the renderer to clear its color, depth or stencil drawing buffer(s). + * Arguments default to true + */ + clear(color?: boolean, depth?: boolean, stencil?: boolean): void; + + clearColor(): void; + clearDepth(): void; + clearStencil(): void; + clearTarget(renderTarget: WebGLRenderTarget, color: boolean, depth: boolean, stencil: boolean): void; + + /** + * @deprecated Use {@link WebGLState#reset .state.reset()} instead. + */ + resetGLState(): void; + dispose(): void; + + renderBufferDirect( + camera: Camera, + scene: Scene, + geometry: BufferGeometry, + material: Material, + object: Object3D, + geometryGroup: any, + ): void; + + /** + * A build in function that can be used instead of requestAnimationFrame. For WebXR projects this function must be used. + * @param callback The function will be called every available frame. If `null` is passed it will stop any already ongoing animation. + */ + setAnimationLoop(callback: XRFrameRequestCallback | null): void; + + /** + * @deprecated Use {@link WebGLRenderer#setAnimationLoop .setAnimationLoop()} instead. + */ + animate(callback: () => void): void; + + /** + * Compiles all materials in the scene with the camera. This is useful to precompile shaders before the first + * rendering. If you want to add a 3D object to an existing scene, use the third optional parameter for applying the + * target scene. + * Note that the (target) scene's lighting should be configured before calling this method. + */ + compile: (scene: Object3D, camera: Camera, targetScene?: Scene | null) => Set; + + /** + * Asynchronous version of {@link compile}(). The method returns a Promise that resolves when the given scene can be + * rendered without unnecessary stalling due to shader compilation. + * This method makes use of the KHR_parallel_shader_compile WebGL extension. + */ + compileAsync: (scene: Object3D, camera: Camera, targetScene?: Scene | null) => Promise; + + /** + * Render a scene or an object using a camera. + * The render is done to a previously specified {@link WebGLRenderTarget#renderTarget .renderTarget} set by calling + * {@link WebGLRenderer#setRenderTarget .setRenderTarget} or to the canvas as usual. + * + * By default render buffers are cleared before rendering but you can prevent this by setting the property + * {@link WebGLRenderer#autoClear autoClear} to false. If you want to prevent only certain buffers being cleared + * you can set either the {@link WebGLRenderer#autoClearColor autoClearColor}, + * {@link WebGLRenderer#autoClearStencil autoClearStencil} or {@link WebGLRenderer#autoClearDepth autoClearDepth} + * properties to false. To forcibly clear one ore more buffers call {@link WebGLRenderer#clear .clear}. + */ + render(scene: Object3D, camera: Camera): void; + + /** + * Returns the current active cube face. + */ + getActiveCubeFace(): number; + + /** + * Returns the current active mipmap level. + */ + getActiveMipmapLevel(): number; + + /** + * Returns the current render target. If no render target is set, null is returned. + */ + getRenderTarget(): WebGLRenderTarget | null; + + /** + * @deprecated Use {@link WebGLRenderer#getRenderTarget .getRenderTarget()} instead. + */ + getCurrentRenderTarget(): WebGLRenderTarget | null; + + /** + * Sets the active render target. + * + * @param renderTarget The {@link WebGLRenderTarget renderTarget} that needs to be activated. When `null` is given, the canvas is set as the active render target instead. + * @param activeCubeFace Specifies the active cube side (PX 0, NX 1, PY 2, NY 3, PZ 4, NZ 5) of {@link WebGLCubeRenderTarget}. + * @param activeMipmapLevel Specifies the active mipmap level. + */ + setRenderTarget( + renderTarget: WebGLRenderTarget | WebGLRenderTarget | null, + activeCubeFace?: number, + activeMipmapLevel?: number, + ): void; + + readRenderTargetPixels( + renderTarget: WebGLRenderTarget | WebGLRenderTarget, + x: number, + y: number, + width: number, + height: number, + buffer: TypedArray, + activeCubeFaceIndex?: number, + ): void; + + readRenderTargetPixelsAsync( + renderTarget: WebGLRenderTarget | WebGLRenderTarget, + x: number, + y: number, + width: number, + height: number, + buffer: TypedArray, + activeCubeFaceIndex?: number, + ): Promise; + + /** + * Copies a region of the currently bound framebuffer into the selected mipmap level of the selected texture. + * This region is defined by the size of the destination texture's mip level, offset by the input position. + * + * @param texture Specifies the destination texture. + * @param position Specifies the pixel offset from which to copy out of the framebuffer. + * @param level Specifies the destination mipmap level of the texture. + */ + copyFramebufferToTexture(texture: Texture, position?: Vector2 | null, level?: number): void; + + /** + * Copies the pixels of a texture in the bounds `srcRegion` in the destination texture starting from the given + * position. The `depthTexture` and `texture` property of render targets are supported as well. + * + * When using render target textures as `srcTexture` and `dstTexture`, you must make sure both render targets are + * intitialized e.g. via {@link .initRenderTarget}(). + * + * @param srcTexture Specifies the source texture. + * @param dstTexture Specifies the destination texture. + * @param srcRegion Specifies the bounds + * @param dstPosition Specifies the pixel offset into the dstTexture where the copy will occur. + * @param level Specifies the destination mipmap level of the texture. + */ + copyTextureToTexture( + srcTexture: Texture, + dstTexture: Texture, + srcRegion?: Box2 | null, + dstPosition?: Vector2 | null, + level?: number, + ): void; + + /** + * Copies the pixels of a texture in the bounds `srcRegion` in the destination texture starting from the given + * position. The `depthTexture` and `texture` property of 3D render targets are supported as well. + * + * When using render target textures as `srcTexture` and `dstTexture`, you must make sure both render targets are + * intitialized e.g. via {@link .initRenderTarget}(). + * + * @param srcTexture Specifies the source texture. + * @param dstTexture Specifies the destination texture. + * @param srcRegion Specifies the bounds + * @param dstPosition Specifies the pixel offset into the dstTexture where the copy will occur. + * @param level Specifies the destination mipmap level of the texture. + */ + copyTextureToTexture3D( + srcTexture: Texture, + dstTexture: Data3DTexture | DataArrayTexture, + srcRegion?: Box3 | null, + dstPosition?: Vector3 | null, + level?: number, + ): void; + + /** + * Initializes the given WebGLRenderTarget memory. Useful for initializing a render target so data can be copied + * into it using {@link WebGLRenderer.copyTextureToTexture} before it has been rendered to. + * @param target + */ + initRenderTarget(target: WebGLRenderTarget): void; + + /** + * Initializes the given texture. Can be used to preload a texture rather than waiting until first render (which can cause noticeable lags due to decode and GPU upload overhead). + * + * @param texture The texture to Initialize. + */ + initTexture(texture: Texture): void; + + /** + * Can be used to reset the internal WebGL state. + */ + resetState(): void; + + /** + * @deprecated Use {@link WebGLRenderer#xr .xr} instead. + */ + vr: boolean; + + /** + * @deprecated Use {@link WebGLShadowMap#enabled .shadowMap.enabled} instead. + */ + shadowMapEnabled: boolean; + + /** + * @deprecated Use {@link WebGLShadowMap#type .shadowMap.type} instead. + */ + shadowMapType: ShadowMapType; + + /** + * @deprecated Use {@link WebGLShadowMap#cullFace .shadowMap.cullFace} instead. + */ + shadowMapCullFace: CullFace; + + /** + * @deprecated Use {@link WebGLExtensions#get .extensions.get( 'OES_texture_float' )} instead. + */ + supportsFloatTextures(): any; + + /** + * @deprecated Use {@link WebGLExtensions#get .extensions.get( 'OES_texture_half_float' )} instead. + */ + supportsHalfFloatTextures(): any; + + /** + * @deprecated Use {@link WebGLExtensions#get .extensions.get( 'OES_standard_derivatives' )} instead. + */ + supportsStandardDerivatives(): any; + + /** + * @deprecated Use {@link WebGLExtensions#get .extensions.get( 'WEBGL_compressed_texture_s3tc' )} instead. + */ + supportsCompressedTextureS3TC(): any; + + /** + * @deprecated Use {@link WebGLExtensions#get .extensions.get( 'WEBGL_compressed_texture_pvrtc' )} instead. + */ + supportsCompressedTexturePVRTC(): any; + + /** + * @deprecated Use {@link WebGLExtensions#get .extensions.get( 'EXT_blend_minmax' )} instead. + */ + supportsBlendMinMax(): any; + + /** + * @deprecated Use {@link WebGLCapabilities#vertexTextures .capabilities.vertexTextures} instead. + */ + supportsVertexTextures(): any; + + /** + * @deprecated Use {@link WebGLExtensions#get .extensions.get( 'ANGLE_instanced_arrays' )} instead. + */ + supportsInstancedArrays(): any; + + /** + * @deprecated Use {@link WebGLRenderer#setScissorTest .setScissorTest()} instead. + */ + enableScissorTest(boolean: any): any; +} diff --git a/src-testing/src/renderers/common/Animation.ts b/src-testing/src/renderers/common/Animation.ts new file mode 100644 index 000000000..0b00319a1 --- /dev/null +++ b/src-testing/src/renderers/common/Animation.ts @@ -0,0 +1,38 @@ +class Animation { + constructor(nodes, info) { + this.nodes = nodes; + this.info = info; + + this.animationLoop = null; + this.requestId = null; + + this._init(); + } + + _init() { + const update = (time, frame) => { + this.requestId = self.requestAnimationFrame(update); + + if (this.info.autoReset === true) this.info.reset(); + + this.nodes.nodeFrame.update(); + + this.info.frame = this.nodes.nodeFrame.frameId; + + if (this.animationLoop !== null) this.animationLoop(time, frame); + }; + + update(); + } + + dispose() { + self.cancelAnimationFrame(this.requestId); + this.requestId = null; + } + + setAnimationLoop(callback) { + this.animationLoop = callback; + } +} + +export default Animation; diff --git a/src-testing/src/renderers/common/Attributes.ts b/src-testing/src/renderers/common/Attributes.ts new file mode 100644 index 000000000..4631d528b --- /dev/null +++ b/src-testing/src/renderers/common/Attributes.ts @@ -0,0 +1,56 @@ +import DataMap from './DataMap.js'; +import { AttributeType } from './Constants.js'; + +import { DynamicDrawUsage } from '../../constants.js'; + +class Attributes extends DataMap { + constructor(backend) { + super(); + + this.backend = backend; + } + + delete(attribute) { + const attributeData = super.delete(attribute); + + if (attributeData !== undefined) { + this.backend.destroyAttribute(attribute); + } + + return attributeData; + } + + update(attribute, type) { + const data = this.get(attribute); + + if (data.version === undefined) { + if (type === AttributeType.VERTEX) { + this.backend.createAttribute(attribute); + } else if (type === AttributeType.INDEX) { + this.backend.createIndexAttribute(attribute); + } else if (type === AttributeType.STORAGE) { + this.backend.createStorageAttribute(attribute); + } else if (type === AttributeType.INDIRECT) { + this.backend.createIndirectStorageAttribute(attribute); + } + + data.version = this._getBufferAttribute(attribute).version; + } else { + const bufferAttribute = this._getBufferAttribute(attribute); + + if (data.version < bufferAttribute.version || bufferAttribute.usage === DynamicDrawUsage) { + this.backend.updateAttribute(attribute); + + data.version = bufferAttribute.version; + } + } + } + + _getBufferAttribute(attribute) { + if (attribute.isInterleavedBufferAttribute) attribute = attribute.data; + + return attribute; + } +} + +export default Attributes; diff --git a/src-testing/src/renderers/common/Backend.ts b/src-testing/src/renderers/common/Backend.ts new file mode 100644 index 000000000..edd4fcf9c --- /dev/null +++ b/src-testing/src/renderers/common/Backend.ts @@ -0,0 +1,170 @@ +let vector2 = null; +let vector4 = null; +let color4 = null; + +import Color4 from './Color4.js'; +import { Vector2 } from '../../math/Vector2.js'; +import { Vector4 } from '../../math/Vector4.js'; +import { createCanvasElement } from '../../utils.js'; +import { REVISION } from '../../constants.js'; + +class Backend { + constructor(parameters = {}) { + this.parameters = Object.assign({}, parameters); + this.data = new WeakMap(); + this.renderer = null; + this.domElement = null; + } + + async init(renderer) { + this.renderer = renderer; + } + + // render context + + begin(/*renderContext*/) {} + + finish(/*renderContext*/) {} + + // render object + + draw(/*renderObject, info*/) {} + + // program + + createProgram(/*program*/) {} + + destroyProgram(/*program*/) {} + + // bindings + + createBindings(/*bingGroup, bindings*/) {} + + updateBindings(/*bingGroup, bindings*/) {} + + // pipeline + + createRenderPipeline(/*renderObject*/) {} + + createComputePipeline(/*computeNode, pipeline*/) {} + + destroyPipeline(/*pipeline*/) {} + + // cache key + + needsRenderUpdate(/*renderObject*/) {} // return Boolean ( fast test ) + + getRenderCacheKey(/*renderObject*/) {} // return String + + // node builder + + createNodeBuilder(/*renderObject*/) {} // return NodeBuilder (ADD IT) + + // textures + + createSampler(/*texture*/) {} + + createDefaultTexture(/*texture*/) {} + + createTexture(/*texture*/) {} + + copyTextureToBuffer(/*texture, x, y, width, height*/) {} + + // attributes + + createAttribute(/*attribute*/) {} + + createIndexAttribute(/*attribute*/) {} + + updateAttribute(/*attribute*/) {} + + destroyAttribute(/*attribute*/) {} + + // canvas + + getContext() {} + + updateSize() {} + + // utils + + resolveTimestampAsync(/*renderContext, type*/) {} + + hasFeatureAsync(/*name*/) {} // return Boolean + + hasFeature(/*name*/) {} // return Boolean + + getInstanceCount(renderObject) { + const { object, geometry } = renderObject; + + return geometry.isInstancedBufferGeometry ? geometry.instanceCount : object.count > 1 ? object.count : 1; + } + + getDrawingBufferSize() { + vector2 = vector2 || new Vector2(); + + return this.renderer.getDrawingBufferSize(vector2); + } + + getScissor() { + vector4 = vector4 || new Vector4(); + + return this.renderer.getScissor(vector4); + } + + setScissorTest(/*boolean*/) {} + + getClearColor() { + const renderer = this.renderer; + + color4 = color4 || new Color4(); + + renderer.getClearColor(color4); + + color4.getRGB(color4, this.renderer.currentColorSpace); + + return color4; + } + + getDomElement() { + let domElement = this.domElement; + + if (domElement === null) { + domElement = this.parameters.canvas !== undefined ? this.parameters.canvas : createCanvasElement(); + + // OffscreenCanvas does not have setAttribute, see #22811 + if ('setAttribute' in domElement) domElement.setAttribute('data-engine', `three.js r${REVISION} webgpu`); + + this.domElement = domElement; + } + + return domElement; + } + + // resource properties + + set(object, value) { + this.data.set(object, value); + } + + get(object) { + let map = this.data.get(object); + + if (map === undefined) { + map = {}; + this.data.set(object, map); + } + + return map; + } + + has(object) { + return this.data.has(object); + } + + delete(object) { + this.data.delete(object); + } +} + +export default Backend; diff --git a/src-testing/src/renderers/common/Background.ts b/src-testing/src/renderers/common/Background.ts new file mode 100644 index 000000000..b56dd3724 --- /dev/null +++ b/src-testing/src/renderers/common/Background.ts @@ -0,0 +1,133 @@ +import DataMap from './DataMap.js'; +import Color4 from './Color4.js'; +import { + vec4, + context, + normalWorld, + backgroundBlurriness, + backgroundIntensity, + modelViewProjection, +} from '../../nodes/TSL.js'; +import NodeMaterial from '../../materials/nodes/NodeMaterial.js'; + +import { Mesh } from '../../objects/Mesh.js'; +import { SphereGeometry } from '../../geometries/SphereGeometry.js'; +import { BackSide, LinearSRGBColorSpace } from '../../constants.js'; + +const _clearColor = /*@__PURE__*/ new Color4(); + +class Background extends DataMap { + constructor(renderer, nodes) { + super(); + + this.renderer = renderer; + this.nodes = nodes; + } + + update(scene, renderList, renderContext) { + const renderer = this.renderer; + const background = this.nodes.getBackgroundNode(scene) || scene.background; + + let forceClear = false; + + if (background === null) { + // no background settings, use clear color configuration from the renderer + + renderer._clearColor.getRGB(_clearColor, LinearSRGBColorSpace); + _clearColor.a = renderer._clearColor.a; + } else if (background.isColor === true) { + // background is an opaque color + + background.getRGB(_clearColor, LinearSRGBColorSpace); + _clearColor.a = 1; + + forceClear = true; + } else if (background.isNode === true) { + const sceneData = this.get(scene); + const backgroundNode = background; + + _clearColor.copy(renderer._clearColor); + + let backgroundMesh = sceneData.backgroundMesh; + + if (backgroundMesh === undefined) { + const backgroundMeshNode = context(vec4(backgroundNode).mul(backgroundIntensity), { + // @TODO: Add Texture2D support using node context + getUV: () => normalWorld, + getTextureLevel: () => backgroundBlurriness, + }); + + let viewProj = modelViewProjection(); + viewProj = viewProj.setZ(viewProj.w); + + const nodeMaterial = new NodeMaterial(); + nodeMaterial.name = 'Background.material'; + nodeMaterial.side = BackSide; + nodeMaterial.depthTest = false; + nodeMaterial.depthWrite = false; + nodeMaterial.fog = false; + nodeMaterial.lights = false; + nodeMaterial.vertexNode = viewProj; + nodeMaterial.colorNode = backgroundMeshNode; + + sceneData.backgroundMeshNode = backgroundMeshNode; + sceneData.backgroundMesh = backgroundMesh = new Mesh(new SphereGeometry(1, 32, 32), nodeMaterial); + backgroundMesh.frustumCulled = false; + backgroundMesh.name = 'Background.mesh'; + + backgroundMesh.onBeforeRender = function (renderer, scene, camera) { + this.matrixWorld.copyPosition(camera.matrixWorld); + }; + } + + const backgroundCacheKey = backgroundNode.getCacheKey(); + + if (sceneData.backgroundCacheKey !== backgroundCacheKey) { + sceneData.backgroundMeshNode.node = vec4(backgroundNode).mul(backgroundIntensity); + sceneData.backgroundMeshNode.needsUpdate = true; + + backgroundMesh.material.needsUpdate = true; + + sceneData.backgroundCacheKey = backgroundCacheKey; + } + + renderList.unshift(backgroundMesh, backgroundMesh.geometry, backgroundMesh.material, 0, 0, null); + } else { + console.error('THREE.Renderer: Unsupported background configuration.', background); + } + + // + + if (renderer.autoClear === true || forceClear === true) { + const clearColorValue = renderContext.clearColorValue; + + clearColorValue.r = _clearColor.r; + clearColorValue.g = _clearColor.g; + clearColorValue.b = _clearColor.b; + clearColorValue.a = _clearColor.a; + + // premultiply alpha + + if (renderer.backend.isWebGLBackend === true || renderer.alpha === true) { + clearColorValue.r *= clearColorValue.a; + clearColorValue.g *= clearColorValue.a; + clearColorValue.b *= clearColorValue.a; + } + + // + + renderContext.depthClearValue = renderer._clearDepth; + renderContext.stencilClearValue = renderer._clearStencil; + + renderContext.clearColor = renderer.autoClearColor === true; + renderContext.clearDepth = renderer.autoClearDepth === true; + renderContext.clearStencil = renderer.autoClearStencil === true; + } else { + renderContext.clearColor = false; + renderContext.clearDepth = false; + renderContext.clearStencil = false; + } + } +} + +export default Background; diff --git a/src-testing/src/renderers/common/BindGroup.ts b/src-testing/src/renderers/common/BindGroup.ts new file mode 100644 index 000000000..ae78d4787 --- /dev/null +++ b/src-testing/src/renderers/common/BindGroup.ts @@ -0,0 +1,14 @@ +let _id = 0; + +class BindGroup { + constructor(name = '', bindings = [], index = 0, bindingsReference = []) { + this.name = name; + this.bindings = bindings; + this.index = index; + this.bindingsReference = bindingsReference; + + this.id = _id++; + } +} + +export default BindGroup; diff --git a/src-testing/src/renderers/common/Binding.ts b/src-testing/src/renderers/common/Binding.ts new file mode 100644 index 000000000..a12f3563b --- /dev/null +++ b/src-testing/src/renderers/common/Binding.ts @@ -0,0 +1,17 @@ +class Binding { + constructor(name = '') { + this.name = name; + + this.visibility = 0; + } + + setVisibility(visibility) { + this.visibility |= visibility; + } + + clone() { + return Object.assign(new this.constructor(), this); + } +} + +export default Binding; diff --git a/src-testing/src/renderers/common/Bindings.ts b/src-testing/src/renderers/common/Bindings.ts new file mode 100644 index 000000000..1414c94fb --- /dev/null +++ b/src-testing/src/renderers/common/Bindings.ts @@ -0,0 +1,160 @@ +import DataMap from './DataMap.js'; +import { AttributeType } from './Constants.js'; + +class Bindings extends DataMap { + constructor(backend, nodes, textures, attributes, pipelines, info) { + super(); + + this.backend = backend; + this.textures = textures; + this.pipelines = pipelines; + this.attributes = attributes; + this.nodes = nodes; + this.info = info; + + this.pipelines.bindings = this; // assign bindings to pipelines + } + + getForRender(renderObject) { + const bindings = renderObject.getBindings(); + + for (const bindGroup of bindings) { + const groupData = this.get(bindGroup); + + if (groupData.bindGroup === undefined) { + // each object defines an array of bindings (ubos, textures, samplers etc.) + + this._init(bindGroup); + + this.backend.createBindings(bindGroup, bindings); + + groupData.bindGroup = bindGroup; + } + } + + return bindings; + } + + getForCompute(computeNode) { + const bindings = this.nodes.getForCompute(computeNode).bindings; + + for (const bindGroup of bindings) { + const groupData = this.get(bindGroup); + + if (groupData.bindGroup === undefined) { + this._init(bindGroup); + + this.backend.createBindings(bindGroup, bindings); + + groupData.bindGroup = bindGroup; + } + } + + return bindings; + } + + updateForCompute(computeNode) { + this._updateBindings(this.getForCompute(computeNode)); + } + + updateForRender(renderObject) { + this._updateBindings(this.getForRender(renderObject)); + } + + _updateBindings(bindings) { + for (const bindGroup of bindings) { + this._update(bindGroup, bindings); + } + } + + _init(bindGroup) { + for (const binding of bindGroup.bindings) { + if (binding.isSampledTexture) { + this.textures.updateTexture(binding.texture); + } else if (binding.isStorageBuffer) { + const attribute = binding.attribute; + const attributeType = attribute.isIndirectStorageBufferAttribute + ? AttributeType.INDIRECT + : AttributeType.STORAGE; + + this.attributes.update(attribute, attributeType); + } + } + } + + _update(bindGroup, bindings) { + const { backend } = this; + + let needsBindingsUpdate = false; + + // iterate over all bindings and check if buffer updates or a new binding group is required + + for (const binding of bindGroup.bindings) { + if (binding.isNodeUniformsGroup) { + const updated = this.nodes.updateGroup(binding); + + if (!updated) continue; + } + + if (binding.isUniformBuffer) { + const updated = binding.update(); + + if (updated) { + backend.updateBinding(binding); + } + } else if (binding.isSampler) { + binding.update(); + } else if (binding.isSampledTexture) { + if (binding.needsBindingsUpdate(this.textures.get(binding.texture).generation)) + needsBindingsUpdate = true; + + const updated = binding.update(); + + const texture = binding.texture; + + if (updated) { + this.textures.updateTexture(texture); + } + + const textureData = backend.get(texture); + + if ( + backend.isWebGPUBackend === true && + textureData.texture === undefined && + textureData.externalTexture === undefined + ) { + // TODO: Remove this once we found why updated === false isn't bound to a texture in the WebGPU backend + console.error( + 'Bindings._update: binding should be available:', + binding, + updated, + texture, + binding.textureNode.value, + needsBindingsUpdate, + ); + + this.textures.updateTexture(texture); + needsBindingsUpdate = true; + } + + if (texture.isStorageTexture === true) { + const textureData = this.get(texture); + + if (binding.store === true) { + textureData.needsMipmap = true; + } else if (this.textures.needsMipmaps(texture) && textureData.needsMipmap === true) { + this.backend.generateMipmaps(texture); + + textureData.needsMipmap = false; + } + } + } + } + + if (needsBindingsUpdate === true) { + this.backend.updateBindings(bindGroup, bindings); + } + } +} + +export default Bindings; diff --git a/src-testing/src/renderers/common/Buffer.ts b/src-testing/src/renderers/common/Buffer.ts new file mode 100644 index 000000000..17013c6dc --- /dev/null +++ b/src-testing/src/renderers/common/Buffer.ts @@ -0,0 +1,28 @@ +import Binding from './Binding.js'; +import { getFloatLength } from './BufferUtils.js'; + +class Buffer extends Binding { + constructor(name, buffer = null) { + super(name); + + this.isBuffer = true; + + this.bytesPerElement = Float32Array.BYTES_PER_ELEMENT; + + this._buffer = buffer; + } + + get byteLength() { + return getFloatLength(this._buffer.byteLength); + } + + get buffer() { + return this._buffer; + } + + update() { + return true; + } +} + +export default Buffer; diff --git a/src-testing/src/renderers/common/BufferUtils.ts b/src-testing/src/renderers/common/BufferUtils.ts new file mode 100644 index 000000000..99ddcb48b --- /dev/null +++ b/src-testing/src/renderers/common/BufferUtils.ts @@ -0,0 +1,23 @@ +import { GPU_CHUNK_BYTES } from './Constants.js'; + +function getFloatLength(floatLength) { + // ensure chunk size alignment (STD140 layout) + + return floatLength + ((GPU_CHUNK_BYTES - (floatLength % GPU_CHUNK_BYTES)) % GPU_CHUNK_BYTES); +} + +function getVectorLength(count, vectorLength = 4) { + const strideLength = getStrideLength(vectorLength); + + const floatLength = strideLength * count; + + return getFloatLength(floatLength); +} + +function getStrideLength(vectorLength) { + const strideLength = 4; + + return vectorLength + ((strideLength - (vectorLength % strideLength)) % strideLength); +} + +export { getFloatLength, getVectorLength, getStrideLength }; diff --git a/src-testing/src/renderers/common/BundleGroup.ts b/src-testing/src/renderers/common/BundleGroup.ts new file mode 100644 index 000000000..1dd8e0a2c --- /dev/null +++ b/src-testing/src/renderers/common/BundleGroup.ts @@ -0,0 +1,20 @@ +import { Group } from '../../objects/Group.js'; + +class BundleGroup extends Group { + constructor() { + super(); + + this.isBundleGroup = true; + + this.type = 'BundleGroup'; + + this.static = true; + this.version = 0; + } + + set needsUpdate(value) { + if (value === true) this.version++; + } +} + +export default BundleGroup; diff --git a/src-testing/src/renderers/common/ChainMap.ts b/src-testing/src/renderers/common/ChainMap.ts new file mode 100644 index 000000000..b17e7080f --- /dev/null +++ b/src-testing/src/renderers/common/ChainMap.ts @@ -0,0 +1,43 @@ +export default class ChainMap { + constructor() { + this.weakMap = new WeakMap(); + } + + get(keys) { + let map = this.weakMap; + + for (let i = 0; i < keys.length; i++) { + map = map.get(keys[i]); + + if (map === undefined) return undefined; + } + + return map.get(keys[keys.length - 1]); + } + + set(keys, value) { + let map = this.weakMap; + + for (let i = 0; i < keys.length; i++) { + const key = keys[i]; + + if (map.has(key) === false) map.set(key, new WeakMap()); + + map = map.get(key); + } + + return map.set(keys[keys.length - 1], value); + } + + delete(keys) { + let map = this.weakMap; + + for (let i = 0; i < keys.length; i++) { + map = map.get(keys[i]); + + if (map === undefined) return false; + } + + return map.delete(keys[keys.length - 1]); + } +} diff --git a/src-testing/src/renderers/common/ClippingContext.ts b/src-testing/src/renderers/common/ClippingContext.ts new file mode 100644 index 000000000..c5659721a --- /dev/null +++ b/src-testing/src/renderers/common/ClippingContext.ts @@ -0,0 +1,136 @@ +import { Matrix3 } from '../../math/Matrix3.js'; +import { Plane } from '../../math/Plane.js'; +import { Vector4 } from '../../math/Vector4.js'; +import { hash } from '../../nodes/core/NodeUtils.js'; + +const _plane = /*@__PURE__*/ new Plane(); + +class ClippingContext { + constructor() { + this.version = 0; + + this.globalClippingCount = 0; + + this.localClippingCount = 0; + this.localClippingEnabled = false; + this.localClipIntersection = false; + + this.planes = []; + + this.parentVersion = 0; + this.viewNormalMatrix = new Matrix3(); + this.cacheKey = 0; + } + + projectPlanes(source, offset) { + const l = source.length; + const planes = this.planes; + + for (let i = 0; i < l; i++) { + _plane.copy(source[i]).applyMatrix4(this.viewMatrix, this.viewNormalMatrix); + + const v = planes[offset + i]; + const normal = _plane.normal; + + v.x = -normal.x; + v.y = -normal.y; + v.z = -normal.z; + v.w = _plane.constant; + } + } + + updateGlobal(renderer, camera) { + const rendererClippingPlanes = renderer.clippingPlanes; + this.viewMatrix = camera.matrixWorldInverse; + + this.viewNormalMatrix.getNormalMatrix(this.viewMatrix); + + let update = false; + + if (Array.isArray(rendererClippingPlanes) && rendererClippingPlanes.length !== 0) { + const l = rendererClippingPlanes.length; + + if (l !== this.globalClippingCount) { + const planes = []; + + for (let i = 0; i < l; i++) { + planes.push(new Vector4()); + } + + this.globalClippingCount = l; + this.planes = planes; + + update = true; + } + + this.projectPlanes(rendererClippingPlanes, 0); + } else if (this.globalClippingCount !== 0) { + this.globalClippingCount = 0; + this.planes = []; + update = true; + } + + if (renderer.localClippingEnabled !== this.localClippingEnabled) { + this.localClippingEnabled = renderer.localClippingEnabled; + update = true; + } + + if (update) { + this.version++; + this.cacheKey = hash(this.globalClippingCount, this.localClippingEnabled === true ? 1 : 0); + } + } + + update(parent, material) { + let update = false; + + if (this !== parent && parent.version !== this.parentVersion) { + this.globalClippingCount = material.isShadowNodeMaterial ? 0 : parent.globalClippingCount; + this.localClippingEnabled = parent.localClippingEnabled; + this.planes = Array.from(parent.planes); + this.parentVersion = parent.version; + this.viewMatrix = parent.viewMatrix; + this.viewNormalMatrix = parent.viewNormalMatrix; + + update = true; + } + + if (this.localClippingEnabled) { + const localClippingPlanes = material.clippingPlanes; + + if (Array.isArray(localClippingPlanes) && localClippingPlanes.length !== 0) { + const l = localClippingPlanes.length; + const planes = this.planes; + const offset = this.globalClippingCount; + + if (update || l !== this.localClippingCount) { + planes.length = offset + l; + + for (let i = 0; i < l; i++) { + planes[offset + i] = new Vector4(); + } + + this.localClippingCount = l; + update = true; + } + + this.projectPlanes(localClippingPlanes, offset); + } else if (this.localClippingCount !== 0) { + this.localClippingCount = 0; + update = true; + } + + if (this.localClipIntersection !== material.clipIntersection) { + this.localClipIntersection = material.clipIntersection; + update = true; + } + } + + if (update) { + this.version += parent.version; + this.cacheKey = hash(parent.cacheKey, this.localClippingCount, this.localClipIntersection === true ? 1 : 0); + } + } +} + +export default ClippingContext; diff --git a/src-testing/src/renderers/common/Color4.ts b/src-testing/src/renderers/common/Color4.ts new file mode 100644 index 000000000..77caa31e0 --- /dev/null +++ b/src-testing/src/renderers/common/Color4.ts @@ -0,0 +1,27 @@ +import { Color } from '../../math/Color.js'; + +class Color4 extends Color { + constructor(r, g, b, a = 1) { + super(r, g, b); + + this.a = a; + } + + set(r, g, b, a = 1) { + this.a = a; + + return super.set(r, g, b); + } + + copy(color) { + if (color.a !== undefined) this.a = color.a; + + return super.copy(color); + } + + clone() { + return new this.constructor(this.r, this.g, this.b, this.a); + } +} + +export default Color4; diff --git a/src-testing/src/renderers/common/ComputePipeline.ts b/src-testing/src/renderers/common/ComputePipeline.ts new file mode 100644 index 000000000..0fd3ca531 --- /dev/null +++ b/src-testing/src/renderers/common/ComputePipeline.ts @@ -0,0 +1,13 @@ +import Pipeline from './Pipeline.js'; + +class ComputePipeline extends Pipeline { + constructor(cacheKey, computeProgram) { + super(cacheKey); + + this.computeProgram = computeProgram; + + this.isComputePipeline = true; + } +} + +export default ComputePipeline; diff --git a/src-testing/src/renderers/common/Constants.ts b/src-testing/src/renderers/common/Constants.ts new file mode 100644 index 000000000..c2dfad4c4 --- /dev/null +++ b/src-testing/src/renderers/common/Constants.ts @@ -0,0 +1,15 @@ +export const AttributeType = { + VERTEX: 1, + INDEX: 2, + STORAGE: 3, + INDIRECT: 4, +}; + +// size of a chunk in bytes (STD140 layout) + +export const GPU_CHUNK_BYTES = 16; + +// @TODO: Move to src/constants.js + +export const BlendColorFactor = 211; +export const OneMinusBlendColorFactor = 212; diff --git a/src-testing/src/renderers/common/CubeRenderTarget.ts b/src-testing/src/renderers/common/CubeRenderTarget.ts new file mode 100644 index 000000000..00c0fd8c4 --- /dev/null +++ b/src-testing/src/renderers/common/CubeRenderTarget.ts @@ -0,0 +1,71 @@ +import { equirectUV } from '../../nodes/utils/EquirectUVNode.js'; +import { texture as TSL_Texture } from '../../nodes/accessors/TextureNode.js'; +import { positionWorldDirection } from '../../nodes/accessors/Position.js'; +import NodeMaterial from '../../materials/nodes/NodeMaterial.js'; + +import { WebGLCubeRenderTarget } from '../../renderers/WebGLCubeRenderTarget.js'; +import { Scene } from '../../scenes/Scene.js'; +import { CubeCamera } from '../../cameras/CubeCamera.js'; +import { BoxGeometry } from '../../geometries/BoxGeometry.js'; +import { Mesh } from '../../objects/Mesh.js'; +import { BackSide, NoBlending, LinearFilter, LinearMipmapLinearFilter } from '../../constants.js'; + +// @TODO: Consider rename WebGLCubeRenderTarget to just CubeRenderTarget + +class CubeRenderTarget extends WebGLCubeRenderTarget { + constructor(size = 1, options = {}) { + super(size, options); + + this.isCubeRenderTarget = true; + } + + fromEquirectangularTexture(renderer, texture) { + const currentMinFilter = texture.minFilter; + const currentGenerateMipmaps = texture.generateMipmaps; + + texture.generateMipmaps = true; + + this.texture.type = texture.type; + this.texture.colorSpace = texture.colorSpace; + + this.texture.generateMipmaps = texture.generateMipmaps; + this.texture.minFilter = texture.minFilter; + this.texture.magFilter = texture.magFilter; + + const geometry = new BoxGeometry(5, 5, 5); + + const uvNode = equirectUV(positionWorldDirection); + + const material = new NodeMaterial(); + material.colorNode = TSL_Texture(texture, uvNode, 0); + material.side = BackSide; + material.blending = NoBlending; + + const mesh = new Mesh(geometry, material); + + const scene = new Scene(); + scene.add(mesh); + + // Avoid blurred poles + if (texture.minFilter === LinearMipmapLinearFilter) texture.minFilter = LinearFilter; + + const camera = new CubeCamera(1, 10, this); + + const currentMRT = renderer.getMRT(); + renderer.setMRT(null); + + camera.update(renderer, scene); + + renderer.setMRT(currentMRT); + + texture.minFilter = currentMinFilter; + texture.currentGenerateMipmaps = currentGenerateMipmaps; + + mesh.geometry.dispose(); + mesh.material.dispose(); + + return this; + } +} + +export default CubeRenderTarget; diff --git a/src-testing/src/renderers/common/DataMap.ts b/src-testing/src/renderers/common/DataMap.ts new file mode 100644 index 000000000..006bc2950 --- /dev/null +++ b/src-testing/src/renderers/common/DataMap.ts @@ -0,0 +1,38 @@ +class DataMap { + constructor() { + this.data = new WeakMap(); + } + + get(object) { + let map = this.data.get(object); + + if (map === undefined) { + map = {}; + this.data.set(object, map); + } + + return map; + } + + delete(object) { + let map; + + if (this.data.has(object)) { + map = this.data.get(object); + + this.data.delete(object); + } + + return map; + } + + has(object) { + return this.data.has(object); + } + + dispose() { + this.data = new WeakMap(); + } +} + +export default DataMap; diff --git a/src-testing/src/renderers/common/Geometries.ts b/src-testing/src/renderers/common/Geometries.ts new file mode 100644 index 000000000..14c52f6f6 --- /dev/null +++ b/src-testing/src/renderers/common/Geometries.ts @@ -0,0 +1,199 @@ +import DataMap from './DataMap.js'; +import { AttributeType } from './Constants.js'; + +import { Uint16BufferAttribute, Uint32BufferAttribute } from '../../core/BufferAttribute.js'; + +function arrayNeedsUint32(array) { + // assumes larger values usually on last + + for (let i = array.length - 1; i >= 0; --i) { + if (array[i] >= 65535) return true; // account for PRIMITIVE_RESTART_FIXED_INDEX, #24565 + } + + return false; +} + +function getWireframeVersion(geometry) { + return geometry.index !== null ? geometry.index.version : geometry.attributes.position.version; +} + +function getWireframeIndex(geometry) { + const indices = []; + + const geometryIndex = geometry.index; + const geometryPosition = geometry.attributes.position; + + if (geometryIndex !== null) { + const array = geometryIndex.array; + + for (let i = 0, l = array.length; i < l; i += 3) { + const a = array[i + 0]; + const b = array[i + 1]; + const c = array[i + 2]; + + indices.push(a, b, b, c, c, a); + } + } else { + const array = geometryPosition.array; + + for (let i = 0, l = array.length / 3 - 1; i < l; i += 3) { + const a = i + 0; + const b = i + 1; + const c = i + 2; + + indices.push(a, b, b, c, c, a); + } + } + + const attribute = new (arrayNeedsUint32(indices) ? Uint32BufferAttribute : Uint16BufferAttribute)(indices, 1); + attribute.version = getWireframeVersion(geometry); + + return attribute; +} + +class Geometries extends DataMap { + constructor(attributes, info) { + super(); + + this.attributes = attributes; + this.info = info; + + this.wireframes = new WeakMap(); + + this.attributeCall = new WeakMap(); + } + + has(renderObject) { + const geometry = renderObject.geometry; + + return super.has(geometry) && this.get(geometry).initialized === true; + } + + updateForRender(renderObject) { + if (this.has(renderObject) === false) this.initGeometry(renderObject); + + this.updateAttributes(renderObject); + } + + initGeometry(renderObject) { + const geometry = renderObject.geometry; + const geometryData = this.get(geometry); + + geometryData.initialized = true; + + this.info.memory.geometries++; + + const onDispose = () => { + this.info.memory.geometries--; + + const index = geometry.index; + const geometryAttributes = renderObject.getAttributes(); + + if (index !== null) { + this.attributes.delete(index); + } + + for (const geometryAttribute of geometryAttributes) { + this.attributes.delete(geometryAttribute); + } + + const wireframeAttribute = this.wireframes.get(geometry); + + if (wireframeAttribute !== undefined) { + this.attributes.delete(wireframeAttribute); + } + + geometry.removeEventListener('dispose', onDispose); + }; + + geometry.addEventListener('dispose', onDispose); + } + + updateAttributes(renderObject) { + // attributes + + const attributes = renderObject.getAttributes(); + + for (const attribute of attributes) { + if (attribute.isStorageBufferAttribute || attribute.isStorageInstancedBufferAttribute) { + this.updateAttribute(attribute, AttributeType.STORAGE); + } else { + this.updateAttribute(attribute, AttributeType.VERTEX); + } + } + + // indexes + + const index = this.getIndex(renderObject); + + if (index !== null) { + this.updateAttribute(index, AttributeType.INDEX); + } + + // indirect + + const indirect = renderObject.geometry.indirect; + + if (indirect !== null) { + this.updateAttribute(indirect, AttributeType.INDIRECT); + } + } + + updateAttribute(attribute, type) { + const callId = this.info.render.calls; + + if (!attribute.isInterleavedBufferAttribute) { + if (this.attributeCall.get(attribute) !== callId) { + this.attributes.update(attribute, type); + + this.attributeCall.set(attribute, callId); + } + } else { + if (this.attributeCall.get(attribute) === undefined) { + this.attributes.update(attribute, type); + + this.attributeCall.set(attribute, callId); + } else if (this.attributeCall.get(attribute.data) !== callId) { + this.attributes.update(attribute, type); + + this.attributeCall.set(attribute.data, callId); + + this.attributeCall.set(attribute, callId); + } + } + } + + getIndirect(renderObject) { + return renderObject.geometry.indirect; + } + + getIndex(renderObject) { + const { geometry, material } = renderObject; + + let index = geometry.index; + + if (material.wireframe === true) { + const wireframes = this.wireframes; + + let wireframeAttribute = wireframes.get(geometry); + + if (wireframeAttribute === undefined) { + wireframeAttribute = getWireframeIndex(geometry); + + wireframes.set(geometry, wireframeAttribute); + } else if (wireframeAttribute.version !== getWireframeVersion(geometry)) { + this.attributes.delete(wireframeAttribute); + + wireframeAttribute = getWireframeIndex(geometry); + + wireframes.set(geometry, wireframeAttribute); + } + + index = wireframeAttribute; + } + + return index; + } +} + +export default Geometries; diff --git a/src-testing/src/renderers/common/IndirectStorageBufferAttribute.d.ts b/src-testing/src/renderers/common/IndirectStorageBufferAttribute.d.ts new file mode 100644 index 000000000..925294395 --- /dev/null +++ b/src-testing/src/renderers/common/IndirectStorageBufferAttribute.d.ts @@ -0,0 +1,10 @@ +import { TypedArray } from "../../core/BufferAttribute.js"; +import StorageBufferAttribute from "./StorageBufferAttribute.js"; + +declare class IndirectStorageBufferAttribute extends StorageBufferAttribute { + readonly isIndirectStorageBufferAttribute: true; + + constructor(array: TypedArray, itemSize: number); +} + +export default IndirectStorageBufferAttribute; diff --git a/src-testing/src/renderers/common/Info.ts b/src-testing/src/renderers/common/Info.ts new file mode 100644 index 000000000..4ede75de7 --- /dev/null +++ b/src-testing/src/renderers/common/Info.ts @@ -0,0 +1,95 @@ +class Info { + constructor() { + this.autoReset = true; + + this.frame = 0; + this.calls = 0; + + this.render = { + calls: 0, + frameCalls: 0, + drawCalls: 0, + triangles: 0, + points: 0, + lines: 0, + timestamp: 0, + previousFrameCalls: 0, + timestampCalls: 0, + }; + + this.compute = { + calls: 0, + frameCalls: 0, + timestamp: 0, + previousFrameCalls: 0, + timestampCalls: 0, + }; + + this.memory = { + geometries: 0, + textures: 0, + }; + } + + update(object, count, instanceCount) { + this.render.drawCalls++; + + if (object.isMesh || object.isSprite) { + this.render.triangles += instanceCount * (count / 3); + } else if (object.isPoints) { + this.render.points += instanceCount * count; + } else if (object.isLineSegments) { + this.render.lines += instanceCount * (count / 2); + } else if (object.isLine) { + this.render.lines += instanceCount * (count - 1); + } else { + console.error('THREE.WebGPUInfo: Unknown object type.'); + } + } + + updateTimestamp(type, time) { + if (this[type].timestampCalls === 0) { + this[type].timestamp = 0; + } + + this[type].timestamp += time; + + this[type].timestampCalls++; + + if (this[type].timestampCalls >= this[type].previousFrameCalls) { + this[type].timestampCalls = 0; + } + } + + reset() { + const previousRenderFrameCalls = this.render.frameCalls; + this.render.previousFrameCalls = previousRenderFrameCalls; + + const previousComputeFrameCalls = this.compute.frameCalls; + this.compute.previousFrameCalls = previousComputeFrameCalls; + + this.render.drawCalls = 0; + this.render.frameCalls = 0; + this.compute.frameCalls = 0; + + this.render.triangles = 0; + this.render.points = 0; + this.render.lines = 0; + } + + dispose() { + this.reset(); + + this.calls = 0; + + this.render.calls = 0; + this.compute.calls = 0; + + this.render.timestamp = 0; + this.compute.timestamp = 0; + this.memory.geometries = 0; + this.memory.textures = 0; + } +} + +export default Info; diff --git a/src-testing/src/renderers/common/Lighting.d.ts b/src-testing/src/renderers/common/Lighting.d.ts new file mode 100644 index 000000000..72842e6e7 --- /dev/null +++ b/src-testing/src/renderers/common/Lighting.d.ts @@ -0,0 +1,15 @@ +import { Camera } from "../../cameras/Camera.js"; +import { Object3D } from "../../core/Object3D.js"; +import { Light } from "../../lights/Light.js"; +import LightsNode from "../../nodes/lighting/LightsNode.js"; +import ChainMap from "./ChainMap.js"; + +declare class Lighting extends ChainMap<[Object3D, Camera], LightsNode> { + constructor(); + + createNode(lights?: Light[]): LightsNode; + + getNode(scene: Object3D, camera: Camera): LightsNode; +} + +export default Lighting; diff --git a/src-testing/src/renderers/common/Pipeline.ts b/src-testing/src/renderers/common/Pipeline.ts new file mode 100644 index 000000000..16017455a --- /dev/null +++ b/src-testing/src/renderers/common/Pipeline.ts @@ -0,0 +1,9 @@ +class Pipeline { + constructor(cacheKey) { + this.cacheKey = cacheKey; + + this.usedTimes = 0; + } +} + +export default Pipeline; diff --git a/src-testing/src/renderers/common/Pipelines.ts b/src-testing/src/renderers/common/Pipelines.ts new file mode 100644 index 000000000..68c8f223c --- /dev/null +++ b/src-testing/src/renderers/common/Pipelines.ts @@ -0,0 +1,270 @@ +import DataMap from './DataMap.js'; +import RenderPipeline from './RenderPipeline.js'; +import ComputePipeline from './ComputePipeline.js'; +import ProgrammableStage from './ProgrammableStage.js'; + +class Pipelines extends DataMap { + constructor(backend, nodes) { + super(); + + this.backend = backend; + this.nodes = nodes; + + this.bindings = null; // set by the bindings + + this.caches = new Map(); + this.programs = { + vertex: new Map(), + fragment: new Map(), + compute: new Map(), + }; + } + + getForCompute(computeNode, bindings) { + const { backend } = this; + + const data = this.get(computeNode); + + if (this._needsComputeUpdate(computeNode)) { + const previousPipeline = data.pipeline; + + if (previousPipeline) { + previousPipeline.usedTimes--; + previousPipeline.computeProgram.usedTimes--; + } + + // get shader + + const nodeBuilderState = this.nodes.getForCompute(computeNode); + + // programmable stage + + let stageCompute = this.programs.compute.get(nodeBuilderState.computeShader); + + if (stageCompute === undefined) { + if (previousPipeline && previousPipeline.computeProgram.usedTimes === 0) + this._releaseProgram(previousPipeline.computeProgram); + + stageCompute = new ProgrammableStage( + nodeBuilderState.computeShader, + 'compute', + nodeBuilderState.transforms, + nodeBuilderState.nodeAttributes, + ); + this.programs.compute.set(nodeBuilderState.computeShader, stageCompute); + + backend.createProgram(stageCompute); + } + + // determine compute pipeline + + const cacheKey = this._getComputeCacheKey(computeNode, stageCompute); + + let pipeline = this.caches.get(cacheKey); + + if (pipeline === undefined) { + if (previousPipeline && previousPipeline.usedTimes === 0) this._releasePipeline(previousPipeline); + + pipeline = this._getComputePipeline(computeNode, stageCompute, cacheKey, bindings); + } + + // keep track of all used times + + pipeline.usedTimes++; + stageCompute.usedTimes++; + + // + + data.version = computeNode.version; + data.pipeline = pipeline; + } + + return data.pipeline; + } + + getForRender(renderObject, promises = null) { + const { backend } = this; + + const data = this.get(renderObject); + + if (this._needsRenderUpdate(renderObject)) { + const previousPipeline = data.pipeline; + + if (previousPipeline) { + previousPipeline.usedTimes--; + previousPipeline.vertexProgram.usedTimes--; + previousPipeline.fragmentProgram.usedTimes--; + } + + // get shader + + const nodeBuilderState = renderObject.getNodeBuilderState(); + + // programmable stages + + let stageVertex = this.programs.vertex.get(nodeBuilderState.vertexShader); + + if (stageVertex === undefined) { + if (previousPipeline && previousPipeline.vertexProgram.usedTimes === 0) + this._releaseProgram(previousPipeline.vertexProgram); + + stageVertex = new ProgrammableStage(nodeBuilderState.vertexShader, 'vertex'); + this.programs.vertex.set(nodeBuilderState.vertexShader, stageVertex); + + backend.createProgram(stageVertex); + } + + let stageFragment = this.programs.fragment.get(nodeBuilderState.fragmentShader); + + if (stageFragment === undefined) { + if (previousPipeline && previousPipeline.fragmentProgram.usedTimes === 0) + this._releaseProgram(previousPipeline.fragmentProgram); + + stageFragment = new ProgrammableStage(nodeBuilderState.fragmentShader, 'fragment'); + this.programs.fragment.set(nodeBuilderState.fragmentShader, stageFragment); + + backend.createProgram(stageFragment); + } + + // determine render pipeline + + const cacheKey = this._getRenderCacheKey(renderObject, stageVertex, stageFragment); + + let pipeline = this.caches.get(cacheKey); + + if (pipeline === undefined) { + if (previousPipeline && previousPipeline.usedTimes === 0) this._releasePipeline(previousPipeline); + + pipeline = this._getRenderPipeline(renderObject, stageVertex, stageFragment, cacheKey, promises); + } else { + renderObject.pipeline = pipeline; + } + + // keep track of all used times + + pipeline.usedTimes++; + stageVertex.usedTimes++; + stageFragment.usedTimes++; + + // + + data.pipeline = pipeline; + } + + return data.pipeline; + } + + delete(object) { + const pipeline = this.get(object).pipeline; + + if (pipeline) { + // pipeline + + pipeline.usedTimes--; + + if (pipeline.usedTimes === 0) this._releasePipeline(pipeline); + + // programs + + if (pipeline.isComputePipeline) { + pipeline.computeProgram.usedTimes--; + + if (pipeline.computeProgram.usedTimes === 0) this._releaseProgram(pipeline.computeProgram); + } else { + pipeline.fragmentProgram.usedTimes--; + pipeline.vertexProgram.usedTimes--; + + if (pipeline.vertexProgram.usedTimes === 0) this._releaseProgram(pipeline.vertexProgram); + if (pipeline.fragmentProgram.usedTimes === 0) this._releaseProgram(pipeline.fragmentProgram); + } + } + + return super.delete(object); + } + + dispose() { + super.dispose(); + + this.caches = new Map(); + this.programs = { + vertex: new Map(), + fragment: new Map(), + compute: new Map(), + }; + } + + updateForRender(renderObject) { + this.getForRender(renderObject); + } + + _getComputePipeline(computeNode, stageCompute, cacheKey, bindings) { + // check for existing pipeline + + cacheKey = cacheKey || this._getComputeCacheKey(computeNode, stageCompute); + + let pipeline = this.caches.get(cacheKey); + + if (pipeline === undefined) { + pipeline = new ComputePipeline(cacheKey, stageCompute); + + this.caches.set(cacheKey, pipeline); + + this.backend.createComputePipeline(pipeline, bindings); + } + + return pipeline; + } + + _getRenderPipeline(renderObject, stageVertex, stageFragment, cacheKey, promises) { + // check for existing pipeline + + cacheKey = cacheKey || this._getRenderCacheKey(renderObject, stageVertex, stageFragment); + + let pipeline = this.caches.get(cacheKey); + + if (pipeline === undefined) { + pipeline = new RenderPipeline(cacheKey, stageVertex, stageFragment); + + this.caches.set(cacheKey, pipeline); + + renderObject.pipeline = pipeline; + + this.backend.createRenderPipeline(renderObject, promises); + } + + return pipeline; + } + + _getComputeCacheKey(computeNode, stageCompute) { + return computeNode.id + ',' + stageCompute.id; + } + + _getRenderCacheKey(renderObject, stageVertex, stageFragment) { + return stageVertex.id + ',' + stageFragment.id + ',' + this.backend.getRenderCacheKey(renderObject); + } + + _releasePipeline(pipeline) { + this.caches.delete(pipeline.cacheKey); + } + + _releaseProgram(program) { + const code = program.code; + const stage = program.stage; + + this.programs[stage].delete(code); + } + + _needsComputeUpdate(computeNode) { + const data = this.get(computeNode); + + return data.pipeline === undefined || data.version !== computeNode.version; + } + + _needsRenderUpdate(renderObject) { + const data = this.get(renderObject); + + return data.pipeline === undefined || this.backend.needsRenderUpdate(renderObject); + } +} + +export default Pipelines; diff --git a/src-testing/src/renderers/common/PostProcessing.d.ts b/src-testing/src/renderers/common/PostProcessing.d.ts new file mode 100644 index 000000000..fdd4e5bdc --- /dev/null +++ b/src-testing/src/renderers/common/PostProcessing.d.ts @@ -0,0 +1,21 @@ +import { Node } from "../../nodes/Nodes.js"; +import Renderer from "./Renderer.js"; + +declare class PostProcessing { + renderer: Renderer; + outputNode: Node; + + outputColorTransform: boolean; + + needsUpdate: boolean; + + constructor(renderer: Renderer, outputNode?: Node); + + render(): void; + + update(): void; + + renderAsync(): Promise; +} + +export default PostProcessing; diff --git a/src-testing/src/renderers/common/PostProcessingUtils.d.ts b/src-testing/src/renderers/common/PostProcessingUtils.d.ts new file mode 100644 index 000000000..2ef80556c --- /dev/null +++ b/src-testing/src/renderers/common/PostProcessingUtils.d.ts @@ -0,0 +1,66 @@ +import { Camera } from "../../cameras/Camera.js"; +import { ToneMapping } from "../../constants.js"; +import { BufferGeometry, GeometryGroup } from "../../core/BufferGeometry.js"; +import { Object3D } from "../../core/Object3D.js"; +import { RenderTarget } from "../../core/RenderTarget.js"; +import { Material } from "../../materials/Material.js"; +import { Color } from "../../math/Color.js"; +import MRTNode from "../../nodes/core/MRTNode.js"; +import LightsNode from "../../nodes/lighting/LightsNode.js"; +import { Scene } from "../../scenes/Scene.js"; +import { CubeTexture } from "../../textures/CubeTexture.js"; +import { Texture } from "../../textures/Texture.js"; +import Color4 from "./Color4.js"; +import Renderer from "./Renderer.js"; + +// renderer state + +export interface RendererState { + toneMapping: ToneMapping; + toneMappingExposure: number; + outputColorSpace: string; + renderTarget: RenderTarget | null; + activeCubeFace: number; + activeMipmapLevel: number; + renderObjectFunction: + | (( + object: Object3D, + scene: Scene, + camera: Camera, + geometry: BufferGeometry, + material: Material, + group: GeometryGroup, + lightsNode: LightsNode, + ) => void) + | null; + pixelRatio: number; + mrt: MRTNode | null; + clearColor: Color4; + clearAlpha: number; + autoClear: boolean; + scissorTest: boolean; +} + +export function saveRendererState(renderer: Renderer, state?: RendererState): RendererState; + +export function resetRendererState(renderer: Renderer, state?: RendererState): RendererState; + +export function restoreRendererState(renderer: Renderer, state: RendererState): void; + +// renderer and scene state + +export interface RendererAndSceneState extends RendererState { + background: Color | Texture | CubeTexture | null; + backgroundNode: Node | null | undefined; + overrideMaterial: Material | null; +} + +export function saveRendererAndSceneState( + renderer: RendererState, + scene: Scene, + state?: RendererAndSceneState, +): RendererAndSceneState; + +export function resetRendererAndSceneState(renderer: Renderer, state?: RendererAndSceneState): RendererAndSceneState; + +export function restoreRendererAndSceneState(renderer: Renderer, state: RendererAndSceneState): void; diff --git a/src-testing/src/renderers/common/ProgrammableStage.ts b/src-testing/src/renderers/common/ProgrammableStage.ts new file mode 100644 index 000000000..a684e4443 --- /dev/null +++ b/src-testing/src/renderers/common/ProgrammableStage.ts @@ -0,0 +1,16 @@ +let _id = 0; + +class ProgrammableStage { + constructor(code, type, transforms = null, attributes = null) { + this.id = _id++; + + this.code = code; + this.stage = type; + this.transforms = transforms; + this.attributes = attributes; + + this.usedTimes = 0; + } +} + +export default ProgrammableStage; diff --git a/src-testing/src/renderers/common/QuadMesh.d.ts b/src-testing/src/renderers/common/QuadMesh.d.ts new file mode 100644 index 000000000..ee2bb93ba --- /dev/null +++ b/src-testing/src/renderers/common/QuadMesh.d.ts @@ -0,0 +1,16 @@ +import { OrthographicCamera } from "../../cameras/OrthographicCamera.js"; +import { Material } from "../../materials/Material.js"; +import { Mesh } from "../../objects/Mesh.js"; +import Renderer from "./Renderer.js"; + +export default class QuadMesh extends Mesh { + camera: OrthographicCamera; + + readonly isQuadMesh: true; + + constructor(material?: Material | null); + + renderAsync(renderer: Renderer): Promise; + + render(renderer: Renderer): void; +} diff --git a/src-testing/src/renderers/common/RenderBundle.ts b/src-testing/src/renderers/common/RenderBundle.ts new file mode 100644 index 000000000..e59e49378 --- /dev/null +++ b/src-testing/src/renderers/common/RenderBundle.ts @@ -0,0 +1,12 @@ +class RenderBundle { + constructor(scene, camera) { + this.scene = scene; + this.camera = camera; + } + + clone() { + return Object.assign(new this.constructor(), this); + } +} + +export default RenderBundle; diff --git a/src-testing/src/renderers/common/RenderBundles.ts b/src-testing/src/renderers/common/RenderBundles.ts new file mode 100644 index 000000000..291403652 --- /dev/null +++ b/src-testing/src/renderers/common/RenderBundles.ts @@ -0,0 +1,28 @@ +import ChainMap from './ChainMap.js'; +import RenderBundle from './RenderBundle.js'; + +class RenderBundles { + constructor() { + this.lists = new ChainMap(); + } + + get(scene, camera) { + const lists = this.lists; + const keys = [scene, camera]; + + let list = lists.get(keys); + + if (list === undefined) { + list = new RenderBundle(scene, camera); + lists.set(keys, list); + } + + return list; + } + + dispose() { + this.lists = new ChainMap(); + } +} + +export default RenderBundles; diff --git a/src-testing/src/renderers/common/RenderContext.ts b/src-testing/src/renderers/common/RenderContext.ts new file mode 100644 index 000000000..9b5ee3a28 --- /dev/null +++ b/src-testing/src/renderers/common/RenderContext.ts @@ -0,0 +1,56 @@ +import { Vector4 } from '../../math/Vector4.js'; +import { hashArray } from '../../nodes/core/NodeUtils.js'; + +let id = 0; + +class RenderContext { + constructor() { + this.id = id++; + + this.color = true; + this.clearColor = true; + this.clearColorValue = { r: 0, g: 0, b: 0, a: 1 }; + + this.depth = true; + this.clearDepth = true; + this.clearDepthValue = 1; + + this.stencil = false; + this.clearStencil = true; + this.clearStencilValue = 1; + + this.viewport = false; + this.viewportValue = new Vector4(); + + this.scissor = false; + this.scissorValue = new Vector4(); + + this.textures = null; + this.depthTexture = null; + this.activeCubeFace = 0; + this.sampleCount = 1; + + this.width = 0; + this.height = 0; + + this.isRenderContext = true; + } + + getCacheKey() { + return getCacheKey(this); + } +} + +export function getCacheKey(renderContext) { + const { textures, activeCubeFace } = renderContext; + + const values = [activeCubeFace]; + + for (const texture of textures) { + values.push(texture.id); + } + + return hashArray(values); +} + +export default RenderContext; diff --git a/src-testing/src/renderers/common/RenderContexts.ts b/src-testing/src/renderers/common/RenderContexts.ts new file mode 100644 index 000000000..e77308c1d --- /dev/null +++ b/src-testing/src/renderers/common/RenderContexts.ts @@ -0,0 +1,47 @@ +import ChainMap from './ChainMap.js'; +import RenderContext from './RenderContext.js'; + +class RenderContexts { + constructor() { + this.chainMaps = {}; + } + + get(scene, camera, renderTarget = null) { + const chainKey = [scene, camera]; + + let attachmentState; + + if (renderTarget === null) { + attachmentState = 'default'; + } else { + const format = renderTarget.texture.format; + const count = renderTarget.textures.length; + + attachmentState = `${count}:${format}:${renderTarget.samples}:${renderTarget.depthBuffer}:${renderTarget.stencilBuffer}`; + } + + const chainMap = this.getChainMap(attachmentState); + + let renderState = chainMap.get(chainKey); + + if (renderState === undefined) { + renderState = new RenderContext(); + + chainMap.set(chainKey, renderState); + } + + if (renderTarget !== null) renderState.sampleCount = renderTarget.samples === 0 ? 1 : renderTarget.samples; + + return renderState; + } + + getChainMap(attachmentState) { + return this.chainMaps[attachmentState] || (this.chainMaps[attachmentState] = new ChainMap()); + } + + dispose() { + this.chainMaps = {}; + } +} + +export default RenderContexts; diff --git a/src-testing/src/renderers/common/RenderList.ts b/src-testing/src/renderers/common/RenderList.ts new file mode 100644 index 000000000..63d236dd0 --- /dev/null +++ b/src-testing/src/renderers/common/RenderList.ts @@ -0,0 +1,142 @@ +function painterSortStable(a, b) { + if (a.groupOrder !== b.groupOrder) { + return a.groupOrder - b.groupOrder; + } else if (a.renderOrder !== b.renderOrder) { + return a.renderOrder - b.renderOrder; + } else if (a.material.id !== b.material.id) { + return a.material.id - b.material.id; + } else if (a.z !== b.z) { + return a.z - b.z; + } else { + return a.id - b.id; + } +} + +function reversePainterSortStable(a, b) { + if (a.groupOrder !== b.groupOrder) { + return a.groupOrder - b.groupOrder; + } else if (a.renderOrder !== b.renderOrder) { + return a.renderOrder - b.renderOrder; + } else if (a.z !== b.z) { + return b.z - a.z; + } else { + return a.id - b.id; + } +} + +class RenderList { + constructor(lighting, scene, camera) { + this.renderItems = []; + this.renderItemsIndex = 0; + + this.opaque = []; + this.transparent = []; + this.bundles = []; + + this.lightsNode = lighting.getNode(scene, camera); + this.lightsArray = []; + + this.scene = scene; + this.camera = camera; + + this.occlusionQueryCount = 0; + } + + begin() { + this.renderItemsIndex = 0; + + this.opaque.length = 0; + this.transparent.length = 0; + this.bundles.length = 0; + + this.lightsArray.length = 0; + + this.occlusionQueryCount = 0; + + return this; + } + + getNextRenderItem(object, geometry, material, groupOrder, z, group) { + let renderItem = this.renderItems[this.renderItemsIndex]; + + if (renderItem === undefined) { + renderItem = { + id: object.id, + object: object, + geometry: geometry, + material: material, + groupOrder: groupOrder, + renderOrder: object.renderOrder, + z: z, + group: group, + }; + + this.renderItems[this.renderItemsIndex] = renderItem; + } else { + renderItem.id = object.id; + renderItem.object = object; + renderItem.geometry = geometry; + renderItem.material = material; + renderItem.groupOrder = groupOrder; + renderItem.renderOrder = object.renderOrder; + renderItem.z = z; + renderItem.group = group; + } + + this.renderItemsIndex++; + + return renderItem; + } + + push(object, geometry, material, groupOrder, z, group) { + const renderItem = this.getNextRenderItem(object, geometry, material, groupOrder, z, group); + + if (object.occlusionTest === true) this.occlusionQueryCount++; + + (material.transparent === true || material.transmission > 0 ? this.transparent : this.opaque).push(renderItem); + } + + unshift(object, geometry, material, groupOrder, z, group) { + const renderItem = this.getNextRenderItem(object, geometry, material, groupOrder, z, group); + + (material.transparent === true ? this.transparent : this.opaque).unshift(renderItem); + } + + pushBundle(group) { + this.bundles.push(group); + } + + pushLight(light) { + this.lightsArray.push(light); + } + + sort(customOpaqueSort, customTransparentSort) { + if (this.opaque.length > 1) this.opaque.sort(customOpaqueSort || painterSortStable); + if (this.transparent.length > 1) this.transparent.sort(customTransparentSort || reversePainterSortStable); + } + + finish() { + // update lights + + this.lightsNode.setLights(this.lightsArray); + + // Clear references from inactive renderItems in the list + + for (let i = this.renderItemsIndex, il = this.renderItems.length; i < il; i++) { + const renderItem = this.renderItems[i]; + + if (renderItem.id === null) break; + + renderItem.id = null; + renderItem.object = null; + renderItem.geometry = null; + renderItem.material = null; + renderItem.groupOrder = null; + renderItem.renderOrder = null; + renderItem.z = null; + renderItem.group = null; + } + } +} + +export default RenderList; diff --git a/src-testing/src/renderers/common/RenderLists.ts b/src-testing/src/renderers/common/RenderLists.ts new file mode 100644 index 000000000..0486f7933 --- /dev/null +++ b/src-testing/src/renderers/common/RenderLists.ts @@ -0,0 +1,30 @@ +import ChainMap from './ChainMap.js'; +import RenderList from './RenderList.js'; + +class RenderLists { + constructor(lighting) { + this.lighting = lighting; + + this.lists = new ChainMap(); + } + + get(scene, camera) { + const lists = this.lists; + const keys = [scene, camera]; + + let list = lists.get(keys); + + if (list === undefined) { + list = new RenderList(this.lighting, scene, camera); + lists.set(keys, list); + } + + return list; + } + + dispose() { + this.lists = new ChainMap(); + } +} + +export default RenderLists; diff --git a/src-testing/src/renderers/common/RenderObject.ts b/src-testing/src/renderers/common/RenderObject.ts new file mode 100644 index 000000000..e46d3871f --- /dev/null +++ b/src-testing/src/renderers/common/RenderObject.ts @@ -0,0 +1,350 @@ +import { hashString } from '../../nodes/core/NodeUtils.js'; +import ClippingContext from './ClippingContext.js'; + +let _id = 0; + +function getKeys(obj) { + const keys = Object.keys(obj); + + let proto = Object.getPrototypeOf(obj); + + while (proto) { + const descriptors = Object.getOwnPropertyDescriptors(proto); + + for (const key in descriptors) { + if (descriptors[key] !== undefined) { + const descriptor = descriptors[key]; + + if (descriptor && typeof descriptor.get === 'function') { + keys.push(key); + } + } + } + + proto = Object.getPrototypeOf(proto); + } + + return keys; +} + +export default class RenderObject { + constructor(nodes, geometries, renderer, object, material, scene, camera, lightsNode, renderContext) { + this._nodes = nodes; + this._geometries = geometries; + + this.id = _id++; + + this.renderer = renderer; + this.object = object; + this.material = material; + this.scene = scene; + this.camera = camera; + this.lightsNode = lightsNode; + this.context = renderContext; + + this.geometry = object.geometry; + this.version = material.version; + + this.drawRange = null; + + this.attributes = null; + this.pipeline = null; + this.vertexBuffers = null; + this.drawParams = null; + + this.bundle = null; + + this.updateClipping(renderContext.clippingContext); + + this.clippingContextVersion = this.clippingContext.version; + + this.initialNodesCacheKey = this.getDynamicCacheKey(); + this.initialCacheKey = this.getCacheKey(); + + this._nodeBuilderState = null; + this._bindings = null; + this._monitor = null; + + this.onDispose = null; + + this.isRenderObject = true; + + this.onMaterialDispose = () => { + this.dispose(); + }; + + this.material.addEventListener('dispose', this.onMaterialDispose); + } + + updateClipping(parent) { + const material = this.material; + + let clippingContext = this.clippingContext; + + if (Array.isArray(material.clippingPlanes)) { + if (clippingContext === parent || !clippingContext) { + clippingContext = new ClippingContext(); + this.clippingContext = clippingContext; + } + + clippingContext.update(parent, material); + } else if (this.clippingContext !== parent) { + this.clippingContext = parent; + } + } + + get clippingNeedsUpdate() { + if (this.clippingContext.version === this.clippingContextVersion) return false; + + this.clippingContextVersion = this.clippingContext.version; + + return true; + } + + getNodeBuilderState() { + return this._nodeBuilderState || (this._nodeBuilderState = this._nodes.getForRender(this)); + } + + getMonitor() { + return this._monitor || (this._monitor = this.getNodeBuilderState().monitor); + } + + getBindings() { + return this._bindings || (this._bindings = this.getNodeBuilderState().createBindings()); + } + + getIndex() { + return this._geometries.getIndex(this); + } + + getIndirect() { + return this._geometries.getIndirect(this); + } + + getChainArray() { + return [this.object, this.material, this.context, this.lightsNode]; + } + + getAttributes() { + if (this.attributes !== null) return this.attributes; + + const nodeAttributes = this.getNodeBuilderState().nodeAttributes; + const geometry = this.geometry; + + const attributes = []; + const vertexBuffers = new Set(); + + for (const nodeAttribute of nodeAttributes) { + const attribute = + nodeAttribute.node && nodeAttribute.node.attribute + ? nodeAttribute.node.attribute + : geometry.getAttribute(nodeAttribute.name); + + if (attribute === undefined) continue; + + attributes.push(attribute); + + const bufferAttribute = attribute.isInterleavedBufferAttribute ? attribute.data : attribute; + vertexBuffers.add(bufferAttribute); + } + + this.attributes = attributes; + this.vertexBuffers = Array.from(vertexBuffers.values()); + + return attributes; + } + + getVertexBuffers() { + if (this.vertexBuffers === null) this.getAttributes(); + + return this.vertexBuffers; + } + + getDrawParameters() { + const { object, material, geometry, group, drawRange } = this; + + const drawParams = + this.drawParams || + (this.drawParams = { + vertexCount: 0, + firstVertex: 0, + instanceCount: 0, + firstInstance: 0, + }); + + const index = this.getIndex(); + const hasIndex = index !== null; + const instanceCount = geometry.isInstancedBufferGeometry + ? geometry.instanceCount + : object.count > 1 + ? object.count + : 1; + + if (instanceCount === 0) return null; + + drawParams.instanceCount = instanceCount; + + if (object.isBatchedMesh === true) return drawParams; + + let rangeFactor = 1; + + if ( + material.wireframe === true && + !object.isPoints && + !object.isLineSegments && + !object.isLine && + !object.isLineLoop + ) { + rangeFactor = 2; + } + + let firstVertex = drawRange.start * rangeFactor; + let lastVertex = (drawRange.start + drawRange.count) * rangeFactor; + + if (group !== null) { + firstVertex = Math.max(firstVertex, group.start * rangeFactor); + lastVertex = Math.min(lastVertex, (group.start + group.count) * rangeFactor); + } + + const position = geometry.attributes.position; + let itemCount = Infinity; + + if (hasIndex) { + itemCount = index.count; + } else if (position !== undefined && position !== null) { + itemCount = position.count; + } + + firstVertex = Math.max(firstVertex, 0); + lastVertex = Math.min(lastVertex, itemCount); + + const count = lastVertex - firstVertex; + + if (count < 0 || count === Infinity) return null; + + drawParams.vertexCount = count; + drawParams.firstVertex = firstVertex; + + return drawParams; + } + + getGeometryCacheKey() { + const { geometry } = this; + + let cacheKey = ''; + + for (const name of Object.keys(geometry.attributes).sort()) { + const attribute = geometry.attributes[name]; + + cacheKey += name + ','; + + if (attribute.data) cacheKey += attribute.data.stride + ','; + if (attribute.offset) cacheKey += attribute.offset + ','; + if (attribute.itemSize) cacheKey += attribute.itemSize + ','; + if (attribute.normalized) cacheKey += 'n,'; + } + + if (geometry.index) { + cacheKey += 'index,'; + } + + return cacheKey; + } + + getMaterialCacheKey() { + const { object, material } = this; + + let cacheKey = material.customProgramCacheKey(); + + for (const property of getKeys(material)) { + if (/^(is[A-Z]|_)|^(visible|version|uuid|name|opacity|userData)$/.test(property)) continue; + + const value = material[property]; + + let valueKey; + + if (value !== null) { + // some material values require a formatting + + const type = typeof value; + + if (type === 'number') { + valueKey = value !== 0 ? '1' : '0'; // Convert to on/off, important for clearcoat, transmission, etc + } else if (type === 'object') { + valueKey = '{'; + + if (value.isTexture) { + valueKey += value.mapping; + } + + valueKey += '}'; + } else { + valueKey = String(value); + } + } else { + valueKey = String(value); + } + + cacheKey += /*property + ':' +*/ valueKey + ','; + } + + cacheKey += this.clippingContext.cacheKey + ','; + + if (object.geometry) { + cacheKey += this.getGeometryCacheKey(); + } + + if (object.skeleton) { + cacheKey += object.skeleton.bones.length + ','; + } + + if (object.morphTargetInfluences) { + cacheKey += object.morphTargetInfluences.length + ','; + } + + if (object.isBatchedMesh) { + cacheKey += object._matricesTexture.uuid + ','; + + if (object._colorsTexture !== null) { + cacheKey += object._colorsTexture.uuid + ','; + } + } + + if (object.count > 1) { + // TODO: https://github.com/mrdoob/three.js/pull/29066#issuecomment-2269400850 + + cacheKey += object.uuid + ','; + } + + return hashString(cacheKey); + } + + get needsUpdate() { + return ( + /*this.object.static !== true &&*/ this.initialNodesCacheKey !== this.getDynamicCacheKey() || + this.clippingNeedsUpdate + ); + } + + getDynamicCacheKey() { + // Environment Nodes Cache Key + + let cacheKey = this._nodes.getCacheKey(this.scene, this.lightsNode); + + if (this.object.receiveShadow) { + cacheKey += 1; + } + + return cacheKey; + } + + getCacheKey() { + return this.getMaterialCacheKey() + this.getDynamicCacheKey(); + } + + dispose() { + this.material.removeEventListener('dispose', this.onMaterialDispose); + + this.onDispose(); + } +} diff --git a/src-testing/src/renderers/common/RenderObjects.ts b/src-testing/src/renderers/common/RenderObjects.ts new file mode 100644 index 000000000..6bd06dd5e --- /dev/null +++ b/src-testing/src/renderers/common/RenderObjects.ts @@ -0,0 +1,107 @@ +import ChainMap from './ChainMap.js'; +import RenderObject from './RenderObject.js'; + +const chainArray = []; + +class RenderObjects { + constructor(renderer, nodes, geometries, pipelines, bindings, info) { + this.renderer = renderer; + this.nodes = nodes; + this.geometries = geometries; + this.pipelines = pipelines; + this.bindings = bindings; + this.info = info; + + this.chainMaps = {}; + } + + get(object, material, scene, camera, lightsNode, renderContext, passId) { + const chainMap = this.getChainMap(passId); + + // reuse chainArray + chainArray[0] = object; + chainArray[1] = material; + chainArray[2] = renderContext; + chainArray[3] = lightsNode; + + let renderObject = chainMap.get(chainArray); + + if (renderObject === undefined) { + renderObject = this.createRenderObject( + this.nodes, + this.geometries, + this.renderer, + object, + material, + scene, + camera, + lightsNode, + renderContext, + passId, + ); + + chainMap.set(chainArray, renderObject); + } else { + renderObject.updateClipping(renderContext.clippingContext); + + if (renderObject.version !== material.version || renderObject.needsUpdate) { + if (renderObject.initialCacheKey !== renderObject.getCacheKey()) { + renderObject.dispose(); + + renderObject = this.get(object, material, scene, camera, lightsNode, renderContext, passId); + } else { + renderObject.version = material.version; + } + } + } + + return renderObject; + } + + getChainMap(passId = 'default') { + return this.chainMaps[passId] || (this.chainMaps[passId] = new ChainMap()); + } + + dispose() { + this.chainMaps = {}; + } + + createRenderObject( + nodes, + geometries, + renderer, + object, + material, + scene, + camera, + lightsNode, + renderContext, + passId, + ) { + const chainMap = this.getChainMap(passId); + + const renderObject = new RenderObject( + nodes, + geometries, + renderer, + object, + material, + scene, + camera, + lightsNode, + renderContext, + ); + + renderObject.onDispose = () => { + this.pipelines.delete(renderObject); + this.bindings.delete(renderObject); + this.nodes.delete(renderObject); + + chainMap.delete(renderObject.getChainArray()); + }; + + return renderObject; + } +} + +export default RenderObjects; diff --git a/src-testing/src/renderers/common/RenderPipeline.ts b/src-testing/src/renderers/common/RenderPipeline.ts new file mode 100644 index 000000000..0ec34b043 --- /dev/null +++ b/src-testing/src/renderers/common/RenderPipeline.ts @@ -0,0 +1,12 @@ +import Pipeline from './Pipeline.js'; + +class RenderPipeline extends Pipeline { + constructor(cacheKey, vertexProgram, fragmentProgram) { + super(cacheKey); + + this.vertexProgram = vertexProgram; + this.fragmentProgram = fragmentProgram; + } +} + +export default RenderPipeline; diff --git a/src-testing/src/renderers/common/Renderer.ts b/src-testing/src/renderers/common/Renderer.ts new file mode 100644 index 000000000..533684051 --- /dev/null +++ b/src-testing/src/renderers/common/Renderer.ts @@ -0,0 +1,1425 @@ +import Animation from './Animation.js'; +import RenderObjects from './RenderObjects.js'; +import Attributes from './Attributes.js'; +import Geometries from './Geometries.js'; +import Info from './Info.js'; +import Pipelines from './Pipelines.js'; +import Bindings from './Bindings.js'; +import RenderLists from './RenderLists.js'; +import RenderContexts from './RenderContexts.js'; +import Textures from './Textures.js'; +import Background from './Background.js'; +import Nodes from './nodes/Nodes.js'; +import Color4 from './Color4.js'; +import ClippingContext from './ClippingContext.js'; +import QuadMesh from './QuadMesh.js'; +import RenderBundles from './RenderBundles.js'; +import NodeLibrary from './nodes/NodeLibrary.js'; +import Lighting from './Lighting.js'; + +import NodeMaterial from '../../materials/nodes/NodeMaterial.js'; + +import { Scene } from '../../scenes/Scene.js'; +import { Frustum } from '../../math/Frustum.js'; +import { Matrix4 } from '../../math/Matrix4.js'; +import { Vector2 } from '../../math/Vector2.js'; +import { Vector4 } from '../../math/Vector4.js'; +import { RenderTarget } from '../../core/RenderTarget.js'; +import { + DoubleSide, + BackSide, + FrontSide, + SRGBColorSpace, + NoToneMapping, + LinearFilter, + LinearSRGBColorSpace, + HalfFloatType, + RGBAFormat, + PCFShadowMap, +} from '../../constants.js'; + +const _scene = /*@__PURE__*/ new Scene(); +const _drawingBufferSize = /*@__PURE__*/ new Vector2(); +const _screen = /*@__PURE__*/ new Vector4(); +const _frustum = /*@__PURE__*/ new Frustum(); +const _projScreenMatrix = /*@__PURE__*/ new Matrix4(); +const _vector4 = /*@__PURE__*/ new Vector4(); + +class Renderer { + constructor(backend, parameters = {}) { + this.isRenderer = true; + + // + + const { + logarithmicDepthBuffer = false, + alpha = true, + depth = true, + stencil = false, + antialias = false, + samples = 0, + getFallback = null, + } = parameters; + + // public + this.domElement = backend.getDomElement(); + + this.backend = backend; + + this.samples = samples || antialias === true ? 4 : 0; + + this.autoClear = true; + this.autoClearColor = true; + this.autoClearDepth = true; + this.autoClearStencil = true; + + this.alpha = alpha; + + this.logarithmicDepthBuffer = logarithmicDepthBuffer; + + this.outputColorSpace = SRGBColorSpace; + + this.toneMapping = NoToneMapping; + this.toneMappingExposure = 1.0; + + this.sortObjects = true; + + this.depth = depth; + this.stencil = stencil; + + this.clippingPlanes = []; + + this.info = new Info(); + + this.nodes = { + modelViewMatrix: null, + modelNormalViewMatrix: null, + }; + + this.library = new NodeLibrary(); + this.lighting = new Lighting(); + + // internals + + this._getFallback = getFallback; + + this._pixelRatio = 1; + this._width = this.domElement.width; + this._height = this.domElement.height; + + this._viewport = new Vector4(0, 0, this._width, this._height); + this._scissor = new Vector4(0, 0, this._width, this._height); + this._scissorTest = false; + + this._attributes = null; + this._geometries = null; + this._nodes = null; + this._animation = null; + this._bindings = null; + this._objects = null; + this._pipelines = null; + this._bundles = null; + this._renderLists = null; + this._renderContexts = null; + this._textures = null; + this._background = null; + + this._quad = new QuadMesh(new NodeMaterial()); + this._quad.material.type = 'Renderer_output'; + + this._currentRenderContext = null; + + this._opaqueSort = null; + this._transparentSort = null; + + this._frameBufferTarget = null; + + const alphaClear = this.alpha === true ? 0 : 1; + + this._clearColor = new Color4(0, 0, 0, alphaClear); + this._clearDepth = 1; + this._clearStencil = 0; + + this._renderTarget = null; + this._activeCubeFace = 0; + this._activeMipmapLevel = 0; + + this._mrt = null; + + this._renderObjectFunction = null; + this._currentRenderObjectFunction = null; + this._currentRenderBundle = null; + + this._handleObjectFunction = this._renderObjectDirect; + + this._initialized = false; + this._initPromise = null; + + this._compilationPromises = null; + + this.transparent = true; + this.opaque = true; + + this.shadowMap = { + enabled: false, + type: PCFShadowMap, + }; + + this.xr = { + enabled: false, + }; + + this.debug = { + checkShaderErrors: true, + onShaderError: null, + getShaderAsync: async (scene, camera, object) => { + await this.compileAsync(scene, camera); + + const renderList = this._renderLists.get(scene, camera); + const renderContext = this._renderContexts.get(scene, camera, this._renderTarget); + + const material = scene.overrideMaterial || object.material; + + const renderObject = this._objects.get( + object, + material, + scene, + camera, + renderList.lightsNode, + renderContext, + ); + + const { fragmentShader, vertexShader } = renderObject.getNodeBuilderState(); + + return { fragmentShader, vertexShader }; + }, + }; + } + + async init() { + if (this._initialized) { + throw new Error('Renderer: Backend has already been initialized.'); + } + + if (this._initPromise !== null) { + return this._initPromise; + } + + this._initPromise = new Promise(async (resolve, reject) => { + let backend = this.backend; + + try { + await backend.init(this); + } catch (error) { + if (this._getFallback !== null) { + // try the fallback + + try { + this.backend = backend = this._getFallback(error); + await backend.init(this); + } catch (error) { + reject(error); + return; + } + } else { + reject(error); + return; + } + } + + this._nodes = new Nodes(this, backend); + this._animation = new Animation(this._nodes, this.info); + this._attributes = new Attributes(backend); + this._background = new Background(this, this._nodes); + this._geometries = new Geometries(this._attributes, this.info); + this._textures = new Textures(this, backend, this.info); + this._pipelines = new Pipelines(backend, this._nodes); + this._bindings = new Bindings( + backend, + this._nodes, + this._textures, + this._attributes, + this._pipelines, + this.info, + ); + this._objects = new RenderObjects( + this, + this._nodes, + this._geometries, + this._pipelines, + this._bindings, + this.info, + ); + this._renderLists = new RenderLists(this.lighting); + this._bundles = new RenderBundles(); + this._renderContexts = new RenderContexts(); + + // + + this._initialized = true; + + resolve(); + }); + + return this._initPromise; + } + + get coordinateSystem() { + return this.backend.coordinateSystem; + } + + async compileAsync(scene, camera, targetScene = null) { + if (this._initialized === false) await this.init(); + + // preserve render tree + + const nodeFrame = this._nodes.nodeFrame; + + const previousRenderId = nodeFrame.renderId; + const previousRenderContext = this._currentRenderContext; + const previousRenderObjectFunction = this._currentRenderObjectFunction; + const previousCompilationPromises = this._compilationPromises; + + // + + const sceneRef = scene.isScene === true ? scene : _scene; + + if (targetScene === null) targetScene = scene; + + const renderTarget = this._renderTarget; + const renderContext = this._renderContexts.get(targetScene, camera, renderTarget); + const activeMipmapLevel = this._activeMipmapLevel; + + const compilationPromises = []; + + this._currentRenderContext = renderContext; + this._currentRenderObjectFunction = this.renderObject; + + this._handleObjectFunction = this._createObjectPipeline; + + this._compilationPromises = compilationPromises; + + nodeFrame.renderId++; + + // + + nodeFrame.update(); + + // + + renderContext.depth = this.depth; + renderContext.stencil = this.stencil; + + if (!renderContext.clippingContext) renderContext.clippingContext = new ClippingContext(); + renderContext.clippingContext.updateGlobal(this, camera); + + // + + sceneRef.onBeforeRender(this, scene, camera, renderTarget); + + // + + const renderList = this._renderLists.get(scene, camera); + renderList.begin(); + + this._projectObject(scene, camera, 0, renderList); + + // include lights from target scene + if (targetScene !== scene) { + targetScene.traverseVisible(function (object) { + if (object.isLight && object.layers.test(camera.layers)) { + renderList.pushLight(object); + } + }); + } + + renderList.finish(); + + // + + if (renderTarget !== null) { + this._textures.updateRenderTarget(renderTarget, activeMipmapLevel); + + const renderTargetData = this._textures.get(renderTarget); + + renderContext.textures = renderTargetData.textures; + renderContext.depthTexture = renderTargetData.depthTexture; + } else { + renderContext.textures = null; + renderContext.depthTexture = null; + } + + // + + this._nodes.updateScene(sceneRef); + + // + + this._background.update(sceneRef, renderList, renderContext); + + // process render lists + + const opaqueObjects = renderList.opaque; + const transparentObjects = renderList.transparent; + const lightsNode = renderList.lightsNode; + + if (this.opaque === true && opaqueObjects.length > 0) + this._renderObjects(opaqueObjects, camera, sceneRef, lightsNode); + if (this.transparent === true && transparentObjects.length > 0) + this._renderObjects(transparentObjects, camera, sceneRef, lightsNode); + + // restore render tree + + nodeFrame.renderId = previousRenderId; + + this._currentRenderContext = previousRenderContext; + this._currentRenderObjectFunction = previousRenderObjectFunction; + this._compilationPromises = previousCompilationPromises; + + this._handleObjectFunction = this._renderObjectDirect; + + // wait for all promises setup by backends awaiting compilation/linking/pipeline creation to complete + + await Promise.all(compilationPromises); + } + + async renderAsync(scene, camera) { + if (this._initialized === false) await this.init(); + + const renderContext = this._renderScene(scene, camera); + + await this.backend.resolveTimestampAsync(renderContext, 'render'); + } + + async waitForGPU() { + await this.backend.waitForGPU(); + } + + setMRT(mrt) { + this._mrt = mrt; + + return this; + } + + getMRT() { + return this._mrt; + } + + _renderBundle(bundle, sceneRef, lightsNode) { + const { bundleGroup, camera, renderList } = bundle; + + const renderContext = this._currentRenderContext; + + // + + const renderBundle = this._bundles.get(bundleGroup, camera); + const renderBundleData = this.backend.get(renderBundle); + + if (renderBundleData.renderContexts === undefined) renderBundleData.renderContexts = new Set(); + + // + + const needsUpdate = bundleGroup.version !== renderBundleData.version; + const renderBundleNeedsUpdate = renderBundleData.renderContexts.has(renderContext) === false || needsUpdate; + + renderBundleData.renderContexts.add(renderContext); + + if (renderBundleNeedsUpdate) { + this.backend.beginBundle(renderContext); + + if (renderBundleData.renderObjects === undefined || needsUpdate) { + renderBundleData.renderObjects = []; + } + + this._currentRenderBundle = renderBundle; + + const opaqueObjects = renderList.opaque; + + if (opaqueObjects.length > 0) this._renderObjects(opaqueObjects, camera, sceneRef, lightsNode); + + this._currentRenderBundle = null; + + // + + this.backend.finishBundle(renderContext, renderBundle); + + renderBundleData.version = bundleGroup.version; + } else { + const { renderObjects } = renderBundleData; + + for (let i = 0, l = renderObjects.length; i < l; i++) { + const renderObject = renderObjects[i]; + + if (this._nodes.needsRefresh(renderObject)) { + this._nodes.updateBefore(renderObject); + + this._nodes.updateForRender(renderObject); + this._bindings.updateForRender(renderObject); + + this._nodes.updateAfter(renderObject); + } + } + } + + this.backend.addBundle(renderContext, renderBundle); + } + + render(scene, camera) { + if (this._initialized === false) { + console.warn( + 'THREE.Renderer: .render() called before the backend is initialized. Try using .renderAsync() instead.', + ); + + return this.renderAsync(scene, camera); + } + + this._renderScene(scene, camera); + } + + _getFrameBufferTarget() { + const { currentToneMapping, currentColorSpace } = this; + + const useToneMapping = currentToneMapping !== NoToneMapping; + const useColorSpace = currentColorSpace !== LinearSRGBColorSpace; + + if (useToneMapping === false && useColorSpace === false) return null; + + const { width, height } = this.getDrawingBufferSize(_drawingBufferSize); + const { depth, stencil } = this; + + let frameBufferTarget = this._frameBufferTarget; + + if (frameBufferTarget === null) { + frameBufferTarget = new RenderTarget(width, height, { + depthBuffer: depth, + stencilBuffer: stencil, + type: HalfFloatType, // FloatType + format: RGBAFormat, + colorSpace: LinearSRGBColorSpace, + generateMipmaps: false, + minFilter: LinearFilter, + magFilter: LinearFilter, + samples: this.samples, + }); + + frameBufferTarget.isPostProcessingRenderTarget = true; + + this._frameBufferTarget = frameBufferTarget; + } + + frameBufferTarget.depthBuffer = depth; + frameBufferTarget.stencilBuffer = stencil; + frameBufferTarget.setSize(width, height); + frameBufferTarget.viewport.copy(this._viewport); + frameBufferTarget.scissor.copy(this._scissor); + frameBufferTarget.viewport.multiplyScalar(this._pixelRatio); + frameBufferTarget.scissor.multiplyScalar(this._pixelRatio); + frameBufferTarget.scissorTest = this._scissorTest; + + return frameBufferTarget; + } + + _renderScene(scene, camera, useFrameBufferTarget = true) { + const frameBufferTarget = useFrameBufferTarget ? this._getFrameBufferTarget() : null; + + // preserve render tree + + const nodeFrame = this._nodes.nodeFrame; + + const previousRenderId = nodeFrame.renderId; + const previousRenderContext = this._currentRenderContext; + const previousRenderObjectFunction = this._currentRenderObjectFunction; + + // + + const sceneRef = scene.isScene === true ? scene : _scene; + + const outputRenderTarget = this._renderTarget; + + const activeCubeFace = this._activeCubeFace; + const activeMipmapLevel = this._activeMipmapLevel; + + // + + let renderTarget; + + if (frameBufferTarget !== null) { + renderTarget = frameBufferTarget; + + this.setRenderTarget(renderTarget); + } else { + renderTarget = outputRenderTarget; + } + + // + + const renderContext = this._renderContexts.get(scene, camera, renderTarget); + + this._currentRenderContext = renderContext; + this._currentRenderObjectFunction = this._renderObjectFunction || this.renderObject; + + // + + this.info.calls++; + this.info.render.calls++; + this.info.render.frameCalls++; + + nodeFrame.renderId = this.info.calls; + + // + + const coordinateSystem = this.coordinateSystem; + + if (camera.coordinateSystem !== coordinateSystem) { + camera.coordinateSystem = coordinateSystem; + + camera.updateProjectionMatrix(); + } + + // + + if (scene.matrixWorldAutoUpdate === true) scene.updateMatrixWorld(); + + if (camera.parent === null && camera.matrixWorldAutoUpdate === true) camera.updateMatrixWorld(); + + // + + let viewport = this._viewport; + let scissor = this._scissor; + let pixelRatio = this._pixelRatio; + + if (renderTarget !== null) { + viewport = renderTarget.viewport; + scissor = renderTarget.scissor; + pixelRatio = 1; + } + + this.getDrawingBufferSize(_drawingBufferSize); + + _screen.set(0, 0, _drawingBufferSize.width, _drawingBufferSize.height); + + const minDepth = viewport.minDepth === undefined ? 0 : viewport.minDepth; + const maxDepth = viewport.maxDepth === undefined ? 1 : viewport.maxDepth; + + renderContext.viewportValue.copy(viewport).multiplyScalar(pixelRatio).floor(); + renderContext.viewportValue.width >>= activeMipmapLevel; + renderContext.viewportValue.height >>= activeMipmapLevel; + renderContext.viewportValue.minDepth = minDepth; + renderContext.viewportValue.maxDepth = maxDepth; + renderContext.viewport = renderContext.viewportValue.equals(_screen) === false; + + renderContext.scissorValue.copy(scissor).multiplyScalar(pixelRatio).floor(); + renderContext.scissor = this._scissorTest && renderContext.scissorValue.equals(_screen) === false; + renderContext.scissorValue.width >>= activeMipmapLevel; + renderContext.scissorValue.height >>= activeMipmapLevel; + + if (!renderContext.clippingContext) renderContext.clippingContext = new ClippingContext(); + renderContext.clippingContext.updateGlobal(this, camera); + + // + + sceneRef.onBeforeRender(this, scene, camera, renderTarget); + + // + + _projScreenMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse); + _frustum.setFromProjectionMatrix(_projScreenMatrix, coordinateSystem); + + const renderList = this._renderLists.get(scene, camera); + renderList.begin(); + + this._projectObject(scene, camera, 0, renderList); + + renderList.finish(); + + if (this.sortObjects === true) { + renderList.sort(this._opaqueSort, this._transparentSort); + } + + // + + if (renderTarget !== null) { + this._textures.updateRenderTarget(renderTarget, activeMipmapLevel); + + const renderTargetData = this._textures.get(renderTarget); + + renderContext.textures = renderTargetData.textures; + renderContext.depthTexture = renderTargetData.depthTexture; + renderContext.width = renderTargetData.width; + renderContext.height = renderTargetData.height; + renderContext.renderTarget = renderTarget; + renderContext.depth = renderTarget.depthBuffer; + renderContext.stencil = renderTarget.stencilBuffer; + } else { + renderContext.textures = null; + renderContext.depthTexture = null; + renderContext.width = this.domElement.width; + renderContext.height = this.domElement.height; + renderContext.depth = this.depth; + renderContext.stencil = this.stencil; + } + + renderContext.width >>= activeMipmapLevel; + renderContext.height >>= activeMipmapLevel; + renderContext.activeCubeFace = activeCubeFace; + renderContext.activeMipmapLevel = activeMipmapLevel; + renderContext.occlusionQueryCount = renderList.occlusionQueryCount; + + // + + this._nodes.updateScene(sceneRef); + + // + + this._background.update(sceneRef, renderList, renderContext); + + // + + this.backend.beginRender(renderContext); + + // process render lists + + const { bundles, lightsNode, transparent: transparentObjects, opaque: opaqueObjects } = renderList; + + if (bundles.length > 0) this._renderBundles(bundles, sceneRef, lightsNode); + if (this.opaque === true && opaqueObjects.length > 0) + this._renderObjects(opaqueObjects, camera, sceneRef, lightsNode); + if (this.transparent === true && transparentObjects.length > 0) + this._renderObjects(transparentObjects, camera, sceneRef, lightsNode); + + // finish render pass + + this.backend.finishRender(renderContext); + + // restore render tree + + nodeFrame.renderId = previousRenderId; + + this._currentRenderContext = previousRenderContext; + this._currentRenderObjectFunction = previousRenderObjectFunction; + + // + + if (frameBufferTarget !== null) { + this.setRenderTarget(outputRenderTarget, activeCubeFace, activeMipmapLevel); + + const quad = this._quad; + + if (this._nodes.hasOutputChange(renderTarget.texture)) { + quad.material.fragmentNode = this._nodes.getOutputNode(renderTarget.texture); + quad.material.needsUpdate = true; + } + + this._renderScene(quad, quad.camera, false); + } + + // + + sceneRef.onAfterRender(this, scene, camera, renderTarget); + + // + + return renderContext; + } + + getMaxAnisotropy() { + return this.backend.getMaxAnisotropy(); + } + + getActiveCubeFace() { + return this._activeCubeFace; + } + + getActiveMipmapLevel() { + return this._activeMipmapLevel; + } + + async setAnimationLoop(callback) { + if (this._initialized === false) await this.init(); + + this._animation.setAnimationLoop(callback); + } + + async getArrayBufferAsync(attribute) { + return await this.backend.getArrayBufferAsync(attribute); + } + + getContext() { + return this.backend.getContext(); + } + + getPixelRatio() { + return this._pixelRatio; + } + + getDrawingBufferSize(target) { + return target.set(this._width * this._pixelRatio, this._height * this._pixelRatio).floor(); + } + + getSize(target) { + return target.set(this._width, this._height); + } + + setPixelRatio(value = 1) { + if (this._pixelRatio === value) return; + + this._pixelRatio = value; + + this.setSize(this._width, this._height, false); + } + + setDrawingBufferSize(width, height, pixelRatio) { + this._width = width; + this._height = height; + + this._pixelRatio = pixelRatio; + + this.domElement.width = Math.floor(width * pixelRatio); + this.domElement.height = Math.floor(height * pixelRatio); + + this.setViewport(0, 0, width, height); + + if (this._initialized) this.backend.updateSize(); + } + + setSize(width, height, updateStyle = true) { + this._width = width; + this._height = height; + + this.domElement.width = Math.floor(width * this._pixelRatio); + this.domElement.height = Math.floor(height * this._pixelRatio); + + if (updateStyle === true) { + this.domElement.style.width = width + 'px'; + this.domElement.style.height = height + 'px'; + } + + this.setViewport(0, 0, width, height); + + if (this._initialized) this.backend.updateSize(); + } + + setOpaqueSort(method) { + this._opaqueSort = method; + } + + setTransparentSort(method) { + this._transparentSort = method; + } + + getScissor(target) { + const scissor = this._scissor; + + target.x = scissor.x; + target.y = scissor.y; + target.width = scissor.width; + target.height = scissor.height; + + return target; + } + + setScissor(x, y, width, height) { + const scissor = this._scissor; + + if (x.isVector4) { + scissor.copy(x); + } else { + scissor.set(x, y, width, height); + } + } + + getScissorTest() { + return this._scissorTest; + } + + setScissorTest(boolean) { + this._scissorTest = boolean; + + this.backend.setScissorTest(boolean); + } + + getViewport(target) { + return target.copy(this._viewport); + } + + setViewport(x, y, width, height, minDepth = 0, maxDepth = 1) { + const viewport = this._viewport; + + if (x.isVector4) { + viewport.copy(x); + } else { + viewport.set(x, y, width, height); + } + + viewport.minDepth = minDepth; + viewport.maxDepth = maxDepth; + } + + getClearColor(target) { + return target.copy(this._clearColor); + } + + setClearColor(color, alpha = 1) { + this._clearColor.set(color); + this._clearColor.a = alpha; + } + + getClearAlpha() { + return this._clearColor.a; + } + + setClearAlpha(alpha) { + this._clearColor.a = alpha; + } + + getClearDepth() { + return this._clearDepth; + } + + setClearDepth(depth) { + this._clearDepth = depth; + } + + getClearStencil() { + return this._clearStencil; + } + + setClearStencil(stencil) { + this._clearStencil = stencil; + } + + isOccluded(object) { + const renderContext = this._currentRenderContext; + + return renderContext && this.backend.isOccluded(renderContext, object); + } + + clear(color = true, depth = true, stencil = true) { + if (this._initialized === false) { + console.warn( + 'THREE.Renderer: .clear() called before the backend is initialized. Try using .clearAsync() instead.', + ); + + return this.clearAsync(color, depth, stencil); + } + + const renderTarget = this._renderTarget || this._getFrameBufferTarget(); + + let renderTargetData = null; + + if (renderTarget !== null) { + this._textures.updateRenderTarget(renderTarget); + + renderTargetData = this._textures.get(renderTarget); + } + + this.backend.clear(color, depth, stencil, renderTargetData); + + if (renderTarget !== null && this._renderTarget === null) { + // If a color space transform or tone mapping is required, + // the clear operation clears the intermediate renderTarget texture, but does not update the screen canvas. + + const quad = this._quad; + + if (this._nodes.hasOutputChange(renderTarget.texture)) { + quad.material.fragmentNode = this._nodes.getOutputNode(renderTarget.texture); + quad.material.needsUpdate = true; + } + + this._renderScene(quad, quad.camera, false); + } + } + + clearColor() { + return this.clear(true, false, false); + } + + clearDepth() { + return this.clear(false, true, false); + } + + clearStencil() { + return this.clear(false, false, true); + } + + async clearAsync(color = true, depth = true, stencil = true) { + if (this._initialized === false) await this.init(); + + this.clear(color, depth, stencil); + } + + clearColorAsync() { + return this.clearAsync(true, false, false); + } + + clearDepthAsync() { + return this.clearAsync(false, true, false); + } + + clearStencilAsync() { + return this.clearAsync(false, false, true); + } + + get currentToneMapping() { + return this._renderTarget !== null ? NoToneMapping : this.toneMapping; + } + + get currentColorSpace() { + return this._renderTarget !== null ? LinearSRGBColorSpace : this.outputColorSpace; + } + + dispose() { + this.info.dispose(); + + this._animation.dispose(); + this._objects.dispose(); + this._pipelines.dispose(); + this._nodes.dispose(); + this._bindings.dispose(); + this._renderLists.dispose(); + this._renderContexts.dispose(); + this._textures.dispose(); + + this.setRenderTarget(null); + this.setAnimationLoop(null); + } + + setRenderTarget(renderTarget, activeCubeFace = 0, activeMipmapLevel = 0) { + this._renderTarget = renderTarget; + this._activeCubeFace = activeCubeFace; + this._activeMipmapLevel = activeMipmapLevel; + } + + getRenderTarget() { + return this._renderTarget; + } + + setRenderObjectFunction(renderObjectFunction) { + this._renderObjectFunction = renderObjectFunction; + } + + getRenderObjectFunction() { + return this._renderObjectFunction; + } + + compute(computeNodes) { + if (this._initialized === false) { + console.warn( + 'THREE.Renderer: .compute() called before the backend is initialized. Try using .computeAsync() instead.', + ); + + return this.computeAsync(computeNodes); + } + + // + + const nodeFrame = this._nodes.nodeFrame; + + const previousRenderId = nodeFrame.renderId; + + // + + this.info.calls++; + this.info.compute.calls++; + this.info.compute.frameCalls++; + + nodeFrame.renderId = this.info.calls; + + // + + const backend = this.backend; + const pipelines = this._pipelines; + const bindings = this._bindings; + const nodes = this._nodes; + + const computeList = Array.isArray(computeNodes) ? computeNodes : [computeNodes]; + + if (computeList[0] === undefined || computeList[0].isComputeNode !== true) { + throw new Error('THREE.Renderer: .compute() expects a ComputeNode.'); + } + + backend.beginCompute(computeNodes); + + for (const computeNode of computeList) { + // onInit + + if (pipelines.has(computeNode) === false) { + const dispose = () => { + computeNode.removeEventListener('dispose', dispose); + + pipelines.delete(computeNode); + bindings.delete(computeNode); + nodes.delete(computeNode); + }; + + computeNode.addEventListener('dispose', dispose); + + // + + const onInitFn = computeNode.onInitFunction; + + if (onInitFn !== null) { + onInitFn.call(computeNode, { renderer: this }); + } + } + + nodes.updateForCompute(computeNode); + bindings.updateForCompute(computeNode); + + const computeBindings = bindings.getForCompute(computeNode); + const computePipeline = pipelines.getForCompute(computeNode, computeBindings); + + backend.compute(computeNodes, computeNode, computeBindings, computePipeline); + } + + backend.finishCompute(computeNodes); + + // + + nodeFrame.renderId = previousRenderId; + } + + async computeAsync(computeNodes) { + if (this._initialized === false) await this.init(); + + this.compute(computeNodes); + + await this.backend.resolveTimestampAsync(computeNodes, 'compute'); + } + + async hasFeatureAsync(name) { + if (this._initialized === false) await this.init(); + + return this.backend.hasFeature(name); + } + + hasFeature(name) { + if (this._initialized === false) { + console.warn( + 'THREE.Renderer: .hasFeature() called before the backend is initialized. Try using .hasFeatureAsync() instead.', + ); + + return false; + } + + return this.backend.hasFeature(name); + } + + copyFramebufferToTexture(framebufferTexture, rectangle = null) { + const renderContext = this._currentRenderContext; + + this._textures.updateTexture(framebufferTexture); + + rectangle = + rectangle === null + ? _vector4.set(0, 0, framebufferTexture.image.width, framebufferTexture.image.height) + : rectangle; + + this.backend.copyFramebufferToTexture(framebufferTexture, renderContext, rectangle); + } + + copyTextureToTexture(srcTexture, dstTexture, srcRegion = null, dstPosition = null, level = 0) { + this._textures.updateTexture(srcTexture); + this._textures.updateTexture(dstTexture); + + this.backend.copyTextureToTexture(srcTexture, dstTexture, srcRegion, dstPosition, level); + } + + readRenderTargetPixelsAsync(renderTarget, x, y, width, height, index = 0, faceIndex = 0) { + return this.backend.copyTextureToBuffer(renderTarget.textures[index], x, y, width, height, faceIndex); + } + + _projectObject(object, camera, groupOrder, renderList) { + if (object.visible === false) return; + + const visible = object.layers.test(camera.layers); + + if (visible) { + if (object.isGroup) { + groupOrder = object.renderOrder; + } else if (object.isLOD) { + if (object.autoUpdate === true) object.update(camera); + } else if (object.isLight) { + renderList.pushLight(object); + } else if (object.isSprite) { + if (!object.frustumCulled || _frustum.intersectsSprite(object)) { + if (this.sortObjects === true) { + _vector4.setFromMatrixPosition(object.matrixWorld).applyMatrix4(_projScreenMatrix); + } + + const { geometry, material } = object; + + if (material.visible) { + renderList.push(object, geometry, material, groupOrder, _vector4.z, null); + } + } + } else if (object.isLineLoop) { + console.error( + 'THREE.Renderer: Objects of type THREE.LineLoop are not supported. Please use THREE.Line or THREE.LineSegments.', + ); + } else if (object.isMesh || object.isLine || object.isPoints) { + if (!object.frustumCulled || _frustum.intersectsObject(object)) { + const { geometry, material } = object; + + if (this.sortObjects === true) { + if (geometry.boundingSphere === null) geometry.computeBoundingSphere(); + + _vector4 + .copy(geometry.boundingSphere.center) + .applyMatrix4(object.matrixWorld) + .applyMatrix4(_projScreenMatrix); + } + + if (Array.isArray(material)) { + const groups = geometry.groups; + + for (let i = 0, l = groups.length; i < l; i++) { + const group = groups[i]; + const groupMaterial = material[group.materialIndex]; + + if (groupMaterial && groupMaterial.visible) { + renderList.push(object, geometry, groupMaterial, groupOrder, _vector4.z, group); + } + } + } else if (material.visible) { + renderList.push(object, geometry, material, groupOrder, _vector4.z, null); + } + } + } + } + + if (object.isBundleGroup === true && this.backend.beginBundle !== undefined) { + const baseRenderList = renderList; + + // replace render list + renderList = this._renderLists.get(object, camera); + + renderList.begin(); + + baseRenderList.pushBundle({ + bundleGroup: object, + camera, + renderList, + }); + + renderList.finish(); + } + + const children = object.children; + + for (let i = 0, l = children.length; i < l; i++) { + this._projectObject(children[i], camera, groupOrder, renderList); + } + } + + _renderBundles(bundles, sceneRef, lightsNode) { + for (const bundle of bundles) { + this._renderBundle(bundle, sceneRef, lightsNode); + } + } + + _renderObjects(renderList, camera, scene, lightsNode) { + // process renderable objects + + for (let i = 0, il = renderList.length; i < il; i++) { + const renderItem = renderList[i]; + + // @TODO: Add support for multiple materials per object. This will require to extract + // the material from the renderItem object and pass it with its group data to renderObject(). + + const { object, geometry, material, group } = renderItem; + + if (camera.isArrayCamera) { + const cameras = camera.cameras; + + for (let j = 0, jl = cameras.length; j < jl; j++) { + const camera2 = cameras[j]; + + if (object.layers.test(camera2.layers)) { + const vp = camera2.viewport; + const minDepth = vp.minDepth === undefined ? 0 : vp.minDepth; + const maxDepth = vp.maxDepth === undefined ? 1 : vp.maxDepth; + + const viewportValue = this._currentRenderContext.viewportValue; + viewportValue.copy(vp).multiplyScalar(this._pixelRatio).floor(); + viewportValue.minDepth = minDepth; + viewportValue.maxDepth = maxDepth; + + this.backend.updateViewport(this._currentRenderContext); + + this._currentRenderObjectFunction( + object, + scene, + camera2, + geometry, + material, + group, + lightsNode, + ); + } + } + } else { + this._currentRenderObjectFunction(object, scene, camera, geometry, material, group, lightsNode); + } + } + } + + renderObject(object, scene, camera, geometry, material, group, lightsNode) { + let overridePositionNode; + let overrideFragmentNode; + let overrideDepthNode; + + // + + object.onBeforeRender(this, scene, camera, geometry, material, group); + + // + + if (scene.overrideMaterial !== null) { + const overrideMaterial = scene.overrideMaterial; + + if (material.positionNode && material.positionNode.isNode) { + overridePositionNode = overrideMaterial.positionNode; + overrideMaterial.positionNode = material.positionNode; + } + + if (overrideMaterial.isShadowNodeMaterial) { + overrideMaterial.side = material.shadowSide === null ? material.side : material.shadowSide; + + if (material.depthNode && material.depthNode.isNode) { + overrideDepthNode = overrideMaterial.depthNode; + overrideMaterial.depthNode = material.depthNode; + } + + if (material.shadowNode && material.shadowNode.isNode) { + overrideFragmentNode = overrideMaterial.fragmentNode; + overrideMaterial.fragmentNode = material.shadowNode; + } + + if (this.localClippingEnabled) { + if (material.clipShadows) { + if (overrideMaterial.clippingPlanes !== material.clippingPlanes) { + overrideMaterial.clippingPlanes = material.clippingPlanes; + overrideMaterial.needsUpdate = true; + } + + if (overrideMaterial.clipIntersection !== material.clipIntersection) { + overrideMaterial.clipIntersection = material.clipIntersection; + } + } else if (Array.isArray(overrideMaterial.clippingPlanes)) { + overrideMaterial.clippingPlanes = null; + overrideMaterial.needsUpdate = true; + } + } + } + + material = overrideMaterial; + } + + // + + if (material.transparent === true && material.side === DoubleSide && material.forceSinglePass === false) { + material.side = BackSide; + this._handleObjectFunction(object, material, scene, camera, lightsNode, group, 'backSide'); // create backSide pass id + + material.side = FrontSide; + this._handleObjectFunction(object, material, scene, camera, lightsNode, group); // use default pass id + + material.side = DoubleSide; + } else { + this._handleObjectFunction(object, material, scene, camera, lightsNode, group); + } + + // + + if (overridePositionNode !== undefined) { + scene.overrideMaterial.positionNode = overridePositionNode; + } + + if (overrideDepthNode !== undefined) { + scene.overrideMaterial.depthNode = overrideDepthNode; + } + + if (overrideFragmentNode !== undefined) { + scene.overrideMaterial.fragmentNode = overrideFragmentNode; + } + + // + + object.onAfterRender(this, scene, camera, geometry, material, group); + } + + _renderObjectDirect(object, material, scene, camera, lightsNode, group, passId) { + const renderObject = this._objects.get( + object, + material, + scene, + camera, + lightsNode, + this._currentRenderContext, + passId, + ); + renderObject.drawRange = object.geometry.drawRange; + renderObject.group = group; + + // + + const needsRefresh = this._nodes.needsRefresh(renderObject); + + if (needsRefresh) { + this._nodes.updateBefore(renderObject); + + this._geometries.updateForRender(renderObject); + + this._nodes.updateForRender(renderObject); + this._bindings.updateForRender(renderObject); + } + + this._pipelines.updateForRender(renderObject); + + // + + if (this._currentRenderBundle !== null) { + const renderBundleData = this.backend.get(this._currentRenderBundle); + + renderBundleData.renderObjects.push(renderObject); + + renderObject.bundle = this._currentRenderBundle.scene; + } + + this.backend.draw(renderObject, this.info); + + if (needsRefresh) this._nodes.updateAfter(renderObject); + } + + _createObjectPipeline(object, material, scene, camera, lightsNode, passId) { + const renderObject = this._objects.get( + object, + material, + scene, + camera, + lightsNode, + this._currentRenderContext, + passId, + ); + + // + + this._nodes.updateBefore(renderObject); + + this._geometries.updateForRender(renderObject); + + this._nodes.updateForRender(renderObject); + this._bindings.updateForRender(renderObject); + + this._pipelines.getForRender(renderObject, this._compilationPromises); + + this._nodes.updateAfter(renderObject); + } + + get compile() { + return this.compileAsync; + } +} + +export default Renderer; diff --git a/src-testing/src/renderers/common/SampledTexture.ts b/src-testing/src/renderers/common/SampledTexture.ts new file mode 100644 index 000000000..841e6a85b --- /dev/null +++ b/src-testing/src/renderers/common/SampledTexture.ts @@ -0,0 +1,68 @@ +import Binding from './Binding.js'; + +let _id = 0; + +class SampledTexture extends Binding { + constructor(name, texture) { + super(name); + + this.id = _id++; + + this.texture = texture; + this.version = texture ? texture.version : 0; + this.store = false; + this.generation = null; + + this.isSampledTexture = true; + } + + needsBindingsUpdate(generation) { + const { texture } = this; + + if (generation !== this.generation) { + this.generation = generation; + + return true; + } + + return texture.isVideoTexture; + } + + update() { + const { texture, version } = this; + + if (version !== texture.version) { + this.version = texture.version; + + return true; + } + + return false; + } +} + +class SampledArrayTexture extends SampledTexture { + constructor(name, texture) { + super(name, texture); + + this.isSampledArrayTexture = true; + } +} + +class Sampled3DTexture extends SampledTexture { + constructor(name, texture) { + super(name, texture); + + this.isSampled3DTexture = true; + } +} + +class SampledCubeTexture extends SampledTexture { + constructor(name, texture) { + super(name, texture); + + this.isSampledCubeTexture = true; + } +} + +export { SampledTexture, SampledArrayTexture, Sampled3DTexture, SampledCubeTexture }; diff --git a/src-testing/src/renderers/common/Sampler.ts b/src-testing/src/renderers/common/Sampler.ts new file mode 100644 index 000000000..8cd20d04a --- /dev/null +++ b/src-testing/src/renderers/common/Sampler.ts @@ -0,0 +1,14 @@ +import Binding from './Binding.js'; + +class Sampler extends Binding { + constructor(name, texture) { + super(name); + + this.texture = texture; + this.version = texture ? texture.version : 0; + + this.isSampler = true; + } +} + +export default Sampler; diff --git a/src-testing/src/renderers/common/StorageBuffer.ts b/src-testing/src/renderers/common/StorageBuffer.ts new file mode 100644 index 000000000..ef5d3e464 --- /dev/null +++ b/src-testing/src/renderers/common/StorageBuffer.ts @@ -0,0 +1,13 @@ +import Buffer from './Buffer.js'; + +class StorageBuffer extends Buffer { + constructor(name, attribute) { + super(name, attribute ? attribute.array : null); + + this.attribute = attribute; + + this.isStorageBuffer = true; + } +} + +export default StorageBuffer; diff --git a/src-testing/src/renderers/common/StorageBufferAttribute.d.ts b/src-testing/src/renderers/common/StorageBufferAttribute.d.ts new file mode 100644 index 000000000..2a864f54a --- /dev/null +++ b/src-testing/src/renderers/common/StorageBufferAttribute.d.ts @@ -0,0 +1,7 @@ +import { BufferAttribute, TypedArray } from "../../core/BufferAttribute.js"; + +export default class StorageBufferAttribute extends BufferAttribute { + readonly isStorageBufferAttribute: true; + + constructor(array: TypedArray, itemSize: number); +} diff --git a/src-testing/src/renderers/common/StorageInstancedBufferAttribute.d.ts b/src-testing/src/renderers/common/StorageInstancedBufferAttribute.d.ts new file mode 100644 index 000000000..3f01891e8 --- /dev/null +++ b/src-testing/src/renderers/common/StorageInstancedBufferAttribute.d.ts @@ -0,0 +1,8 @@ +import { TypedArray } from "../../core/BufferAttribute.js"; +import { InstancedBufferAttribute } from "../../core/InstancedBufferAttribute.js"; + +export default class StorageInstancedBufferAttribute extends InstancedBufferAttribute { + readonly isStorageInstancedBufferAttribute: true; + + constructor(array: TypedArray | number, itemSize: number); +} diff --git a/src-testing/src/renderers/common/StorageTexture.d.ts b/src-testing/src/renderers/common/StorageTexture.d.ts new file mode 100644 index 000000000..435ef9ba3 --- /dev/null +++ b/src-testing/src/renderers/common/StorageTexture.d.ts @@ -0,0 +1,5 @@ +import { Texture } from "../../textures/Texture.js"; + +export default class StorageTexture extends Texture { + constructor(width?: number, height?: number); +} diff --git a/src-testing/src/renderers/common/Textures.ts b/src-testing/src/renderers/common/Textures.ts new file mode 100644 index 000000000..8d35f664f --- /dev/null +++ b/src-testing/src/renderers/common/Textures.ts @@ -0,0 +1,294 @@ +import DataMap from './DataMap.js'; + +import { Vector3 } from '../../math/Vector3.js'; +import { DepthTexture } from '../../textures/DepthTexture.js'; +import { + DepthStencilFormat, + DepthFormat, + UnsignedIntType, + UnsignedInt248Type, + EquirectangularReflectionMapping, + EquirectangularRefractionMapping, + CubeReflectionMapping, + CubeRefractionMapping, + UnsignedByteType, +} from '../../constants.js'; + +const _size = /*@__PURE__*/ new Vector3(); + +class Textures extends DataMap { + constructor(renderer, backend, info) { + super(); + + this.renderer = renderer; + this.backend = backend; + this.info = info; + } + + updateRenderTarget(renderTarget, activeMipmapLevel = 0) { + const renderTargetData = this.get(renderTarget); + + const sampleCount = renderTarget.samples === 0 ? 1 : renderTarget.samples; + const depthTextureMips = renderTargetData.depthTextureMips || (renderTargetData.depthTextureMips = {}); + + const textures = renderTarget.textures; + + const size = this.getSize(textures[0]); + + const mipWidth = size.width >> activeMipmapLevel; + const mipHeight = size.height >> activeMipmapLevel; + + let depthTexture = renderTarget.depthTexture || depthTextureMips[activeMipmapLevel]; + const useDepthTexture = renderTarget.depthBuffer === true || renderTarget.stencilBuffer === true; + + let textureNeedsUpdate = false; + + if (depthTexture === undefined && useDepthTexture) { + depthTexture = new DepthTexture(); + depthTexture.format = renderTarget.stencilBuffer ? DepthStencilFormat : DepthFormat; + depthTexture.type = renderTarget.stencilBuffer ? UnsignedInt248Type : UnsignedIntType; // FloatType + depthTexture.image.width = mipWidth; + depthTexture.image.height = mipHeight; + + depthTextureMips[activeMipmapLevel] = depthTexture; + } + + if (renderTargetData.width !== size.width || size.height !== renderTargetData.height) { + textureNeedsUpdate = true; + + if (depthTexture) { + depthTexture.needsUpdate = true; + depthTexture.image.width = mipWidth; + depthTexture.image.height = mipHeight; + } + } + + renderTargetData.width = size.width; + renderTargetData.height = size.height; + renderTargetData.textures = textures; + renderTargetData.depthTexture = depthTexture || null; + renderTargetData.depth = renderTarget.depthBuffer; + renderTargetData.stencil = renderTarget.stencilBuffer; + renderTargetData.renderTarget = renderTarget; + + if (renderTargetData.sampleCount !== sampleCount) { + textureNeedsUpdate = true; + + if (depthTexture) { + depthTexture.needsUpdate = true; + } + + renderTargetData.sampleCount = sampleCount; + } + + // + + const options = { sampleCount }; + + for (let i = 0; i < textures.length; i++) { + const texture = textures[i]; + + if (textureNeedsUpdate) texture.needsUpdate = true; + + this.updateTexture(texture, options); + } + + if (depthTexture) { + this.updateTexture(depthTexture, options); + } + + // dispose handler + + if (renderTargetData.initialized !== true) { + renderTargetData.initialized = true; + + // dispose + + const onDispose = () => { + renderTarget.removeEventListener('dispose', onDispose); + + for (let i = 0; i < textures.length; i++) { + this._destroyTexture(textures[i]); + } + + if (depthTexture) { + this._destroyTexture(depthTexture); + } + + this.delete(renderTarget); + }; + + renderTarget.addEventListener('dispose', onDispose); + } + } + + updateTexture(texture, options = {}) { + const textureData = this.get(texture); + if (textureData.initialized === true && textureData.version === texture.version) return; + + const isRenderTarget = texture.isRenderTargetTexture || texture.isDepthTexture || texture.isFramebufferTexture; + const backend = this.backend; + + if (isRenderTarget && textureData.initialized === true) { + // it's an update + + backend.destroySampler(texture); + backend.destroyTexture(texture); + } + + // + + if (texture.isFramebufferTexture) { + const renderer = this.renderer; + const renderTarget = renderer.getRenderTarget(); + + if (renderTarget) { + texture.type = renderTarget.texture.type; + } else { + texture.type = UnsignedByteType; + } + } + + // + + const { width, height, depth } = this.getSize(texture); + + options.width = width; + options.height = height; + options.depth = depth; + options.needsMipmaps = this.needsMipmaps(texture); + options.levels = options.needsMipmaps ? this.getMipLevels(texture, width, height) : 1; + + // + + if (isRenderTarget || texture.isStorageTexture === true) { + backend.createSampler(texture); + backend.createTexture(texture, options); + + textureData.generation = texture.version; + } else { + const needsCreate = textureData.initialized !== true; + + if (needsCreate) backend.createSampler(texture); + + if (texture.version > 0) { + const image = texture.image; + + if (image === undefined) { + console.warn('THREE.Renderer: Texture marked for update but image is undefined.'); + } else if (image.complete === false) { + console.warn('THREE.Renderer: Texture marked for update but image is incomplete.'); + } else { + if (texture.images) { + const images = []; + + for (const image of texture.images) { + images.push(image); + } + + options.images = images; + } else { + options.image = image; + } + + if (textureData.isDefaultTexture === undefined || textureData.isDefaultTexture === true) { + backend.createTexture(texture, options); + + textureData.isDefaultTexture = false; + textureData.generation = texture.version; + } + + if (texture.source.dataReady === true) backend.updateTexture(texture, options); + + if (options.needsMipmaps && texture.mipmaps.length === 0) backend.generateMipmaps(texture); + } + } else { + // async update + + backend.createDefaultTexture(texture); + + textureData.isDefaultTexture = true; + textureData.generation = texture.version; + } + } + + // dispose handler + + if (textureData.initialized !== true) { + textureData.initialized = true; + textureData.generation = texture.version; + + // + + this.info.memory.textures++; + + // dispose + + const onDispose = () => { + texture.removeEventListener('dispose', onDispose); + + this._destroyTexture(texture); + + this.info.memory.textures--; + }; + + texture.addEventListener('dispose', onDispose); + } + + // + + textureData.version = texture.version; + } + + getSize(texture, target = _size) { + let image = texture.images ? texture.images[0] : texture.image; + + if (image) { + if (image.image !== undefined) image = image.image; + + target.width = image.width; + target.height = image.height; + target.depth = texture.isCubeTexture ? 6 : image.depth || 1; + } else { + target.width = target.height = target.depth = 1; + } + + return target; + } + + getMipLevels(texture, width, height) { + let mipLevelCount; + + if (texture.isCompressedTexture) { + mipLevelCount = texture.mipmaps.length; + } else { + mipLevelCount = Math.floor(Math.log2(Math.max(width, height))) + 1; + } + + return mipLevelCount; + } + + needsMipmaps(texture) { + return this.isEnvironmentTexture(texture) || texture.isCompressedTexture === true || texture.generateMipmaps; + } + + isEnvironmentTexture(texture) { + const mapping = texture.mapping; + + return ( + mapping === EquirectangularReflectionMapping || + mapping === EquirectangularRefractionMapping || + mapping === CubeReflectionMapping || + mapping === CubeRefractionMapping + ); + } + + _destroyTexture(texture) { + this.backend.destroySampler(texture); + this.backend.destroyTexture(texture); + + this.delete(texture); + } +} + +export default Textures; diff --git a/src-testing/src/renderers/common/Uniform.ts b/src-testing/src/renderers/common/Uniform.ts new file mode 100644 index 000000000..80c131494 --- /dev/null +++ b/src-testing/src/renderers/common/Uniform.ts @@ -0,0 +1,105 @@ +import { Color } from '../../math/Color.js'; +import { Matrix3 } from '../../math/Matrix3.js'; +import { Matrix4 } from '../../math/Matrix4.js'; +import { Vector2 } from '../../math/Vector2.js'; +import { Vector3 } from '../../math/Vector3.js'; +import { Vector4 } from '../../math/Vector4.js'; + +class Uniform { + constructor(name, value) { + this.name = name; + this.value = value; + + this.boundary = 0; // used to build the uniform buffer according to the STD140 layout + this.itemSize = 0; + + this.offset = 0; // this property is set by WebGPUUniformsGroup and marks the start position in the uniform buffer + } + + setValue(value) { + this.value = value; + } + + getValue() { + return this.value; + } +} + +class NumberUniform extends Uniform { + constructor(name, value = 0) { + super(name, value); + + this.isNumberUniform = true; + + this.boundary = 4; + this.itemSize = 1; + } +} + +class Vector2Uniform extends Uniform { + constructor(name, value = new Vector2()) { + super(name, value); + + this.isVector2Uniform = true; + + this.boundary = 8; + this.itemSize = 2; + } +} + +class Vector3Uniform extends Uniform { + constructor(name, value = new Vector3()) { + super(name, value); + + this.isVector3Uniform = true; + + this.boundary = 16; + this.itemSize = 3; + } +} + +class Vector4Uniform extends Uniform { + constructor(name, value = new Vector4()) { + super(name, value); + + this.isVector4Uniform = true; + + this.boundary = 16; + this.itemSize = 4; + } +} + +class ColorUniform extends Uniform { + constructor(name, value = new Color()) { + super(name, value); + + this.isColorUniform = true; + + this.boundary = 16; + this.itemSize = 3; + } +} + +class Matrix3Uniform extends Uniform { + constructor(name, value = new Matrix3()) { + super(name, value); + + this.isMatrix3Uniform = true; + + this.boundary = 48; + this.itemSize = 12; + } +} + +class Matrix4Uniform extends Uniform { + constructor(name, value = new Matrix4()) { + super(name, value); + + this.isMatrix4Uniform = true; + + this.boundary = 64; + this.itemSize = 16; + } +} + +export { NumberUniform, Vector2Uniform, Vector3Uniform, Vector4Uniform, ColorUniform, Matrix3Uniform, Matrix4Uniform }; diff --git a/src-testing/src/renderers/common/UniformBuffer.ts b/src-testing/src/renderers/common/UniformBuffer.ts new file mode 100644 index 000000000..28aac0d7e --- /dev/null +++ b/src-testing/src/renderers/common/UniformBuffer.ts @@ -0,0 +1,11 @@ +import Buffer from './Buffer.js'; + +class UniformBuffer extends Buffer { + constructor(name, buffer = null) { + super(name, buffer); + + this.isUniformBuffer = true; + } +} + +export default UniformBuffer; diff --git a/src-testing/src/renderers/common/UniformsGroup.ts b/src-testing/src/renderers/common/UniformsGroup.ts new file mode 100644 index 000000000..e2b62671a --- /dev/null +++ b/src-testing/src/renderers/common/UniformsGroup.ts @@ -0,0 +1,277 @@ +import UniformBuffer from './UniformBuffer.js'; +import { GPU_CHUNK_BYTES } from './Constants.js'; + +class UniformsGroup extends UniformBuffer { + constructor(name) { + super(name); + + this.isUniformsGroup = true; + + this._values = null; + + // the order of uniforms in this array must match the order of uniforms in the shader + + this.uniforms = []; + } + + addUniform(uniform) { + this.uniforms.push(uniform); + + return this; + } + + removeUniform(uniform) { + const index = this.uniforms.indexOf(uniform); + + if (index !== -1) { + this.uniforms.splice(index, 1); + } + + return this; + } + + get values() { + if (this._values === null) { + this._values = Array.from(this.buffer); + } + + return this._values; + } + + get buffer() { + let buffer = this._buffer; + + if (buffer === null) { + const byteLength = this.byteLength; + + buffer = new Float32Array(new ArrayBuffer(byteLength)); + + this._buffer = buffer; + } + + return buffer; + } + + get byteLength() { + let offset = 0; // global buffer offset in bytes + + for (let i = 0, l = this.uniforms.length; i < l; i++) { + const uniform = this.uniforms[i]; + + const { boundary, itemSize } = uniform; + + // offset within a single chunk in bytes + + const chunkOffset = offset % GPU_CHUNK_BYTES; + const remainingSizeInChunk = GPU_CHUNK_BYTES - chunkOffset; + + // conformance tests + + if (chunkOffset !== 0 && remainingSizeInChunk - boundary < 0) { + // check for chunk overflow + + offset += GPU_CHUNK_BYTES - chunkOffset; + } else if (chunkOffset % boundary !== 0) { + // check for correct alignment + + offset += chunkOffset % boundary; + } + + uniform.offset = offset / this.bytesPerElement; + + offset += itemSize * this.bytesPerElement; + } + + return Math.ceil(offset / GPU_CHUNK_BYTES) * GPU_CHUNK_BYTES; + } + + update() { + let updated = false; + + for (const uniform of this.uniforms) { + if (this.updateByType(uniform) === true) { + updated = true; + } + } + + return updated; + } + + updateByType(uniform) { + if (uniform.isNumberUniform) return this.updateNumber(uniform); + if (uniform.isVector2Uniform) return this.updateVector2(uniform); + if (uniform.isVector3Uniform) return this.updateVector3(uniform); + if (uniform.isVector4Uniform) return this.updateVector4(uniform); + if (uniform.isColorUniform) return this.updateColor(uniform); + if (uniform.isMatrix3Uniform) return this.updateMatrix3(uniform); + if (uniform.isMatrix4Uniform) return this.updateMatrix4(uniform); + + console.error('THREE.WebGPUUniformsGroup: Unsupported uniform type.', uniform); + } + + updateNumber(uniform) { + let updated = false; + + const a = this.values; + const v = uniform.getValue(); + const offset = uniform.offset; + + if (a[offset] !== v) { + const b = this.buffer; + + b[offset] = a[offset] = v; + updated = true; + } + + return updated; + } + + updateVector2(uniform) { + let updated = false; + + const a = this.values; + const v = uniform.getValue(); + const offset = uniform.offset; + + if (a[offset + 0] !== v.x || a[offset + 1] !== v.y) { + const b = this.buffer; + + b[offset + 0] = a[offset + 0] = v.x; + b[offset + 1] = a[offset + 1] = v.y; + + updated = true; + } + + return updated; + } + + updateVector3(uniform) { + let updated = false; + + const a = this.values; + const v = uniform.getValue(); + const offset = uniform.offset; + + if (a[offset + 0] !== v.x || a[offset + 1] !== v.y || a[offset + 2] !== v.z) { + const b = this.buffer; + + b[offset + 0] = a[offset + 0] = v.x; + b[offset + 1] = a[offset + 1] = v.y; + b[offset + 2] = a[offset + 2] = v.z; + + updated = true; + } + + return updated; + } + + updateVector4(uniform) { + let updated = false; + + const a = this.values; + const v = uniform.getValue(); + const offset = uniform.offset; + + if (a[offset + 0] !== v.x || a[offset + 1] !== v.y || a[offset + 2] !== v.z || a[offset + 4] !== v.w) { + const b = this.buffer; + + b[offset + 0] = a[offset + 0] = v.x; + b[offset + 1] = a[offset + 1] = v.y; + b[offset + 2] = a[offset + 2] = v.z; + b[offset + 3] = a[offset + 3] = v.w; + + updated = true; + } + + return updated; + } + + updateColor(uniform) { + let updated = false; + + const a = this.values; + const c = uniform.getValue(); + const offset = uniform.offset; + + if (a[offset + 0] !== c.r || a[offset + 1] !== c.g || a[offset + 2] !== c.b) { + const b = this.buffer; + + b[offset + 0] = a[offset + 0] = c.r; + b[offset + 1] = a[offset + 1] = c.g; + b[offset + 2] = a[offset + 2] = c.b; + + updated = true; + } + + return updated; + } + + updateMatrix3(uniform) { + let updated = false; + + const a = this.values; + const e = uniform.getValue().elements; + const offset = uniform.offset; + + if ( + a[offset + 0] !== e[0] || + a[offset + 1] !== e[1] || + a[offset + 2] !== e[2] || + a[offset + 4] !== e[3] || + a[offset + 5] !== e[4] || + a[offset + 6] !== e[5] || + a[offset + 8] !== e[6] || + a[offset + 9] !== e[7] || + a[offset + 10] !== e[8] + ) { + const b = this.buffer; + + b[offset + 0] = a[offset + 0] = e[0]; + b[offset + 1] = a[offset + 1] = e[1]; + b[offset + 2] = a[offset + 2] = e[2]; + b[offset + 4] = a[offset + 4] = e[3]; + b[offset + 5] = a[offset + 5] = e[4]; + b[offset + 6] = a[offset + 6] = e[5]; + b[offset + 8] = a[offset + 8] = e[6]; + b[offset + 9] = a[offset + 9] = e[7]; + b[offset + 10] = a[offset + 10] = e[8]; + + updated = true; + } + + return updated; + } + + updateMatrix4(uniform) { + let updated = false; + + const a = this.values; + const e = uniform.getValue().elements; + const offset = uniform.offset; + + if (arraysEqual(a, e, offset) === false) { + const b = this.buffer; + b.set(e, offset); + setArray(a, e, offset); + updated = true; + } + + return updated; + } +} + +function setArray(a, b, offset) { + for (let i = 0, l = b.length; i < l; i++) { + a[offset + i] = b[i]; + } +} + +function arraysEqual(a, b, offset) { + for (let i = 0, l = b.length; i < l; i++) { + if (a[offset + i] !== b[i]) return false; + } + + return true; +} + +export default UniformsGroup; diff --git a/src-testing/src/renderers/common/extras/PMREMGenerator.ts b/src-testing/src/renderers/common/extras/PMREMGenerator.ts new file mode 100644 index 000000000..b317f950c --- /dev/null +++ b/src-testing/src/renderers/common/extras/PMREMGenerator.ts @@ -0,0 +1,657 @@ +import NodeMaterial from '../../../materials/nodes/NodeMaterial.js'; +import { getDirection, blur } from '../../../nodes/pmrem/PMREMUtils.js'; +import { equirectUV } from '../../../nodes/utils/EquirectUVNode.js'; +import { uniform } from '../../../nodes/core/UniformNode.js'; +import { uniformArray } from '../../../nodes/accessors/UniformArrayNode.js'; +import { texture } from '../../../nodes/accessors/TextureNode.js'; +import { cubeTexture } from '../../../nodes/accessors/CubeTextureNode.js'; +import { float, vec3 } from '../../../nodes/tsl/TSLBase.js'; +import { uv } from '../../../nodes/accessors/UV.js'; +import { attribute } from '../../../nodes/core/AttributeNode.js'; + +import { OrthographicCamera } from '../../../cameras/OrthographicCamera.js'; +import { Color } from '../../../math/Color.js'; +import { Vector3 } from '../../../math/Vector3.js'; +import { BufferGeometry } from '../../../core/BufferGeometry.js'; +import { BufferAttribute } from '../../../core/BufferAttribute.js'; +import { RenderTarget } from '../../../core/RenderTarget.js'; +import { Mesh } from '../../../objects/Mesh.js'; +import { PerspectiveCamera } from '../../../cameras/PerspectiveCamera.js'; +import { MeshBasicMaterial } from '../../../materials/MeshBasicMaterial.js'; +import { BoxGeometry } from '../../../geometries/BoxGeometry.js'; +import { + CubeReflectionMapping, + CubeRefractionMapping, + CubeUVReflectionMapping, + LinearFilter, + NoBlending, + RGBAFormat, + HalfFloatType, + BackSide, + LinearSRGBColorSpace, +} from '../../../constants.js'; + +const LOD_MIN = 4; + +// The standard deviations (radians) associated with the extra mips. These are +// chosen to approximate a Trowbridge-Reitz distribution function times the +// geometric shadowing function. These sigma values squared must match the +// variance #defines in cube_uv_reflection_fragment.glsl.js. +const EXTRA_LOD_SIGMA = [0.125, 0.215, 0.35, 0.446, 0.526, 0.582]; + +// The maximum length of the blur for loop. Smaller sigmas will use fewer +// samples and exit early, but not recompile the shader. +const MAX_SAMPLES = 20; + +const _flatCamera = /*@__PURE__*/ new OrthographicCamera(-1, 1, 1, -1, 0, 1); +const _cubeCamera = /*@__PURE__*/ new PerspectiveCamera(90, 1); +const _clearColor = /*@__PURE__*/ new Color(); +let _oldTarget = null; +let _oldActiveCubeFace = 0; +let _oldActiveMipmapLevel = 0; + +// Golden Ratio +const PHI = (1 + Math.sqrt(5)) / 2; +const INV_PHI = 1 / PHI; + +// Vertices of a dodecahedron (except the opposites, which represent the +// same axis), used as axis directions evenly spread on a sphere. +const _axisDirections = [ + /*@__PURE__*/ new Vector3(-PHI, INV_PHI, 0), + /*@__PURE__*/ new Vector3(PHI, INV_PHI, 0), + /*@__PURE__*/ new Vector3(-INV_PHI, 0, PHI), + /*@__PURE__*/ new Vector3(INV_PHI, 0, PHI), + /*@__PURE__*/ new Vector3(0, PHI, -INV_PHI), + /*@__PURE__*/ new Vector3(0, PHI, INV_PHI), + /*@__PURE__*/ new Vector3(-1, 1, -1), + /*@__PURE__*/ new Vector3(1, 1, -1), + /*@__PURE__*/ new Vector3(-1, 1, 1), + /*@__PURE__*/ new Vector3(1, 1, 1), +]; + +// + +// WebGPU Face indices +const _faceLib = [3, 1, 5, 0, 4, 2]; + +const direction = getDirection(uv(), attribute('faceIndex')).normalize(); +const outputDirection = vec3(direction.x, direction.y.negate(), direction.z); + +/** + * This class generates a Prefiltered, Mipmapped Radiance Environment Map + * (PMREM) from a cubeMap environment texture. This allows different levels of + * blur to be quickly accessed based on material roughness. It is packed into a + * special CubeUV format that allows us to perform custom interpolation so that + * we can support nonlinear formats such as RGBE. Unlike a traditional mipmap + * chain, it only goes down to the LOD_MIN level (above), and then creates extra + * even more filtered 'mips' at the same LOD_MIN resolution, associated with + * higher roughness levels. In this way we maintain resolution to smoothly + * interpolate diffuse lighting while limiting sampling computation. + * + * Paper: Fast, Accurate Image-Based Lighting + * https://drive.google.com/file/d/15y8r_UpKlU9SvV4ILb0C3qCPecS8pvLz/view + */ + +class PMREMGenerator { + constructor(renderer) { + this._renderer = renderer; + this._pingPongRenderTarget = null; + + this._lodMax = 0; + this._cubeSize = 0; + this._lodPlanes = []; + this._sizeLods = []; + this._sigmas = []; + this._lodMeshes = []; + + this._blurMaterial = null; + this._cubemapMaterial = null; + this._equirectMaterial = null; + this._backgroundBox = null; + } + + /** + * Generates a PMREM from a supplied Scene, which can be faster than using an + * image if networking bandwidth is low. Optional sigma specifies a blur radius + * in radians to be applied to the scene before PMREM generation. Optional near + * and far planes ensure the scene is rendered in its entirety (the cubeCamera + * is placed at the origin). + */ + fromScene(scene, sigma = 0, near = 0.1, far = 100) { + _oldTarget = this._renderer.getRenderTarget(); + _oldActiveCubeFace = this._renderer.getActiveCubeFace(); + _oldActiveMipmapLevel = this._renderer.getActiveMipmapLevel(); + + this._setSize(256); + + const cubeUVRenderTarget = this._allocateTargets(); + cubeUVRenderTarget.depthBuffer = true; + + this._sceneToCubeUV(scene, near, far, cubeUVRenderTarget); + + if (sigma > 0) { + this._blur(cubeUVRenderTarget, 0, 0, sigma); + } + + this._applyPMREM(cubeUVRenderTarget); + + this._cleanup(cubeUVRenderTarget); + + return cubeUVRenderTarget; + } + + /** + * Generates a PMREM from an equirectangular texture, which can be either LDR + * or HDR. The ideal input image size is 1k (1024 x 512), + * as this matches best with the 256 x 256 cubemap output. + */ + fromEquirectangular(equirectangular, renderTarget = null) { + return this._fromTexture(equirectangular, renderTarget); + } + + /** + * Generates a PMREM from an cubemap texture, which can be either LDR + * or HDR. The ideal input cube size is 256 x 256, + * as this matches best with the 256 x 256 cubemap output. + */ + fromCubemap(cubemap, renderTarget = null) { + return this._fromTexture(cubemap, renderTarget); + } + + /** + * Pre-compiles the cubemap shader. You can get faster start-up by invoking this method during + * your texture's network fetch for increased concurrency. + */ + async compileCubemapShader() { + if (this._cubemapMaterial === null) { + this._cubemapMaterial = _getCubemapMaterial(); + await this._compileMaterial(this._cubemapMaterial); + } + } + + /** + * Pre-compiles the equirectangular shader. You can get faster start-up by invoking this method during + * your texture's network fetch for increased concurrency. + */ + async compileEquirectangularShader() { + if (this._equirectMaterial === null) { + this._equirectMaterial = _getEquirectMaterial(); + await this._compileMaterial(this._equirectMaterial); + } + } + + /** + * Disposes of the PMREMGenerator's internal memory. Note that PMREMGenerator is a static class, + * so you should not need more than one PMREMGenerator object. If you do, calling dispose() on + * one of them will cause any others to also become unusable. + */ + dispose() { + this._dispose(); + + if (this._cubemapMaterial !== null) this._cubemapMaterial.dispose(); + if (this._equirectMaterial !== null) this._equirectMaterial.dispose(); + if (this._backgroundBox !== null) { + this._backgroundBox.geometry.dispose(); + this._backgroundBox.material.dispose(); + } + } + + // private interface + + _setSize(cubeSize) { + this._lodMax = Math.floor(Math.log2(cubeSize)); + this._cubeSize = Math.pow(2, this._lodMax); + } + + _dispose() { + if (this._blurMaterial !== null) this._blurMaterial.dispose(); + + if (this._pingPongRenderTarget !== null) this._pingPongRenderTarget.dispose(); + + for (let i = 0; i < this._lodPlanes.length; i++) { + this._lodPlanes[i].dispose(); + } + } + + _cleanup(outputTarget) { + this._renderer.setRenderTarget(_oldTarget, _oldActiveCubeFace, _oldActiveMipmapLevel); + outputTarget.scissorTest = false; + _setViewport(outputTarget, 0, 0, outputTarget.width, outputTarget.height); + } + + _fromTexture(texture, renderTarget) { + if (texture.mapping === CubeReflectionMapping || texture.mapping === CubeRefractionMapping) { + this._setSize(texture.image.length === 0 ? 16 : texture.image[0].width || texture.image[0].image.width); + } else { + // Equirectangular + + this._setSize(texture.image.width / 4); + } + + _oldTarget = this._renderer.getRenderTarget(); + _oldActiveCubeFace = this._renderer.getActiveCubeFace(); + _oldActiveMipmapLevel = this._renderer.getActiveMipmapLevel(); + + const cubeUVRenderTarget = renderTarget || this._allocateTargets(); + this._textureToCubeUV(texture, cubeUVRenderTarget); + this._applyPMREM(cubeUVRenderTarget); + this._cleanup(cubeUVRenderTarget); + + return cubeUVRenderTarget; + } + + _allocateTargets() { + const width = 3 * Math.max(this._cubeSize, 16 * 7); + const height = 4 * this._cubeSize; + + const params = { + magFilter: LinearFilter, + minFilter: LinearFilter, + generateMipmaps: false, + type: HalfFloatType, + format: RGBAFormat, + colorSpace: LinearSRGBColorSpace, + //depthBuffer: false + }; + + const cubeUVRenderTarget = _createRenderTarget(width, height, params); + + if ( + this._pingPongRenderTarget === null || + this._pingPongRenderTarget.width !== width || + this._pingPongRenderTarget.height !== height + ) { + if (this._pingPongRenderTarget !== null) { + this._dispose(); + } + + this._pingPongRenderTarget = _createRenderTarget(width, height, params); + + const { _lodMax } = this; + ({ + sizeLods: this._sizeLods, + lodPlanes: this._lodPlanes, + sigmas: this._sigmas, + lodMeshes: this._lodMeshes, + } = _createPlanes(_lodMax)); + + this._blurMaterial = _getBlurShader(_lodMax, width, height); + } + + return cubeUVRenderTarget; + } + + async _compileMaterial(material) { + const tmpMesh = new Mesh(this._lodPlanes[0], material); + await this._renderer.compile(tmpMesh, _flatCamera); + } + + _sceneToCubeUV(scene, near, far, cubeUVRenderTarget) { + const cubeCamera = _cubeCamera; + cubeCamera.near = near; + cubeCamera.far = far; + + // px, py, pz, nx, ny, nz + const upSign = [-1, 1, -1, -1, -1, -1]; + const forwardSign = [1, 1, 1, -1, -1, -1]; + + const renderer = this._renderer; + + const originalAutoClear = renderer.autoClear; + + renderer.getClearColor(_clearColor); + + renderer.autoClear = false; + + let backgroundBox = this._backgroundBox; + + if (backgroundBox === null) { + const backgroundMaterial = new MeshBasicMaterial({ + name: 'PMREM.Background', + side: BackSide, + depthWrite: false, + depthTest: false, + }); + + backgroundBox = new Mesh(new BoxGeometry(), backgroundMaterial); + } + + let useSolidColor = false; + const background = scene.background; + + if (background) { + if (background.isColor) { + backgroundBox.material.color.copy(background); + scene.background = null; + useSolidColor = true; + } + } else { + backgroundBox.material.color.copy(_clearColor); + useSolidColor = true; + } + + renderer.setRenderTarget(cubeUVRenderTarget); + + renderer.clear(); + + if (useSolidColor) { + renderer.render(backgroundBox, cubeCamera); + } + + for (let i = 0; i < 6; i++) { + const col = i % 3; + + if (col === 0) { + cubeCamera.up.set(0, upSign[i], 0); + cubeCamera.lookAt(forwardSign[i], 0, 0); + } else if (col === 1) { + cubeCamera.up.set(0, 0, upSign[i]); + cubeCamera.lookAt(0, forwardSign[i], 0); + } else { + cubeCamera.up.set(0, upSign[i], 0); + cubeCamera.lookAt(0, 0, forwardSign[i]); + } + + const size = this._cubeSize; + + _setViewport(cubeUVRenderTarget, col * size, i > 2 ? size : 0, size, size); + + renderer.render(scene, cubeCamera); + } + + renderer.autoClear = originalAutoClear; + scene.background = background; + } + + _textureToCubeUV(texture, cubeUVRenderTarget) { + const renderer = this._renderer; + + const isCubeTexture = texture.mapping === CubeReflectionMapping || texture.mapping === CubeRefractionMapping; + + if (isCubeTexture) { + if (this._cubemapMaterial === null) { + this._cubemapMaterial = _getCubemapMaterial(texture); + } + } else { + if (this._equirectMaterial === null) { + this._equirectMaterial = _getEquirectMaterial(texture); + } + } + + const material = isCubeTexture ? this._cubemapMaterial : this._equirectMaterial; + material.fragmentNode.value = texture; + + const mesh = this._lodMeshes[0]; + mesh.material = material; + + const size = this._cubeSize; + + _setViewport(cubeUVRenderTarget, 0, 0, 3 * size, 2 * size); + + renderer.setRenderTarget(cubeUVRenderTarget); + renderer.render(mesh, _flatCamera); + } + + _applyPMREM(cubeUVRenderTarget) { + const renderer = this._renderer; + const autoClear = renderer.autoClear; + renderer.autoClear = false; + const n = this._lodPlanes.length; + + for (let i = 1; i < n; i++) { + const sigma = Math.sqrt(this._sigmas[i] * this._sigmas[i] - this._sigmas[i - 1] * this._sigmas[i - 1]); + + const poleAxis = _axisDirections[(n - i - 1) % _axisDirections.length]; + + this._blur(cubeUVRenderTarget, i - 1, i, sigma, poleAxis); + } + + renderer.autoClear = autoClear; + } + + /** + * This is a two-pass Gaussian blur for a cubemap. Normally this is done + * vertically and horizontally, but this breaks down on a cube. Here we apply + * the blur latitudinally (around the poles), and then longitudinally (towards + * the poles) to approximate the orthogonally-separable blur. It is least + * accurate at the poles, but still does a decent job. + */ + _blur(cubeUVRenderTarget, lodIn, lodOut, sigma, poleAxis) { + const pingPongRenderTarget = this._pingPongRenderTarget; + + this._halfBlur(cubeUVRenderTarget, pingPongRenderTarget, lodIn, lodOut, sigma, 'latitudinal', poleAxis); + + this._halfBlur(pingPongRenderTarget, cubeUVRenderTarget, lodOut, lodOut, sigma, 'longitudinal', poleAxis); + } + + _halfBlur(targetIn, targetOut, lodIn, lodOut, sigmaRadians, direction, poleAxis) { + const renderer = this._renderer; + const blurMaterial = this._blurMaterial; + + if (direction !== 'latitudinal' && direction !== 'longitudinal') { + console.error('blur direction must be either latitudinal or longitudinal!'); + } + + // Number of standard deviations at which to cut off the discrete approximation. + const STANDARD_DEVIATIONS = 3; + + const blurMesh = this._lodMeshes[lodOut]; + blurMesh.material = blurMaterial; + + const blurUniforms = blurMaterial.uniforms; + + const pixels = this._sizeLods[lodIn] - 1; + const radiansPerPixel = isFinite(sigmaRadians) ? Math.PI / (2 * pixels) : (2 * Math.PI) / (2 * MAX_SAMPLES - 1); + const sigmaPixels = sigmaRadians / radiansPerPixel; + const samples = isFinite(sigmaRadians) ? 1 + Math.floor(STANDARD_DEVIATIONS * sigmaPixels) : MAX_SAMPLES; + + if (samples > MAX_SAMPLES) { + console.warn( + `sigmaRadians, ${sigmaRadians}, is too large and will clip, as it requested ${ + samples + } samples when the maximum is set to ${MAX_SAMPLES}`, + ); + } + + const weights = []; + let sum = 0; + + for (let i = 0; i < MAX_SAMPLES; ++i) { + const x = i / sigmaPixels; + const weight = Math.exp((-x * x) / 2); + weights.push(weight); + + if (i === 0) { + sum += weight; + } else if (i < samples) { + sum += 2 * weight; + } + } + + for (let i = 0; i < weights.length; i++) { + weights[i] = weights[i] / sum; + } + + targetIn.texture.frame = (targetIn.texture.frame || 0) + 1; + + blurUniforms.envMap.value = targetIn.texture; + blurUniforms.samples.value = samples; + blurUniforms.weights.array = weights; + blurUniforms.latitudinal.value = direction === 'latitudinal' ? 1 : 0; + + if (poleAxis) { + blurUniforms.poleAxis.value = poleAxis; + } + + const { _lodMax } = this; + blurUniforms.dTheta.value = radiansPerPixel; + blurUniforms.mipInt.value = _lodMax - lodIn; + + const outputSize = this._sizeLods[lodOut]; + const x = 3 * outputSize * (lodOut > _lodMax - LOD_MIN ? lodOut - _lodMax + LOD_MIN : 0); + const y = 4 * (this._cubeSize - outputSize); + + _setViewport(targetOut, x, y, 3 * outputSize, 2 * outputSize); + renderer.setRenderTarget(targetOut); + renderer.render(blurMesh, _flatCamera); + } +} + +function _createPlanes(lodMax) { + const lodPlanes = []; + const sizeLods = []; + const sigmas = []; + const lodMeshes = []; + + let lod = lodMax; + + const totalLods = lodMax - LOD_MIN + 1 + EXTRA_LOD_SIGMA.length; + + for (let i = 0; i < totalLods; i++) { + const sizeLod = Math.pow(2, lod); + sizeLods.push(sizeLod); + let sigma = 1.0 / sizeLod; + + if (i > lodMax - LOD_MIN) { + sigma = EXTRA_LOD_SIGMA[i - lodMax + LOD_MIN - 1]; + } else if (i === 0) { + sigma = 0; + } + + sigmas.push(sigma); + + const texelSize = 1.0 / (sizeLod - 2); + const min = -texelSize; + const max = 1 + texelSize; + const uv1 = [min, min, max, min, max, max, min, min, max, max, min, max]; + + const cubeFaces = 6; + const vertices = 6; + const positionSize = 3; + const uvSize = 2; + const faceIndexSize = 1; + + const position = new Float32Array(positionSize * vertices * cubeFaces); + const uv = new Float32Array(uvSize * vertices * cubeFaces); + const faceIndex = new Float32Array(faceIndexSize * vertices * cubeFaces); + + for (let face = 0; face < cubeFaces; face++) { + const x = ((face % 3) * 2) / 3 - 1; + const y = face > 2 ? 0 : -1; + const coordinates = [ + x, + y, + 0, + x + 2 / 3, + y, + 0, + x + 2 / 3, + y + 1, + 0, + x, + y, + 0, + x + 2 / 3, + y + 1, + 0, + x, + y + 1, + 0, + ]; + + const faceIdx = _faceLib[face]; + position.set(coordinates, positionSize * vertices * faceIdx); + uv.set(uv1, uvSize * vertices * faceIdx); + const fill = [faceIdx, faceIdx, faceIdx, faceIdx, faceIdx, faceIdx]; + faceIndex.set(fill, faceIndexSize * vertices * faceIdx); + } + + const planes = new BufferGeometry(); + planes.setAttribute('position', new BufferAttribute(position, positionSize)); + planes.setAttribute('uv', new BufferAttribute(uv, uvSize)); + planes.setAttribute('faceIndex', new BufferAttribute(faceIndex, faceIndexSize)); + lodPlanes.push(planes); + lodMeshes.push(new Mesh(planes, null)); + + if (lod > LOD_MIN) { + lod--; + } + } + + return { lodPlanes, sizeLods, sigmas, lodMeshes }; +} + +function _createRenderTarget(width, height, params) { + const cubeUVRenderTarget = new RenderTarget(width, height, params); + cubeUVRenderTarget.texture.mapping = CubeUVReflectionMapping; + cubeUVRenderTarget.texture.name = 'PMREM.cubeUv'; + cubeUVRenderTarget.texture.isPMREMTexture = true; + cubeUVRenderTarget.scissorTest = true; + return cubeUVRenderTarget; +} + +function _setViewport(target, x, y, width, height) { + target.viewport.set(x, y, width, height); + target.scissor.set(x, y, width, height); +} + +function _getMaterial(type) { + const material = new NodeMaterial(); + material.depthTest = false; + material.depthWrite = false; + material.blending = NoBlending; + material.name = `PMREM_${type}`; + + return material; +} + +function _getBlurShader(lodMax, width, height) { + const weights = uniformArray(new Array(MAX_SAMPLES).fill(0)); + const poleAxis = uniform(new Vector3(0, 1, 0)); + const dTheta = uniform(0); + const n = float(MAX_SAMPLES); + const latitudinal = uniform(0); // false, bool + const samples = uniform(1); // int + const envMap = texture(null); + const mipInt = uniform(0); // int + const CUBEUV_TEXEL_WIDTH = float(1 / width); + const CUBEUV_TEXEL_HEIGHT = float(1 / height); + const CUBEUV_MAX_MIP = float(lodMax); + + const materialUniforms = { + n, + latitudinal, + weights, + poleAxis, + outputDirection, + dTheta, + samples, + envMap, + mipInt, + CUBEUV_TEXEL_WIDTH, + CUBEUV_TEXEL_HEIGHT, + CUBEUV_MAX_MIP, + }; + + const material = _getMaterial('blur'); + material.uniforms = materialUniforms; // TODO: Move to outside of the material + material.fragmentNode = blur({ ...materialUniforms, latitudinal: latitudinal.equal(1) }); + + return material; +} + +function _getCubemapMaterial(envTexture) { + const material = _getMaterial('cubemap'); + material.fragmentNode = cubeTexture(envTexture, outputDirection); + + return material; +} + +function _getEquirectMaterial(envTexture) { + const material = _getMaterial('equirect'); + material.fragmentNode = texture(envTexture, equirectUV(outputDirection), 0); + + return material; +} + +export default PMREMGenerator; diff --git a/src-testing/src/renderers/common/nodes/NodeBuilderState.ts b/src-testing/src/renderers/common/nodes/NodeBuilderState.ts new file mode 100644 index 000000000..520a3c918 --- /dev/null +++ b/src-testing/src/renderers/common/nodes/NodeBuilderState.ts @@ -0,0 +1,55 @@ +import BindGroup from '../BindGroup.js'; + +class NodeBuilderState { + constructor( + vertexShader, + fragmentShader, + computeShader, + nodeAttributes, + bindings, + updateNodes, + updateBeforeNodes, + updateAfterNodes, + monitor, + transforms = [], + ) { + this.vertexShader = vertexShader; + this.fragmentShader = fragmentShader; + this.computeShader = computeShader; + this.transforms = transforms; + + this.nodeAttributes = nodeAttributes; + this.bindings = bindings; + + this.updateNodes = updateNodes; + this.updateBeforeNodes = updateBeforeNodes; + this.updateAfterNodes = updateAfterNodes; + + this.monitor = monitor; + + this.usedTimes = 0; + } + + createBindings() { + const bindings = []; + + for (const instanceGroup of this.bindings) { + const shared = instanceGroup.bindings[0].groupNode.shared; + + if (shared !== true) { + const bindingsGroup = new BindGroup(instanceGroup.name, [], instanceGroup.index, instanceGroup); + bindings.push(bindingsGroup); + + for (const instanceBinding of instanceGroup.bindings) { + bindingsGroup.bindings.push(instanceBinding.clone()); + } + } else { + bindings.push(instanceGroup); + } + } + + return bindings; + } +} + +export default NodeBuilderState; diff --git a/src-testing/src/renderers/common/nodes/NodeLibrary.ts b/src-testing/src/renderers/common/nodes/NodeLibrary.ts new file mode 100644 index 000000000..b6738b95a --- /dev/null +++ b/src-testing/src/renderers/common/nodes/NodeLibrary.ts @@ -0,0 +1,76 @@ +class NodeLibrary { + constructor() { + this.lightNodes = new WeakMap(); + this.materialNodes = new Map(); + this.toneMappingNodes = new Map(); + } + + fromMaterial(material) { + if (material.isNodeMaterial) return material; + + let nodeMaterial = null; + + const nodeMaterialClass = this.getMaterialNodeClass(material.type); + + if (nodeMaterialClass !== null) { + nodeMaterial = new nodeMaterialClass(); + + for (const key in material) { + nodeMaterial[key] = material[key]; + } + } + + return nodeMaterial; + } + + addToneMapping(toneMappingNode, toneMapping) { + this.addType(toneMappingNode, toneMapping, this.toneMappingNodes); + } + + getToneMappingFunction(toneMapping) { + return this.toneMappingNodes.get(toneMapping) || null; + } + + getMaterialNodeClass(materialType) { + return this.materialNodes.get(materialType) || null; + } + + addMaterial(materialNodeClass, materialClass) { + this.addType(materialNodeClass, materialClass.type, this.materialNodes); + } + + getLightNodeClass(light) { + return this.lightNodes.get(light) || null; + } + + addLight(lightNodeClass, lightClass) { + this.addClass(lightNodeClass, lightClass, this.lightNodes); + } + + addType(nodeClass, type, library) { + if (library.has(type)) { + console.warn(`Redefinition of node ${type}`); + return; + } + + if (typeof nodeClass !== 'function') throw new Error(`Node class ${nodeClass.name} is not a class.`); + if (typeof type === 'function' || typeof type === 'object') + throw new Error(`Base class ${type} is not a class.`); + + library.set(type, nodeClass); + } + + addClass(nodeClass, baseClass, library) { + if (library.has(baseClass)) { + console.warn(`Redefinition of node ${baseClass.name}`); + return; + } + + if (typeof nodeClass !== 'function') throw new Error(`Node class ${nodeClass.name} is not a class.`); + if (typeof baseClass !== 'function') throw new Error(`Base class ${baseClass.name} is not a class.`); + + library.set(baseClass, nodeClass); + } +} + +export default NodeLibrary; diff --git a/src-testing/src/renderers/common/nodes/NodeSampledTexture.d.ts b/src-testing/src/renderers/common/nodes/NodeSampledTexture.d.ts new file mode 100644 index 000000000..97c3c3adf --- /dev/null +++ b/src-testing/src/renderers/common/nodes/NodeSampledTexture.d.ts @@ -0,0 +1,29 @@ +import TextureNode from "../../../nodes/accessors/TextureNode.js"; +import UniformGroupNode from "../../../nodes/core/UniformGroupNode.js"; +import { SampledTexture } from "../SampledTexture.js"; + +type GPUStorageTextureAccess = "read-only" | "read-write" | "write-only"; + +declare class NodeSampledTexture extends SampledTexture { + textureNode: TextureNode | undefined; + groupNode: UniformGroupNode; + + access: "read-write" | "read-only" | "write-only"; + + constructor( + name: string, + textureNode: TextureNode | undefined, + groupNode: UniformGroupNode, + access?: GPUStorageTextureAccess | null, + ); +} + +declare class NodeSampledCubeTexture extends NodeSampledTexture { + readonly isSampledCubeTexture: true; +} + +declare class NodeSampledTexture3D extends NodeSampledTexture { + readonly isSampledTexture3D = true; +} + +export { NodeSampledCubeTexture, NodeSampledTexture, NodeSampledTexture3D }; diff --git a/src-testing/src/renderers/common/nodes/NodeSampler.d.ts b/src-testing/src/renderers/common/nodes/NodeSampler.d.ts new file mode 100644 index 000000000..60db177d5 --- /dev/null +++ b/src-testing/src/renderers/common/nodes/NodeSampler.d.ts @@ -0,0 +1,12 @@ +import TextureNode from "../../../nodes/accessors/TextureNode.js"; +import UniformGroupNode from "../../../nodes/core/UniformGroupNode.js"; +import Sampler from "../Sampler.js"; + +declare class NodeSampler extends Sampler { + textureNode: TextureNode | undefined; + groupNode: UniformGroupNode; + constructor(name: string, textureNode: TextureNode | undefined, groupNode: UniformGroupNode); + update(): void; +} + +export default NodeSampler; diff --git a/src-testing/src/renderers/common/nodes/NodeUniform.ts b/src-testing/src/renderers/common/nodes/NodeUniform.ts new file mode 100644 index 000000000..659f5a82f --- /dev/null +++ b/src-testing/src/renderers/common/nodes/NodeUniform.ts @@ -0,0 +1,103 @@ +import { + NumberUniform, + Vector2Uniform, + Vector3Uniform, + Vector4Uniform, + ColorUniform, + Matrix3Uniform, + Matrix4Uniform, +} from '../Uniform.js'; + +class NumberNodeUniform extends NumberUniform { + constructor(nodeUniform) { + super(nodeUniform.name, nodeUniform.value); + + this.nodeUniform = nodeUniform; + } + + getValue() { + return this.nodeUniform.value; + } +} + +class Vector2NodeUniform extends Vector2Uniform { + constructor(nodeUniform) { + super(nodeUniform.name, nodeUniform.value); + + this.nodeUniform = nodeUniform; + } + + getValue() { + return this.nodeUniform.value; + } +} + +class Vector3NodeUniform extends Vector3Uniform { + constructor(nodeUniform) { + super(nodeUniform.name, nodeUniform.value); + + this.nodeUniform = nodeUniform; + } + + getValue() { + return this.nodeUniform.value; + } +} + +class Vector4NodeUniform extends Vector4Uniform { + constructor(nodeUniform) { + super(nodeUniform.name, nodeUniform.value); + + this.nodeUniform = nodeUniform; + } + + getValue() { + return this.nodeUniform.value; + } +} + +class ColorNodeUniform extends ColorUniform { + constructor(nodeUniform) { + super(nodeUniform.name, nodeUniform.value); + + this.nodeUniform = nodeUniform; + } + + getValue() { + return this.nodeUniform.value; + } +} + +class Matrix3NodeUniform extends Matrix3Uniform { + constructor(nodeUniform) { + super(nodeUniform.name, nodeUniform.value); + + this.nodeUniform = nodeUniform; + } + + getValue() { + return this.nodeUniform.value; + } +} + +class Matrix4NodeUniform extends Matrix4Uniform { + constructor(nodeUniform) { + super(nodeUniform.name, nodeUniform.value); + + this.nodeUniform = nodeUniform; + } + + getValue() { + return this.nodeUniform.value; + } +} + +export { + NumberNodeUniform, + Vector2NodeUniform, + Vector3NodeUniform, + Vector4NodeUniform, + ColorNodeUniform, + Matrix3NodeUniform, + Matrix4NodeUniform, +}; diff --git a/src-testing/src/renderers/common/nodes/NodeUniformsGroup.ts b/src-testing/src/renderers/common/nodes/NodeUniformsGroup.ts new file mode 100644 index 000000000..d2d92cb20 --- /dev/null +++ b/src-testing/src/renderers/common/nodes/NodeUniformsGroup.ts @@ -0,0 +1,30 @@ +import UniformsGroup from '../UniformsGroup.js'; + +let _id = 0; + +class NodeUniformsGroup extends UniformsGroup { + constructor(name, groupNode) { + super(name); + + this.id = _id++; + this.groupNode = groupNode; + + this.isNodeUniformsGroup = true; + } + + getNodes() { + const nodes = []; + + for (const uniform of this.uniforms) { + const node = uniform.nodeUniform.node; + + if (!node) throw new Error('NodeUniformsGroup: Uniform has no node.'); + + nodes.push(node); + } + + return nodes; + } +} + +export default NodeUniformsGroup; diff --git a/src-testing/src/renderers/common/nodes/Nodes.ts b/src-testing/src/renderers/common/nodes/Nodes.ts new file mode 100644 index 000000000..f409c2b15 --- /dev/null +++ b/src-testing/src/renderers/common/nodes/Nodes.ts @@ -0,0 +1,433 @@ +import DataMap from '../DataMap.js'; +import ChainMap from '../ChainMap.js'; +import NodeBuilderState from './NodeBuilderState.js'; +import { cubeMapNode } from '../../../nodes/utils/CubeMapNode.js'; +import { NodeFrame } from '../../../nodes/Nodes.js'; +import { + objectGroup, + renderGroup, + frameGroup, + cubeTexture, + texture, + rangeFog, + densityFog, + reference, + normalWorld, + pmremTexture, + screenUV, +} from '../../../nodes/TSL.js'; + +import { + CubeUVReflectionMapping, + EquirectangularReflectionMapping, + EquirectangularRefractionMapping, +} from '../../../constants.js'; +import { hashArray } from '../../../nodes/core/NodeUtils.js'; + +const outputNodeMap = new WeakMap(); + +class Nodes extends DataMap { + constructor(renderer, backend) { + super(); + + this.renderer = renderer; + this.backend = backend; + this.nodeFrame = new NodeFrame(); + this.nodeBuilderCache = new Map(); + this.callHashCache = new ChainMap(); + this.groupsData = new ChainMap(); + } + + updateGroup(nodeUniformsGroup) { + const groupNode = nodeUniformsGroup.groupNode; + const name = groupNode.name; + + // objectGroup is every updated + + if (name === objectGroup.name) return true; + + // renderGroup is updated once per render/compute call + + if (name === renderGroup.name) { + const uniformsGroupData = this.get(nodeUniformsGroup); + const renderId = this.nodeFrame.renderId; + + if (uniformsGroupData.renderId !== renderId) { + uniformsGroupData.renderId = renderId; + + return true; + } + + return false; + } + + // frameGroup is updated once per frame + + if (name === frameGroup.name) { + const uniformsGroupData = this.get(nodeUniformsGroup); + const frameId = this.nodeFrame.frameId; + + if (uniformsGroupData.frameId !== frameId) { + uniformsGroupData.frameId = frameId; + + return true; + } + + return false; + } + + // other groups are updated just when groupNode.needsUpdate is true + + const groupChain = [groupNode, nodeUniformsGroup]; + + let groupData = this.groupsData.get(groupChain); + if (groupData === undefined) this.groupsData.set(groupChain, (groupData = {})); + + if (groupData.version !== groupNode.version) { + groupData.version = groupNode.version; + + return true; + } + + return false; + } + + getForRenderCacheKey(renderObject) { + return renderObject.initialCacheKey; + } + + getForRender(renderObject) { + const renderObjectData = this.get(renderObject); + + let nodeBuilderState = renderObjectData.nodeBuilderState; + + if (nodeBuilderState === undefined) { + const { nodeBuilderCache } = this; + + const cacheKey = this.getForRenderCacheKey(renderObject); + + nodeBuilderState = nodeBuilderCache.get(cacheKey); + + if (nodeBuilderState === undefined) { + const nodeBuilder = this.backend.createNodeBuilder(renderObject.object, this.renderer); + nodeBuilder.scene = renderObject.scene; + nodeBuilder.material = renderObject.material; + nodeBuilder.camera = renderObject.camera; + nodeBuilder.context.material = renderObject.material; + nodeBuilder.lightsNode = renderObject.lightsNode; + nodeBuilder.environmentNode = this.getEnvironmentNode(renderObject.scene); + nodeBuilder.fogNode = this.getFogNode(renderObject.scene); + nodeBuilder.clippingContext = renderObject.clippingContext; + nodeBuilder.build(); + + nodeBuilderState = this._createNodeBuilderState(nodeBuilder); + + nodeBuilderCache.set(cacheKey, nodeBuilderState); + } + + nodeBuilderState.usedTimes++; + + renderObjectData.nodeBuilderState = nodeBuilderState; + } + + return nodeBuilderState; + } + + delete(object) { + if (object.isRenderObject) { + const nodeBuilderState = this.get(object).nodeBuilderState; + nodeBuilderState.usedTimes--; + + if (nodeBuilderState.usedTimes === 0) { + this.nodeBuilderCache.delete(this.getForRenderCacheKey(object)); + } + } + + return super.delete(object); + } + + getForCompute(computeNode) { + const computeData = this.get(computeNode); + + let nodeBuilderState = computeData.nodeBuilderState; + + if (nodeBuilderState === undefined) { + const nodeBuilder = this.backend.createNodeBuilder(computeNode, this.renderer); + nodeBuilder.build(); + + nodeBuilderState = this._createNodeBuilderState(nodeBuilder); + + computeData.nodeBuilderState = nodeBuilderState; + } + + return nodeBuilderState; + } + + _createNodeBuilderState(nodeBuilder) { + return new NodeBuilderState( + nodeBuilder.vertexShader, + nodeBuilder.fragmentShader, + nodeBuilder.computeShader, + nodeBuilder.getAttributesArray(), + nodeBuilder.getBindings(), + nodeBuilder.updateNodes, + nodeBuilder.updateBeforeNodes, + nodeBuilder.updateAfterNodes, + nodeBuilder.monitor, + nodeBuilder.transforms, + ); + } + + getEnvironmentNode(scene) { + return scene.environmentNode || this.get(scene).environmentNode || null; + } + + getBackgroundNode(scene) { + return scene.backgroundNode || this.get(scene).backgroundNode || null; + } + + getFogNode(scene) { + return scene.fogNode || this.get(scene).fogNode || null; + } + + getCacheKey(scene, lightsNode) { + const chain = [scene, lightsNode]; + const callId = this.renderer.info.calls; + + let cacheKeyData = this.callHashCache.get(chain); + + if (cacheKeyData === undefined || cacheKeyData.callId !== callId) { + const environmentNode = this.getEnvironmentNode(scene); + const fogNode = this.getFogNode(scene); + + const values = []; + + if (lightsNode) values.push(lightsNode.getCacheKey(true)); + if (environmentNode) values.push(environmentNode.getCacheKey()); + if (fogNode) values.push(fogNode.getCacheKey()); + + values.push(this.renderer.shadowMap.enabled ? 1 : 0); + + cacheKeyData = { + callId, + cacheKey: hashArray(values), + }; + + this.callHashCache.set(chain, cacheKeyData); + } + + return cacheKeyData.cacheKey; + } + + updateScene(scene) { + this.updateEnvironment(scene); + this.updateFog(scene); + this.updateBackground(scene); + } + + get isToneMappingState() { + return this.renderer.getRenderTarget() ? false : true; + } + + updateBackground(scene) { + const sceneData = this.get(scene); + const background = scene.background; + + if (background) { + const forceUpdate = + (scene.backgroundBlurriness === 0 && sceneData.backgroundBlurriness > 0) || + (scene.backgroundBlurriness > 0 && sceneData.backgroundBlurriness === 0); + + if (sceneData.background !== background || forceUpdate) { + let backgroundNode = null; + + if ( + background.isCubeTexture === true || + background.mapping === EquirectangularReflectionMapping || + background.mapping === EquirectangularRefractionMapping || + background.mapping === CubeUVReflectionMapping + ) { + if (scene.backgroundBlurriness > 0 || background.mapping === CubeUVReflectionMapping) { + backgroundNode = pmremTexture(background, normalWorld); + } else { + let envMap; + + if (background.isCubeTexture === true) { + envMap = cubeTexture(background); + } else { + envMap = texture(background); + } + + backgroundNode = cubeMapNode(envMap); + } + } else if (background.isTexture === true) { + backgroundNode = texture(background, screenUV.flipY()).setUpdateMatrix(true); + } else if (background.isColor !== true) { + console.error('WebGPUNodes: Unsupported background configuration.', background); + } + + sceneData.backgroundNode = backgroundNode; + sceneData.background = background; + sceneData.backgroundBlurriness = scene.backgroundBlurriness; + } + } else if (sceneData.backgroundNode) { + delete sceneData.backgroundNode; + delete sceneData.background; + } + } + + updateFog(scene) { + const sceneData = this.get(scene); + const fog = scene.fog; + + if (fog) { + if (sceneData.fog !== fog) { + let fogNode = null; + + if (fog.isFogExp2) { + const color = reference('color', 'color', fog).setGroup(renderGroup); + const density = reference('density', 'float', fog).setGroup(renderGroup); + + fogNode = densityFog(color, density); + } else if (fog.isFog) { + const color = reference('color', 'color', fog).setGroup(renderGroup); + const near = reference('near', 'float', fog).setGroup(renderGroup); + const far = reference('far', 'float', fog).setGroup(renderGroup); + + fogNode = rangeFog(color, near, far); + } else { + console.error('WebGPUNodes: Unsupported fog configuration.', fog); + } + + sceneData.fogNode = fogNode; + sceneData.fog = fog; + } + } else { + delete sceneData.fogNode; + delete sceneData.fog; + } + } + + updateEnvironment(scene) { + const sceneData = this.get(scene); + const environment = scene.environment; + + if (environment) { + if (sceneData.environment !== environment) { + let environmentNode = null; + + if (environment.isCubeTexture === true) { + environmentNode = cubeTexture(environment); + } else if (environment.isTexture === true) { + environmentNode = texture(environment); + } else { + console.error('Nodes: Unsupported environment configuration.', environment); + } + + sceneData.environmentNode = environmentNode; + sceneData.environment = environment; + } + } else if (sceneData.environmentNode) { + delete sceneData.environmentNode; + delete sceneData.environment; + } + } + + getNodeFrame(renderer = this.renderer, scene = null, object = null, camera = null, material = null) { + const nodeFrame = this.nodeFrame; + nodeFrame.renderer = renderer; + nodeFrame.scene = scene; + nodeFrame.object = object; + nodeFrame.camera = camera; + nodeFrame.material = material; + + return nodeFrame; + } + + getNodeFrameForRender(renderObject) { + return this.getNodeFrame( + renderObject.renderer, + renderObject.scene, + renderObject.object, + renderObject.camera, + renderObject.material, + ); + } + + getOutputCacheKey() { + const renderer = this.renderer; + + return renderer.toneMapping + ',' + renderer.currentColorSpace; + } + + hasOutputChange(outputTarget) { + const cacheKey = outputNodeMap.get(outputTarget); + + return cacheKey !== this.getOutputCacheKey(); + } + + getOutputNode(outputTexture) { + const renderer = this.renderer; + const cacheKey = this.getOutputCacheKey(); + + const output = texture(outputTexture, screenUV).renderOutput(renderer.toneMapping, renderer.currentColorSpace); + + outputNodeMap.set(outputTexture, cacheKey); + + return output; + } + + updateBefore(renderObject) { + const nodeBuilder = renderObject.getNodeBuilderState(); + + for (const node of nodeBuilder.updateBeforeNodes) { + // update frame state for each node + + this.getNodeFrameForRender(renderObject).updateBeforeNode(node); + } + } + + updateAfter(renderObject) { + const nodeBuilder = renderObject.getNodeBuilderState(); + + for (const node of nodeBuilder.updateAfterNodes) { + // update frame state for each node + + this.getNodeFrameForRender(renderObject).updateAfterNode(node); + } + } + + updateForCompute(computeNode) { + const nodeFrame = this.getNodeFrame(); + const nodeBuilder = this.getForCompute(computeNode); + + for (const node of nodeBuilder.updateNodes) { + nodeFrame.updateNode(node); + } + } + + updateForRender(renderObject) { + const nodeFrame = this.getNodeFrameForRender(renderObject); + const nodeBuilder = renderObject.getNodeBuilderState(); + + for (const node of nodeBuilder.updateNodes) { + nodeFrame.updateNode(node); + } + } + + needsRefresh(renderObject) { + const nodeFrame = this.getNodeFrameForRender(renderObject); + const monitor = renderObject.getMonitor(); + + return monitor.needsRefresh(renderObject, nodeFrame); + } + + dispose() { + super.dispose(); + + this.nodeFrame = new NodeFrame(); + this.nodeBuilderCache = new Map(); + } +} + +export default Nodes; diff --git a/src-testing/src/renderers/common/nodes/StandardNodeLibrary.d.ts b/src-testing/src/renderers/common/nodes/StandardNodeLibrary.d.ts new file mode 100644 index 000000000..d7db44562 --- /dev/null +++ b/src-testing/src/renderers/common/nodes/StandardNodeLibrary.d.ts @@ -0,0 +1,5 @@ +import NodeLibrary from "./NodeLibrary.js"; +declare class StandardNodeLibrary extends NodeLibrary { + constructor(); +} +export default StandardNodeLibrary; diff --git a/src-testing/src/renderers/shaders/ShaderChunk.d.ts b/src-testing/src/renderers/shaders/ShaderChunk.d.ts new file mode 100644 index 000000000..caf4e39bb --- /dev/null +++ b/src-testing/src/renderers/shaders/ShaderChunk.d.ts @@ -0,0 +1,143 @@ +// Renderers / Shaders ///////////////////////////////////////////////////////////////////// +export const ShaderChunk: { + alphahash_fragment: string; + alphahash_pars_fragment: string; + alphamap_fragment: string; + alphamap_pars_fragment: string; + alphatest_fragment: string; + alphatest_pars_fragment: string; + aomap_fragment: string; + aomap_pars_fragment: string; + batching_pars_vertex: string; + begin_vertex: string; + beginnormal_vertex: string; + bsdfs: string; + iridescence_fragment: string; + bumpmap_pars_fragment: string; + clipping_planes_fragment: string; + clipping_planes_pars_fragment: string; + clipping_planes_pars_vertex: string; + clipping_planes_vertex: string; + color_fragment: string; + color_pars_fragment: string; + color_pars_vertex: string; + color_vertex: string; + common: string; + cube_uv_reflection_fragment: string; + defaultnormal_vertex: string; + displacementmap_pars_vertex: string; + displacementmap_vertex: string; + emissivemap_fragment: string; + emissivemap_pars_fragment: string; + colorspace_fragment: string; + colorspace_pars_fragment: string; + envmap_fragment: string; + envmap_common_pars_fragment: string; + envmap_pars_fragment: string; + envmap_pars_vertex: string; + envmap_physical_pars_fragment: string; + envmap_vertex: string; + fog_vertex: string; + fog_pars_vertex: string; + fog_fragment: string; + fog_pars_fragment: string; + gradientmap_pars_fragment: string; + lightmap_pars_fragment: string; + lights_lambert_fragment: string; + lights_lambert_pars_fragment: string; + lights_pars_begin: string; + lights_toon_fragment: string; + lights_toon_pars_fragment: string; + lights_phong_fragment: string; + lights_phong_pars_fragment: string; + lights_physical_fragment: string; + lights_physical_pars_fragment: string; + lights_fragment_begin: string; + lights_fragment_maps: string; + lights_fragment_end: string; + logdepthbuf_fragment: string; + logdepthbuf_pars_fragment: string; + logdepthbuf_pars_vertex: string; + logdepthbuf_vertex: string; + map_fragment: string; + map_pars_fragment: string; + map_particle_fragment: string; + map_particle_pars_fragment: string; + metalnessmap_fragment: string; + metalnessmap_pars_fragment: string; + morphcolor_vertex: string; + morphnormal_vertex: string; + morphtarget_pars_vertex: string; + morphtarget_vertex: string; + normal_fragment_begin: string; + normal_fragment_maps: string; + normal_pars_fragment: string; + normal_pars_vertex: string; + normal_vertex: string; + normalmap_pars_fragment: string; + clearcoat_normal_fragment_begin: string; + clearcoat_normal_fragment_maps: string; + clearcoat_pars_fragment: string; + iridescence_pars_fragment: string; + opaque_fragment: string; + packing: string; + premultiplied_alpha_fragment: string; + project_vertex: string; + dithering_fragment: string; + dithering_pars_fragment: string; + roughnessmap_fragment: string; + roughnessmap_pars_fragment: string; + shadowmap_pars_fragment: string; + shadowmap_pars_vertex: string; + shadowmap_vertex: string; + shadowmask_pars_fragment: string; + skinbase_vertex: string; + skinning_pars_vertex: string; + skinning_vertex: string; + skinnormal_vertex: string; + specularmap_fragment: string; + specularmap_pars_fragment: string; + tonemapping_fragment: string; + tonemapping_pars_fragment: string; + transmission_fragment: string; + transmission_pars_fragment: string; + uv_pars_fragment: string; + uv_pars_vertex: string; + uv_vertex: string; + worldpos_vertex: string; + + background_vert: string; + background_frag: string; + backgroundCube_vert: string; + backgroundCube_frag: string; + cube_vert: string; + cube_frag: string; + depth_vert: string; + depth_frag: string; + distanceRGBA_vert: string; + distanceRGBA_frag: string; + equirect_vert: string; + equirect_frag: string; + linedashed_vert: string; + linedashed_frag: string; + meshbasic_vert: string; + meshbasic_frag: string; + meshlambert_vert: string; + meshlambert_frag: string; + meshmatcap_vert: string; + meshmatcap_frag: string; + meshnormal_vert: string; + meshnormal_frag: string; + meshphong_vert: string; + meshphong_frag: string; + meshphysical_vert: string; + meshphysical_frag: string; + meshtoon_vert: string; + meshtoon_frag: string; + points_vert: string; + points_frag: string; + shadow_vert: string; + shadow_frag: string; + sprite_vert: string; + sprite_frag: string; +}; diff --git a/src-testing/src/renderers/shaders/ShaderLib.d.ts b/src-testing/src/renderers/shaders/ShaderLib.d.ts new file mode 100644 index 000000000..9a52c4dcd --- /dev/null +++ b/src-testing/src/renderers/shaders/ShaderLib.d.ts @@ -0,0 +1,29 @@ +import { IUniform } from "./UniformsLib.js"; + +export interface ShaderLibShader { + uniforms: { [uniform: string]: IUniform }; + vertexShader: string; + fragmentShader: string; +} + +declare const ShaderLib: { + [name: string]: ShaderLibShader; + basic: ShaderLibShader; + lambert: ShaderLibShader; + phong: ShaderLibShader; + standard: ShaderLibShader; + matcap: ShaderLibShader; + points: ShaderLibShader; + dashed: ShaderLibShader; + depth: ShaderLibShader; + normal: ShaderLibShader; + sprite: ShaderLibShader; + background: ShaderLibShader; + cube: ShaderLibShader; + equirect: ShaderLibShader; + distanceRGBA: ShaderLibShader; + shadow: ShaderLibShader; + physical: ShaderLibShader; +}; + +export { ShaderLib }; diff --git a/src-testing/src/renderers/shaders/UniformsLib.d.ts b/src-testing/src/renderers/shaders/UniformsLib.d.ts new file mode 100644 index 000000000..cb0d808bd --- /dev/null +++ b/src-testing/src/renderers/shaders/UniformsLib.d.ts @@ -0,0 +1,189 @@ +import { Color } from "../../math/Color.js"; +import { Matrix3 } from "../../math/Matrix3.js"; +import { Vector2 } from "../../math/Vector2.js"; + +// eslint-disable-next-line @typescript-eslint/naming-convention +export interface IUniform { + value: TValue; +} + +export const UniformsLib: { + common: { + diffuse: IUniform; + opacity: IUniform; + map: IUniform; + mapTransform: IUniform; + alphaMap: IUniform; + alphaMapTransform: IUniform; + alphaTest: IUniform; + }; + specularmap: { + specularMap: IUniform; + specularMapTransform: IUniform; + }; + envmap: { + envMap: IUniform; + envMapRotation: IUniform; + flipEnvMap: IUniform; + reflectivity: IUniform; + ior: IUniform; + refractRatio: IUniform; + }; + aomap: { + aoMap: IUniform; + aoMapIntensity: IUniform; + aoMapTransform: IUniform; + }; + lightmap: { + lightMap: IUniform; + lightMapIntensity: IUniform; + lightMapTransform: IUniform; + }; + bumpmap: { + bumpMap: IUniform; + bumpMapTransform: IUniform; + bumpScale: IUniform; + }; + normalmap: { + normalMap: IUniform; + normalMapTransform: IUniform; + normalScale: IUniform; + }; + displacementmap: { + displacementMap: IUniform; + displacementMapTransform: IUniform; + displacementScale: IUniform; + displacementBias: IUniform; + }; + emissivemap: { + emissiveMap: IUniform; + emissiveMapTransform: IUniform; + }; + metalnessmap: { + metalnessMap: IUniform; + metalnessMapTransform: IUniform; + }; + roughnessmap: { + roughnessMap: IUniform; + roughnessMapTransform: IUniform; + }; + gradientmap: { + gradientMap: IUniform; + }; + fog: { + fogDensity: IUniform; + fogNear: IUniform; + fogFar: IUniform; + fogColor: IUniform; + }; + lights: { + ambientLightColor: IUniform; + lightProbe: IUniform; + directionalLights: { + value: unknown[]; + properties: { + direction: {}; + color: {}; + }; + }; + directionalLightShadows: { + value: unknown[]; + properties: { + shadowIntensity: number; + shadowBias: {}; + shadowNormalBias: {}; + shadowRadius: {}; + shadowMapSize: {}; + }; + }; + directionalShadowMap: IUniform; + directionalShadowMatrix: IUniform; + spotLights: { + value: unknown[]; + properties: { + color: {}; + position: {}; + direction: {}; + distance: {}; + coneCos: {}; + penumbraCos: {}; + decay: {}; + }; + }; + spotLightShadows: { + value: unknown[]; + properties: { + shadowIntensity: number; + shadowBias: {}; + shadowNormalBias: {}; + shadowRadius: {}; + shadowMapSize: {}; + }; + }; + spotLightMap: IUniform; + spotShadowMap: IUniform; + spotLightMatrix: IUniform; + pointLights: { + value: unknown[]; + properties: { + color: {}; + position: {}; + decay: {}; + distance: {}; + }; + }; + pointLightShadows: { + value: unknown[]; + properties: { + shadowIntensity: number; + shadowBias: {}; + shadowNormalBias: {}; + shadowRadius: {}; + shadowMapSize: {}; + shadowCameraNear: {}; + shadowCameraFar: {}; + }; + }; + pointShadowMap: IUniform; + pointShadowMatrix: IUniform; + hemisphereLights: { + value: unknown[]; + properties: { + direction: {}; + skycolor: {}; + groundColor: {}; + }; + }; + rectAreaLights: { + value: unknown[]; + properties: { + color: {}; + position: {}; + width: {}; + height: {}; + }; + }; + ltc_1: IUniform; + ltc_2: IUniform; + }; + points: { + diffuse: IUniform; + opacity: IUniform; + size: IUniform; + scale: IUniform; + map: IUniform; + alphaMap: IUniform; + alphaTest: IUniform; + uvTransform: IUniform; + }; + sprite: { + diffuse: IUniform; + opacity: IUniform; + center: IUniform; + rotation: IUniform; + map: IUniform; + mapTransform: IUniform; + alphaMap: IUniform; + alphaTest: IUniform; + }; +}; diff --git a/src-testing/src/renderers/shaders/UniformsUtils.d.ts b/src-testing/src/renderers/shaders/UniformsUtils.d.ts new file mode 100644 index 000000000..fe5178d55 --- /dev/null +++ b/src-testing/src/renderers/shaders/UniformsUtils.d.ts @@ -0,0 +1,14 @@ +import { UniformsGroup } from "../../core/UniformsGroup.js"; +import { IUniform } from "./UniformsLib.js"; + +export function cloneUniforms(uniformsSrc: T): T; +export function mergeUniforms(uniforms: Array<{ [uniform: string]: IUniform }>): { [uniform: string]: IUniform }; + +export function cloneUniformsGroups(src: UniformsGroup[]): UniformsGroup[]; + +declare const UniformsUtils: { + clone: typeof cloneUniforms; + merge: typeof mergeUniforms; +}; + +export { UniformsUtils }; diff --git a/src-testing/src/renderers/webgl-fallback/WebGLBackend.ts b/src-testing/src/renderers/webgl-fallback/WebGLBackend.ts new file mode 100644 index 000000000..ccf00b986 --- /dev/null +++ b/src-testing/src/renderers/webgl-fallback/WebGLBackend.ts @@ -0,0 +1,1349 @@ +import GLSLNodeBuilder from './nodes/GLSLNodeBuilder.js'; +import Backend from '../common/Backend.js'; +import { getCacheKey } from '../common/RenderContext.js'; + +import WebGLAttributeUtils from './utils/WebGLAttributeUtils.js'; +import WebGLState from './utils/WebGLState.js'; +import WebGLUtils from './utils/WebGLUtils.js'; +import WebGLTextureUtils from './utils/WebGLTextureUtils.js'; +import WebGLExtensions from './utils/WebGLExtensions.js'; +import WebGLCapabilities from './utils/WebGLCapabilities.js'; +import { GLFeatureName } from './utils/WebGLConstants.js'; +import { WebGLBufferRenderer } from './WebGLBufferRenderer.js'; + +import { warnOnce } from '../../utils.js'; +import { WebGLCoordinateSystem } from '../../constants.js'; + +// + +class WebGLBackend extends Backend { + constructor(parameters = {}) { + super(parameters); + + this.isWebGLBackend = true; + } + + init(renderer) { + super.init(renderer); + + // + + const parameters = this.parameters; + + const glContext = + parameters.context !== undefined ? parameters.context : renderer.domElement.getContext('webgl2'); + + this.gl = glContext; + + this.extensions = new WebGLExtensions(this); + this.capabilities = new WebGLCapabilities(this); + this.attributeUtils = new WebGLAttributeUtils(this); + this.textureUtils = new WebGLTextureUtils(this); + this.bufferRenderer = new WebGLBufferRenderer(this); + + this.state = new WebGLState(this); + this.utils = new WebGLUtils(this); + + this.vaoCache = {}; + this.transformFeedbackCache = {}; + this.discard = false; + this.trackTimestamp = parameters.trackTimestamp === true; + + this.extensions.get('EXT_color_buffer_float'); + this.extensions.get('WEBGL_clip_cull_distance'); + this.extensions.get('OES_texture_float_linear'); + this.extensions.get('EXT_color_buffer_half_float'); + this.extensions.get('WEBGL_multisampled_render_to_texture'); + this.extensions.get('WEBGL_render_shared_exponent'); + this.extensions.get('WEBGL_multi_draw'); + + this.disjoint = this.extensions.get('EXT_disjoint_timer_query_webgl2'); + this.parallel = this.extensions.get('KHR_parallel_shader_compile'); + + this._knownBindings = new WeakSet(); + + this._currentContext = null; + } + + get coordinateSystem() { + return WebGLCoordinateSystem; + } + + async getArrayBufferAsync(attribute) { + return await this.attributeUtils.getArrayBufferAsync(attribute); + } + + async waitForGPU() { + await this.utils._clientWaitAsync(); + } + + initTimestampQuery(renderContext) { + if (!this.disjoint || !this.trackTimestamp) return; + + const renderContextData = this.get(renderContext); + + if (this.queryRunning) { + if (!renderContextData.queryQueue) renderContextData.queryQueue = []; + renderContextData.queryQueue.push(renderContext); + return; + } + + if (renderContextData.activeQuery) { + this.gl.endQuery(this.disjoint.TIME_ELAPSED_EXT); + renderContextData.activeQuery = null; + } + + renderContextData.activeQuery = this.gl.createQuery(); + + if (renderContextData.activeQuery !== null) { + this.gl.beginQuery(this.disjoint.TIME_ELAPSED_EXT, renderContextData.activeQuery); + this.queryRunning = true; + } + } + + // timestamp utils + + prepareTimestampBuffer(renderContext) { + if (!this.disjoint || !this.trackTimestamp) return; + + const renderContextData = this.get(renderContext); + + if (renderContextData.activeQuery) { + this.gl.endQuery(this.disjoint.TIME_ELAPSED_EXT); + + if (!renderContextData.gpuQueries) renderContextData.gpuQueries = []; + renderContextData.gpuQueries.push({ query: renderContextData.activeQuery }); + renderContextData.activeQuery = null; + this.queryRunning = false; + + if (renderContextData.queryQueue && renderContextData.queryQueue.length > 0) { + const nextRenderContext = renderContextData.queryQueue.shift(); + this.initTimestampQuery(nextRenderContext); + } + } + } + + async resolveTimestampAsync(renderContext, type = 'render') { + if (!this.disjoint || !this.trackTimestamp) return; + + const renderContextData = this.get(renderContext); + + if (!renderContextData.gpuQueries) renderContextData.gpuQueries = []; + + for (let i = 0; i < renderContextData.gpuQueries.length; i++) { + const queryInfo = renderContextData.gpuQueries[i]; + const available = this.gl.getQueryParameter(queryInfo.query, this.gl.QUERY_RESULT_AVAILABLE); + const disjoint = this.gl.getParameter(this.disjoint.GPU_DISJOINT_EXT); + + if (available && !disjoint) { + const elapsed = this.gl.getQueryParameter(queryInfo.query, this.gl.QUERY_RESULT); + const duration = Number(elapsed) / 1000000; // Convert nanoseconds to milliseconds + this.gl.deleteQuery(queryInfo.query); + renderContextData.gpuQueries.splice(i, 1); // Remove the processed query + i--; + this.renderer.info.updateTimestamp(type, duration); + } + } + } + + getContext() { + return this.gl; + } + + beginRender(renderContext) { + const { gl } = this; + const renderContextData = this.get(renderContext); + + // + + // + + this.initTimestampQuery(renderContext); + + renderContextData.previousContext = this._currentContext; + this._currentContext = renderContext; + + this._setFramebuffer(renderContext); + + this.clear( + renderContext.clearColor, + renderContext.clearDepth, + renderContext.clearStencil, + renderContext, + false, + ); + + // + if (renderContext.viewport) { + this.updateViewport(renderContext); + } else { + gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); + } + + if (renderContext.scissor) { + const { x, y, width, height } = renderContext.scissorValue; + + gl.scissor(x, renderContext.height - height - y, width, height); + } + + const occlusionQueryCount = renderContext.occlusionQueryCount; + + if (occlusionQueryCount > 0) { + // Get a reference to the array of objects with queries. The renderContextData property + // can be changed by another render pass before the async reading of all previous queries complete + renderContextData.currentOcclusionQueries = renderContextData.occlusionQueries; + renderContextData.currentOcclusionQueryObjects = renderContextData.occlusionQueryObjects; + + renderContextData.lastOcclusionObject = null; + renderContextData.occlusionQueries = new Array(occlusionQueryCount); + renderContextData.occlusionQueryObjects = new Array(occlusionQueryCount); + renderContextData.occlusionQueryIndex = 0; + } + } + + finishRender(renderContext) { + const { gl, state } = this; + const renderContextData = this.get(renderContext); + const previousContext = renderContextData.previousContext; + + const occlusionQueryCount = renderContext.occlusionQueryCount; + + if (occlusionQueryCount > 0) { + if (occlusionQueryCount > renderContextData.occlusionQueryIndex) { + gl.endQuery(gl.ANY_SAMPLES_PASSED); + } + + this.resolveOccludedAsync(renderContext); + } + + const textures = renderContext.textures; + + if (textures !== null) { + for (let i = 0; i < textures.length; i++) { + const texture = textures[i]; + + if (texture.generateMipmaps) { + this.generateMipmaps(texture); + } + } + } + + this._currentContext = previousContext; + + if (renderContext.textures !== null && renderContext.renderTarget) { + const renderTargetContextData = this.get(renderContext.renderTarget); + + const { samples } = renderContext.renderTarget; + + if (samples > 0) { + const fb = renderTargetContextData.framebuffers[renderContext.getCacheKey()]; + + const mask = gl.COLOR_BUFFER_BIT; + + const msaaFrameBuffer = renderTargetContextData.msaaFrameBuffer; + + const textures = renderContext.textures; + + state.bindFramebuffer(gl.READ_FRAMEBUFFER, msaaFrameBuffer); + state.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fb); + + for (let i = 0; i < textures.length; i++) { + // TODO Add support for MRT + + if (renderContext.scissor) { + const { x, y, width, height } = renderContext.scissorValue; + + const viewY = renderContext.height - height - y; + + gl.blitFramebuffer( + x, + viewY, + x + width, + viewY + height, + x, + viewY, + x + width, + viewY + height, + mask, + gl.NEAREST, + ); + gl.invalidateSubFramebuffer( + gl.READ_FRAMEBUFFER, + renderTargetContextData.invalidationArray, + x, + viewY, + width, + height, + ); + } else { + gl.blitFramebuffer( + 0, + 0, + renderContext.width, + renderContext.height, + 0, + 0, + renderContext.width, + renderContext.height, + mask, + gl.NEAREST, + ); + gl.invalidateFramebuffer(gl.READ_FRAMEBUFFER, renderTargetContextData.invalidationArray); + } + } + } + } + + if (previousContext !== null) { + this._setFramebuffer(previousContext); + + if (previousContext.viewport) { + this.updateViewport(previousContext); + } else { + gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); + } + } + + this.prepareTimestampBuffer(renderContext); + } + + resolveOccludedAsync(renderContext) { + const renderContextData = this.get(renderContext); + + // handle occlusion query results + + const { currentOcclusionQueries, currentOcclusionQueryObjects } = renderContextData; + + if (currentOcclusionQueries && currentOcclusionQueryObjects) { + const occluded = new WeakSet(); + const { gl } = this; + + renderContextData.currentOcclusionQueryObjects = null; + renderContextData.currentOcclusionQueries = null; + + const check = () => { + let completed = 0; + + // check all queries and requeue as appropriate + for (let i = 0; i < currentOcclusionQueries.length; i++) { + const query = currentOcclusionQueries[i]; + + if (query === null) continue; + + if (gl.getQueryParameter(query, gl.QUERY_RESULT_AVAILABLE)) { + if (gl.getQueryParameter(query, gl.QUERY_RESULT) > 0) + occluded.add(currentOcclusionQueryObjects[i]); + + currentOcclusionQueries[i] = null; + gl.deleteQuery(query); + + completed++; + } + } + + if (completed < currentOcclusionQueries.length) { + requestAnimationFrame(check); + } else { + renderContextData.occluded = occluded; + } + }; + + check(); + } + } + + isOccluded(renderContext, object) { + const renderContextData = this.get(renderContext); + + return renderContextData.occluded && renderContextData.occluded.has(object); + } + + updateViewport(renderContext) { + const gl = this.gl; + const { x, y, width, height } = renderContext.viewportValue; + + gl.viewport(x, renderContext.height - height - y, width, height); + } + + setScissorTest(boolean) { + const gl = this.gl; + + if (boolean) { + gl.enable(gl.SCISSOR_TEST); + } else { + gl.disable(gl.SCISSOR_TEST); + } + } + + clear(color, depth, stencil, descriptor = null, setFrameBuffer = true) { + const { gl } = this; + + if (descriptor === null) { + const clearColor = this.getClearColor(); + + // premultiply alpha + + clearColor.r *= clearColor.a; + clearColor.g *= clearColor.a; + clearColor.b *= clearColor.a; + + descriptor = { + textures: null, + clearColorValue: clearColor, + }; + } + + // + + let clear = 0; + + if (color) clear |= gl.COLOR_BUFFER_BIT; + if (depth) clear |= gl.DEPTH_BUFFER_BIT; + if (stencil) clear |= gl.STENCIL_BUFFER_BIT; + + if (clear !== 0) { + let clearColor; + + if (descriptor.clearColorValue) { + clearColor = descriptor.clearColorValue; + } else { + clearColor = this.getClearColor(); + + // premultiply alpha + + clearColor.r *= clearColor.a; + clearColor.g *= clearColor.a; + clearColor.b *= clearColor.a; + } + + if (depth) this.state.setDepthMask(true); + + if (descriptor.textures === null) { + gl.clearColor(clearColor.r, clearColor.g, clearColor.b, clearColor.a); + gl.clear(clear); + } else { + if (setFrameBuffer) this._setFramebuffer(descriptor); + + if (color) { + for (let i = 0; i < descriptor.textures.length; i++) { + gl.clearBufferfv(gl.COLOR, i, [clearColor.r, clearColor.g, clearColor.b, clearColor.a]); + } + } + + if (depth && stencil) { + gl.clearBufferfi(gl.DEPTH_STENCIL, 0, 1, 0); + } else if (depth) { + gl.clearBufferfv(gl.DEPTH, 0, [1.0]); + } else if (stencil) { + gl.clearBufferiv(gl.STENCIL, 0, [0]); + } + } + } + } + + beginCompute(computeGroup) { + const { state, gl } = this; + + state.bindFramebuffer(gl.FRAMEBUFFER, null); + this.initTimestampQuery(computeGroup); + } + + compute(computeGroup, computeNode, bindings, pipeline) { + const { state, gl } = this; + + if (!this.discard) { + // required here to handle async behaviour of render.compute() + gl.enable(gl.RASTERIZER_DISCARD); + this.discard = true; + } + + const { programGPU, transformBuffers, attributes } = this.get(pipeline); + + const vaoKey = this._getVaoKey(null, attributes); + + const vaoGPU = this.vaoCache[vaoKey]; + + if (vaoGPU === undefined) { + this._createVao(null, attributes); + } else { + gl.bindVertexArray(vaoGPU); + } + + state.useProgram(programGPU); + + this._bindUniforms(bindings); + + const transformFeedbackGPU = this._getTransformFeedback(transformBuffers); + + gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, transformFeedbackGPU); + gl.beginTransformFeedback(gl.POINTS); + + if (attributes[0].isStorageInstancedBufferAttribute) { + gl.drawArraysInstanced(gl.POINTS, 0, 1, computeNode.count); + } else { + gl.drawArrays(gl.POINTS, 0, computeNode.count); + } + + gl.endTransformFeedback(); + gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null); + + // switch active buffers + + for (let i = 0; i < transformBuffers.length; i++) { + const dualAttributeData = transformBuffers[i]; + + if (dualAttributeData.pbo) { + this.textureUtils.copyBufferToTexture(dualAttributeData.transformBuffer, dualAttributeData.pbo); + } + + dualAttributeData.switchBuffers(); + } + } + + finishCompute(computeGroup) { + const gl = this.gl; + + this.discard = false; + + gl.disable(gl.RASTERIZER_DISCARD); + + this.prepareTimestampBuffer(computeGroup); + + if (this._currentContext) { + this._setFramebuffer(this._currentContext); + } + } + + draw(renderObject /*, info*/) { + const { object, pipeline, material, context } = renderObject; + const { programGPU } = this.get(pipeline); + + const { gl, state } = this; + + const contextData = this.get(context); + + const drawParams = renderObject.getDrawParameters(); + + if (drawParams === null) return; + + // + + this._bindUniforms(renderObject.getBindings()); + + const frontFaceCW = object.isMesh && object.matrixWorld.determinant() < 0; + + state.setMaterial(material, frontFaceCW); + + state.useProgram(programGPU); + + // + + let vaoGPU = renderObject.staticVao; + + if (vaoGPU === undefined) { + const vaoKey = this._getVaoKey(renderObject.getIndex(), renderObject.getAttributes()); + + vaoGPU = this.vaoCache[vaoKey]; + + if (vaoGPU === undefined) { + let staticVao; + + ({ vaoGPU, staticVao } = this._createVao(renderObject.getIndex(), renderObject.getAttributes())); + + if (staticVao) renderObject.staticVao = vaoGPU; + } + } + + gl.bindVertexArray(vaoGPU); + + // + + const index = renderObject.getIndex(); + + // + + const lastObject = contextData.lastOcclusionObject; + + if (lastObject !== object && lastObject !== undefined) { + if (lastObject !== null && lastObject.occlusionTest === true) { + gl.endQuery(gl.ANY_SAMPLES_PASSED); + + contextData.occlusionQueryIndex++; + } + + if (object.occlusionTest === true) { + const query = gl.createQuery(); + + gl.beginQuery(gl.ANY_SAMPLES_PASSED, query); + + contextData.occlusionQueries[contextData.occlusionQueryIndex] = query; + contextData.occlusionQueryObjects[contextData.occlusionQueryIndex] = object; + } + + contextData.lastOcclusionObject = object; + } + + // + const renderer = this.bufferRenderer; + + if (object.isPoints) renderer.mode = gl.POINTS; + else if (object.isLineSegments) renderer.mode = gl.LINES; + else if (object.isLine) renderer.mode = gl.LINE_STRIP; + else if (object.isLineLoop) renderer.mode = gl.LINE_LOOP; + else { + if (material.wireframe === true) { + state.setLineWidth(material.wireframeLinewidth * this.renderer.getPixelRatio()); + renderer.mode = gl.LINES; + } else { + renderer.mode = gl.TRIANGLES; + } + } + + // + + const { vertexCount, instanceCount } = drawParams; + let { firstVertex } = drawParams; + + renderer.object = object; + + if (index !== null) { + firstVertex *= index.array.BYTES_PER_ELEMENT; + + const indexData = this.get(index); + + renderer.index = index.count; + renderer.type = indexData.type; + } else { + renderer.index = 0; + } + + if (object.isBatchedMesh) { + if (object._multiDrawInstances !== null) { + renderer.renderMultiDrawInstances( + object._multiDrawStarts, + object._multiDrawCounts, + object._multiDrawCount, + object._multiDrawInstances, + ); + } else if (!this.hasFeature('WEBGL_multi_draw')) { + warnOnce('THREE.WebGLRenderer: WEBGL_multi_draw not supported.'); + } else { + renderer.renderMultiDraw(object._multiDrawStarts, object._multiDrawCounts, object._multiDrawCount); + } + } else if (instanceCount > 1) { + renderer.renderInstances(firstVertex, vertexCount, instanceCount); + } else { + renderer.render(firstVertex, vertexCount); + } + // + + gl.bindVertexArray(null); + } + + needsRenderUpdate(/*renderObject*/) { + return false; + } + + getRenderCacheKey(/*renderObject*/) { + return ''; + } + + // textures + + createDefaultTexture(texture) { + this.textureUtils.createDefaultTexture(texture); + } + + createTexture(texture, options) { + this.textureUtils.createTexture(texture, options); + } + + updateTexture(texture, options) { + this.textureUtils.updateTexture(texture, options); + } + + generateMipmaps(texture) { + this.textureUtils.generateMipmaps(texture); + } + + destroyTexture(texture) { + this.textureUtils.destroyTexture(texture); + } + + copyTextureToBuffer(texture, x, y, width, height, faceIndex) { + return this.textureUtils.copyTextureToBuffer(texture, x, y, width, height, faceIndex); + } + + createSampler(/*texture*/) { + //console.warn( 'Abstract class.' ); + } + + destroySampler() {} + + // node builder + + createNodeBuilder(object, renderer) { + return new GLSLNodeBuilder(object, renderer); + } + + // program + + createProgram(program) { + const gl = this.gl; + const { stage, code } = program; + + const shader = stage === 'fragment' ? gl.createShader(gl.FRAGMENT_SHADER) : gl.createShader(gl.VERTEX_SHADER); + + gl.shaderSource(shader, code); + gl.compileShader(shader); + + this.set(program, { + shaderGPU: shader, + }); + } + + destroyProgram(/*program*/) { + console.warn('Abstract class.'); + } + + createRenderPipeline(renderObject, promises) { + const gl = this.gl; + const pipeline = renderObject.pipeline; + + // Program + + const { fragmentProgram, vertexProgram } = pipeline; + + const programGPU = gl.createProgram(); + + const fragmentShader = this.get(fragmentProgram).shaderGPU; + const vertexShader = this.get(vertexProgram).shaderGPU; + + gl.attachShader(programGPU, fragmentShader); + gl.attachShader(programGPU, vertexShader); + gl.linkProgram(programGPU); + + this.set(pipeline, { + programGPU, + fragmentShader, + vertexShader, + }); + + if (promises !== null && this.parallel) { + const p = new Promise((resolve /*, reject*/) => { + const parallel = this.parallel; + const checkStatus = () => { + if (gl.getProgramParameter(programGPU, parallel.COMPLETION_STATUS_KHR)) { + this._completeCompile(renderObject, pipeline); + resolve(); + } else { + requestAnimationFrame(checkStatus); + } + }; + + checkStatus(); + }); + + promises.push(p); + + return; + } + + this._completeCompile(renderObject, pipeline); + } + + _handleSource(string, errorLine) { + const lines = string.split('\n'); + const lines2 = []; + + const from = Math.max(errorLine - 6, 0); + const to = Math.min(errorLine + 6, lines.length); + + for (let i = from; i < to; i++) { + const line = i + 1; + lines2.push(`${line === errorLine ? '>' : ' '} ${line}: ${lines[i]}`); + } + + return lines2.join('\n'); + } + + _getShaderErrors(gl, shader, type) { + const status = gl.getShaderParameter(shader, gl.COMPILE_STATUS); + const errors = gl.getShaderInfoLog(shader).trim(); + + if (status && errors === '') return ''; + + const errorMatches = /ERROR: 0:(\d+)/.exec(errors); + if (errorMatches) { + const errorLine = parseInt(errorMatches[1]); + return ( + type.toUpperCase() + + '\n\n' + + errors + + '\n\n' + + this._handleSource(gl.getShaderSource(shader), errorLine) + ); + } else { + return errors; + } + } + + _logProgramError(programGPU, glFragmentShader, glVertexShader) { + if (this.renderer.debug.checkShaderErrors) { + const gl = this.gl; + + const programLog = gl.getProgramInfoLog(programGPU).trim(); + + if (gl.getProgramParameter(programGPU, gl.LINK_STATUS) === false) { + if (typeof this.renderer.debug.onShaderError === 'function') { + this.renderer.debug.onShaderError(gl, programGPU, glVertexShader, glFragmentShader); + } else { + // default error reporting + + const vertexErrors = this._getShaderErrors(gl, glVertexShader, 'vertex'); + const fragmentErrors = this._getShaderErrors(gl, glFragmentShader, 'fragment'); + + console.error( + 'THREE.WebGLProgram: Shader Error ' + + gl.getError() + + ' - ' + + 'VALIDATE_STATUS ' + + gl.getProgramParameter(programGPU, gl.VALIDATE_STATUS) + + '\n\n' + + 'Program Info Log: ' + + programLog + + '\n' + + vertexErrors + + '\n' + + fragmentErrors, + ); + } + } else if (programLog !== '') { + console.warn('THREE.WebGLProgram: Program Info Log:', programLog); + } + } + } + + _completeCompile(renderObject, pipeline) { + const { state, gl } = this; + const pipelineData = this.get(pipeline); + const { programGPU, fragmentShader, vertexShader } = pipelineData; + + if (gl.getProgramParameter(programGPU, gl.LINK_STATUS) === false) { + this._logProgramError(programGPU, fragmentShader, vertexShader); + } + + state.useProgram(programGPU); + + // Bindings + + const bindings = renderObject.getBindings(); + + this._setupBindings(bindings, programGPU); + + // + + this.set(pipeline, { + programGPU, + }); + } + + createComputePipeline(computePipeline, bindings) { + const { state, gl } = this; + + // Program + + const fragmentProgram = { + stage: 'fragment', + code: '#version 300 es\nprecision highp float;\nvoid main() {}', + }; + + this.createProgram(fragmentProgram); + + const { computeProgram } = computePipeline; + + const programGPU = gl.createProgram(); + + const fragmentShader = this.get(fragmentProgram).shaderGPU; + const vertexShader = this.get(computeProgram).shaderGPU; + + const transforms = computeProgram.transforms; + + const transformVaryingNames = []; + const transformAttributeNodes = []; + + for (let i = 0; i < transforms.length; i++) { + const transform = transforms[i]; + + transformVaryingNames.push(transform.varyingName); + transformAttributeNodes.push(transform.attributeNode); + } + + gl.attachShader(programGPU, fragmentShader); + gl.attachShader(programGPU, vertexShader); + + gl.transformFeedbackVaryings(programGPU, transformVaryingNames, gl.SEPARATE_ATTRIBS); + + gl.linkProgram(programGPU); + + if (gl.getProgramParameter(programGPU, gl.LINK_STATUS) === false) { + this._logProgramError(programGPU, fragmentShader, vertexShader); + } + + state.useProgram(programGPU); + + // Bindings + + this._setupBindings(bindings, programGPU); + + const attributeNodes = computeProgram.attributes; + const attributes = []; + const transformBuffers = []; + + for (let i = 0; i < attributeNodes.length; i++) { + const attribute = attributeNodes[i].node.attribute; + + attributes.push(attribute); + + if (!this.has(attribute)) this.attributeUtils.createAttribute(attribute, gl.ARRAY_BUFFER); + } + + for (let i = 0; i < transformAttributeNodes.length; i++) { + const attribute = transformAttributeNodes[i].attribute; + + if (!this.has(attribute)) this.attributeUtils.createAttribute(attribute, gl.ARRAY_BUFFER); + + const attributeData = this.get(attribute); + + transformBuffers.push(attributeData); + } + + // + + this.set(computePipeline, { + programGPU, + transformBuffers, + attributes, + }); + } + + createBindings(bindGroup, bindings) { + if (this._knownBindings.has(bindings) === false) { + this._knownBindings.add(bindings); + + let uniformBuffers = 0; + let textures = 0; + + for (const bindGroup of bindings) { + this.set(bindGroup, { + textures: textures, + uniformBuffers: uniformBuffers, + }); + + for (const binding of bindGroup.bindings) { + if (binding.isUniformBuffer) uniformBuffers++; + if (binding.isSampledTexture) textures++; + } + } + } + + this.updateBindings(bindGroup, bindings); + } + + updateBindings(bindGroup /*, bindings*/) { + const { gl } = this; + + const bindGroupData = this.get(bindGroup); + + let i = bindGroupData.uniformBuffers; + let t = bindGroupData.textures; + + for (const binding of bindGroup.bindings) { + if (binding.isUniformsGroup || binding.isUniformBuffer) { + const data = binding.buffer; + const bufferGPU = gl.createBuffer(); + + gl.bindBuffer(gl.UNIFORM_BUFFER, bufferGPU); + gl.bufferData(gl.UNIFORM_BUFFER, data, gl.DYNAMIC_DRAW); + + this.set(binding, { + index: i++, + bufferGPU, + }); + } else if (binding.isSampledTexture) { + const { textureGPU, glTextureType } = this.get(binding.texture); + + this.set(binding, { + index: t++, + textureGPU, + glTextureType, + }); + } + } + } + + updateBinding(binding) { + const gl = this.gl; + + if (binding.isUniformsGroup || binding.isUniformBuffer) { + const bindingData = this.get(binding); + const bufferGPU = bindingData.bufferGPU; + const data = binding.buffer; + + gl.bindBuffer(gl.UNIFORM_BUFFER, bufferGPU); + gl.bufferData(gl.UNIFORM_BUFFER, data, gl.DYNAMIC_DRAW); + } + } + + // attributes + + createIndexAttribute(attribute) { + const gl = this.gl; + + this.attributeUtils.createAttribute(attribute, gl.ELEMENT_ARRAY_BUFFER); + } + + createAttribute(attribute) { + if (this.has(attribute)) return; + + const gl = this.gl; + + this.attributeUtils.createAttribute(attribute, gl.ARRAY_BUFFER); + } + + createStorageAttribute(attribute) { + if (this.has(attribute)) return; + + const gl = this.gl; + + this.attributeUtils.createAttribute(attribute, gl.ARRAY_BUFFER); + } + + updateAttribute(attribute) { + this.attributeUtils.updateAttribute(attribute); + } + + destroyAttribute(attribute) { + this.attributeUtils.destroyAttribute(attribute); + } + + updateSize() { + //console.warn( 'Abstract class.' ); + } + + hasFeature(name) { + const keysMatching = Object.keys(GLFeatureName).filter(key => GLFeatureName[key] === name); + + const extensions = this.extensions; + + for (let i = 0; i < keysMatching.length; i++) { + if (extensions.has(keysMatching[i])) return true; + } + + return false; + } + + getMaxAnisotropy() { + return this.capabilities.getMaxAnisotropy(); + } + + copyTextureToTexture(srcTexture, dstTexture, srcRegion, dstPosition, level) { + this.textureUtils.copyTextureToTexture(srcTexture, dstTexture, srcRegion, dstPosition, level); + } + + copyFramebufferToTexture(texture, renderContext, rectangle) { + this.textureUtils.copyFramebufferToTexture(texture, renderContext, rectangle); + } + + _setFramebuffer(descriptor) { + const { gl, state } = this; + + let currentFrameBuffer = null; + + if (descriptor.textures !== null) { + const renderTarget = descriptor.renderTarget; + const renderTargetContextData = this.get(renderTarget); + const { samples, depthBuffer, stencilBuffer } = renderTarget; + + const isCube = renderTarget.isWebGLCubeRenderTarget === true; + + let msaaFb = renderTargetContextData.msaaFrameBuffer; + let depthRenderbuffer = renderTargetContextData.depthRenderbuffer; + + const cacheKey = getCacheKey(descriptor); + + let fb; + + if (isCube) { + renderTargetContextData.cubeFramebuffers || (renderTargetContextData.cubeFramebuffers = {}); + + fb = renderTargetContextData.cubeFramebuffers[cacheKey]; + } else { + renderTargetContextData.framebuffers || (renderTargetContextData.framebuffers = {}); + + fb = renderTargetContextData.framebuffers[cacheKey]; + } + + if (fb === undefined) { + fb = gl.createFramebuffer(); + + state.bindFramebuffer(gl.FRAMEBUFFER, fb); + + const textures = descriptor.textures; + + if (isCube) { + renderTargetContextData.cubeFramebuffers[cacheKey] = fb; + + const { textureGPU } = this.get(textures[0]); + + const cubeFace = this.renderer._activeCubeFace; + + gl.framebufferTexture2D( + gl.FRAMEBUFFER, + gl.COLOR_ATTACHMENT0, + gl.TEXTURE_CUBE_MAP_POSITIVE_X + cubeFace, + textureGPU, + 0, + ); + } else { + renderTargetContextData.framebuffers[cacheKey] = fb; + + for (let i = 0; i < textures.length; i++) { + const texture = textures[i]; + const textureData = this.get(texture); + textureData.renderTarget = descriptor.renderTarget; + textureData.cacheKey = cacheKey; // required for copyTextureToTexture() + + const attachment = gl.COLOR_ATTACHMENT0 + i; + + gl.framebufferTexture2D(gl.FRAMEBUFFER, attachment, gl.TEXTURE_2D, textureData.textureGPU, 0); + } + + state.drawBuffers(descriptor, fb); + } + + if (descriptor.depthTexture !== null) { + const textureData = this.get(descriptor.depthTexture); + const depthStyle = stencilBuffer ? gl.DEPTH_STENCIL_ATTACHMENT : gl.DEPTH_ATTACHMENT; + textureData.renderTarget = descriptor.renderTarget; + textureData.cacheKey = cacheKey; // required for copyTextureToTexture() + + gl.framebufferTexture2D(gl.FRAMEBUFFER, depthStyle, gl.TEXTURE_2D, textureData.textureGPU, 0); + } + } + + if (samples > 0) { + if (msaaFb === undefined) { + const invalidationArray = []; + + msaaFb = gl.createFramebuffer(); + + state.bindFramebuffer(gl.FRAMEBUFFER, msaaFb); + + const msaaRenderbuffers = []; + + const textures = descriptor.textures; + + for (let i = 0; i < textures.length; i++) { + msaaRenderbuffers[i] = gl.createRenderbuffer(); + + gl.bindRenderbuffer(gl.RENDERBUFFER, msaaRenderbuffers[i]); + + invalidationArray.push(gl.COLOR_ATTACHMENT0 + i); + + if (depthBuffer) { + const depthStyle = stencilBuffer ? gl.DEPTH_STENCIL_ATTACHMENT : gl.DEPTH_ATTACHMENT; + invalidationArray.push(depthStyle); + } + + const texture = descriptor.textures[i]; + const textureData = this.get(texture); + + gl.renderbufferStorageMultisample( + gl.RENDERBUFFER, + samples, + textureData.glInternalFormat, + descriptor.width, + descriptor.height, + ); + gl.framebufferRenderbuffer( + gl.FRAMEBUFFER, + gl.COLOR_ATTACHMENT0 + i, + gl.RENDERBUFFER, + msaaRenderbuffers[i], + ); + } + + renderTargetContextData.msaaFrameBuffer = msaaFb; + renderTargetContextData.msaaRenderbuffers = msaaRenderbuffers; + + if (depthRenderbuffer === undefined) { + depthRenderbuffer = gl.createRenderbuffer(); + this.textureUtils.setupRenderBufferStorage(depthRenderbuffer, descriptor); + + renderTargetContextData.depthRenderbuffer = depthRenderbuffer; + + const depthStyle = stencilBuffer ? gl.DEPTH_STENCIL_ATTACHMENT : gl.DEPTH_ATTACHMENT; + invalidationArray.push(depthStyle); + } + + renderTargetContextData.invalidationArray = invalidationArray; + } + + currentFrameBuffer = renderTargetContextData.msaaFrameBuffer; + } else { + currentFrameBuffer = fb; + } + } + + state.bindFramebuffer(gl.FRAMEBUFFER, currentFrameBuffer); + } + + _getVaoKey(index, attributes) { + let key = []; + + if (index !== null) { + const indexData = this.get(index); + + key += ':' + indexData.id; + } + + for (let i = 0; i < attributes.length; i++) { + const attributeData = this.get(attributes[i]); + + key += ':' + attributeData.id; + } + + return key; + } + + _createVao(index, attributes) { + const { gl } = this; + + const vaoGPU = gl.createVertexArray(); + let key = ''; + + let staticVao = true; + + gl.bindVertexArray(vaoGPU); + + if (index !== null) { + const indexData = this.get(index); + + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexData.bufferGPU); + + key += ':' + indexData.id; + } + + for (let i = 0; i < attributes.length; i++) { + const attribute = attributes[i]; + const attributeData = this.get(attribute); + + key += ':' + attributeData.id; + + gl.bindBuffer(gl.ARRAY_BUFFER, attributeData.bufferGPU); + gl.enableVertexAttribArray(i); + + if (attribute.isStorageBufferAttribute || attribute.isStorageInstancedBufferAttribute) staticVao = false; + + let stride, offset; + + if (attribute.isInterleavedBufferAttribute === true) { + stride = attribute.data.stride * attributeData.bytesPerElement; + offset = attribute.offset * attributeData.bytesPerElement; + } else { + stride = 0; + offset = 0; + } + + if (attributeData.isInteger) { + gl.vertexAttribIPointer(i, attribute.itemSize, attributeData.type, stride, offset); + } else { + gl.vertexAttribPointer(i, attribute.itemSize, attributeData.type, attribute.normalized, stride, offset); + } + + if (attribute.isInstancedBufferAttribute && !attribute.isInterleavedBufferAttribute) { + gl.vertexAttribDivisor(i, attribute.meshPerAttribute); + } else if (attribute.isInterleavedBufferAttribute && attribute.data.isInstancedInterleavedBuffer) { + gl.vertexAttribDivisor(i, attribute.data.meshPerAttribute); + } + } + + gl.bindBuffer(gl.ARRAY_BUFFER, null); + + this.vaoCache[key] = vaoGPU; + + return { vaoGPU, staticVao }; + } + + _getTransformFeedback(transformBuffers) { + let key = ''; + + for (let i = 0; i < transformBuffers.length; i++) { + key += ':' + transformBuffers[i].id; + } + + let transformFeedbackGPU = this.transformFeedbackCache[key]; + + if (transformFeedbackGPU !== undefined) { + return transformFeedbackGPU; + } + + const { gl } = this; + + transformFeedbackGPU = gl.createTransformFeedback(); + + gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, transformFeedbackGPU); + + for (let i = 0; i < transformBuffers.length; i++) { + const attributeData = transformBuffers[i]; + + gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, i, attributeData.transformBuffer); + } + + gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null); + + this.transformFeedbackCache[key] = transformFeedbackGPU; + + return transformFeedbackGPU; + } + + _setupBindings(bindings, programGPU) { + const gl = this.gl; + + for (const bindGroup of bindings) { + for (const binding of bindGroup.bindings) { + const bindingData = this.get(binding); + const index = bindingData.index; + + if (binding.isUniformsGroup || binding.isUniformBuffer) { + const location = gl.getUniformBlockIndex(programGPU, binding.name); + gl.uniformBlockBinding(programGPU, location, index); + } else if (binding.isSampledTexture) { + const location = gl.getUniformLocation(programGPU, binding.name); + gl.uniform1i(location, index); + } + } + } + } + + _bindUniforms(bindings) { + const { gl, state } = this; + + for (const bindGroup of bindings) { + for (const binding of bindGroup.bindings) { + const bindingData = this.get(binding); + const index = bindingData.index; + + if (binding.isUniformsGroup || binding.isUniformBuffer) { + // TODO USE bindBufferRange to group multiple uniform buffers + state.bindBufferBase(gl.UNIFORM_BUFFER, index, bindingData.bufferGPU); + } else if (binding.isSampledTexture) { + state.bindTexture(bindingData.glTextureType, bindingData.textureGPU, gl.TEXTURE0 + index); + } + } + } + } +} + +export default WebGLBackend; diff --git a/src-testing/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.ts b/src-testing/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.ts new file mode 100644 index 000000000..b1e720647 --- /dev/null +++ b/src-testing/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.ts @@ -0,0 +1,812 @@ +import { GLSLNodeParser, NodeBuilder, TextureNode, vectorComponents } from '../../../nodes/Nodes.js'; + +import NodeUniformBuffer from '../../common/nodes/NodeUniformBuffer.js'; +import NodeUniformsGroup from '../../common/nodes/NodeUniformsGroup.js'; + +import { + NodeSampledTexture, + NodeSampledCubeTexture, + NodeSampledTexture3D, +} from '../../common/nodes/NodeSampledTexture.js'; + +import { + NoColorSpace, + ByteType, + ShortType, + RGBAIntegerFormat, + RGBIntegerFormat, + RedIntegerFormat, + RGIntegerFormat, + UnsignedByteType, + UnsignedIntType, + UnsignedShortType, + RedFormat, + RGFormat, + IntType, + RGBFormat, + RGBAFormat, + FloatType, +} from '../../../constants.js'; +import { DataTexture } from '../../../textures/DataTexture.js'; + +const glslMethods = { + atan2: 'atan', + textureDimensions: 'textureSize', + equals: 'equal', +}; + +const precisionLib = { + low: 'lowp', + medium: 'mediump', + high: 'highp', +}; + +const supports = { + swizzleAssign: true, + storageBuffer: false, +}; + +const defaultPrecisions = ` +precision highp float; +precision highp int; +precision highp sampler2D; +precision highp sampler3D; +precision highp samplerCube; +precision highp sampler2DArray; + +precision highp usampler2D; +precision highp usampler3D; +precision highp usamplerCube; +precision highp usampler2DArray; + +precision highp isampler2D; +precision highp isampler3D; +precision highp isamplerCube; +precision highp isampler2DArray; + +precision lowp sampler2DShadow; +`; + +class GLSLNodeBuilder extends NodeBuilder { + constructor(object, renderer) { + super(object, renderer, new GLSLNodeParser()); + + this.uniformGroups = {}; + this.transforms = []; + this.extensions = {}; + + this.useComparisonMethod = true; + } + + needsColorSpaceToLinearSRGB(texture) { + return texture.isVideoTexture === true && texture.colorSpace !== NoColorSpace; + } + + getMethod(method) { + return glslMethods[method] || method; + } + + getOutputStructName() { + return ''; + } + + buildFunctionCode(shaderNode) { + const layout = shaderNode.layout; + const flowData = this.flowShaderNode(shaderNode); + + const parameters = []; + + for (const input of layout.inputs) { + parameters.push(this.getType(input.type) + ' ' + input.name); + } + + // + + const code = `${this.getType(layout.type)} ${layout.name}( ${parameters.join(', ')} ) { + + ${flowData.vars} + +${flowData.code} + return ${flowData.result}; + +}`; + + // + + return code; + } + + setupPBO(storageBufferNode) { + const attribute = storageBufferNode.value; + + if (attribute.pbo === undefined) { + const originalArray = attribute.array; + const numElements = attribute.count * attribute.itemSize; + + const { itemSize } = attribute; + + const isInteger = attribute.array.constructor.name.toLowerCase().includes('int'); + + let format = isInteger ? RedIntegerFormat : RedFormat; + + if (itemSize === 2) { + format = isInteger ? RGIntegerFormat : RGFormat; + } else if (itemSize === 3) { + format = isInteger ? RGBIntegerFormat : RGBFormat; + } else if (itemSize === 4) { + format = isInteger ? RGBAIntegerFormat : RGBAFormat; + } + + const typeMap = { + Float32Array: FloatType, + Uint8Array: UnsignedByteType, + Uint16Array: UnsignedShortType, + Uint32Array: UnsignedIntType, + Int8Array: ByteType, + Int16Array: ShortType, + Int32Array: IntType, + Uint8ClampedArray: UnsignedByteType, + }; + + const width = Math.pow(2, Math.ceil(Math.log2(Math.sqrt(numElements / itemSize)))); + let height = Math.ceil(numElements / itemSize / width); + if (width * height * itemSize < numElements) height++; // Ensure enough space + + const newSize = width * height * itemSize; + + const newArray = new originalArray.constructor(newSize); + + newArray.set(originalArray, 0); + + attribute.array = newArray; + + const pboTexture = new DataTexture( + attribute.array, + width, + height, + format, + typeMap[attribute.array.constructor.name] || FloatType, + ); + pboTexture.needsUpdate = true; + pboTexture.isPBOTexture = true; + + const pbo = new TextureNode(pboTexture, null, null); + pbo.setPrecision('high'); + + attribute.pboNode = pbo; + attribute.pbo = pbo.value; + + this.getUniformFromNode(attribute.pboNode, 'texture', this.shaderStage, this.context.label); + } + } + + getPropertyName(node, shaderStage = this.shaderStage) { + if (node.isNodeUniform && node.node.isTextureNode !== true && node.node.isBufferNode !== true) { + return shaderStage.charAt(0) + '_' + node.name; + } + + return super.getPropertyName(node, shaderStage); + } + + generatePBO(storageArrayElementNode) { + const { node, indexNode } = storageArrayElementNode; + const attribute = node.value; + + if (this.renderer.backend.has(attribute)) { + const attributeData = this.renderer.backend.get(attribute); + attributeData.pbo = attribute.pbo; + } + + const nodeUniform = this.getUniformFromNode(attribute.pboNode, 'texture', this.shaderStage, this.context.label); + const textureName = this.getPropertyName(nodeUniform); + + this.increaseUsage(indexNode); // force cache generate to be used as index in x,y + const indexSnippet = indexNode.build(this, 'uint'); + + const elementNodeData = this.getDataFromNode(storageArrayElementNode); + + let propertyName = elementNodeData.propertyName; + + if (propertyName === undefined) { + // property element + + const nodeVar = this.getVarFromNode(storageArrayElementNode); + + propertyName = this.getPropertyName(nodeVar); + + // property size + + const bufferNodeData = this.getDataFromNode(node); + + let propertySizeName = bufferNodeData.propertySizeName; + + if (propertySizeName === undefined) { + propertySizeName = propertyName + 'Size'; + + this.getVarFromNode(node, propertySizeName, 'uint'); + + this.addLineFlowCode( + `${propertySizeName} = uint( textureSize( ${textureName}, 0 ).x )`, + storageArrayElementNode, + ); + + bufferNodeData.propertySizeName = propertySizeName; + } + + // + + const { itemSize } = attribute; + + const channel = '.' + vectorComponents.join('').slice(0, itemSize); + const uvSnippet = `ivec2(${indexSnippet} % ${propertySizeName}, ${indexSnippet} / ${propertySizeName})`; + + const snippet = this.generateTextureLoad(null, textureName, uvSnippet, null, '0'); + + // + + let prefix = 'vec4'; + + if (attribute.pbo.type === UnsignedIntType) { + prefix = 'uvec4'; + } else if (attribute.pbo.type === IntType) { + prefix = 'ivec4'; + } + + this.addLineFlowCode(`${propertyName} = ${prefix}(${snippet})${channel}`, storageArrayElementNode); + + elementNodeData.propertyName = propertyName; + } + + return propertyName; + } + + generateTextureLoad(texture, textureProperty, uvIndexSnippet, depthSnippet, levelSnippet = '0') { + if (depthSnippet) { + return `texelFetch( ${textureProperty}, ivec3( ${uvIndexSnippet}, ${depthSnippet} ), ${levelSnippet} )`; + } else { + return `texelFetch( ${textureProperty}, ${uvIndexSnippet}, ${levelSnippet} )`; + } + } + + generateTexture(texture, textureProperty, uvSnippet, depthSnippet) { + if (texture.isDepthTexture) { + return `texture( ${textureProperty}, ${uvSnippet} ).x`; + } else { + if (depthSnippet) uvSnippet = `vec3( ${uvSnippet}, ${depthSnippet} )`; + + return `texture( ${textureProperty}, ${uvSnippet} )`; + } + } + + generateTextureLevel(texture, textureProperty, uvSnippet, levelSnippet) { + return `textureLod( ${textureProperty}, ${uvSnippet}, ${levelSnippet} )`; + } + + generateTextureBias(texture, textureProperty, uvSnippet, biasSnippet) { + return `texture( ${textureProperty}, ${uvSnippet}, ${biasSnippet} )`; + } + + generateTextureGrad(texture, textureProperty, uvSnippet, gradSnippet) { + return `textureGrad( ${textureProperty}, ${uvSnippet}, ${gradSnippet[0]}, ${gradSnippet[1]} )`; + } + + generateTextureCompare( + texture, + textureProperty, + uvSnippet, + compareSnippet, + depthSnippet, + shaderStage = this.shaderStage, + ) { + if (shaderStage === 'fragment') { + return `texture( ${textureProperty}, vec3( ${uvSnippet}, ${compareSnippet} ) )`; + } else { + console.error( + `WebGPURenderer: THREE.DepthTexture.compareFunction() does not support ${shaderStage} shader.`, + ); + } + } + + getVars(shaderStage) { + const snippets = []; + + const vars = this.vars[shaderStage]; + + if (vars !== undefined) { + for (const variable of vars) { + snippets.push(`${this.getVar(variable.type, variable.name)};`); + } + } + + return snippets.join('\n\t'); + } + + getUniforms(shaderStage) { + const uniforms = this.uniforms[shaderStage]; + + const bindingSnippets = []; + const uniformGroups = {}; + + for (const uniform of uniforms) { + let snippet = null; + let group = false; + + if (uniform.type === 'texture') { + const texture = uniform.node.value; + + let typePrefix = ''; + + if (texture.isDataTexture === true) { + if (texture.type === UnsignedIntType) { + typePrefix = 'u'; + } else if (texture.type === IntType) { + typePrefix = 'i'; + } + } + + if (texture.compareFunction) { + snippet = `sampler2DShadow ${uniform.name};`; + } else if (texture.isDataArrayTexture === true || texture.isCompressedArrayTexture === true) { + snippet = `${typePrefix}sampler2DArray ${uniform.name};`; + } else { + snippet = `${typePrefix}sampler2D ${uniform.name};`; + } + } else if (uniform.type === 'cubeTexture') { + snippet = `samplerCube ${uniform.name};`; + } else if (uniform.type === 'texture3D') { + snippet = `sampler3D ${uniform.name};`; + } else if (uniform.type === 'buffer') { + const bufferNode = uniform.node; + const bufferType = this.getType(bufferNode.bufferType); + const bufferCount = bufferNode.bufferCount; + + const bufferCountSnippet = bufferCount > 0 ? bufferCount : ''; + snippet = `${bufferNode.name} {\n\t${bufferType} ${uniform.name}[${bufferCountSnippet}];\n};\n`; + } else { + const vectorType = this.getVectorType(uniform.type); + + snippet = `${vectorType} ${this.getPropertyName(uniform, shaderStage)};`; + + group = true; + } + + const precision = uniform.node.precision; + + if (precision !== null) { + snippet = precisionLib[precision] + ' ' + snippet; + } + + if (group) { + snippet = '\t' + snippet; + + const groupName = uniform.groupNode.name; + const groupSnippets = uniformGroups[groupName] || (uniformGroups[groupName] = []); + + groupSnippets.push(snippet); + } else { + snippet = 'uniform ' + snippet; + + bindingSnippets.push(snippet); + } + } + + let output = ''; + + for (const name in uniformGroups) { + const groupSnippets = uniformGroups[name]; + + output += this._getGLSLUniformStruct(shaderStage + '_' + name, groupSnippets.join('\n')) + '\n'; + } + + output += bindingSnippets.join('\n'); + + return output; + } + + getTypeFromAttribute(attribute) { + let nodeType = super.getTypeFromAttribute(attribute); + + if (/^[iu]/.test(nodeType) && attribute.gpuType !== IntType) { + let dataAttribute = attribute; + + if (attribute.isInterleavedBufferAttribute) dataAttribute = attribute.data; + + const array = dataAttribute.array; + + if ((array instanceof Uint32Array || array instanceof Int32Array) === false) { + nodeType = nodeType.slice(1); + } + } + + return nodeType; + } + + getAttributes(shaderStage) { + let snippet = ''; + + if (shaderStage === 'vertex' || shaderStage === 'compute') { + const attributes = this.getAttributesArray(); + + let location = 0; + + for (const attribute of attributes) { + snippet += `layout( location = ${location++} ) in ${attribute.type} ${attribute.name};\n`; + } + } + + return snippet; + } + + getStructMembers(struct) { + const snippets = []; + const members = struct.getMemberTypes(); + + for (let i = 0; i < members.length; i++) { + const member = members[i]; + snippets.push(`layout( location = ${i} ) out ${member} m${i};`); + } + + return snippets.join('\n'); + } + + getStructs(shaderStage) { + const snippets = []; + const structs = this.structs[shaderStage]; + + if (structs.length === 0) { + return 'layout( location = 0 ) out vec4 fragColor;\n'; + } + + for (let index = 0, length = structs.length; index < length; index++) { + const struct = structs[index]; + + let snippet = '\n'; + snippet += this.getStructMembers(struct); + snippet += '\n'; + + snippets.push(snippet); + } + + return snippets.join('\n\n'); + } + + getVaryings(shaderStage) { + let snippet = ''; + + const varyings = this.varyings; + + if (shaderStage === 'vertex' || shaderStage === 'compute') { + for (const varying of varyings) { + if (shaderStage === 'compute') varying.needsInterpolation = true; + const type = varying.type; + const flat = type.includes('int') || type.includes('uv') || type.includes('iv') ? 'flat ' : ''; + + snippet += `${flat}${varying.needsInterpolation ? 'out' : '/*out*/'} ${type} ${varying.name};\n`; + } + } else if (shaderStage === 'fragment') { + for (const varying of varyings) { + if (varying.needsInterpolation) { + const type = varying.type; + const flat = type.includes('int') || type.includes('uv') || type.includes('iv') ? 'flat ' : ''; + + snippet += `${flat}in ${type} ${varying.name};\n`; + } + } + } + + return snippet; + } + + getVertexIndex() { + return 'uint( gl_VertexID )'; + } + + getInstanceIndex() { + return 'uint( gl_InstanceID )'; + } + + getInvocationLocalIndex() { + const workgroupSize = this.object.workgroupSize; + + const size = workgroupSize.reduce((acc, curr) => acc * curr, 1); + + return `uint( gl_InstanceID ) % ${size}u`; + } + + getDrawIndex() { + const extensions = this.renderer.backend.extensions; + + if (extensions.has('WEBGL_multi_draw')) { + return 'uint( gl_DrawID )'; + } + + return null; + } + + getFrontFacing() { + return 'gl_FrontFacing'; + } + + getFragCoord() { + return 'gl_FragCoord.xy'; + } + + getFragDepth() { + return 'gl_FragDepth'; + } + + enableExtension(name, behavior, shaderStage = this.shaderStage) { + const map = this.extensions[shaderStage] || (this.extensions[shaderStage] = new Map()); + + if (map.has(name) === false) { + map.set(name, { + name, + behavior, + }); + } + } + + getExtensions(shaderStage) { + const snippets = []; + + if (shaderStage === 'vertex') { + const ext = this.renderer.backend.extensions; + const isBatchedMesh = this.object.isBatchedMesh; + + if (isBatchedMesh && ext.has('WEBGL_multi_draw')) { + this.enableExtension('GL_ANGLE_multi_draw', 'require', shaderStage); + } + } + + const extensions = this.extensions[shaderStage]; + + if (extensions !== undefined) { + for (const { name, behavior } of extensions.values()) { + snippets.push(`#extension ${name} : ${behavior}`); + } + } + + return snippets.join('\n'); + } + + isAvailable(name) { + let result = supports[name]; + + if (result === undefined) { + if (name === 'float32Filterable') { + const extensions = this.renderer.backend.extensions; + + if (extensions.has('OES_texture_float_linear')) { + extensions.get('OES_texture_float_linear'); + result = true; + } else { + result = false; + } + } + + supports[name] = result; + } + + return result; + } + + isFlipY() { + return true; + } + + registerTransform(varyingName, attributeNode) { + this.transforms.push({ varyingName, attributeNode }); + } + + getTransforms(/* shaderStage */) { + const transforms = this.transforms; + + let snippet = ''; + + for (let i = 0; i < transforms.length; i++) { + const transform = transforms[i]; + + const attributeName = this.getPropertyName(transform.attributeNode); + + snippet += `${transform.varyingName} = ${attributeName};\n\t`; + } + + return snippet; + } + + _getGLSLUniformStruct(name, vars) { + return ` +layout( std140 ) uniform ${name} { +${vars} +};`; + } + + _getGLSLVertexCode(shaderData) { + return `#version 300 es + +${this.getSignature()} + +// extensions +${shaderData.extensions} + +// precision +${defaultPrecisions} + +// uniforms +${shaderData.uniforms} + +// varyings +${shaderData.varyings} + +// attributes +${shaderData.attributes} + +// codes +${shaderData.codes} + +void main() { + + // vars + ${shaderData.vars} + + // transforms + ${shaderData.transforms} + + // flow + ${shaderData.flow} + + gl_PointSize = 1.0; + +} +`; + } + + _getGLSLFragmentCode(shaderData) { + return `#version 300 es + +${this.getSignature()} + +// precision +${defaultPrecisions} + +// uniforms +${shaderData.uniforms} + +// varyings +${shaderData.varyings} + +// codes +${shaderData.codes} + +${shaderData.structs} + +void main() { + + // vars + ${shaderData.vars} + + // flow + ${shaderData.flow} + +} +`; + } + + buildCode() { + const shadersData = this.material !== null ? { fragment: {}, vertex: {} } : { compute: {} }; + + this.sortBindingGroups(); + + for (const shaderStage in shadersData) { + let flow = '// code\n\n'; + flow += this.flowCode[shaderStage]; + + const flowNodes = this.flowNodes[shaderStage]; + const mainNode = flowNodes[flowNodes.length - 1]; + + for (const node of flowNodes) { + const flowSlotData = this.getFlowData(node /*, shaderStage*/); + const slotName = node.name; + + if (slotName) { + if (flow.length > 0) flow += '\n'; + + flow += `\t// flow -> ${slotName}\n\t`; + } + + flow += `${flowSlotData.code}\n\t`; + + if (node === mainNode && shaderStage !== 'compute') { + flow += '// result\n\t'; + + if (shaderStage === 'vertex') { + flow += 'gl_Position = '; + flow += `${flowSlotData.result};`; + } else if (shaderStage === 'fragment') { + if (!node.outputNode.isOutputStructNode) { + flow += 'fragColor = '; + flow += `${flowSlotData.result};`; + } + } + } + } + + const stageData = shadersData[shaderStage]; + + stageData.extensions = this.getExtensions(shaderStage); + stageData.uniforms = this.getUniforms(shaderStage); + stageData.attributes = this.getAttributes(shaderStage); + stageData.varyings = this.getVaryings(shaderStage); + stageData.vars = this.getVars(shaderStage); + stageData.structs = this.getStructs(shaderStage); + stageData.codes = this.getCodes(shaderStage); + stageData.transforms = this.getTransforms(shaderStage); + stageData.flow = flow; + } + + if (this.material !== null) { + this.vertexShader = this._getGLSLVertexCode(shadersData.vertex); + this.fragmentShader = this._getGLSLFragmentCode(shadersData.fragment); + } else { + this.computeShader = this._getGLSLVertexCode(shadersData.compute); + } + } + + getUniformFromNode(node, type, shaderStage, name = null) { + const uniformNode = super.getUniformFromNode(node, type, shaderStage, name); + const nodeData = this.getDataFromNode(node, shaderStage, this.globalCache); + + let uniformGPU = nodeData.uniformGPU; + + if (uniformGPU === undefined) { + const group = node.groupNode; + const groupName = group.name; + + const bindings = this.getBindGroupArray(groupName, shaderStage); + + if (type === 'texture') { + uniformGPU = new NodeSampledTexture(uniformNode.name, uniformNode.node, group); + bindings.push(uniformGPU); + } else if (type === 'cubeTexture') { + uniformGPU = new NodeSampledCubeTexture(uniformNode.name, uniformNode.node, group); + bindings.push(uniformGPU); + } else if (type === 'texture3D') { + uniformGPU = new NodeSampledTexture3D(uniformNode.name, uniformNode.node, group); + bindings.push(uniformGPU); + } else if (type === 'buffer') { + node.name = `NodeBuffer_${node.id}`; + uniformNode.name = `buffer${node.id}`; + + const buffer = new NodeUniformBuffer(node, group); + buffer.name = node.name; + + bindings.push(buffer); + + uniformGPU = buffer; + } else { + const uniformsStage = this.uniformGroups[shaderStage] || (this.uniformGroups[shaderStage] = {}); + + let uniformsGroup = uniformsStage[groupName]; + + if (uniformsGroup === undefined) { + uniformsGroup = new NodeUniformsGroup(shaderStage + '_' + groupName, group); + //uniformsGroup.setVisibility( gpuShaderStageLib[ shaderStage ] ); + + uniformsStage[groupName] = uniformsGroup; + + bindings.push(uniformsGroup); + } + + uniformGPU = this.getNodeUniform(uniformNode, type); + + uniformsGroup.addUniform(uniformGPU); + } + + nodeData.uniformGPU = uniformGPU; + } + + return uniformNode; + } +} + +export default GLSLNodeBuilder; diff --git a/src-testing/src/renderers/webgl/WebGLAttributes.d.ts b/src-testing/src/renderers/webgl/WebGLAttributes.d.ts new file mode 100644 index 000000000..8f4a9757b --- /dev/null +++ b/src-testing/src/renderers/webgl/WebGLAttributes.d.ts @@ -0,0 +1,21 @@ +import { BufferAttribute } from "../../core/BufferAttribute.js"; +import { GLBufferAttribute } from "../../core/GLBufferAttribute.js"; +import { InterleavedBufferAttribute } from "../../core/InterleavedBufferAttribute.js"; + +export class WebGLAttributes { + constructor(gl: WebGLRenderingContext | WebGL2RenderingContext); + + get(attribute: BufferAttribute | InterleavedBufferAttribute | GLBufferAttribute): + | { + buffer: WebGLBuffer; + type: number; + bytesPerElement: number; + version: number; + size: number; + } + | undefined; + + remove(attribute: BufferAttribute | InterleavedBufferAttribute | GLBufferAttribute): void; + + update(attribute: BufferAttribute | InterleavedBufferAttribute | GLBufferAttribute, bufferType: number): void; +} diff --git a/src-testing/src/renderers/webgl/WebGLBindingStates.d.ts b/src-testing/src/renderers/webgl/WebGLBindingStates.d.ts new file mode 100644 index 000000000..0b96de770 --- /dev/null +++ b/src-testing/src/renderers/webgl/WebGLBindingStates.d.ts @@ -0,0 +1,26 @@ +import { BufferAttribute } from "../../core/BufferAttribute.js"; +import { BufferGeometry } from "../../core/BufferGeometry.js"; +import { Object3D } from "../../core/Object3D.js"; +import { Material } from "../../materials/Material.js"; +import { WebGLAttributes } from "./WebGLAttributes.js"; +import { WebGLProgram } from "./WebGLProgram.js"; + +export class WebGLBindingStates { + constructor(gl: WebGLRenderingContext, attributes: WebGLAttributes); + + setup( + object: Object3D, + material: Material, + program: WebGLProgram, + geometry: BufferGeometry, + index: BufferAttribute, + ): void; + reset(): void; + resetDefaultState(): void; + dispose(): void; + releaseStatesOfGeometry(): void; + releaseStatesOfProgram(): void; + initAttributes(): void; + enableAttribute(attribute: number): void; + disableUnusedAttributes(): void; +} diff --git a/src-testing/src/renderers/webgl/WebGLBufferRenderer.d.ts b/src-testing/src/renderers/webgl/WebGLBufferRenderer.d.ts new file mode 100644 index 000000000..c75f74745 --- /dev/null +++ b/src-testing/src/renderers/webgl/WebGLBufferRenderer.d.ts @@ -0,0 +1,21 @@ +import { WebGLExtensions } from "./WebGLExtensions.js"; +import { WebGLInfo } from "./WebGLInfo.js"; + +export class WebGLBufferRenderer { + constructor( + gl: WebGLRenderingContext, + extensions: WebGLExtensions, + info: WebGLInfo, + ); + + setMode: (value: any) => void; + render: (start: any, count: number) => void; + renderInstances: (start: any, count: number, primcount: number) => void; + renderMultiDraw: (starts: Int32Array, counts: Int32Array, drawCount: number) => void; + renderMultiDrawInstances: ( + starts: Int32Array, + counts: Int32Array, + drawCount: number, + primcount: Int32Array, + ) => void; +} diff --git a/src-testing/src/renderers/webgl/WebGLCapabilities.d.ts b/src-testing/src/renderers/webgl/WebGLCapabilities.d.ts new file mode 100644 index 000000000..c36a9b0f2 --- /dev/null +++ b/src-testing/src/renderers/webgl/WebGLCapabilities.d.ts @@ -0,0 +1,48 @@ +import { PixelFormat, TextureDataType } from "../../constants.js"; + +export interface WebGLCapabilitiesParameters { + /** + * shader precision. Can be "highp", "mediump" or "lowp". + */ + precision?: string | undefined; + + /** + * default is false. + */ + logarithmicDepthBuffer?: boolean | undefined; + + /** + * default is false. + */ + reverseDepthBuffer?: boolean | undefined; +} + +export class WebGLCapabilities { + constructor(gl: WebGLRenderingContext, extensions: any, parameters: WebGLCapabilitiesParameters); + + readonly isWebGL2: boolean; + + getMaxAnisotropy: () => number; + getMaxPrecision: (precision: string) => string; + + textureFormatReadable: (textureFormat: PixelFormat) => boolean; + textureTypeReadable: (textureType: TextureDataType) => boolean; + + precision: string; + logarithmicDepthBuffer: boolean; + reverseDepthBuffer: boolean; + + maxTextures: number; + maxVertexTextures: number; + maxTextureSize: number; + maxCubemapSize: number; + + maxAttributes: number; + maxVertexUniforms: number; + maxVaryings: number; + maxFragmentUniforms: number; + + vertexTextures: boolean; + + maxSamples: number; +} diff --git a/src-testing/src/renderers/webgl/WebGLClipping.d.ts b/src-testing/src/renderers/webgl/WebGLClipping.d.ts new file mode 100644 index 000000000..167a16b35 --- /dev/null +++ b/src-testing/src/renderers/webgl/WebGLClipping.d.ts @@ -0,0 +1,26 @@ +import { Camera } from "../../cameras/Camera.js"; +import { Material } from "../../materials/Material.js"; +import { Plane } from "../../math/Plane.js"; +import { WebGLProperties } from "./WebGLProperties.js"; + +export class WebGLClipping { + constructor(properties: WebGLProperties); + + uniform: { value: any; needsUpdate: boolean }; + + /** + * @default 0 + */ + numPlanes: number; + + /** + * @default 0 + */ + numIntersection: number; + + init(planes: any[], enableLocalClipping: boolean): boolean; + beginShadows(): void; + endShadows(): void; + setGlobalState(planes: Plane[], camera: Camera): void; + setState(material: Material, camera: Camera, useCache: boolean): void; +} diff --git a/src-testing/src/renderers/webgl/WebGLCubeMaps.d.ts b/src-testing/src/renderers/webgl/WebGLCubeMaps.d.ts new file mode 100644 index 000000000..32cda3f61 --- /dev/null +++ b/src-testing/src/renderers/webgl/WebGLCubeMaps.d.ts @@ -0,0 +1,8 @@ +import { WebGLRenderer } from "../WebGLRenderer.js"; + +export class WebGLCubeMaps { + constructor(renderer: WebGLRenderer); + + get(texture: any): any; + dispose(): void; +} diff --git a/src-testing/src/renderers/webgl/WebGLCubeUVMaps.d.ts b/src-testing/src/renderers/webgl/WebGLCubeUVMaps.d.ts new file mode 100644 index 000000000..e94246325 --- /dev/null +++ b/src-testing/src/renderers/webgl/WebGLCubeUVMaps.d.ts @@ -0,0 +1,9 @@ +import { Texture } from "../../textures/Texture.js"; +import { WebGLRenderer } from "../WebGLRenderer.js"; + +export class WebGLCubeUVMaps { + constructor(renderer: WebGLRenderer); + + get(texture: T): T extends Texture ? Texture : T; + dispose(): void; +} diff --git a/src-testing/src/renderers/webgl/WebGLExtensions.d.ts b/src-testing/src/renderers/webgl/WebGLExtensions.d.ts new file mode 100644 index 000000000..0f0c0bf4b --- /dev/null +++ b/src-testing/src/renderers/webgl/WebGLExtensions.d.ts @@ -0,0 +1,7 @@ +export class WebGLExtensions { + constructor(gl: WebGLRenderingContext); + + has(name: string): boolean; + init(): void; + get(name: string): any; +} diff --git a/src-testing/src/renderers/webgl/WebGLGeometries.d.ts b/src-testing/src/renderers/webgl/WebGLGeometries.d.ts new file mode 100644 index 000000000..422249f37 --- /dev/null +++ b/src-testing/src/renderers/webgl/WebGLGeometries.d.ts @@ -0,0 +1,13 @@ +import { BufferAttribute } from "../../core/BufferAttribute.js"; +import { BufferGeometry } from "../../core/BufferGeometry.js"; +import { Object3D } from "../../core/Object3D.js"; +import { WebGLAttributes } from "./WebGLAttributes.js"; +import { WebGLInfo } from "./WebGLInfo.js"; + +export class WebGLGeometries { + constructor(gl: WebGLRenderingContext, attributes: WebGLAttributes, info: WebGLInfo); + + get(object: Object3D, geometry: BufferGeometry): BufferGeometry; + update(geometry: BufferGeometry): void; + getWireframeAttribute(geometry: BufferGeometry): BufferAttribute; +} diff --git a/src-testing/src/renderers/webgl/WebGLIndexedBufferRenderer.d.ts b/src-testing/src/renderers/webgl/WebGLIndexedBufferRenderer.d.ts new file mode 100644 index 000000000..8e016e847 --- /dev/null +++ b/src-testing/src/renderers/webgl/WebGLIndexedBufferRenderer.d.ts @@ -0,0 +1,15 @@ +export class WebGLIndexedBufferRenderer { + constructor(gl: WebGLRenderingContext, extensions: any, info: any); + + setMode: (value: any) => void; + setIndex: (index: any) => void; + render: (start: any, count: number) => void; + renderInstances: (start: any, count: number, primcount: number) => void; + renderMultiDraw: (starts: Int32Array, counts: Int32Array, drawCount: number) => void; + renderMultiDrawInstances: ( + starts: Int32Array, + counts: Int32Array, + drawCount: number, + primcount: Int32Array, + ) => void; +} diff --git a/src-testing/src/renderers/webgl/WebGLInfo.d.ts b/src-testing/src/renderers/webgl/WebGLInfo.d.ts new file mode 100644 index 000000000..952ff6f9f --- /dev/null +++ b/src-testing/src/renderers/webgl/WebGLInfo.d.ts @@ -0,0 +1,39 @@ +import { WebGLProgram } from "./WebGLProgram.js"; + +/** + * An object with a series of statistical information about the graphics board memory and the rendering process. + */ +export class WebGLInfo { + constructor(gl: WebGLRenderingContext); + + /** + * @default true + */ + autoReset: boolean; + + /** + * @default { geometries: 0, textures: 0 } + */ + memory: { + geometries: number; + textures: number; + }; + + /** + * @default null + */ + programs: WebGLProgram[] | null; + + /** + * @default { frame: 0, calls: 0, triangles: 0, points: 0, lines: 0 } + */ + render: { + calls: number; + frame: number; + lines: number; + points: number; + triangles: number; + }; + update(count: number, mode: number, instanceCount: number): void; + reset(): void; +} diff --git a/src-testing/src/renderers/webgl/WebGLLights.d.ts b/src-testing/src/renderers/webgl/WebGLLights.d.ts new file mode 100644 index 000000000..4c01422e8 --- /dev/null +++ b/src-testing/src/renderers/webgl/WebGLLights.d.ts @@ -0,0 +1,49 @@ +import { WebGLExtensions } from "./WebGLExtensions.js"; + +export interface WebGLLightsState { + version: number; + + hash: { + directionalLength: number; + pointLength: number; + spotLength: number; + rectAreaLength: number; + hemiLength: number; + + numDirectionalShadows: number; + numPointShadows: number; + numSpotShadows: number; + numSpotMaps: number; + + numLightProbes: number; + }; + + ambient: number[]; + probe: any[]; + directional: any[]; + directionalShadow: any[]; + directionalShadowMap: any[]; + directionalShadowMatrix: any[]; + spot: any[]; + spotShadow: any[]; + spotShadowMap: any[]; + spotShadowMatrix: any[]; + rectArea: any[]; + point: any[]; + pointShadow: any[]; + pointShadowMap: any[]; + pointShadowMatrix: any[]; + hemi: any[]; + numSpotLightShadowsWithMaps: number; + numLightProbes: number; +} + +export class WebGLLights { + constructor(extensions: WebGLExtensions); + + state: WebGLLightsState; + + get(light: any): any; + setup(lights: any): void; + setupView(lights: any, camera: any): void; +} diff --git a/src-testing/src/renderers/webgl/WebGLObjects.d.ts b/src-testing/src/renderers/webgl/WebGLObjects.d.ts new file mode 100644 index 000000000..aeb0356f7 --- /dev/null +++ b/src-testing/src/renderers/webgl/WebGLObjects.d.ts @@ -0,0 +1,6 @@ +export class WebGLObjects { + constructor(gl: WebGLRenderingContext, geometries: any, attributes: any, info: any); + + update(object: any): any; + dispose(): void; +} diff --git a/src-testing/src/renderers/webgl/WebGLProgram.d.ts b/src-testing/src/renderers/webgl/WebGLProgram.d.ts new file mode 100644 index 000000000..b3e5d6fd8 --- /dev/null +++ b/src-testing/src/renderers/webgl/WebGLProgram.d.ts @@ -0,0 +1,30 @@ +import { WebGLRenderer } from "../WebGLRenderer.js"; +import { WebGLUniforms } from "./WebGLUniforms.js"; + +export class WebGLProgram { + constructor(renderer: WebGLRenderer, cacheKey: string, parameters: object); + + name: string; + id: number; + cacheKey: string; // unique identifier for this program, used for looking up compiled programs from cache. + + /** + * @default 1 + */ + usedTimes: number; + program: any; + vertexShader: WebGLShader; + fragmentShader: WebGLShader; + /** + * @deprecated Use {@link WebGLProgram#getUniforms getUniforms()} instead. + */ + uniforms: any; + /** + * @deprecated Use {@link WebGLProgram#getAttributes getAttributes()} instead. + */ + attributes: any; + + getUniforms(): WebGLUniforms; + getAttributes(): any; + destroy(): void; +} diff --git a/src-testing/src/renderers/webgl/WebGLPrograms.d.ts b/src-testing/src/renderers/webgl/WebGLPrograms.d.ts new file mode 100644 index 000000000..8f5999f06 --- /dev/null +++ b/src-testing/src/renderers/webgl/WebGLPrograms.d.ts @@ -0,0 +1,233 @@ +import { Combine, DepthPackingStrategies, GLSLVersion, Mapping, ShadowMapType, ToneMapping } from "../../constants.js"; +import { Object3D } from "../../core/Object3D.js"; +import { Light } from "../../lights/Light.js"; +import { Material } from "../../materials/Material.js"; +import { Scene } from "../../scenes/Scene.js"; +import { IUniform } from "../shaders/UniformsLib.js"; +import { WebGLRenderer } from "../WebGLRenderer.js"; +import { WebGLBindingStates } from "./WebGLBindingStates.js"; +import { WebGLCapabilities } from "./WebGLCapabilities.js"; +import { WebGLClipping } from "./WebGLClipping.js"; +import { WebGLCubeMaps } from "./WebGLCubeMaps.js"; +import { WebGLExtensions } from "./WebGLExtensions.js"; +import { WebGLLightsState } from "./WebGLLights.js"; +import { WebGLProgram } from "./WebGLProgram.js"; + +export interface WebGLProgramParameters { + shaderID: string; + shaderType: string; + shaderName: string; + + vertexShader: string; + fragmentShader: string; + defines: { [define: string]: string | number | boolean } | undefined; + + customVertexShaderID: string | undefined; + customFragmentShaderID: string | undefined; + + isRawShaderMaterial: boolean; + glslVersion: GLSLVersion | null | undefined; + + precision: "lowp" | "mediump" | "highp"; + + batching: boolean; + batchingColor: boolean; + instancing: boolean; + instancingColor: boolean; + instancingMorph: boolean; + + supportsVertexTextures: boolean; + outputColorSpace: string; + alphaToCoverage: boolean; + + map: boolean; + matcap: boolean; + envMap: boolean; + envMapMode: Mapping | false; + envMapCubeUVHeight: number | null; + aoMap: boolean; + lightMap: boolean; + bumpMap: boolean; + normalMap: boolean; + displacementMap: boolean; + emissiveMap: boolean; + + normalMapObjectSpace: boolean; + normalMapTangentSpace: boolean; + + metalnessMap: boolean; + roughnessMap: boolean; + + anisotropy: boolean; + anisotropyMap: boolean; + + clearcoat: boolean; + clearcoatMap: boolean; + clearcoatNormalMap: boolean; + clearcoatRoughnessMap: boolean; + + dispersion: boolean; + + iridescence: boolean; + iridescenceMap: boolean; + iridescenceThicknessMap: boolean; + + sheen: boolean; + sheenColorMap: boolean; + sheenRoughnessMap: boolean; + + specularMap: boolean; + specularColorMap: boolean; + specularIntensityMap: boolean; + + transmission: boolean; + transmissionMap: boolean; + thicknessMap: boolean; + + gradientMap: boolean; + + opaque: boolean; + + alphaMap: boolean; + alphaTest: boolean; + alphaHash: boolean; + + combine: Combine | undefined; + + // + + mapUv: string | false; + aoMapUv: string | false; + lightMapUv: string | false; + bumpMapUv: string | false; + normalMapUv: string | false; + displacementMapUv: string | false; + emissiveMapUv: string | false; + + metalnessMapUv: string | false; + roughnessMapUv: string | false; + + anisotropyMapUv: string | false; + + clearcoatMapUv: string | false; + clearcoatNormalMapUv: string | false; + clearcoatRoughnessMapUv: string | false; + + iridescenceMapUv: string | false; + iridescenceThicknessMapUv: string | false; + + sheenColorMapUv: string | false; + sheenRoughnessMapUv: string | false; + + specularMapUv: string | false; + specularColorMapUv: string | false; + specularIntensityMapUv: string | false; + + transmissionMapUv: string | false; + thicknessMapUv: string | false; + + alphaMapUv: string | false; + + // + + vertexTangents: boolean; + vertexColors: boolean; + vertexAlphas: boolean; + vertexUv1s: boolean; + vertexUv2s: boolean; + vertexUv3s: boolean; + + pointsUvs: boolean; + + fog: boolean; + useFog: boolean; + fogExp2: boolean; + + flatShading: boolean; + + sizeAttenuation: boolean; + logarithmicDepthBuffer: boolean; + reverseDepthBuffer: boolean; + + skinning: boolean; + + morphTargets: boolean; + morphNormals: boolean; + morphColors: boolean; + morphTargetsCount: number; + morphTextureStride: number; + + numDirLights: number; + numPointLights: number; + numSpotLights: number; + numSpotLightMaps: number; + numRectAreaLights: number; + numHemiLights: number; + + numDirLightShadows: number; + numPointLightShadows: number; + numSpotLightShadows: number; + numSpotLightShadowsWithMaps: number; + + numLightProbes: number; + + numClippingPlanes: number; + numClipIntersection: number; + + dithering: boolean; + + shadowMapEnabled: boolean; + shadowMapType: ShadowMapType; + + toneMapping: ToneMapping; + + decodeVideoTexture: boolean; + decodeVideoTextureEmissive: boolean; + + premultipliedAlpha: boolean; + + doubleSided: boolean; + flipSided: boolean; + + useDepthPacking: boolean; + depthPacking: DepthPackingStrategies | 0; + + index0AttributeName: string | undefined; + + extensionClipCullDistance: boolean; + extensionMultiDraw: boolean; + + rendererExtensionParallelShaderCompile: boolean; + + customProgramCacheKey: string; +} + +export interface WebGLProgramParametersWithUniforms extends WebGLProgramParameters { + uniforms: { [uniform: string]: IUniform }; +} + +export class WebGLPrograms { + constructor( + renderer: WebGLRenderer, + cubemaps: WebGLCubeMaps, + extensions: WebGLExtensions, + capabilities: WebGLCapabilities, + bindingStates: WebGLBindingStates, + clipping: WebGLClipping, + ); + + programs: WebGLProgram[]; + + getParameters( + material: Material, + lights: WebGLLightsState, + shadows: Light[], + scene: Scene, + object: Object3D, + ): WebGLProgramParameters; + + getProgramCacheKey(parameters: WebGLProgramParameters): string; + getUniforms(material: Material): { [uniform: string]: IUniform }; + acquireProgram(parameters: WebGLProgramParametersWithUniforms, cacheKey: string): WebGLProgram; + releaseProgram(program: WebGLProgram): void; +} diff --git a/src-testing/src/renderers/webgl/WebGLProperties.d.ts b/src-testing/src/renderers/webgl/WebGLProperties.d.ts new file mode 100644 index 000000000..adcf01ec9 --- /dev/null +++ b/src-testing/src/renderers/webgl/WebGLProperties.d.ts @@ -0,0 +1,9 @@ +export class WebGLProperties { + constructor(); + + has: (object: unknown) => boolean; + get: (object: unknown) => unknown; + remove: (object: unknown) => void; + update: (object: unknown, key: unknown, value: unknown) => unknown; + dispose: () => void; +} diff --git a/src-testing/src/renderers/webgl/WebGLRenderLists.d.ts b/src-testing/src/renderers/webgl/WebGLRenderLists.d.ts new file mode 100644 index 000000000..0f16a4287 --- /dev/null +++ b/src-testing/src/renderers/webgl/WebGLRenderLists.d.ts @@ -0,0 +1,66 @@ +import { Camera } from "../../cameras/Camera.js"; +import { BufferGeometry } from "../../core/BufferGeometry.js"; +import { Object3D } from "../../core/Object3D.js"; +import { Material } from "../../materials/Material.js"; +import { Group } from "../../objects/Group.js"; +import { Scene } from "../../scenes/Scene.js"; +import { WebGLProgram } from "./WebGLProgram.js"; +import { WebGLProperties } from "./WebGLProperties.js"; + +export interface RenderItem { + id: number; + object: Object3D; + geometry: BufferGeometry | null; + material: Material; + program: WebGLProgram; + groupOrder: number; + renderOrder: number; + z: number; + group: Group | null; +} + +export class WebGLRenderList { + constructor(properties: WebGLProperties); + + /** + * @default [] + */ + opaque: RenderItem[]; + + /** + * @default [] + */ + transparent: RenderItem[]; + + /** + * @default [] + */ + transmissive: RenderItem[]; + + init(): void; + push( + object: Object3D, + geometry: BufferGeometry | null, + material: Material, + groupOrder: number, + z: number, + group: Group | null, + ): void; + unshift( + object: Object3D, + geometry: BufferGeometry | null, + material: Material, + groupOrder: number, + z: number, + group: Group | null, + ): void; + sort(opaqueSort: (a: any, b: any) => number, transparentSort: (a: any, b: any) => number): void; + finish(): void; +} + +export class WebGLRenderLists { + constructor(properties: WebGLProperties); + + dispose(): void; + get(scene: Scene, renderCallDepth: number): WebGLRenderList; +} diff --git a/src-testing/src/renderers/webgl/WebGLShader.d.ts b/src-testing/src/renderers/webgl/WebGLShader.d.ts new file mode 100644 index 000000000..5704fb88e --- /dev/null +++ b/src-testing/src/renderers/webgl/WebGLShader.d.ts @@ -0,0 +1 @@ +export function WebGLShader(gl: WebGLRenderingContext, type: string, string: string): WebGLShader; diff --git a/src-testing/src/renderers/webgl/WebGLShadowMap.d.ts b/src-testing/src/renderers/webgl/WebGLShadowMap.d.ts new file mode 100644 index 000000000..8368fdee7 --- /dev/null +++ b/src-testing/src/renderers/webgl/WebGLShadowMap.d.ts @@ -0,0 +1,38 @@ +import { Camera } from "../../cameras/Camera.js"; +import { ShadowMapType } from "../../constants.js"; +import { Light } from "../../lights/Light.js"; +import { Scene } from "../../scenes/Scene.js"; +import { WebGLRenderer } from "../WebGLRenderer.js"; +import { WebGLCapabilities } from "./WebGLCapabilities.js"; +import { WebGLObjects } from "./WebGLObjects.js"; + +export class WebGLShadowMap { + constructor(_renderer: WebGLRenderer, _objects: WebGLObjects, _capabilities: WebGLCapabilities); + + /** + * @default false + */ + enabled: boolean; + + /** + * @default true + */ + autoUpdate: boolean; + + /** + * @default false + */ + needsUpdate: boolean; + + /** + * @default THREE.PCFShadowMap + */ + type: ShadowMapType; + + render(shadowsArray: Light[], scene: Scene, camera: Camera): void; + + /** + * @deprecated Use {@link Material#shadowSide} instead. + */ + cullFace: any; +} diff --git a/src-testing/src/renderers/webgl/WebGLState.d.ts b/src-testing/src/renderers/webgl/WebGLState.d.ts new file mode 100644 index 000000000..13d4850e9 --- /dev/null +++ b/src-testing/src/renderers/webgl/WebGLState.d.ts @@ -0,0 +1,116 @@ +import { + Blending, + BlendingDstFactor, + BlendingEquation, + BlendingSrcFactor, + CullFace, + DepthModes, +} from "../../constants.js"; +import { Material } from "../../materials/Material.js"; +import { Vector4 } from "../../math/Vector4.js"; +import { WebGLRenderTarget } from "../WebGLRenderTarget.js"; + +export class WebGLColorBuffer { + constructor(); + + setMask(colorMask: boolean): void; + setLocked(lock: boolean): void; + setClear(r: number, g: number, b: number, a: number, premultipliedAlpha: boolean): void; + reset(): void; +} + +export class WebGLDepthBuffer { + constructor(); + + setTest(depthTest: boolean): void; + setMask(depthMask: boolean): void; + setFunc(depthFunc: DepthModes): void; + setLocked(lock: boolean): void; + setClear(depth: number): void; + reset(): void; +} + +export class WebGLStencilBuffer { + constructor(); + + setTest(stencilTest: boolean): void; + setMask(stencilMask: number): void; + setFunc(stencilFunc: number, stencilRef: number, stencilMask: number): void; + setOp(stencilFail: number, stencilZFail: number, stencilZPass: number): void; + setLocked(lock: boolean): void; + setClear(stencil: number): void; + reset(): void; +} + +export class WebGLState { + constructor(gl: WebGLRenderingContext); + + buffers: { + color: WebGLColorBuffer; + depth: WebGLDepthBuffer; + stencil: WebGLStencilBuffer; + }; + + enable(id: number): void; + disable(id: number): void; + bindFramebuffer(target: number, framebuffer: WebGLFramebuffer | null): void; + drawBuffers(renderTarget: WebGLRenderTarget | null, framebuffer: WebGLFramebuffer | null): void; + useProgram(program: any): boolean; + setBlending( + blending: Blending, + blendEquation?: BlendingEquation, + blendSrc?: BlendingSrcFactor, + blendDst?: BlendingDstFactor, + blendEquationAlpha?: BlendingEquation, + blendSrcAlpha?: BlendingSrcFactor, + blendDstAlpha?: BlendingDstFactor, + premultiplyAlpha?: boolean, + ): void; + setMaterial(material: Material, frontFaceCW: boolean): void; + setFlipSided(flipSided: boolean): void; + setCullFace(cullFace: CullFace): void; + setLineWidth(width: number): void; + setPolygonOffset(polygonoffset: boolean, factor?: number, units?: number): void; + setScissorTest(scissorTest: boolean): void; + activeTexture(webglSlot: number): void; + bindTexture(webglType: number, webglTexture: any): void; + unbindTexture(): void; + // Same interface as https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/compressedTexImage2D + compressedTexImage2D( + target: number, + level: number, + internalformat: number, + width: number, + height: number, + border: number, + data: ArrayBufferView, + ): void; + // Same interface as https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/texImage2D + texImage2D( + target: number, + level: number, + internalformat: number, + width: number, + height: number, + border: number, + format: number, + type: number, + pixels: ArrayBufferView | null, + ): void; + texImage2D(target: number, level: number, internalformat: number, format: number, type: number, source: any): void; + texImage3D( + target: number, + level: number, + internalformat: number, + width: number, + height: number, + depth: number, + border: number, + format: number, + type: number, + pixels: any, + ): void; + scissor(scissor: Vector4): void; + viewport(viewport: Vector4): void; + reset(): void; +} diff --git a/src-testing/src/renderers/webgl/WebGLTextures.d.ts b/src-testing/src/renderers/webgl/WebGLTextures.d.ts new file mode 100644 index 000000000..031866dee --- /dev/null +++ b/src-testing/src/renderers/webgl/WebGLTextures.d.ts @@ -0,0 +1,30 @@ +import { WebGLCapabilities } from "./WebGLCapabilities.js"; +import { WebGLExtensions } from "./WebGLExtensions.js"; +import { WebGLInfo } from "./WebGLInfo.js"; +import { WebGLProperties } from "./WebGLProperties.js"; +import { WebGLState } from "./WebGLState.js"; +import { WebGLUtils } from "./WebGLUtils.js"; + +export class WebGLTextures { + constructor( + gl: WebGLRenderingContext, + extensions: WebGLExtensions, + state: WebGLState, + properties: WebGLProperties, + capabilities: WebGLCapabilities, + utils: WebGLUtils, + info: WebGLInfo, + ); + + allocateTextureUnit(): void; + resetTextureUnits(): void; + setTexture2D(texture: any, slot: number): void; + setTexture2DArray(texture: any, slot: number): void; + setTexture3D(texture: any, slot: number): void; + setTextureCube(texture: any, slot: number): void; + setupRenderTarget(renderTarget: any): void; + updateRenderTargetMipmap(renderTarget: any): void; + updateMultisampleRenderTarget(renderTarget: any): void; + safeSetTexture2D(texture: any, slot: number): void; + safeSetTextureCube(texture: any, slot: number): void; +} diff --git a/src-testing/src/renderers/webgl/WebGLUniforms.d.ts b/src-testing/src/renderers/webgl/WebGLUniforms.d.ts new file mode 100644 index 000000000..925b5e4bf --- /dev/null +++ b/src-testing/src/renderers/webgl/WebGLUniforms.d.ts @@ -0,0 +1,12 @@ +import { WebGLProgram } from "./WebGLProgram.js"; +import { WebGLTextures } from "./WebGLTextures.js"; + +export class WebGLUniforms { + constructor(gl: WebGLRenderingContext, program: WebGLProgram); + + setValue(gl: WebGLRenderingContext, name: string, value: any, textures: WebGLTextures): void; + setOptional(gl: WebGLRenderingContext, object: any, name: string): void; + + static upload(gl: WebGLRenderingContext, seq: any, values: any[], textures: WebGLTextures): void; + static seqWithValue(seq: any, values: any[]): any[]; +} diff --git a/src-testing/src/renderers/webgl/WebGLUniformsGroups.d.ts b/src-testing/src/renderers/webgl/WebGLUniformsGroups.d.ts new file mode 100644 index 000000000..a5e052c1f --- /dev/null +++ b/src-testing/src/renderers/webgl/WebGLUniformsGroups.d.ts @@ -0,0 +1,17 @@ +import { UniformsGroup } from "../../core/UniformsGroup.js"; + +import { WebGLCapabilities } from "./WebGLCapabilities.js"; +import { WebGLInfo } from "./WebGLInfo.js"; +import { WebGLProgram } from "./WebGLProgram.js"; +import { WebGLState } from "./WebGLState.js"; + +export function WebGLUniformsGroups( + gl: WebGLRenderingContext, + info: WebGLInfo, + capabilities: WebGLCapabilities, + state: WebGLState, +): { + dispose: () => void; + update: (uniformsGroup: UniformsGroup, program: WebGLProgram) => void; + bind: (uniformsGroup: UniformsGroup, program: WebGLProgram) => void; +}; diff --git a/src-testing/src/renderers/webgl/WebGLUtils.d.ts b/src-testing/src/renderers/webgl/WebGLUtils.d.ts new file mode 100644 index 000000000..53011bfe6 --- /dev/null +++ b/src-testing/src/renderers/webgl/WebGLUtils.d.ts @@ -0,0 +1,11 @@ +import { CompressedPixelFormat, PixelFormat, TextureDataType } from "../../constants.js"; +import { WebGLExtensions } from "./WebGLExtensions.js"; + +export class WebGLUtils { + constructor( + gl: WebGLRenderingContext | WebGL2RenderingContext, + extensions: WebGLExtensions, + ); + + convert(p: PixelFormat | CompressedPixelFormat | TextureDataType, colorSpace?: string): number | null; +} diff --git a/src-testing/src/renderers/webgpu/WebGPUBackend.ts b/src-testing/src/renderers/webgpu/WebGPUBackend.ts new file mode 100644 index 000000000..930197a02 --- /dev/null +++ b/src-testing/src/renderers/webgpu/WebGPUBackend.ts @@ -0,0 +1,1297 @@ +/*// debugger tools +import 'https://greggman.github.io/webgpu-avoid-redundant-state-setting/webgpu-check-redundant-state-setting.js'; +//*/ + +import { + GPUFeatureName, + GPULoadOp, + GPUStoreOp, + GPUIndexFormat, + GPUTextureViewDimension, +} from './utils/WebGPUConstants.js'; + +import WGSLNodeBuilder from './nodes/WGSLNodeBuilder.js'; +import Backend from '../common/Backend.js'; + +import WebGPUUtils from './utils/WebGPUUtils.js'; +import WebGPUAttributeUtils from './utils/WebGPUAttributeUtils.js'; +import WebGPUBindingUtils from './utils/WebGPUBindingUtils.js'; +import WebGPUPipelineUtils from './utils/WebGPUPipelineUtils.js'; +import WebGPUTextureUtils from './utils/WebGPUTextureUtils.js'; + +import { WebGPUCoordinateSystem } from '../../constants.js'; + +// + +class WebGPUBackend extends Backend { + constructor(parameters = {}) { + super(parameters); + + this.isWebGPUBackend = true; + + // some parameters require default values other than "undefined" + this.parameters.alpha = parameters.alpha === undefined ? true : parameters.alpha; + + this.parameters.requiredLimits = parameters.requiredLimits === undefined ? {} : parameters.requiredLimits; + + this.trackTimestamp = parameters.trackTimestamp === true; + + this.device = null; + this.context = null; + this.colorBuffer = null; + this.defaultRenderPassdescriptor = null; + + this.utils = new WebGPUUtils(this); + this.attributeUtils = new WebGPUAttributeUtils(this); + this.bindingUtils = new WebGPUBindingUtils(this); + this.pipelineUtils = new WebGPUPipelineUtils(this); + this.textureUtils = new WebGPUTextureUtils(this); + this.occludedResolveCache = new Map(); + } + + async init(renderer) { + await super.init(renderer); + + // + + const parameters = this.parameters; + + // create the device if it is not passed with parameters + + let device; + + if (parameters.device === undefined) { + const adapterOptions = { + powerPreference: parameters.powerPreference, + }; + + const adapter = await navigator.gpu.requestAdapter(adapterOptions); + + if (adapter === null) { + throw new Error('WebGPUBackend: Unable to create WebGPU adapter.'); + } + + // feature support + + const features = Object.values(GPUFeatureName); + + const supportedFeatures = []; + + for (const name of features) { + if (adapter.features.has(name)) { + supportedFeatures.push(name); + } + } + + const deviceDescriptor = { + requiredFeatures: supportedFeatures, + requiredLimits: parameters.requiredLimits, + }; + + device = await adapter.requestDevice(deviceDescriptor); + } else { + device = parameters.device; + } + + const context = + parameters.context !== undefined ? parameters.context : renderer.domElement.getContext('webgpu'); + + this.device = device; + this.context = context; + + const alphaMode = parameters.alpha ? 'premultiplied' : 'opaque'; + + this.trackTimestamp = this.trackTimestamp && this.hasFeature(GPUFeatureName.TimestampQuery); + + this.context.configure({ + device: this.device, + format: this.utils.getPreferredCanvasFormat(), + usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.COPY_SRC, + alphaMode: alphaMode, + }); + + this.updateSize(); + } + + get coordinateSystem() { + return WebGPUCoordinateSystem; + } + + async getArrayBufferAsync(attribute) { + return await this.attributeUtils.getArrayBufferAsync(attribute); + } + + getContext() { + return this.context; + } + + _getDefaultRenderPassDescriptor() { + let descriptor = this.defaultRenderPassdescriptor; + + if (descriptor === null) { + const renderer = this.renderer; + + descriptor = { + colorAttachments: [ + { + view: null, + }, + ], + }; + + if (this.renderer.depth === true || this.renderer.stencil === true) { + descriptor.depthStencilAttachment = { + view: this.textureUtils.getDepthBuffer(renderer.depth, renderer.stencil).createView(), + }; + } + + const colorAttachment = descriptor.colorAttachments[0]; + + if (this.renderer.samples > 0) { + colorAttachment.view = this.colorBuffer.createView(); + } else { + colorAttachment.resolveTarget = undefined; + } + + this.defaultRenderPassdescriptor = descriptor; + } + + const colorAttachment = descriptor.colorAttachments[0]; + + if (this.renderer.samples > 0) { + colorAttachment.resolveTarget = this.context.getCurrentTexture().createView(); + } else { + colorAttachment.view = this.context.getCurrentTexture().createView(); + } + + return descriptor; + } + + _getRenderPassDescriptor(renderContext) { + const renderTarget = renderContext.renderTarget; + const renderTargetData = this.get(renderTarget); + + let descriptors = renderTargetData.descriptors; + + if ( + descriptors === undefined || + renderTargetData.width !== renderTarget.width || + renderTargetData.height !== renderTarget.height || + renderTargetData.activeMipmapLevel !== renderTarget.activeMipmapLevel || + renderTargetData.samples !== renderTarget.samples + ) { + descriptors = {}; + + renderTargetData.descriptors = descriptors; + + // dispose + + const onDispose = () => { + renderTarget.removeEventListener('dispose', onDispose); + + this.delete(renderTarget); + }; + + renderTarget.addEventListener('dispose', onDispose); + } + + const cacheKey = renderContext.getCacheKey(); + + let descriptor = descriptors[cacheKey]; + + if (descriptor === undefined) { + const textures = renderContext.textures; + const colorAttachments = []; + + for (let i = 0; i < textures.length; i++) { + const textureData = this.get(textures[i]); + + const textureView = textureData.texture.createView({ + baseMipLevel: renderContext.activeMipmapLevel, + mipLevelCount: 1, + baseArrayLayer: renderContext.activeCubeFace, + dimension: GPUTextureViewDimension.TwoD, + }); + + let view, resolveTarget; + + if (textureData.msaaTexture !== undefined) { + view = textureData.msaaTexture.createView(); + resolveTarget = textureView; + } else { + view = textureView; + resolveTarget = undefined; + } + + colorAttachments.push({ + view, + resolveTarget, + loadOp: GPULoadOp.Load, + storeOp: GPUStoreOp.Store, + }); + } + + descriptor = { + colorAttachments, + }; + + if (renderContext.depth) { + const depthTextureData = this.get(renderContext.depthTexture); + + const depthStencilAttachment = { + view: depthTextureData.texture.createView(), + }; + descriptor.depthStencilAttachment = depthStencilAttachment; + } + + descriptors[cacheKey] = descriptor; + + renderTargetData.width = renderTarget.width; + renderTargetData.height = renderTarget.height; + renderTargetData.samples = renderTarget.samples; + renderTargetData.activeMipmapLevel = renderTarget.activeMipmapLevel; + } + + return descriptor; + } + + beginRender(renderContext) { + const renderContextData = this.get(renderContext); + + const device = this.device; + const occlusionQueryCount = renderContext.occlusionQueryCount; + + let occlusionQuerySet; + + if (occlusionQueryCount > 0) { + if (renderContextData.currentOcclusionQuerySet) renderContextData.currentOcclusionQuerySet.destroy(); + if (renderContextData.currentOcclusionQueryBuffer) renderContextData.currentOcclusionQueryBuffer.destroy(); + + // Get a reference to the array of objects with queries. The renderContextData property + // can be changed by another render pass before the buffer.mapAsyc() completes. + renderContextData.currentOcclusionQuerySet = renderContextData.occlusionQuerySet; + renderContextData.currentOcclusionQueryBuffer = renderContextData.occlusionQueryBuffer; + renderContextData.currentOcclusionQueryObjects = renderContextData.occlusionQueryObjects; + + // + + occlusionQuerySet = device.createQuerySet({ type: 'occlusion', count: occlusionQueryCount }); + + renderContextData.occlusionQuerySet = occlusionQuerySet; + renderContextData.occlusionQueryIndex = 0; + renderContextData.occlusionQueryObjects = new Array(occlusionQueryCount); + + renderContextData.lastOcclusionObject = null; + } + + let descriptor; + + if (renderContext.textures === null) { + descriptor = this._getDefaultRenderPassDescriptor(); + } else { + descriptor = this._getRenderPassDescriptor(renderContext); + } + + this.initTimestampQuery(renderContext, descriptor); + + descriptor.occlusionQuerySet = occlusionQuerySet; + + const depthStencilAttachment = descriptor.depthStencilAttachment; + + if (renderContext.textures !== null) { + const colorAttachments = descriptor.colorAttachments; + + for (let i = 0; i < colorAttachments.length; i++) { + const colorAttachment = colorAttachments[i]; + + if (renderContext.clearColor) { + colorAttachment.clearValue = i === 0 ? renderContext.clearColorValue : { r: 0, g: 0, b: 0, a: 1 }; + colorAttachment.loadOp = GPULoadOp.Clear; + colorAttachment.storeOp = GPUStoreOp.Store; + } else { + colorAttachment.loadOp = GPULoadOp.Load; + colorAttachment.storeOp = GPUStoreOp.Store; + } + } + } else { + const colorAttachment = descriptor.colorAttachments[0]; + + if (renderContext.clearColor) { + colorAttachment.clearValue = renderContext.clearColorValue; + colorAttachment.loadOp = GPULoadOp.Clear; + colorAttachment.storeOp = GPUStoreOp.Store; + } else { + colorAttachment.loadOp = GPULoadOp.Load; + colorAttachment.storeOp = GPUStoreOp.Store; + } + } + + // + + if (renderContext.depth) { + if (renderContext.clearDepth) { + depthStencilAttachment.depthClearValue = renderContext.clearDepthValue; + depthStencilAttachment.depthLoadOp = GPULoadOp.Clear; + depthStencilAttachment.depthStoreOp = GPUStoreOp.Store; + } else { + depthStencilAttachment.depthLoadOp = GPULoadOp.Load; + depthStencilAttachment.depthStoreOp = GPUStoreOp.Store; + } + } + + if (renderContext.stencil) { + if (renderContext.clearStencil) { + depthStencilAttachment.stencilClearValue = renderContext.clearStencilValue; + depthStencilAttachment.stencilLoadOp = GPULoadOp.Clear; + depthStencilAttachment.stencilStoreOp = GPUStoreOp.Store; + } else { + depthStencilAttachment.stencilLoadOp = GPULoadOp.Load; + depthStencilAttachment.stencilStoreOp = GPUStoreOp.Store; + } + } + + // + + const encoder = device.createCommandEncoder({ label: 'renderContext_' + renderContext.id }); + const currentPass = encoder.beginRenderPass(descriptor); + + // + + renderContextData.descriptor = descriptor; + renderContextData.encoder = encoder; + renderContextData.currentPass = currentPass; + renderContextData.currentSets = { attributes: {}, bindingGroups: [], pipeline: null, index: null }; + renderContextData.renderBundles = []; + + // + + if (renderContext.viewport) { + this.updateViewport(renderContext); + } + + if (renderContext.scissor) { + const { x, y, width, height } = renderContext.scissorValue; + + currentPass.setScissorRect(x, y, width, height); + } + } + + finishRender(renderContext) { + const renderContextData = this.get(renderContext); + const occlusionQueryCount = renderContext.occlusionQueryCount; + + if (renderContextData.renderBundles.length > 0) { + renderContextData.currentPass.executeBundles(renderContextData.renderBundles); + } + + if (occlusionQueryCount > renderContextData.occlusionQueryIndex) { + renderContextData.currentPass.endOcclusionQuery(); + } + + renderContextData.currentPass.end(); + + if (occlusionQueryCount > 0) { + const bufferSize = occlusionQueryCount * 8; // 8 byte entries for query results + + // + + let queryResolveBuffer = this.occludedResolveCache.get(bufferSize); + + if (queryResolveBuffer === undefined) { + queryResolveBuffer = this.device.createBuffer({ + size: bufferSize, + usage: GPUBufferUsage.QUERY_RESOLVE | GPUBufferUsage.COPY_SRC, + }); + + this.occludedResolveCache.set(bufferSize, queryResolveBuffer); + } + + // + + const readBuffer = this.device.createBuffer({ + size: bufferSize, + usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ, + }); + + // two buffers required here - WebGPU doesn't allow usage of QUERY_RESOLVE & MAP_READ to be combined + renderContextData.encoder.resolveQuerySet( + renderContextData.occlusionQuerySet, + 0, + occlusionQueryCount, + queryResolveBuffer, + 0, + ); + renderContextData.encoder.copyBufferToBuffer(queryResolveBuffer, 0, readBuffer, 0, bufferSize); + + renderContextData.occlusionQueryBuffer = readBuffer; + + // + + this.resolveOccludedAsync(renderContext); + } + + this.prepareTimestampBuffer(renderContext, renderContextData.encoder); + + this.device.queue.submit([renderContextData.encoder.finish()]); + + // + + if (renderContext.textures !== null) { + const textures = renderContext.textures; + + for (let i = 0; i < textures.length; i++) { + const texture = textures[i]; + + if (texture.generateMipmaps === true) { + this.textureUtils.generateMipmaps(texture); + } + } + } + } + + isOccluded(renderContext, object) { + const renderContextData = this.get(renderContext); + + return renderContextData.occluded && renderContextData.occluded.has(object); + } + + async resolveOccludedAsync(renderContext) { + const renderContextData = this.get(renderContext); + + // handle occlusion query results + + const { currentOcclusionQueryBuffer, currentOcclusionQueryObjects } = renderContextData; + + if (currentOcclusionQueryBuffer && currentOcclusionQueryObjects) { + const occluded = new WeakSet(); + + renderContextData.currentOcclusionQueryObjects = null; + renderContextData.currentOcclusionQueryBuffer = null; + + await currentOcclusionQueryBuffer.mapAsync(GPUMapMode.READ); + + const buffer = currentOcclusionQueryBuffer.getMappedRange(); + const results = new BigUint64Array(buffer); + + for (let i = 0; i < currentOcclusionQueryObjects.length; i++) { + if (results[i] !== BigInt(0)) { + occluded.add(currentOcclusionQueryObjects[i]); + } + } + + currentOcclusionQueryBuffer.destroy(); + + renderContextData.occluded = occluded; + } + } + + updateViewport(renderContext) { + const { currentPass } = this.get(renderContext); + const { x, y, width, height, minDepth, maxDepth } = renderContext.viewportValue; + + currentPass.setViewport(x, y, width, height, minDepth, maxDepth); + } + + clear(color, depth, stencil, renderTargetData = null) { + const device = this.device; + const renderer = this.renderer; + + let colorAttachments = []; + + let depthStencilAttachment; + let clearValue; + + let supportsDepth; + let supportsStencil; + + if (color) { + const clearColor = this.getClearColor(); + + if (this.renderer.alpha === true) { + // premultiply alpha + + const a = clearColor.a; + + clearValue = { r: clearColor.r * a, g: clearColor.g * a, b: clearColor.b * a, a: a }; + } else { + clearValue = { r: clearColor.r, g: clearColor.g, b: clearColor.b, a: clearColor.a }; + } + } + + if (renderTargetData === null) { + supportsDepth = renderer.depth; + supportsStencil = renderer.stencil; + + const descriptor = this._getDefaultRenderPassDescriptor(); + + if (color) { + colorAttachments = descriptor.colorAttachments; + + const colorAttachment = colorAttachments[0]; + + colorAttachment.clearValue = clearValue; + colorAttachment.loadOp = GPULoadOp.Clear; + colorAttachment.storeOp = GPUStoreOp.Store; + } + + if (supportsDepth || supportsStencil) { + depthStencilAttachment = descriptor.depthStencilAttachment; + } + } else { + supportsDepth = renderTargetData.depth; + supportsStencil = renderTargetData.stencil; + + if (color) { + for (const texture of renderTargetData.textures) { + const textureData = this.get(texture); + const textureView = textureData.texture.createView(); + + let view, resolveTarget; + + if (textureData.msaaTexture !== undefined) { + view = textureData.msaaTexture.createView(); + resolveTarget = textureView; + } else { + view = textureView; + resolveTarget = undefined; + } + + colorAttachments.push({ + view, + resolveTarget, + clearValue, + loadOp: GPULoadOp.Clear, + storeOp: GPUStoreOp.Store, + }); + } + } + + if (supportsDepth || supportsStencil) { + const depthTextureData = this.get(renderTargetData.depthTexture); + + depthStencilAttachment = { + view: depthTextureData.texture.createView(), + }; + } + } + + // + + if (supportsDepth) { + if (depth) { + depthStencilAttachment.depthLoadOp = GPULoadOp.Clear; + depthStencilAttachment.depthClearValue = renderer.getClearDepth(); + depthStencilAttachment.depthStoreOp = GPUStoreOp.Store; + } else { + depthStencilAttachment.depthLoadOp = GPULoadOp.Load; + depthStencilAttachment.depthStoreOp = GPUStoreOp.Store; + } + } + + // + + if (supportsStencil) { + if (stencil) { + depthStencilAttachment.stencilLoadOp = GPULoadOp.Clear; + depthStencilAttachment.stencilClearValue = renderer.getClearStencil(); + depthStencilAttachment.stencilStoreOp = GPUStoreOp.Store; + } else { + depthStencilAttachment.stencilLoadOp = GPULoadOp.Load; + depthStencilAttachment.stencilStoreOp = GPUStoreOp.Store; + } + } + + // + + const encoder = device.createCommandEncoder({}); + const currentPass = encoder.beginRenderPass({ + colorAttachments, + depthStencilAttachment, + }); + + currentPass.end(); + + device.queue.submit([encoder.finish()]); + } + + // compute + + beginCompute(computeGroup) { + const groupGPU = this.get(computeGroup); + + const descriptor = {}; + + this.initTimestampQuery(computeGroup, descriptor); + + groupGPU.cmdEncoderGPU = this.device.createCommandEncoder(); + + groupGPU.passEncoderGPU = groupGPU.cmdEncoderGPU.beginComputePass(descriptor); + } + + compute(computeGroup, computeNode, bindings, pipeline) { + const { passEncoderGPU } = this.get(computeGroup); + + // pipeline + + const pipelineGPU = this.get(pipeline).pipeline; + passEncoderGPU.setPipeline(pipelineGPU); + + // bind groups + + for (let i = 0, l = bindings.length; i < l; i++) { + const bindGroup = bindings[i]; + const bindingsData = this.get(bindGroup); + + passEncoderGPU.setBindGroup(i, bindingsData.group); + } + + const maxComputeWorkgroupsPerDimension = this.device.limits.maxComputeWorkgroupsPerDimension; + + const computeNodeData = this.get(computeNode); + + if (computeNodeData.dispatchSize === undefined) computeNodeData.dispatchSize = { x: 0, y: 1, z: 1 }; + + const { dispatchSize } = computeNodeData; + + if (computeNode.dispatchCount > maxComputeWorkgroupsPerDimension) { + dispatchSize.x = Math.min(computeNode.dispatchCount, maxComputeWorkgroupsPerDimension); + dispatchSize.y = Math.ceil(computeNode.dispatchCount / maxComputeWorkgroupsPerDimension); + } else { + dispatchSize.x = computeNode.dispatchCount; + } + + passEncoderGPU.dispatchWorkgroups(dispatchSize.x, dispatchSize.y, dispatchSize.z); + } + + finishCompute(computeGroup) { + const groupData = this.get(computeGroup); + + groupData.passEncoderGPU.end(); + + this.prepareTimestampBuffer(computeGroup, groupData.cmdEncoderGPU); + + this.device.queue.submit([groupData.cmdEncoderGPU.finish()]); + } + + async waitForGPU() { + await this.device.queue.onSubmittedWorkDone(); + } + + // render object + + draw(renderObject, info) { + const { object, context, pipeline } = renderObject; + const bindings = renderObject.getBindings(); + const renderContextData = this.get(context); + const pipelineGPU = this.get(pipeline).pipeline; + const currentSets = renderContextData.currentSets; + const passEncoderGPU = renderContextData.currentPass; + + const drawParams = renderObject.getDrawParameters(); + + if (drawParams === null) return; + + // pipeline + + if (currentSets.pipeline !== pipelineGPU) { + passEncoderGPU.setPipeline(pipelineGPU); + + currentSets.pipeline = pipelineGPU; + } + + // bind groups + + const currentBindingGroups = currentSets.bindingGroups; + + for (let i = 0, l = bindings.length; i < l; i++) { + const bindGroup = bindings[i]; + const bindingsData = this.get(bindGroup); + + if (currentBindingGroups[bindGroup.index] !== bindGroup.id) { + passEncoderGPU.setBindGroup(bindGroup.index, bindingsData.group); + currentBindingGroups[bindGroup.index] = bindGroup.id; + } + } + + // attributes + + const index = renderObject.getIndex(); + + const hasIndex = index !== null; + + // index + + if (hasIndex === true) { + if (currentSets.index !== index) { + const buffer = this.get(index).buffer; + const indexFormat = index.array instanceof Uint16Array ? GPUIndexFormat.Uint16 : GPUIndexFormat.Uint32; + + passEncoderGPU.setIndexBuffer(buffer, indexFormat); + + currentSets.index = index; + } + } + + // vertex buffers + + const vertexBuffers = renderObject.getVertexBuffers(); + + for (let i = 0, l = vertexBuffers.length; i < l; i++) { + const vertexBuffer = vertexBuffers[i]; + + if (currentSets.attributes[i] !== vertexBuffer) { + const buffer = this.get(vertexBuffer).buffer; + passEncoderGPU.setVertexBuffer(i, buffer); + + currentSets.attributes[i] = vertexBuffer; + } + } + + // occlusion queries - handle multiple consecutive draw calls for an object + + if (renderContextData.occlusionQuerySet !== undefined) { + const lastObject = renderContextData.lastOcclusionObject; + + if (lastObject !== object) { + if (lastObject !== null && lastObject.occlusionTest === true) { + passEncoderGPU.endOcclusionQuery(); + renderContextData.occlusionQueryIndex++; + } + + if (object.occlusionTest === true) { + passEncoderGPU.beginOcclusionQuery(renderContextData.occlusionQueryIndex); + renderContextData.occlusionQueryObjects[renderContextData.occlusionQueryIndex] = object; + } + + renderContextData.lastOcclusionObject = object; + } + } + + // draw + + if (object.isBatchedMesh === true) { + const starts = object._multiDrawStarts; + const counts = object._multiDrawCounts; + const drawCount = object._multiDrawCount; + const drawInstances = object._multiDrawInstances; + + const bytesPerElement = hasIndex ? index.array.BYTES_PER_ELEMENT : 1; + + for (let i = 0; i < drawCount; i++) { + const count = drawInstances ? drawInstances[i] : 1; + const firstInstance = count > 1 ? 0 : i; + + passEncoderGPU.drawIndexed(counts[i], count, starts[i] / bytesPerElement, 0, firstInstance); + } + } else if (hasIndex === true) { + const { vertexCount: indexCount, instanceCount, firstVertex: firstIndex } = drawParams; + + const indirect = renderObject.getIndirect(); + + if (indirect !== null) { + const buffer = this.get(indirect).buffer; + + passEncoderGPU.drawIndexedIndirect(buffer, 0); + } else { + passEncoderGPU.drawIndexed(indexCount, instanceCount, firstIndex, 0, 0); + } + + info.update(object, indexCount, instanceCount); + } else { + const { vertexCount, instanceCount, firstVertex } = drawParams; + + const indirect = renderObject.getIndirect(); + + if (indirect !== null) { + const buffer = this.get(indirect).buffer; + + passEncoderGPU.drawIndirect(buffer, 0); + } else { + passEncoderGPU.draw(vertexCount, instanceCount, firstVertex, 0); + } + + info.update(object, vertexCount, instanceCount); + } + } + + // cache key + + needsRenderUpdate(renderObject) { + const data = this.get(renderObject); + + const { object, material } = renderObject; + + const utils = this.utils; + + const sampleCount = utils.getSampleCountRenderContext(renderObject.context); + const colorSpace = utils.getCurrentColorSpace(renderObject.context); + const colorFormat = utils.getCurrentColorFormat(renderObject.context); + const depthStencilFormat = utils.getCurrentDepthStencilFormat(renderObject.context); + const primitiveTopology = utils.getPrimitiveTopology(object, material); + + let needsUpdate = false; + + if ( + data.material !== material || + data.materialVersion !== material.version || + data.transparent !== material.transparent || + data.blending !== material.blending || + data.premultipliedAlpha !== material.premultipliedAlpha || + data.blendSrc !== material.blendSrc || + data.blendDst !== material.blendDst || + data.blendEquation !== material.blendEquation || + data.blendSrcAlpha !== material.blendSrcAlpha || + data.blendDstAlpha !== material.blendDstAlpha || + data.blendEquationAlpha !== material.blendEquationAlpha || + data.colorWrite !== material.colorWrite || + data.depthWrite !== material.depthWrite || + data.depthTest !== material.depthTest || + data.depthFunc !== material.depthFunc || + data.stencilWrite !== material.stencilWrite || + data.stencilFunc !== material.stencilFunc || + data.stencilFail !== material.stencilFail || + data.stencilZFail !== material.stencilZFail || + data.stencilZPass !== material.stencilZPass || + data.stencilFuncMask !== material.stencilFuncMask || + data.stencilWriteMask !== material.stencilWriteMask || + data.side !== material.side || + data.alphaToCoverage !== material.alphaToCoverage || + data.sampleCount !== sampleCount || + data.colorSpace !== colorSpace || + data.colorFormat !== colorFormat || + data.depthStencilFormat !== depthStencilFormat || + data.primitiveTopology !== primitiveTopology || + data.clippingContextCacheKey !== renderObject.clippingContext.cacheKey + ) { + data.material = material; + data.materialVersion = material.version; + data.transparent = material.transparent; + data.blending = material.blending; + data.premultipliedAlpha = material.premultipliedAlpha; + data.blendSrc = material.blendSrc; + data.blendDst = material.blendDst; + data.blendEquation = material.blendEquation; + data.blendSrcAlpha = material.blendSrcAlpha; + data.blendDstAlpha = material.blendDstAlpha; + data.blendEquationAlpha = material.blendEquationAlpha; + data.colorWrite = material.colorWrite; + data.depthWrite = material.depthWrite; + data.depthTest = material.depthTest; + data.depthFunc = material.depthFunc; + data.stencilWrite = material.stencilWrite; + data.stencilFunc = material.stencilFunc; + data.stencilFail = material.stencilFail; + data.stencilZFail = material.stencilZFail; + data.stencilZPass = material.stencilZPass; + data.stencilFuncMask = material.stencilFuncMask; + data.stencilWriteMask = material.stencilWriteMask; + data.side = material.side; + data.alphaToCoverage = material.alphaToCoverage; + data.sampleCount = sampleCount; + data.colorSpace = colorSpace; + data.colorFormat = colorFormat; + data.depthStencilFormat = depthStencilFormat; + data.primitiveTopology = primitiveTopology; + data.clippingContextCacheKey = renderObject.clippingContext.cacheKey; + + needsUpdate = true; + } + + return needsUpdate; + } + + getRenderCacheKey(renderObject) { + const { object, material } = renderObject; + + const utils = this.utils; + const renderContext = renderObject.context; + + return [ + material.transparent, + material.blending, + material.premultipliedAlpha, + material.blendSrc, + material.blendDst, + material.blendEquation, + material.blendSrcAlpha, + material.blendDstAlpha, + material.blendEquationAlpha, + material.colorWrite, + material.depthWrite, + material.depthTest, + material.depthFunc, + material.stencilWrite, + material.stencilFunc, + material.stencilFail, + material.stencilZFail, + material.stencilZPass, + material.stencilFuncMask, + material.stencilWriteMask, + material.side, + utils.getSampleCountRenderContext(renderContext), + utils.getCurrentColorSpace(renderContext), + utils.getCurrentColorFormat(renderContext), + utils.getCurrentDepthStencilFormat(renderContext), + utils.getPrimitiveTopology(object, material), + renderObject.getGeometryCacheKey(), + renderObject.clippingContext.cacheKey, + ].join(); + } + + // textures + + createSampler(texture) { + this.textureUtils.createSampler(texture); + } + + destroySampler(texture) { + this.textureUtils.destroySampler(texture); + } + + createDefaultTexture(texture) { + this.textureUtils.createDefaultTexture(texture); + } + + createTexture(texture, options) { + this.textureUtils.createTexture(texture, options); + } + + updateTexture(texture, options) { + this.textureUtils.updateTexture(texture, options); + } + + generateMipmaps(texture) { + this.textureUtils.generateMipmaps(texture); + } + + destroyTexture(texture) { + this.textureUtils.destroyTexture(texture); + } + + copyTextureToBuffer(texture, x, y, width, height, faceIndex) { + return this.textureUtils.copyTextureToBuffer(texture, x, y, width, height, faceIndex); + } + + initTimestampQuery(renderContext, descriptor) { + if (!this.trackTimestamp) return; + + const renderContextData = this.get(renderContext); + + if (!renderContextData.timeStampQuerySet) { + // Create a GPUQuerySet which holds 2 timestamp query results: one for the + // beginning and one for the end of compute pass execution. + const timeStampQuerySet = this.device.createQuerySet({ type: 'timestamp', count: 2 }); + + const timestampWrites = { + querySet: timeStampQuerySet, + beginningOfPassWriteIndex: 0, // Write timestamp in index 0 when pass begins. + endOfPassWriteIndex: 1, // Write timestamp in index 1 when pass ends. + }; + + Object.assign(descriptor, { + timestampWrites, + }); + + renderContextData.timeStampQuerySet = timeStampQuerySet; + } + } + + // timestamp utils + + prepareTimestampBuffer(renderContext, encoder) { + if (!this.trackTimestamp) return; + + const renderContextData = this.get(renderContext); + + const size = 2 * BigInt64Array.BYTES_PER_ELEMENT; + + if (renderContextData.currentTimestampQueryBuffers === undefined) { + renderContextData.currentTimestampQueryBuffers = { + resolveBuffer: this.device.createBuffer({ + label: 'timestamp resolve buffer', + size: size, + usage: GPUBufferUsage.QUERY_RESOLVE | GPUBufferUsage.COPY_SRC, + }), + resultBuffer: this.device.createBuffer({ + label: 'timestamp result buffer', + size: size, + usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ, + }), + isMappingPending: false, + }; + } + + const { resolveBuffer, resultBuffer, isMappingPending } = renderContextData.currentTimestampQueryBuffers; + + if (isMappingPending === true) return; + + encoder.resolveQuerySet(renderContextData.timeStampQuerySet, 0, 2, resolveBuffer, 0); + encoder.copyBufferToBuffer(resolveBuffer, 0, resultBuffer, 0, size); + } + + async resolveTimestampAsync(renderContext, type = 'render') { + if (!this.trackTimestamp) return; + + const renderContextData = this.get(renderContext); + + if (renderContextData.currentTimestampQueryBuffers === undefined) return; + + const { resultBuffer, isMappingPending } = renderContextData.currentTimestampQueryBuffers; + + if (isMappingPending === true) return; + + renderContextData.currentTimestampQueryBuffers.isMappingPending = true; + + resultBuffer.mapAsync(GPUMapMode.READ).then(() => { + const times = new BigUint64Array(resultBuffer.getMappedRange()); + const duration = Number(times[1] - times[0]) / 1000000; + + this.renderer.info.updateTimestamp(type, duration); + + resultBuffer.unmap(); + + renderContextData.currentTimestampQueryBuffers.isMappingPending = false; + }); + } + + // node builder + + createNodeBuilder(object, renderer) { + return new WGSLNodeBuilder(object, renderer); + } + + // program + + createProgram(program) { + const programGPU = this.get(program); + + programGPU.module = { + module: this.device.createShaderModule({ code: program.code, label: program.stage }), + entryPoint: 'main', + }; + } + + destroyProgram(program) { + this.delete(program); + } + + // pipelines + + createRenderPipeline(renderObject, promises) { + this.pipelineUtils.createRenderPipeline(renderObject, promises); + } + + createComputePipeline(computePipeline, bindings) { + this.pipelineUtils.createComputePipeline(computePipeline, bindings); + } + + beginBundle(renderContext) { + const renderContextData = this.get(renderContext); + + renderContextData._currentPass = renderContextData.currentPass; + renderContextData._currentSets = renderContextData.currentSets; + + renderContextData.currentSets = { attributes: {}, bindingGroups: [], pipeline: null, index: null }; + renderContextData.currentPass = this.pipelineUtils.createBundleEncoder(renderContext); + } + + finishBundle(renderContext, bundle) { + const renderContextData = this.get(renderContext); + + const bundleEncoder = renderContextData.currentPass; + const bundleGPU = bundleEncoder.finish(); + + this.get(bundle).bundleGPU = bundleGPU; + + // restore render pass state + + renderContextData.currentSets = renderContextData._currentSets; + renderContextData.currentPass = renderContextData._currentPass; + } + + addBundle(renderContext, bundle) { + const renderContextData = this.get(renderContext); + + renderContextData.renderBundles.push(this.get(bundle).bundleGPU); + } + + // bindings + + createBindings(bindGroup) { + this.bindingUtils.createBindings(bindGroup); + } + + updateBindings(bindGroup) { + this.bindingUtils.createBindings(bindGroup); + } + + updateBinding(binding) { + this.bindingUtils.updateBinding(binding); + } + + // attributes + + createIndexAttribute(attribute) { + this.attributeUtils.createAttribute( + attribute, + GPUBufferUsage.INDEX | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST, + ); + } + + createAttribute(attribute) { + this.attributeUtils.createAttribute( + attribute, + GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST, + ); + } + + createStorageAttribute(attribute) { + this.attributeUtils.createAttribute( + attribute, + GPUBufferUsage.STORAGE | GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST, + ); + } + + createIndirectStorageAttribute(attribute) { + this.attributeUtils.createAttribute( + attribute, + GPUBufferUsage.STORAGE | GPUBufferUsage.INDIRECT | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST, + ); + } + + updateAttribute(attribute) { + this.attributeUtils.updateAttribute(attribute); + } + + destroyAttribute(attribute) { + this.attributeUtils.destroyAttribute(attribute); + } + + // canvas + + updateSize() { + this.colorBuffer = this.textureUtils.getColorBuffer(); + this.defaultRenderPassdescriptor = null; + } + + // utils public + + getMaxAnisotropy() { + return 16; + } + + hasFeature(name) { + return this.device.features.has(name); + } + + copyTextureToTexture(srcTexture, dstTexture, srcRegion = null, dstPosition = null, level = 0) { + let dstX = 0; + let dstY = 0; + let dstLayer = 0; + + let srcX = 0; + let srcY = 0; + let srcLayer = 0; + + let srcWidth = srcTexture.image.width; + let srcHeight = srcTexture.image.height; + + if (srcRegion !== null) { + srcX = srcRegion.x; + srcY = srcRegion.y; + srcLayer = srcRegion.z || 0; + srcWidth = srcRegion.width; + srcHeight = srcRegion.height; + } + + if (dstPosition !== null) { + dstX = dstPosition.x; + dstY = dstPosition.y; + dstLayer = dstPosition.z || 0; + } + + const encoder = this.device.createCommandEncoder({ + label: 'copyTextureToTexture_' + srcTexture.id + '_' + dstTexture.id, + }); + + const sourceGPU = this.get(srcTexture).texture; + const destinationGPU = this.get(dstTexture).texture; + + encoder.copyTextureToTexture( + { + texture: sourceGPU, + mipLevel: level, + origin: { x: srcX, y: srcY, z: srcLayer }, + }, + { + texture: destinationGPU, + mipLevel: level, + origin: { x: dstX, y: dstY, z: dstLayer }, + }, + [srcWidth, srcHeight, 1], + ); + + this.device.queue.submit([encoder.finish()]); + } + + copyFramebufferToTexture(texture, renderContext, rectangle) { + const renderContextData = this.get(renderContext); + + const { encoder, descriptor } = renderContextData; + + let sourceGPU = null; + + if (renderContext.renderTarget) { + if (texture.isDepthTexture) { + sourceGPU = this.get(renderContext.depthTexture).texture; + } else { + sourceGPU = this.get(renderContext.textures[0]).texture; + } + } else { + if (texture.isDepthTexture) { + sourceGPU = this.textureUtils.getDepthBuffer(renderContext.depth, renderContext.stencil); + } else { + sourceGPU = this.context.getCurrentTexture(); + } + } + + const destinationGPU = this.get(texture).texture; + + if (sourceGPU.format !== destinationGPU.format) { + console.error( + 'WebGPUBackend: copyFramebufferToTexture: Source and destination formats do not match.', + sourceGPU.format, + destinationGPU.format, + ); + + return; + } + + renderContextData.currentPass.end(); + + encoder.copyTextureToTexture( + { + texture: sourceGPU, + origin: { x: rectangle.x, y: rectangle.y, z: 0 }, + }, + { + texture: destinationGPU, + }, + [rectangle.z, rectangle.w], + ); + + if (texture.generateMipmaps) this.textureUtils.generateMipmaps(texture); + + for (let i = 0; i < descriptor.colorAttachments.length; i++) { + descriptor.colorAttachments[i].loadOp = GPULoadOp.Load; + } + + if (renderContext.depth) descriptor.depthStencilAttachment.depthLoadOp = GPULoadOp.Load; + if (renderContext.stencil) descriptor.depthStencilAttachment.stencilLoadOp = GPULoadOp.Load; + + renderContextData.currentPass = encoder.beginRenderPass(descriptor); + renderContextData.currentSets = { attributes: {}, bindingGroups: [], pipeline: null, index: null }; + } +} + +export default WebGPUBackend; diff --git a/src-testing/src/renderers/webgpu/WebGPURenderer.Nodes.d.ts b/src-testing/src/renderers/webgpu/WebGPURenderer.Nodes.d.ts new file mode 100644 index 000000000..b9eb0ddeb --- /dev/null +++ b/src-testing/src/renderers/webgpu/WebGPURenderer.Nodes.d.ts @@ -0,0 +1,12 @@ +import Renderer, { RendererParameters } from "../common/Renderer.js"; +import { WebGPUBackendParameters } from "./WebGPUBackend.js"; + +export interface WebGPURendererParameters extends RendererParameters, WebGPUBackendParameters { + forceWebGL?: boolean | undefined; +} + +export default class WebGPURenderer extends Renderer { + readonly isWebGPURenderer: true; + + constructor(parameters?: WebGPURendererParameters); +} diff --git a/src-testing/src/renderers/webgpu/WebGPURenderer.ts b/src-testing/src/renderers/webgpu/WebGPURenderer.ts new file mode 100644 index 000000000..1b4e424f4 --- /dev/null +++ b/src-testing/src/renderers/webgpu/WebGPURenderer.ts @@ -0,0 +1,46 @@ +import Renderer from '../common/Renderer.js'; +import WebGLBackend from '../webgl-fallback/WebGLBackend.js'; +import WebGPUBackend from './WebGPUBackend.js'; +import StandardNodeLibrary from './nodes/StandardNodeLibrary.js'; +/* +const debugHandler = { + + get: function ( target, name ) { + + // Add |update + if ( /^(create|destroy)/.test( name ) ) console.log( 'WebGPUBackend.' + name ); + + return target[ name ]; + + } + +}; +*/ +class WebGPURenderer extends Renderer { + constructor(parameters = {}) { + let BackendClass; + + if (parameters.forceWebGL) { + BackendClass = WebGLBackend; + } else { + BackendClass = WebGPUBackend; + + parameters.getFallback = () => { + console.warn('THREE.WebGPURenderer: WebGPU is not available, running under WebGL2 backend.'); + + return new WebGLBackend(parameters); + }; + } + + const backend = new BackendClass(parameters); + + //super( new Proxy( backend, debugHandler ) ); + super(backend, parameters); + + this.library = new StandardNodeLibrary(); + + this.isWebGPURenderer = true; + } +} + +export default WebGPURenderer; diff --git a/src-testing/src/renderers/webgpu/nodes/BasicNodeLibrary.ts b/src-testing/src/renderers/webgpu/nodes/BasicNodeLibrary.ts new file mode 100644 index 000000000..665bffa32 --- /dev/null +++ b/src-testing/src/renderers/webgpu/nodes/BasicNodeLibrary.ts @@ -0,0 +1,61 @@ +import NodeLibrary from '../../common/nodes/NodeLibrary.js'; + +// Lights +import { PointLight } from '../../../lights/PointLight.js'; +import { PointLightNode } from '../../../nodes/Nodes.js'; +import { DirectionalLight } from '../../../lights/DirectionalLight.js'; +import { DirectionalLightNode } from '../../../nodes/Nodes.js'; +import { RectAreaLight } from '../../../lights/RectAreaLight.js'; +import { RectAreaLightNode } from '../../../nodes/Nodes.js'; +import { SpotLight } from '../../../lights/SpotLight.js'; +import { SpotLightNode } from '../../../nodes/Nodes.js'; +import { AmbientLight } from '../../../lights/AmbientLight.js'; +import { AmbientLightNode } from '../../../nodes/Nodes.js'; +import { HemisphereLight } from '../../../lights/HemisphereLight.js'; +import { HemisphereLightNode } from '../../../nodes/Nodes.js'; +import { LightProbe } from '../../../lights/LightProbe.js'; +import { LightProbeNode } from '../../../nodes/Nodes.js'; +import IESSpotLight from '../../../lights/webgpu/IESSpotLight.js'; +import { IESSpotLightNode } from '../../../nodes/Nodes.js'; + +// Tone Mapping +import { + LinearToneMapping, + ReinhardToneMapping, + CineonToneMapping, + ACESFilmicToneMapping, + AgXToneMapping, + NeutralToneMapping, +} from '../../../constants.js'; +import { + linearToneMapping, + reinhardToneMapping, + cineonToneMapping, + acesFilmicToneMapping, + agxToneMapping, + neutralToneMapping, +} from '../../../nodes/display/ToneMappingFunctions.js'; + +class BasicNodeLibrary extends NodeLibrary { + constructor() { + super(); + + this.addLight(PointLightNode, PointLight); + this.addLight(DirectionalLightNode, DirectionalLight); + this.addLight(RectAreaLightNode, RectAreaLight); + this.addLight(SpotLightNode, SpotLight); + this.addLight(AmbientLightNode, AmbientLight); + this.addLight(HemisphereLightNode, HemisphereLight); + this.addLight(LightProbeNode, LightProbe); + this.addLight(IESSpotLightNode, IESSpotLight); + + this.addToneMapping(linearToneMapping, LinearToneMapping); + this.addToneMapping(reinhardToneMapping, ReinhardToneMapping); + this.addToneMapping(cineonToneMapping, CineonToneMapping); + this.addToneMapping(acesFilmicToneMapping, ACESFilmicToneMapping); + this.addToneMapping(agxToneMapping, AgXToneMapping); + this.addToneMapping(neutralToneMapping, NeutralToneMapping); + } +} + +export default BasicNodeLibrary; diff --git a/src-testing/src/renderers/webgpu/nodes/StandardNodeLibrary.ts b/src-testing/src/renderers/webgpu/nodes/StandardNodeLibrary.ts new file mode 100644 index 000000000..bca482b4d --- /dev/null +++ b/src-testing/src/renderers/webgpu/nodes/StandardNodeLibrary.ts @@ -0,0 +1,107 @@ +import NodeLibrary from '../../common/nodes/NodeLibrary.js'; + +// Materials +import { MeshPhongMaterial } from '../../../materials/MeshPhongMaterial.js'; +import MeshPhongNodeMaterial from '../../../materials/nodes/MeshPhongNodeMaterial.js'; +import { MeshStandardMaterial } from '../../../materials/MeshStandardMaterial.js'; +import MeshStandardNodeMaterial from '../../../materials/nodes/MeshStandardNodeMaterial.js'; +import { MeshPhysicalMaterial } from '../../../materials/MeshPhysicalMaterial.js'; +import MeshPhysicalNodeMaterial from '../../../materials/nodes/MeshPhysicalNodeMaterial.js'; +import { MeshToonMaterial } from '../../../materials/MeshToonMaterial.js'; +import MeshToonNodeMaterial from '../../../materials/nodes/MeshToonNodeMaterial.js'; +import { MeshBasicMaterial } from '../../../materials/MeshBasicMaterial.js'; +import MeshBasicNodeMaterial from '../../../materials/nodes/MeshBasicNodeMaterial.js'; +import { MeshLambertMaterial } from '../../../materials/MeshLambertMaterial.js'; +import MeshLambertNodeMaterial from '../../../materials/nodes/MeshLambertNodeMaterial.js'; +import { MeshNormalMaterial } from '../../../materials/MeshNormalMaterial.js'; +import MeshNormalNodeMaterial from '../../../materials/nodes/MeshNormalNodeMaterial.js'; +import { MeshMatcapMaterial } from '../../../materials/MeshMatcapMaterial.js'; +import MeshMatcapNodeMaterial from '../../../materials/nodes/MeshMatcapNodeMaterial.js'; +import { LineBasicMaterial } from '../../../materials/LineBasicMaterial.js'; +import LineBasicNodeMaterial from '../../../materials/nodes/LineBasicNodeMaterial.js'; +import { LineDashedMaterial } from '../../../materials/LineDashedMaterial.js'; +import LineDashedNodeMaterial from '../../../materials/nodes/LineDashedNodeMaterial.js'; +import { PointsMaterial } from '../../../materials/PointsMaterial.js'; +import PointsNodeMaterial from '../../../materials/nodes/PointsNodeMaterial.js'; +import { SpriteMaterial } from '../../../materials/SpriteMaterial.js'; +import SpriteNodeMaterial from '../../../materials/nodes/SpriteNodeMaterial.js'; +import { ShadowMaterial } from '../../../materials/ShadowMaterial.js'; +import ShadowNodeMaterial from '../../../materials/nodes/ShadowNodeMaterial.js'; +//import { MeshDepthMaterial } from '../../../materials/MeshDepthMaterial.js'; +//import MeshDepthNodeMaterial from '../../../materials/nodes/MeshDepthNodeMaterial.js'; +//import { MeshDistanceMaterial } from '../../../materials/MeshDistanceMaterial.js'; +//import MeshDistanceNodeMaterial from '../../../materials/nodes/MeshDistanceNodeMaterial.js'; + +// Lights +import { PointLight } from '../../../lights/PointLight.js'; +import { PointLightNode } from '../../../nodes/Nodes.js'; +import { DirectionalLight } from '../../../lights/DirectionalLight.js'; +import { DirectionalLightNode } from '../../../nodes/Nodes.js'; +import { RectAreaLight } from '../../../lights/RectAreaLight.js'; +import { RectAreaLightNode } from '../../../nodes/Nodes.js'; +import { SpotLight } from '../../../lights/SpotLight.js'; +import { SpotLightNode } from '../../../nodes/Nodes.js'; +import { AmbientLight } from '../../../lights/AmbientLight.js'; +import { AmbientLightNode } from '../../../nodes/Nodes.js'; +import { HemisphereLight } from '../../../lights/HemisphereLight.js'; +import { HemisphereLightNode } from '../../../nodes/Nodes.js'; +import { LightProbe } from '../../../lights/LightProbe.js'; +import { LightProbeNode } from '../../../nodes/Nodes.js'; +import IESSpotLight from '../../../lights/webgpu/IESSpotLight.js'; +import { IESSpotLightNode } from '../../../nodes/Nodes.js'; + +// Tone Mapping +import { + LinearToneMapping, + ReinhardToneMapping, + CineonToneMapping, + ACESFilmicToneMapping, + AgXToneMapping, + NeutralToneMapping, +} from '../../../constants.js'; +import { + linearToneMapping, + reinhardToneMapping, + cineonToneMapping, + acesFilmicToneMapping, + agxToneMapping, + neutralToneMapping, +} from '../../../nodes/display/ToneMappingFunctions.js'; + +class StandardNodeLibrary extends NodeLibrary { + constructor() { + super(); + + this.addMaterial(MeshPhongNodeMaterial, MeshPhongMaterial); + this.addMaterial(MeshStandardNodeMaterial, MeshStandardMaterial); + this.addMaterial(MeshPhysicalNodeMaterial, MeshPhysicalMaterial); + this.addMaterial(MeshToonNodeMaterial, MeshToonMaterial); + this.addMaterial(MeshBasicNodeMaterial, MeshBasicMaterial); + this.addMaterial(MeshLambertNodeMaterial, MeshLambertMaterial); + this.addMaterial(MeshNormalNodeMaterial, MeshNormalMaterial); + this.addMaterial(MeshMatcapNodeMaterial, MeshMatcapMaterial); + this.addMaterial(LineBasicNodeMaterial, LineBasicMaterial); + this.addMaterial(LineDashedNodeMaterial, LineDashedMaterial); + this.addMaterial(PointsNodeMaterial, PointsMaterial); + this.addMaterial(SpriteNodeMaterial, SpriteMaterial); + this.addMaterial(ShadowNodeMaterial, ShadowMaterial); + + this.addLight(PointLightNode, PointLight); + this.addLight(DirectionalLightNode, DirectionalLight); + this.addLight(RectAreaLightNode, RectAreaLight); + this.addLight(SpotLightNode, SpotLight); + this.addLight(AmbientLightNode, AmbientLight); + this.addLight(HemisphereLightNode, HemisphereLight); + this.addLight(LightProbeNode, LightProbe); + this.addLight(IESSpotLightNode, IESSpotLight); + + this.addToneMapping(linearToneMapping, LinearToneMapping); + this.addToneMapping(reinhardToneMapping, ReinhardToneMapping); + this.addToneMapping(cineonToneMapping, CineonToneMapping); + this.addToneMapping(acesFilmicToneMapping, ACESFilmicToneMapping); + this.addToneMapping(agxToneMapping, AgXToneMapping); + this.addToneMapping(neutralToneMapping, NeutralToneMapping); + } +} + +export default StandardNodeLibrary; diff --git a/src-testing/src/renderers/webgpu/nodes/WGSLNodeBuilder.ts b/src-testing/src/renderers/webgpu/nodes/WGSLNodeBuilder.ts new file mode 100644 index 000000000..dc3aa7280 --- /dev/null +++ b/src-testing/src/renderers/webgpu/nodes/WGSLNodeBuilder.ts @@ -0,0 +1,1178 @@ +import NodeUniformsGroup from '../../common/nodes/NodeUniformsGroup.js'; + +import NodeSampler from '../../common/nodes/NodeSampler.js'; +import { + NodeSampledTexture, + NodeSampledCubeTexture, + NodeSampledTexture3D, +} from '../../common/nodes/NodeSampledTexture.js'; + +import NodeUniformBuffer from '../../common/nodes/NodeUniformBuffer.js'; +import NodeStorageBuffer from '../../common/nodes/NodeStorageBuffer.js'; + +import { NodeBuilder, CodeNode } from '../../../nodes/Nodes.js'; + +import { getFormat } from '../utils/WebGPUTextureUtils.js'; + +import WGSLNodeParser from './WGSLNodeParser.js'; +import { GPUBufferBindingType, GPUStorageTextureAccess } from '../utils/WebGPUConstants.js'; + +import { NoColorSpace, FloatType } from '../../../constants.js'; + +// GPUShaderStage is not defined in browsers not supporting WebGPU +const GPUShaderStage = self.GPUShaderStage; + +const gpuShaderStageLib = { + vertex: GPUShaderStage ? GPUShaderStage.VERTEX : 1, + fragment: GPUShaderStage ? GPUShaderStage.FRAGMENT : 2, + compute: GPUShaderStage ? GPUShaderStage.COMPUTE : 4, +}; + +const supports = { + instance: true, + swizzleAssign: false, + storageBuffer: true, +}; + +const wgslFnOpLib = { + '^^': 'tsl_xor', +}; + +const wgslTypeLib = { + float: 'f32', + int: 'i32', + uint: 'u32', + bool: 'bool', + color: 'vec3', + + vec2: 'vec2', + ivec2: 'vec2', + uvec2: 'vec2', + bvec2: 'vec2', + + vec3: 'vec3', + ivec3: 'vec3', + uvec3: 'vec3', + bvec3: 'vec3', + + vec4: 'vec4', + ivec4: 'vec4', + uvec4: 'vec4', + bvec4: 'vec4', + + mat2: 'mat2x2', + mat3: 'mat3x3', + mat4: 'mat4x4', +}; + +const wgslPolyfill = { + tsl_xor: new CodeNode('fn tsl_xor( a : bool, b : bool ) -> bool { return ( a || b ) && !( a && b ); }'), + mod_float: new CodeNode('fn tsl_mod_float( x : f32, y : f32 ) -> f32 { return x - y * floor( x / y ); }'), + mod_vec2: new CodeNode('fn tsl_mod_vec2( x : vec2f, y : vec2f ) -> vec2f { return x - y * floor( x / y ); }'), + mod_vec3: new CodeNode('fn tsl_mod_vec3( x : vec3f, y : vec3f ) -> vec3f { return x - y * floor( x / y ); }'), + mod_vec4: new CodeNode('fn tsl_mod_vec4( x : vec4f, y : vec4f ) -> vec4f { return x - y * floor( x / y ); }'), + equals_bool: new CodeNode('fn tsl_equals_bool( a : bool, b : bool ) -> bool { return a == b; }'), + equals_bvec2: new CodeNode( + 'fn tsl_equals_bvec2( a : vec2f, b : vec2f ) -> vec2 { return vec2( a.x == b.x, a.y == b.y ); }', + ), + equals_bvec3: new CodeNode( + 'fn tsl_equals_bvec3( a : vec3f, b : vec3f ) -> vec3 { return vec3( a.x == b.x, a.y == b.y, a.z == b.z ); }', + ), + equals_bvec4: new CodeNode( + 'fn tsl_equals_bvec4( a : vec4f, b : vec4f ) -> vec4 { return vec4( a.x == b.x, a.y == b.y, a.z == b.z, a.w == b.w ); }', + ), + repeatWrapping: new CodeNode(` +fn tsl_repeatWrapping( uv : vec2, dimension : vec2 ) -> vec2 { + + let uvScaled = vec2( uv * vec2( dimension ) ); + + return ( ( uvScaled % dimension ) + dimension ) % dimension; + +} +`), + biquadraticTexture: new CodeNode(` +fn tsl_biquadraticTexture( map : texture_2d, coord : vec2f, level : i32 ) -> vec4f { + + let iRes = vec2i( textureDimensions( map, level ) ); + let res = vec2f( iRes ); + + let uvScaled = coord * res; + let uvWrapping = ( ( uvScaled % res ) + res ) % res; + + // https://www.shadertoy.com/view/WtyXRy + + let uv = uvWrapping - 0.5; + let iuv = floor( uv ); + let f = fract( uv ); + + let rg1 = textureLoad( map, vec2i( iuv + vec2( 0.5, 0.5 ) ) % iRes, level ); + let rg2 = textureLoad( map, vec2i( iuv + vec2( 1.5, 0.5 ) ) % iRes, level ); + let rg3 = textureLoad( map, vec2i( iuv + vec2( 0.5, 1.5 ) ) % iRes, level ); + let rg4 = textureLoad( map, vec2i( iuv + vec2( 1.5, 1.5 ) ) % iRes, level ); + + return mix( mix( rg1, rg2, f.x ), mix( rg3, rg4, f.x ), f.y ); + +} +`), +}; + +const wgslMethods = { + dFdx: 'dpdx', + dFdy: '- dpdy', + mod_float: 'tsl_mod_float', + mod_vec2: 'tsl_mod_vec2', + mod_vec3: 'tsl_mod_vec3', + mod_vec4: 'tsl_mod_vec4', + equals_bool: 'tsl_equals_bool', + equals_bvec2: 'tsl_equals_bvec2', + equals_bvec3: 'tsl_equals_bvec3', + equals_bvec4: 'tsl_equals_bvec4', + inversesqrt: 'inverseSqrt', + bitcast: 'bitcast', +}; + +// WebGPU issue: does not support pow() with negative base on Windows + +if (/Windows/g.test(navigator.userAgent)) { + wgslPolyfill.pow_float = new CodeNode( + 'fn tsl_pow_float( a : f32, b : f32 ) -> f32 { return select( -pow( -a, b ), pow( a, b ), a > 0.0 ); }', + ); + wgslPolyfill.pow_vec2 = new CodeNode( + 'fn tsl_pow_vec2( a : vec2f, b : vec2f ) -> vec2f { return vec2f( tsl_pow_float( a.x, b.x ), tsl_pow_float( a.y, b.y ) ); }', + [wgslPolyfill.pow_float], + ); + wgslPolyfill.pow_vec3 = new CodeNode( + 'fn tsl_pow_vec3( a : vec3f, b : vec3f ) -> vec3f { return vec3f( tsl_pow_float( a.x, b.x ), tsl_pow_float( a.y, b.y ), tsl_pow_float( a.z, b.z ) ); }', + [wgslPolyfill.pow_float], + ); + wgslPolyfill.pow_vec4 = new CodeNode( + 'fn tsl_pow_vec4( a : vec4f, b : vec4f ) -> vec4f { return vec4f( tsl_pow_float( a.x, b.x ), tsl_pow_float( a.y, b.y ), tsl_pow_float( a.z, b.z ), tsl_pow_float( a.w, b.w ) ); }', + [wgslPolyfill.pow_float], + ); + + wgslMethods.pow_float = 'tsl_pow_float'; + wgslMethods.pow_vec2 = 'tsl_pow_vec2'; + wgslMethods.pow_vec3 = 'tsl_pow_vec3'; + wgslMethods.pow_vec4 = 'tsl_pow_vec4'; +} + +// + +let diagnostics = ''; + +if (/Firefox|Deno/g.test(navigator.userAgent) !== true) { + diagnostics += 'diagnostic( off, derivative_uniformity );\n'; +} + +// + +class WGSLNodeBuilder extends NodeBuilder { + constructor(object, renderer) { + super(object, renderer, new WGSLNodeParser()); + + this.uniformGroups = {}; + + this.builtins = {}; + + this.directives = {}; + + this.scopedArrays = new Map(); + } + + needsToWorkingColorSpace(texture) { + return texture.isVideoTexture === true && texture.colorSpace !== NoColorSpace; + } + + _generateTextureSample(texture, textureProperty, uvSnippet, depthSnippet, shaderStage = this.shaderStage) { + if (shaderStage === 'fragment') { + if (depthSnippet) { + return `textureSample( ${textureProperty}, ${textureProperty}_sampler, ${uvSnippet}, ${depthSnippet} )`; + } else { + return `textureSample( ${textureProperty}, ${textureProperty}_sampler, ${uvSnippet} )`; + } + } else if (this.isFilteredTexture(texture)) { + return this.generateFilteredTexture(texture, textureProperty, uvSnippet); + } else { + return this.generateTextureLod(texture, textureProperty, uvSnippet, '0'); + } + } + + _generateVideoSample(textureProperty, uvSnippet, shaderStage = this.shaderStage) { + if (shaderStage === 'fragment') { + return `textureSampleBaseClampToEdge( ${textureProperty}, ${textureProperty}_sampler, vec2( ${uvSnippet}.x, 1.0 - ${uvSnippet}.y ) )`; + } else { + console.error(`WebGPURenderer: THREE.VideoTexture does not support ${shaderStage} shader.`); + } + } + + _generateTextureSampleLevel( + texture, + textureProperty, + uvSnippet, + levelSnippet, + depthSnippet, + shaderStage = this.shaderStage, + ) { + if (shaderStage === 'fragment' && this.isUnfilterable(texture) === false) { + return `textureSampleLevel( ${textureProperty}, ${textureProperty}_sampler, ${uvSnippet}, ${levelSnippet} )`; + } else if (this.isFilteredTexture(texture)) { + return this.generateFilteredTexture(texture, textureProperty, uvSnippet, levelSnippet); + } else { + return this.generateTextureLod(texture, textureProperty, uvSnippet, levelSnippet); + } + } + + generateFilteredTexture(texture, textureProperty, uvSnippet, levelSnippet = '0') { + this._include('biquadraticTexture'); + + return `tsl_biquadraticTexture( ${textureProperty}, ${uvSnippet}, i32( ${levelSnippet} ) )`; + } + + generateTextureLod(texture, textureProperty, uvSnippet, levelSnippet = '0') { + this._include('repeatWrapping'); + + const dimension = + texture.isMultisampleRenderTargetTexture === true + ? `textureDimensions( ${textureProperty} )` + : `textureDimensions( ${textureProperty}, 0 )`; + + return `textureLoad( ${textureProperty}, tsl_repeatWrapping( ${uvSnippet}, ${dimension} ), i32( ${levelSnippet} ) )`; + } + + generateTextureLoad(texture, textureProperty, uvIndexSnippet, depthSnippet, levelSnippet = '0u') { + if (depthSnippet) { + return `textureLoad( ${textureProperty}, ${uvIndexSnippet}, ${depthSnippet}, ${levelSnippet} )`; + } else { + return `textureLoad( ${textureProperty}, ${uvIndexSnippet}, ${levelSnippet} )`; + } + } + + generateTextureStore(texture, textureProperty, uvIndexSnippet, valueSnippet) { + return `textureStore( ${textureProperty}, ${uvIndexSnippet}, ${valueSnippet} )`; + } + + isUnfilterable(texture) { + return ( + this.getComponentTypeFromTexture(texture) !== 'float' || + (!this.isAvailable('float32Filterable') && texture.isDataTexture === true && texture.type === FloatType) || + texture.isMultisampleRenderTargetTexture === true + ); + } + + generateTexture(texture, textureProperty, uvSnippet, depthSnippet, shaderStage = this.shaderStage) { + let snippet = null; + + if (texture.isVideoTexture === true) { + snippet = this._generateVideoSample(textureProperty, uvSnippet, shaderStage); + } else if (this.isUnfilterable(texture)) { + snippet = this.generateTextureLod(texture, textureProperty, uvSnippet, '0', depthSnippet, shaderStage); + } else { + snippet = this._generateTextureSample(texture, textureProperty, uvSnippet, depthSnippet, shaderStage); + } + + return snippet; + } + + generateTextureGrad( + texture, + textureProperty, + uvSnippet, + gradSnippet, + depthSnippet, + shaderStage = this.shaderStage, + ) { + if (shaderStage === 'fragment') { + // TODO handle i32 or u32 --> uvSnippet, array_index: A, ddx, ddy + return `textureSampleGrad( ${textureProperty}, ${textureProperty}_sampler, ${uvSnippet}, ${gradSnippet[0]}, ${gradSnippet[1]} )`; + } else { + console.error(`WebGPURenderer: THREE.TextureNode.gradient() does not support ${shaderStage} shader.`); + } + } + + generateTextureCompare( + texture, + textureProperty, + uvSnippet, + compareSnippet, + depthSnippet, + shaderStage = this.shaderStage, + ) { + if (shaderStage === 'fragment') { + return `textureSampleCompare( ${textureProperty}, ${textureProperty}_sampler, ${uvSnippet}, ${compareSnippet} )`; + } else { + console.error( + `WebGPURenderer: THREE.DepthTexture.compareFunction() does not support ${shaderStage} shader.`, + ); + } + } + + generateTextureLevel( + texture, + textureProperty, + uvSnippet, + levelSnippet, + depthSnippet, + shaderStage = this.shaderStage, + ) { + let snippet = null; + + if (texture.isVideoTexture === true) { + snippet = this._generateVideoSample(textureProperty, uvSnippet, shaderStage); + } else { + snippet = this._generateTextureSampleLevel( + texture, + textureProperty, + uvSnippet, + levelSnippet, + depthSnippet, + shaderStage, + ); + } + + return snippet; + } + + generateTextureBias( + texture, + textureProperty, + uvSnippet, + biasSnippet, + depthSnippet, + shaderStage = this.shaderStage, + ) { + if (shaderStage === 'fragment') { + return `textureSampleBias( ${textureProperty}, ${textureProperty}_sampler, ${uvSnippet}, ${biasSnippet} )`; + } else { + console.error(`WebGPURenderer: THREE.TextureNode.biasNode does not support ${shaderStage} shader.`); + } + } + + getPropertyName(node, shaderStage = this.shaderStage) { + if (node.isNodeVarying === true && node.needsInterpolation === true) { + if (shaderStage === 'vertex') { + return `varyings.${node.name}`; + } + } else if (node.isNodeUniform === true) { + const name = node.name; + const type = node.type; + + if (type === 'texture' || type === 'cubeTexture' || type === 'storageTexture' || type === 'texture3D') { + return name; + } else if (type === 'buffer' || type === 'storageBuffer' || type === 'indirectStorageBuffer') { + return `NodeBuffer_${node.id}.${name}`; + } else { + return node.groupNode.name + '.' + name; + } + } + + return super.getPropertyName(node); + } + + getOutputStructName() { + return 'output'; + } + + _getUniformGroupCount(shaderStage) { + return Object.keys(this.uniforms[shaderStage]).length; + } + + getFunctionOperator(op) { + const fnOp = wgslFnOpLib[op]; + + if (fnOp !== undefined) { + this._include(fnOp); + + return fnOp; + } + + return null; + } + + getStorageAccess(node) { + if (node.isStorageTextureNode) { + switch (node.access) { + case GPUStorageTextureAccess.ReadOnly: + return 'read'; + + case GPUStorageTextureAccess.WriteOnly: + return 'write'; + + default: + return 'read_write'; + } + } else { + switch (node.access) { + case GPUBufferBindingType.Storage: + return 'read_write'; + + case GPUBufferBindingType.ReadOnlyStorage: + return 'read'; + + default: + return 'write'; + } + } + } + + getUniformFromNode(node, type, shaderStage, name = null) { + const uniformNode = super.getUniformFromNode(node, type, shaderStage, name); + const nodeData = this.getDataFromNode(node, shaderStage, this.globalCache); + + if (nodeData.uniformGPU === undefined) { + let uniformGPU; + + const group = node.groupNode; + const groupName = group.name; + + const bindings = this.getBindGroupArray(groupName, shaderStage); + + if (type === 'texture' || type === 'cubeTexture' || type === 'storageTexture' || type === 'texture3D') { + let texture = null; + + if (type === 'texture' || type === 'storageTexture') { + texture = new NodeSampledTexture( + uniformNode.name, + uniformNode.node, + group, + node.access ? node.access : null, + ); + } else if (type === 'cubeTexture') { + texture = new NodeSampledCubeTexture( + uniformNode.name, + uniformNode.node, + group, + node.access ? node.access : null, + ); + } else if (type === 'texture3D') { + texture = new NodeSampledTexture3D( + uniformNode.name, + uniformNode.node, + group, + node.access ? node.access : null, + ); + } + + texture.store = node.isStorageTextureNode === true; + texture.setVisibility(gpuShaderStageLib[shaderStage]); + + if ( + shaderStage === 'fragment' && + this.isUnfilterable(node.value) === false && + texture.store === false + ) { + const sampler = new NodeSampler(`${uniformNode.name}_sampler`, uniformNode.node, group); + sampler.setVisibility(gpuShaderStageLib[shaderStage]); + + bindings.push(sampler, texture); + + uniformGPU = [sampler, texture]; + } else { + bindings.push(texture); + + uniformGPU = [texture]; + } + } else if (type === 'buffer' || type === 'storageBuffer' || type === 'indirectStorageBuffer') { + const bufferClass = type === 'buffer' ? NodeUniformBuffer : NodeStorageBuffer; + + const buffer = new bufferClass(node, group); + buffer.setVisibility(gpuShaderStageLib[shaderStage]); + + bindings.push(buffer); + + uniformGPU = buffer; + } else { + const uniformsStage = this.uniformGroups[shaderStage] || (this.uniformGroups[shaderStage] = {}); + + let uniformsGroup = uniformsStage[groupName]; + + if (uniformsGroup === undefined) { + uniformsGroup = new NodeUniformsGroup(groupName, group); + uniformsGroup.setVisibility(gpuShaderStageLib[shaderStage]); + + uniformsStage[groupName] = uniformsGroup; + + bindings.push(uniformsGroup); + } + + uniformGPU = this.getNodeUniform(uniformNode, type); + + uniformsGroup.addUniform(uniformGPU); + } + + nodeData.uniformGPU = uniformGPU; + } + + return uniformNode; + } + + getBuiltin(name, property, type, shaderStage = this.shaderStage) { + const map = this.builtins[shaderStage] || (this.builtins[shaderStage] = new Map()); + + if (map.has(name) === false) { + map.set(name, { + name, + property, + type, + }); + } + + return property; + } + + hasBuiltin(name, shaderStage = this.shaderStage) { + return this.builtins[shaderStage] !== undefined && this.builtins[shaderStage].has(name); + } + + getVertexIndex() { + if (this.shaderStage === 'vertex') { + return this.getBuiltin('vertex_index', 'vertexIndex', 'u32', 'attribute'); + } + + return 'vertexIndex'; + } + + buildFunctionCode(shaderNode) { + const layout = shaderNode.layout; + const flowData = this.flowShaderNode(shaderNode); + + const parameters = []; + + for (const input of layout.inputs) { + parameters.push(input.name + ' : ' + this.getType(input.type)); + } + + // + + let code = `fn ${layout.name}( ${parameters.join(', ')} ) -> ${this.getType(layout.type)} { +${flowData.vars} +${flowData.code} +`; + + if (flowData.result) { + code += `\treturn ${flowData.result};\n`; + } + + code += '\n}\n'; + + // + + return code; + } + + getInstanceIndex() { + if (this.shaderStage === 'vertex') { + return this.getBuiltin('instance_index', 'instanceIndex', 'u32', 'attribute'); + } + + return 'instanceIndex'; + } + + getInvocationLocalIndex() { + return this.getBuiltin('local_invocation_index', 'invocationLocalIndex', 'u32', 'attribute'); + } + + getSubgroupSize() { + this.enableSubGroups(); + + return this.getBuiltin('subgroup_size', 'subgroupSize', 'u32', 'attribute'); + } + + getInvocationSubgroupIndex() { + this.enableSubGroups(); + + return this.getBuiltin('subgroup_invocation_id', 'invocationSubgroupIndex', 'u32', 'attribute'); + } + + getSubgroupIndex() { + this.enableSubGroups(); + + return this.getBuiltin('subgroup_id', 'subgroupIndex', 'u32', 'attribute'); + } + + getDrawIndex() { + return null; + } + + getFrontFacing() { + return this.getBuiltin('front_facing', 'isFront', 'bool'); + } + + getFragCoord() { + return this.getBuiltin('position', 'fragCoord', 'vec4') + '.xy'; + } + + getFragDepth() { + return 'output.' + this.getBuiltin('frag_depth', 'depth', 'f32', 'output'); + } + + isFlipY() { + return false; + } + + enableDirective(name, shaderStage = this.shaderStage) { + const stage = this.directives[shaderStage] || (this.directives[shaderStage] = new Set()); + stage.add(name); + } + + getDirectives(shaderStage) { + const snippets = []; + const directives = this.directives[shaderStage]; + + if (directives !== undefined) { + for (const directive of directives) { + snippets.push(`enable ${directive};`); + } + } + + return snippets.join('\n'); + } + + enableSubGroups() { + this.enableDirective('subgroups'); + } + + enableSubgroupsF16() { + this.enableDirective('subgroups-f16'); + } + + enableClipDistances() { + this.enableDirective('clip_distances'); + } + + enableShaderF16() { + this.enableDirective('f16'); + } + + enableDualSourceBlending() { + this.enableDirective('dual_source_blending'); + } + + getBuiltins(shaderStage) { + const snippets = []; + const builtins = this.builtins[shaderStage]; + + if (builtins !== undefined) { + for (const { name, property, type } of builtins.values()) { + snippets.push(`@builtin( ${name} ) ${property} : ${type}`); + } + } + + return snippets.join(',\n\t'); + } + + getScopedArray(name, scope, bufferType, bufferCount) { + if (this.scopedArrays.has(name) === false) { + this.scopedArrays.set(name, { + name, + scope, + bufferType, + bufferCount, + }); + } + + return name; + } + + getScopedArrays(shaderStage) { + if (shaderStage !== 'compute') { + return; + } + + const snippets = []; + + for (const { name, scope, bufferType, bufferCount } of this.scopedArrays.values()) { + const type = this.getType(bufferType); + + snippets.push(`var<${scope}> ${name}: array< ${type}, ${bufferCount} >;`); + } + + return snippets.join('\n'); + } + + getAttributes(shaderStage) { + const snippets = []; + + if (shaderStage === 'compute') { + this.getBuiltin('global_invocation_id', 'id', 'vec3', 'attribute'); + this.getBuiltin('workgroup_id', 'workgroupId', 'vec3', 'attribute'); + this.getBuiltin('local_invocation_id', 'localId', 'vec3', 'attribute'); + this.getBuiltin('num_workgroups', 'numWorkgroups', 'vec3', 'attribute'); + + if (this.renderer.hasFeature('subgroups')) { + this.enableDirective('subgroups', shaderStage); + this.getBuiltin('subgroup_size', 'subgroupSize', 'u32', 'attribute'); + } + } + + if (shaderStage === 'vertex' || shaderStage === 'compute') { + const builtins = this.getBuiltins('attribute'); + + if (builtins) snippets.push(builtins); + + const attributes = this.getAttributesArray(); + + for (let index = 0, length = attributes.length; index < length; index++) { + const attribute = attributes[index]; + const name = attribute.name; + const type = this.getType(attribute.type); + + snippets.push(`@location( ${index} ) ${name} : ${type}`); + } + } + + return snippets.join(',\n\t'); + } + + getStructMembers(struct) { + const snippets = []; + const members = struct.getMemberTypes(); + + for (let i = 0; i < members.length; i++) { + const member = members[i]; + snippets.push(`\t@location( ${i} ) m${i} : ${member}`); + } + + const builtins = this.getBuiltins('output'); + + if (builtins) snippets.push('\t' + builtins); + + return snippets.join(',\n'); + } + + getStructs(shaderStage) { + const snippets = []; + const structs = this.structs[shaderStage]; + + for (let index = 0, length = structs.length; index < length; index++) { + const struct = structs[index]; + const name = struct.name; + + let snippet = `\struct ${name} {\n`; + snippet += this.getStructMembers(struct); + snippet += '\n}'; + + snippets.push(snippet); + + snippets.push(`\nvar output : ${name};\n\n`); + } + + return snippets.join('\n\n'); + } + + getVar(type, name) { + return `var ${name} : ${this.getType(type)}`; + } + + getVars(shaderStage) { + const snippets = []; + const vars = this.vars[shaderStage]; + + if (vars !== undefined) { + for (const variable of vars) { + snippets.push(`\t${this.getVar(variable.type, variable.name)};`); + } + } + + return `\n${snippets.join('\n')}\n`; + } + + getVaryings(shaderStage) { + const snippets = []; + + if (shaderStage === 'vertex') { + this.getBuiltin('position', 'Vertex', 'vec4', 'vertex'); + } + + if (shaderStage === 'vertex' || shaderStage === 'fragment') { + const varyings = this.varyings; + const vars = this.vars[shaderStage]; + + for (let index = 0; index < varyings.length; index++) { + const varying = varyings[index]; + + if (varying.needsInterpolation) { + let attributesSnippet = `@location( ${index} )`; + + if (/^(int|uint|ivec|uvec)/.test(varying.type)) { + attributesSnippet += ' @interpolate( flat )'; + } + + snippets.push(`${attributesSnippet} ${varying.name} : ${this.getType(varying.type)}`); + } else if (shaderStage === 'vertex' && vars.includes(varying) === false) { + vars.push(varying); + } + } + } + + const builtins = this.getBuiltins(shaderStage); + + if (builtins) snippets.push(builtins); + + const code = snippets.join(',\n\t'); + + return shaderStage === 'vertex' ? this._getWGSLStruct('VaryingsStruct', '\t' + code) : code; + } + + getUniforms(shaderStage) { + const uniforms = this.uniforms[shaderStage]; + + const bindingSnippets = []; + const bufferSnippets = []; + const structSnippets = []; + const uniformGroups = {}; + + for (const uniform of uniforms) { + const groupName = uniform.groupNode.name; + const uniformIndexes = this.bindingsIndexes[groupName]; + + if ( + uniform.type === 'texture' || + uniform.type === 'cubeTexture' || + uniform.type === 'storageTexture' || + uniform.type === 'texture3D' + ) { + const texture = uniform.node.value; + + if ( + shaderStage === 'fragment' && + this.isUnfilterable(texture) === false && + uniform.node.isStorageTextureNode !== true + ) { + if (texture.isDepthTexture === true && texture.compareFunction !== null) { + bindingSnippets.push( + `@binding( ${uniformIndexes.binding++} ) @group( ${uniformIndexes.group} ) var ${uniform.name}_sampler : sampler_comparison;`, + ); + } else { + bindingSnippets.push( + `@binding( ${uniformIndexes.binding++} ) @group( ${uniformIndexes.group} ) var ${uniform.name}_sampler : sampler;`, + ); + } + } + + let textureType; + + let multisampled = ''; + + if (texture.isMultisampleRenderTargetTexture === true) { + multisampled = '_multisampled'; + } + + if (texture.isCubeTexture === true) { + textureType = 'texture_cube'; + } else if (texture.isDataArrayTexture === true || texture.isCompressedArrayTexture === true) { + textureType = 'texture_2d_array'; + } else if (texture.isDepthTexture === true) { + textureType = `texture_depth${multisampled}_2d`; + } else if (texture.isVideoTexture === true) { + textureType = 'texture_external'; + } else if (texture.isData3DTexture === true) { + textureType = 'texture_3d'; + } else if (uniform.node.isStorageTextureNode === true) { + const format = getFormat(texture); + const access = this.getStorageAccess(uniform.node); + + textureType = `texture_storage_2d<${format}, ${access}>`; + } else { + const componentPrefix = this.getComponentTypeFromTexture(texture).charAt(0); + + textureType = `texture${multisampled}_2d<${componentPrefix}32>`; + } + + bindingSnippets.push( + `@binding( ${uniformIndexes.binding++} ) @group( ${uniformIndexes.group} ) var ${uniform.name} : ${textureType};`, + ); + } else if ( + uniform.type === 'buffer' || + uniform.type === 'storageBuffer' || + uniform.type === 'indirectStorageBuffer' + ) { + const bufferNode = uniform.node; + const bufferType = this.getType(bufferNode.bufferType); + const bufferCount = bufferNode.bufferCount; + + const bufferCountSnippet = bufferCount > 0 && uniform.type === 'buffer' ? ', ' + bufferCount : ''; + const bufferTypeSnippet = bufferNode.isAtomic ? `atomic<${bufferType}>` : `${bufferType}`; + const bufferSnippet = `\t${uniform.name} : array< ${bufferTypeSnippet}${bufferCountSnippet} >\n`; + const bufferAccessMode = bufferNode.isStorageBufferNode + ? `storage, ${this.getStorageAccess(bufferNode)}` + : 'uniform'; + + bufferSnippets.push( + this._getWGSLStructBinding( + 'NodeBuffer_' + bufferNode.id, + bufferSnippet, + bufferAccessMode, + uniformIndexes.binding++, + uniformIndexes.group, + ), + ); + } else { + const vectorType = this.getType(this.getVectorType(uniform.type)); + const groupName = uniform.groupNode.name; + + const group = + uniformGroups[groupName] || + (uniformGroups[groupName] = { + index: uniformIndexes.binding++, + id: uniformIndexes.group, + snippets: [], + }); + + group.snippets.push(`\t${uniform.name} : ${vectorType}`); + } + } + + for (const name in uniformGroups) { + const group = uniformGroups[name]; + + structSnippets.push( + this._getWGSLStructBinding(name, group.snippets.join(',\n'), 'uniform', group.index, group.id), + ); + } + + let code = bindingSnippets.join('\n'); + code += bufferSnippets.join('\n'); + code += structSnippets.join('\n'); + + return code; + } + + buildCode() { + const shadersData = this.material !== null ? { fragment: {}, vertex: {} } : { compute: {} }; + + this.sortBindingGroups(); + + for (const shaderStage in shadersData) { + const stageData = shadersData[shaderStage]; + stageData.uniforms = this.getUniforms(shaderStage); + stageData.attributes = this.getAttributes(shaderStage); + stageData.varyings = this.getVaryings(shaderStage); + stageData.structs = this.getStructs(shaderStage); + stageData.vars = this.getVars(shaderStage); + stageData.codes = this.getCodes(shaderStage); + stageData.directives = this.getDirectives(shaderStage); + stageData.scopedArrays = this.getScopedArrays(shaderStage); + + // + + let flow = '// code\n\n'; + flow += this.flowCode[shaderStage]; + + const flowNodes = this.flowNodes[shaderStage]; + const mainNode = flowNodes[flowNodes.length - 1]; + + const outputNode = mainNode.outputNode; + const isOutputStruct = outputNode !== undefined && outputNode.isOutputStructNode === true; + + for (const node of flowNodes) { + const flowSlotData = this.getFlowData(node /*, shaderStage*/); + const slotName = node.name; + + if (slotName) { + if (flow.length > 0) flow += '\n'; + + flow += `\t// flow -> ${slotName}\n\t`; + } + + flow += `${flowSlotData.code}\n\t`; + + if (node === mainNode && shaderStage !== 'compute') { + flow += '// result\n\n\t'; + + if (shaderStage === 'vertex') { + flow += `varyings.Vertex = ${flowSlotData.result};`; + } else if (shaderStage === 'fragment') { + if (isOutputStruct) { + stageData.returnType = outputNode.nodeType; + + flow += `return ${flowSlotData.result};`; + } else { + let structSnippet = '\t@location(0) color: vec4'; + + const builtins = this.getBuiltins('output'); + + if (builtins) structSnippet += ',\n\t' + builtins; + + stageData.returnType = 'OutputStruct'; + stageData.structs += this._getWGSLStruct('OutputStruct', structSnippet); + stageData.structs += '\nvar output : OutputStruct;\n\n'; + + flow += `output.color = ${flowSlotData.result};\n\n\treturn output;`; + } + } + } + } + + stageData.flow = flow; + } + + if (this.material !== null) { + this.vertexShader = this._getWGSLVertexCode(shadersData.vertex); + this.fragmentShader = this._getWGSLFragmentCode(shadersData.fragment); + } else { + this.computeShader = this._getWGSLComputeCode( + shadersData.compute, + (this.object.workgroupSize || [64]).join(', '), + ); + } + } + + getMethod(method, output = null) { + let wgslMethod; + + if (output !== null) { + wgslMethod = this._getWGSLMethod(method + '_' + output); + } + + if (wgslMethod === undefined) { + wgslMethod = this._getWGSLMethod(method); + } + + return wgslMethod || method; + } + + getType(type) { + return wgslTypeLib[type] || type; + } + + isAvailable(name) { + let result = supports[name]; + + if (result === undefined) { + if (name === 'float32Filterable') { + result = this.renderer.hasFeature('float32-filterable'); + } + + supports[name] = result; + } + + return result; + } + + _getWGSLMethod(method) { + if (wgslPolyfill[method] !== undefined) { + this._include(method); + } + + return wgslMethods[method]; + } + + _include(name) { + const codeNode = wgslPolyfill[name]; + codeNode.build(this); + + if (this.currentFunctionNode !== null) { + this.currentFunctionNode.includes.push(codeNode); + } + + return codeNode; + } + + _getWGSLVertexCode(shaderData) { + return `${this.getSignature()} +// directives +${shaderData.directives} + +// uniforms +${shaderData.uniforms} + +// varyings +${shaderData.varyings} +var varyings : VaryingsStruct; + +// codes +${shaderData.codes} + +@vertex +fn main( ${shaderData.attributes} ) -> VaryingsStruct { + + // vars + ${shaderData.vars} + + // flow + ${shaderData.flow} + + return varyings; + +} +`; + } + + _getWGSLFragmentCode(shaderData) { + return `${this.getSignature()} +// global +${diagnostics} + +// uniforms +${shaderData.uniforms} + +// structs +${shaderData.structs} + +// codes +${shaderData.codes} + +@fragment +fn main( ${shaderData.varyings} ) -> ${shaderData.returnType} { + + // vars + ${shaderData.vars} + + // flow + ${shaderData.flow} + +} +`; + } + + _getWGSLComputeCode(shaderData, workgroupSize) { + return `${this.getSignature()} +// directives +${shaderData.directives} + +// system +var instanceIndex : u32; + +// locals +${shaderData.scopedArrays} + +// uniforms +${shaderData.uniforms} + +// codes +${shaderData.codes} + +@compute @workgroup_size( ${workgroupSize} ) +fn main( ${shaderData.attributes} ) { + + // system + instanceIndex = id.x + id.y * numWorkgroups.x * u32(${workgroupSize}) + id.z * numWorkgroups.x * numWorkgroups.y * u32(${workgroupSize}); + + // vars + ${shaderData.vars} + + // flow + ${shaderData.flow} + +} +`; + } + + _getWGSLStruct(name, vars) { + return ` +struct ${name} { +${vars} +};`; + } + + _getWGSLStructBinding(name, vars, access, binding = 0, group = 0) { + const structName = name + 'Struct'; + const structSnippet = this._getWGSLStruct(structName, vars); + + return `${structSnippet} +@binding( ${binding} ) @group( ${group} ) +var<${access}> ${name} : ${structName};`; + } +} + +export default WGSLNodeBuilder; diff --git a/src-testing/src/renderers/webgpu/nodes/WGSLNodeFunction.ts b/src-testing/src/renderers/webgpu/nodes/WGSLNodeFunction.ts new file mode 100644 index 000000000..33b0d2688 --- /dev/null +++ b/src-testing/src/renderers/webgpu/nodes/WGSLNodeFunction.ts @@ -0,0 +1,142 @@ +import NodeFunction from '../../../nodes/core/NodeFunction.js'; +import NodeFunctionInput from '../../../nodes/core/NodeFunctionInput.js'; + +const declarationRegexp = /^[fn]*\s*([a-z_0-9]+)?\s*\(([\s\S]*?)\)\s*[\-\>]*\s*([a-z_0-9]+(?:<[\s\S]+?>)?)/i; +const propertiesRegexp = /([a-z_0-9]+)\s*:\s*([a-z_0-9]+(?:<[\s\S]+?>)?)/gi; + +const wgslTypeLib = { + f32: 'float', + i32: 'int', + u32: 'uint', + bool: 'bool', + + 'vec2': 'vec2', + 'vec2': 'ivec2', + 'vec2': 'uvec2', + 'vec2': 'bvec2', + + vec2f: 'vec2', + vec2i: 'ivec2', + vec2u: 'uvec2', + vec2b: 'bvec2', + + 'vec3': 'vec3', + 'vec3': 'ivec3', + 'vec3': 'uvec3', + 'vec3': 'bvec3', + + vec3f: 'vec3', + vec3i: 'ivec3', + vec3u: 'uvec3', + vec3b: 'bvec3', + + 'vec4': 'vec4', + 'vec4': 'ivec4', + 'vec4': 'uvec4', + 'vec4': 'bvec4', + + vec4f: 'vec4', + vec4i: 'ivec4', + vec4u: 'uvec4', + vec4b: 'bvec4', + + 'mat2x2': 'mat2', + mat2x2f: 'mat2', + + 'mat3x3': 'mat3', + mat3x3f: 'mat3', + + 'mat4x4': 'mat4', + mat4x4f: 'mat4', + + sampler: 'sampler', + + texture_1d: 'texture', + + texture_2d: 'texture', + texture_2d_array: 'texture', + texture_multisampled_2d: 'cubeTexture', + + texture_depth_2d: 'depthTexture', + + texture_3d: 'texture3D', + + texture_cube: 'cubeTexture', + texture_cube_array: 'cubeTexture', + + texture_storage_1d: 'storageTexture', + texture_storage_2d: 'storageTexture', + texture_storage_2d_array: 'storageTexture', + texture_storage_3d: 'storageTexture', +}; + +const parse = source => { + source = source.trim(); + + const declaration = source.match(declarationRegexp); + + if (declaration !== null && declaration.length === 4) { + const inputsCode = declaration[2]; + const propsMatches = []; + let match = null; + + while ((match = propertiesRegexp.exec(inputsCode)) !== null) { + propsMatches.push({ name: match[1], type: match[2] }); + } + + // Process matches to correctly pair names and types + const inputs = []; + for (let i = 0; i < propsMatches.length; i++) { + const { name, type } = propsMatches[i]; + + let resolvedType = type; + + if (resolvedType.startsWith('texture')) { + resolvedType = type.split('<')[0]; + } else if (resolvedType.startsWith('ptr')) { + resolvedType = 'pointer'; + } + + resolvedType = wgslTypeLib[resolvedType] || resolvedType; + + inputs.push(new NodeFunctionInput(resolvedType, name)); + } + + const blockCode = source.substring(declaration[0].length); + const outputType = declaration[3] || 'void'; + + const name = declaration[1] !== undefined ? declaration[1] : ''; + const type = wgslTypeLib[outputType] || outputType; + + return { + type, + inputs, + name, + inputsCode, + blockCode, + outputType, + }; + } else { + throw new Error('FunctionNode: Function is not a WGSL code.'); + } +}; + +class WGSLNodeFunction extends NodeFunction { + constructor(source) { + const { type, inputs, name, inputsCode, blockCode, outputType } = parse(source); + + super(type, inputs, name); + + this.inputsCode = inputsCode; + this.blockCode = blockCode; + this.outputType = outputType; + } + + getCode(name = this.name) { + const outputType = this.outputType !== 'void' ? '-> ' + this.outputType : ''; + + return `fn ${name} ( ${this.inputsCode.trim()} ) ${outputType}` + this.blockCode; + } +} + +export default WGSLNodeFunction; diff --git a/src-testing/src/renderers/webgpu/nodes/WGSLNodeParser.ts b/src-testing/src/renderers/webgpu/nodes/WGSLNodeParser.ts new file mode 100644 index 000000000..c32133df4 --- /dev/null +++ b/src-testing/src/renderers/webgpu/nodes/WGSLNodeParser.ts @@ -0,0 +1,10 @@ +import NodeParser from '../../../nodes/core/NodeParser.js'; +import WGSLNodeFunction from './WGSLNodeFunction.js'; + +class WGSLNodeParser extends NodeParser { + parseFunction(source) { + return new WGSLNodeFunction(source); + } +} + +export default WGSLNodeParser; diff --git a/src-testing/src/renderers/webgpu/utils/WebGPUConstants.d.ts b/src-testing/src/renderers/webgpu/utils/WebGPUConstants.d.ts new file mode 100644 index 000000000..baa36f901 --- /dev/null +++ b/src-testing/src/renderers/webgpu/utils/WebGPUConstants.d.ts @@ -0,0 +1,328 @@ +export enum GPUPrimitiveTopology { + PointList = "point-list", + LineList = "line-list", + LineStrip = "line-strip", + TriangleList = "triangle-list", + TriangleStrip = "triangle-strip", +} + +export enum GPUCompareFunction { + Never = "never", + Less = "less", + Equal = "equal", + LessEqual = "less-equal", + Greater = "greater", + NotEqual = "not-equal", + GreaterEqual = "greater-equal", + Always = "always", +} + +export enum GPUStoreOp { + Store = "store", + Discard = "discard", +} + +export enum GPULoadOp { + Load = "load", + Clear = "clear", +} + +export enum GPUFrontFace { + CCW = "ccw", + CW = "cw", +} + +export enum GPUCullMode { + None = "none", + Front = "front", + Back = "back", +} + +export enum GPUIndexFormat { + Uint16 = "uint16", + Uint32 = "uint32", +} + +export enum GPUVertexFormat { + Uint8x2 = "uint8x2", + Uint8x4 = "uint8x4", + Sint8x2 = "sint8x2", + Sint8x4 = "sint8x4", + Unorm8x2 = "unorm8x2", + Unorm8x4 = "unorm8x4", + Snorm8x2 = "snorm8x2", + Snorm8x4 = "snorm8x4", + Uint16x2 = "uint16x2", + Uint16x4 = "uint16x4", + Sint16x2 = "sint16x2", + Sint16x4 = "sint16x4", + Unorm16x2 = "unorm16x2", + Unorm16x4 = "unorm16x4", + Snorm16x2 = "snorm16x2", + Snorm16x4 = "snorm16x4", + Float16x2 = "float16x2", + Float16x4 = "float16x4", + Float32 = "float32", + Float32x2 = "float32x2", + Float32x3 = "float32x3", + Float32x4 = "float32x4", + Uint32 = "uint32", + Uint32x2 = "uint32x2", + Uint32x3 = "uint32x3", + Uint32x4 = "uint32x4", + Sint32 = "sint32", + Sint32x2 = "sint32x2", + Sint32x3 = "sint32x3", + Sint32x4 = "sint32x4", +} + +export enum GPUTextureFormat { + // 8-bit formats + + R8Unorm = "r8unorm", + R8Snorm = "r8snorm", + R8Uint = "r8uint", + R8Sint = "r8sint", + + // 16-bit formats + + R16Uint = "r16uint", + R16Sint = "r16sint", + R16Float = "r16float", + RG8Unorm = "rg8unorm", + RG8Snorm = "rg8snorm", + RG8Uint = "rg8uint", + RG8Sint = "rg8sint", + + // 32-bit formats + + R32Uint = "r32uint", + R32Sint = "r32sint", + R32Float = "r32float", + RG16Uint = "rg16uint", + RG16Sint = "rg16sint", + RG16Float = "rg16float", + RGBA8Unorm = "rgba8unorm", + RGBA8UnormSRGB = "rgba8unorm-srgb", + RGBA8Snorm = "rgba8snorm", + RGBA8Uint = "rgba8uint", + RGBA8Sint = "rgba8sint", + BGRA8Unorm = "bgra8unorm", + BGRA8UnormSRGB = "bgra8unorm-srgb", + // Packed 32-bit formats + RGB9E5UFloat = "rgb9e5ufloat", + RGB10A2Unorm = "rgb10a2unorm", + RG11B10uFloat = "rgb10a2unorm", + + // 64-bit formats + + RG32Uint = "rg32uint", + RG32Sint = "rg32sint", + RG32Float = "rg32float", + RGBA16Uint = "rgba16uint", + RGBA16Sint = "rgba16sint", + RGBA16Float = "rgba16float", + + // 128-bit formats + + RGBA32Uint = "rgba32uint", + RGBA32Sint = "rgba32sint", + RGBA32Float = "rgba32float", + + // Depth and stencil formats + + Stencil8 = "stencil8", + Depth16Unorm = "depth16unorm", + Depth24Plus = "depth24plus", + Depth24PlusStencil8 = "depth24plus-stencil8", + Depth32Float = "depth32float", + + // 'depth32float-stencil8' extension + + Depth32FloatStencil8 = "depth32float-stencil8", + + // BC compressed formats usable if 'texture-compression-bc' is both + // supported by the device/user agent and enabled in requestDevice. + + BC1RGBAUnorm = "bc1-rgba-unorm", + BC1RGBAUnormSRGB = "bc1-rgba-unorm-srgb", + BC2RGBAUnorm = "bc2-rgba-unorm", + BC2RGBAUnormSRGB = "bc2-rgba-unorm-srgb", + BC3RGBAUnorm = "bc3-rgba-unorm", + BC3RGBAUnormSRGB = "bc3-rgba-unorm-srgb", + BC4RUnorm = "bc4-r-unorm", + BC4RSnorm = "bc4-r-snorm", + BC5RGUnorm = "bc5-rg-unorm", + BC5RGSnorm = "bc5-rg-snorm", + BC6HRGBUFloat = "bc6h-rgb-ufloat", + BC6HRGBFloat = "bc6h-rgb-float", + BC7RGBAUnorm = "bc7-rgba-unorm", + BC7RGBAUnormSRGB = "bc7-rgba-srgb", + + // ETC2 compressed formats usable if 'texture-compression-etc2' is both + // supported by the device/user agent and enabled in requestDevice. + + ETC2RGB8Unorm = "etc2-rgb8unorm", + ETC2RGB8UnormSRGB = "etc2-rgb8unorm-srgb", + ETC2RGB8A1Unorm = "etc2-rgb8a1unorm", + ETC2RGB8A1UnormSRGB = "etc2-rgb8a1unorm-srgb", + ETC2RGBA8Unorm = "etc2-rgba8unorm", + ETC2RGBA8UnormSRGB = "etc2-rgba8unorm-srgb", + EACR11Unorm = "eac-r11unorm", + EACR11Snorm = "eac-r11snorm", + EACRG11Unorm = "eac-rg11unorm", + EACRG11Snorm = "eac-rg11snorm", + + // ASTC compressed formats usable if 'texture-compression-astc' is both + // supported by the device/user agent and enabled in requestDevice. + + ASTC4x4Unorm = "astc-4x4-unorm", + ASTC4x4UnormSRGB = "astc-4x4-unorm-srgb", + ASTC5x4Unorm = "astc-5x4-unorm", + ASTC5x4UnormSRGB = "astc-5x4-unorm-srgb", + ASTC5x5Unorm = "astc-5x5-unorm", + ASTC5x5UnormSRGB = "astc-5x5-unorm-srgb", + ASTC6x5Unorm = "astc-6x5-unorm", + ASTC6x5UnormSRGB = "astc-6x5-unorm-srgb", + ASTC6x6Unorm = "astc-6x6-unorm", + ASTC6x6UnormSRGB = "astc-6x6-unorm-srgb", + ASTC8x5Unorm = "astc-8x5-unorm", + ASTC8x5UnormSRGB = "astc-8x5-unorm-srgb", + ASTC8x6Unorm = "astc-8x6-unorm", + ASTC8x6UnormSRGB = "astc-8x6-unorm-srgb", + ASTC8x8Unorm = "astc-8x8-unorm", + ASTC8x8UnormSRGB = "astc-8x8-unorm-srgb", + ASTC10x5Unorm = "astc-10x5-unorm", + ASTC10x5UnormSRGB = "astc-10x5-unorm-srgb", + ASTC10x6Unorm = "astc-10x6-unorm", + ASTC10x6UnormSRGB = "astc-10x6-unorm-srgb", + ASTC10x8Unorm = "astc-10x8-unorm", + ASTC10x8UnormSRGB = "astc-10x8-unorm-srgb", + ASTC10x10Unorm = "astc-10x10-unorm", + ASTC10x10UnormSRGB = "astc-10x10-unorm-srgb", + ASTC12x10Unorm = "astc-12x10-unorm", + ASTC12x10UnormSRGB = "astc-12x10-unorm-srgb", + ASTC12x12Unorm = "astc-12x12-unorm", + ASTC12x12UnormSRGB = "astc-12x12-unorm-srgb", +} + +export enum GPUAddressMode { + ClampToEdge = "clamp-to-edge", + Repeat = "repeat", + MirrorRepeat = "mirror-repeat", +} + +export enum GPUFilterMode { + Linear = "linear", + Nearest = "nearest", +} + +export enum GPUBlendFactor { + Zero = "zero", + One = "one", + Src = "src", + OneMinusSrc = "one-minus-src", + SrcAlpha = "src-alpha", + OneMinusSrcAlpha = "one-minus-src-alpha", + Dst = "dst", + OneMinusDstColor = "one-minus-dst", + DstAlpha = "dst-alpha", + OneMinusDstAlpha = "one-minus-dst-alpha", + SrcAlphaSaturated = "src-alpha-saturated", + Constant = "constant", + OneMinusConstant = "one-minus-constant", +} + +export enum GPUBlendOperation { + Add = "add", + Subtract = "subtract", + ReverseSubtract = "reverse-subtract", + Min = "min", + Max = "max", +} + +export enum GPUColorWriteFlags { + None = 0, + Red = 0x1, + Green = 0x2, + Blue = 0x4, + Alpha = 0x8, + All = 0xF, +} + +export enum GPUStencilOperation { + Keep = "keep", + Zero = "zero", + Replace = "replace", + Invert = "invert", + IncrementClamp = "increment-clamp", + DecrementClamp = "decrement-clamp", + IncrementWrap = "increment-wrap", + DecrementWrap = "decrement-wrap", +} + +export enum GPUBufferBindingType { + Uniform = "uniform", + Storage = "storage", + ReadOnlyStorage = "read-only-storage", +} + +export enum GPUStorageTextureAccess { + WriteOnly = "write-only", + ReadOnly = "read-only", + ReadWrite = "read-write", +} + +export enum GPUSamplerBindingType { + Filtering = "filtering", + NonFiltering = "non-filtering", + Comparison = "comparison", +} + +export enum GPUTextureSampleType { + Float = "float", + UnfilterableFloat = "unfilterable-float", + Depth = "depth", + SInt = "sint", + UInt = "uint", +} + +export enum GPUTextureDimension { + OneD = "1d", + TwoD = "2d", + ThreeD = "3d", +} + +export enum GPUTextureViewDimension { + OneD = "1d", + TwoD = "2d", + TwoDArray = "2d-array", + Cube = "cube", + CubeArray = "cube-array", + ThreeD = "3d", +} + +export enum GPUTextureAspect { + All = "all", + StencilOnly = "stencil-only", + DepthOnly = "depth-only", +} + +export enum GPUInputStepMode { + Vertex = "vertex", + Instance = "instance", +} + +export enum GPUFeatureName { + DepthClipControl = "depth-clip-control", + Depth32FloatStencil8 = "depth32float-stencil8", + TextureCompressionBC = "texture-compression-bc", + TextureCompressionETC2 = "texture-compression-etc2", + TextureCompressionASTC = "texture-compression-astc", + TimestampQuery = "timestamp-query", + IndirectFirstInstance = "indirect-first-instance", + ShaderF16 = "shader-f16", + RG11B10UFloat = "rg11b10ufloat-renderable", + BGRA8UNormStorage = "bgra8unorm-storage", + Float32Filterable = "float32-filterable", +} diff --git a/src-testing/src/renderers/webxr/WebXRController.d.ts b/src-testing/src/renderers/webxr/WebXRController.d.ts new file mode 100644 index 000000000..956a036b4 --- /dev/null +++ b/src-testing/src/renderers/webxr/WebXRController.d.ts @@ -0,0 +1,63 @@ +import { Object3DEventMap } from "../../core/Object3D.js"; +import { Vector3 } from "../../math/Vector3.js"; +import { Group } from "../../objects/Group.js"; + +export type XRControllerEventType = XRSessionEventType | XRInputSourceEventType | "disconnected" | "connected"; + +export class XRJointSpace extends Group { + readonly jointRadius: number | undefined; +} + +export type XRHandJoints = Record; + +export interface XRHandInputState { + pinching: boolean; +} + +export interface WebXRSpaceEventMap extends Object3DEventMap { + select: { data: XRInputSource }; + selectstart: { data: XRInputSource }; + selectend: { data: XRInputSource }; + squeeze: { data: XRInputSource }; + squeezestart: { data: XRInputSource }; + squeezeend: { data: XRInputSource }; + + connected: { data: XRInputSource }; + disconnected: { data: XRInputSource }; + + pinchend: { handedness: XRHandedness; target: WebXRController }; // This Event break the THREE.EventDispatcher contract, replacing the target to the wrong instance. + pinchstart: { handedness: XRHandedness; target: WebXRController }; // This Event break the THREE.EventDispatcher contract, replacing the target to the wrong instance. + + move: {}; +} + +export class XRHandSpace extends Group { + readonly joints: Partial; + readonly inputState: XRHandInputState; +} + +export class XRTargetRaySpace extends Group { + hasLinearVelocity: boolean; + readonly linearVelocity: Vector3; + hasAngularVelocity: boolean; + readonly angularVelocity: Vector3; +} + +export class XRGripSpace extends Group { + hasLinearVelocity: boolean; + readonly linearVelocity: Vector3; + hasAngularVelocity: boolean; + readonly angularVelocity: Vector3; +} + +export class WebXRController { + constructor(); + + getHandSpace(): XRHandSpace; + getTargetRaySpace(): XRTargetRaySpace; + getGripSpace(): XRGripSpace; + dispatchEvent(event: { type: XRControllerEventType; data?: XRInputSource }): this; + connect(inputSource: XRInputSource): this; + disconnect(inputSource: XRInputSource): this; + update(inputSource: XRInputSource, frame: XRFrame, referenceSpace: XRReferenceSpace): this; +} diff --git a/src-testing/src/renderers/webxr/WebXRDepthSensing.d.ts b/src-testing/src/renderers/webxr/WebXRDepthSensing.d.ts new file mode 100644 index 000000000..23914f679 --- /dev/null +++ b/src-testing/src/renderers/webxr/WebXRDepthSensing.d.ts @@ -0,0 +1,22 @@ +import { Mesh } from "../../objects/Mesh.js"; +import { Texture } from "../../textures/Texture.js"; +import { WebGLRenderer } from "../WebGLRenderer.js"; +import { WebXRArrayCamera } from "./WebXRManager.js"; + +export class WebXRDepthSensing { + texture: Texture | null; + mesh: Mesh | null; + + depthNear: number; + depthFar: number; + + constructor(); + + init(renderer: WebGLRenderer, depthData: XRWebGLDepthInformation, renderState: XRRenderState): void; + + getMesh(cameraXR: WebXRArrayCamera): Mesh | null; + + reset(): void; + + getDepthTexture(): Texture | null; +} diff --git a/src-testing/src/renderers/webxr/WebXRManager.d.ts b/src-testing/src/renderers/webxr/WebXRManager.d.ts new file mode 100644 index 000000000..4b2073101 --- /dev/null +++ b/src-testing/src/renderers/webxr/WebXRManager.d.ts @@ -0,0 +1,85 @@ +/// + +import { ArrayCamera } from "../../cameras/ArrayCamera.js"; +import { PerspectiveCamera } from "../../cameras/PerspectiveCamera.js"; +import { EventDispatcher } from "../../core/EventDispatcher.js"; +import { Vector4 } from "../../math/Vector4.js"; +import { Mesh } from "../../objects/Mesh.js"; +import { Texture } from "../../textures/Texture.js"; +import { WebGLRenderer } from "../WebGLRenderer.js"; +import { XRGripSpace, XRHandSpace, XRTargetRaySpace } from "./WebXRController.js"; + +export type WebXRCamera = PerspectiveCamera & { viewport: Vector4 }; +export type WebXRArrayCamera = Omit & { cameras: [WebXRCamera, WebXRCamera] }; + +export interface WebXRManagerEventMap { + sessionstart: {}; + sessionend: {}; + planeadded: { data: XRPlane }; + planeremoved: { data: XRPlane }; + planechanged: { data: XRPlane }; + planesdetected: { data: XRPlaneSet }; +} + +export class WebXRManager extends EventDispatcher { + /** + * @default true + */ + cameraAutoUpdate: boolean; + + /** + * @default false + */ + enabled: boolean; + + /** + * @default false + */ + isPresenting: boolean; + + constructor(renderer: WebGLRenderer, gl: WebGLRenderingContext); + + getController: (index: number) => XRTargetRaySpace; + + getControllerGrip: (index: number) => XRGripSpace; + + getHand: (index: number) => XRHandSpace; + + setFramebufferScaleFactor: (value: number) => void; + + setReferenceSpaceType: (value: XRReferenceSpaceType) => void; + + getReferenceSpace: () => XRReferenceSpace | null; + + setReferenceSpace: (value: XRReferenceSpace) => void; + + getBaseLayer: () => XRWebGLLayer | XRProjectionLayer; + + getBinding: () => XRWebGLBinding; + + getFrame: () => XRFrame; + + getSession: () => XRSession | null; + + setSession: (value: XRSession | null) => Promise; + + getEnvironmentBlendMode: () => XREnvironmentBlendMode | undefined; + + getDepthTexture: () => Texture | null; + + updateCamera: (camera: PerspectiveCamera) => void; + + getCamera: () => WebXRArrayCamera; + + getFoveation: () => number | undefined; + + setFoveation: (value: number) => void; + + hasDepthSensing: () => boolean; + + getDepthSensingMesh: () => Mesh | null; + + setAnimationLoop: (callback: XRFrameRequestCallback | null) => void; + + dispose: () => void; +} diff --git a/src-testing/src/scenes/Fog.d.ts b/src-testing/src/scenes/Fog.d.ts new file mode 100644 index 000000000..fc0f18019 --- /dev/null +++ b/src-testing/src/scenes/Fog.d.ts @@ -0,0 +1,77 @@ +import { Color, ColorRepresentation } from "../math/Color.js"; + +export interface FogJSON { + type: string; + name: string; + color: number; + near: number; + far: number; +} + +/** + * This class contains the parameters that define linear fog, i.e., that grows linearly denser with the distance. + * @example + * ```typescript + * const scene = new THREE.Scene(); + * scene.fog = new THREE.Fog(0xcccccc, 10, 15); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/scenes/Fog | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/scenes/Fog.js | Source} + */ +export class Fog { + /** + * The color parameter is passed to the {@link THREE.Color | Color} constructor to set the color property + * @remarks + * Color can be a hexadecimal integer or a CSS-style string. + * @param color + * @param near Expects a `Float` + * @param far Expects a `Float` + */ + constructor(color: ColorRepresentation, near?: number, far?: number); + + /** + * Read-only flag to check if a given object is of type {@link Fog}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isFog: true; + + /** + * Optional name of the object + * @remarks _(doesn't need to be unique)_. + * @defaultValue `""` + */ + name: string; + + /** + * Fog color. + * @remarks If set to black, far away objects will be rendered black. + */ + color: Color; + + /** + * The minimum distance to start applying fog. + * @remarks Objects that are less than **near** units from the active camera won't be affected by fog. + * @defaultValue `1` + * @remarks Expects a `Float` + */ + near: number; + + /** + * The maximum distance at which fog stops being calculated and applied. + * @remarks Objects that are more than **far** units away from the active camera won't be affected by fog. + * @defaultValue `1000` + * @remarks Expects a `Float` + */ + far: number; + + /** + * Returns a new {@link Fog} instance with the same parameters as this one. + */ + clone(): Fog; + + /** + * Return {@link Fog} data in JSON format. + */ + toJSON(): FogJSON; +} diff --git a/src-testing/src/scenes/FogExp2.d.ts b/src-testing/src/scenes/FogExp2.d.ts new file mode 100644 index 000000000..af00981e6 --- /dev/null +++ b/src-testing/src/scenes/FogExp2.d.ts @@ -0,0 +1,66 @@ +import { Color, ColorRepresentation } from "../math/Color.js"; + +export interface FogExp2JSON { + type: string; + name: string; + color: number; + density: number; +} + +/** + * This class contains the parameters that define exponential squared fog, which gives a clear view near the camera and a faster than exponentially densening fog farther from the camera. + * @example + * ```typescript + * const scene = new THREE.Scene(); + * scene.fog = new THREE.FogExp2(0xcccccc, 0.002); + * ``` + * @see Example: {@link https://threejs.org/examples/#webgl_geometry_terrain | webgl geometry terrain} + * @see {@link https://threejs.org/docs/index.html#api/en/scenes/FogExp2 | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/scenes/FogExp2.js | Source} + */ +export class FogExp2 { + /** + * The color parameter is passed to the {@link THREE.Color | Color} constructor to set the color property + * @remarks Color can be a hexadecimal integer or a CSS-style string. + * @param color + * @param density Expects a `Float` + */ + constructor(color: ColorRepresentation, density?: number); + + /** + * Read-only flag to check if a given object is of type {@link FogExp2}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isFogExp2: true; + + /** + * Optional name of the object + * @remarks _(doesn't need to be unique)_. + * @defaultValue `""` + */ + name: string; + + /** + * Fog color. + * @remarks If set to black, far away objects will be rendered black. + */ + color: Color; + + /** + * Defines how fast the fog will grow dense. + * @defaultValue `0.00025` + * @remarks Expects a `Float` + */ + density: number; + + /** + * Returns a new {@link FogExp2} instance with the same parameters as this one. + */ + clone(): FogExp2; + + /** + * Return {@link FogExp2} data in JSON format. + */ + toJSON(): FogExp2JSON; +} diff --git a/src-testing/src/scenes/Scene.d.ts b/src-testing/src/scenes/Scene.d.ts new file mode 100644 index 000000000..c2f43afd7 --- /dev/null +++ b/src-testing/src/scenes/Scene.d.ts @@ -0,0 +1,118 @@ +import { JSONMeta, Object3D, Object3DJSON, Object3DJSONObject } from "../core/Object3D.js"; +import { Material } from "../materials/Material.js"; +import { Color } from "../math/Color.js"; +import { Euler, EulerTuple } from "../math/Euler.js"; +import { CubeTexture } from "../textures/CubeTexture.js"; +import { Texture } from "../textures/Texture.js"; +import { Fog, FogJSON } from "./Fog.js"; +import { FogExp2, FogExp2JSON } from "./FogExp2.js"; + +export interface SceneJSONObject extends Object3DJSONObject { + fog?: FogJSON | FogExp2JSON; + + backgroundBlurriness?: number; + backgroundIntensity?: number; + backgroundRotation: EulerTuple; + + environmentIntensity?: number; + environmentRotation: EulerTuple; +} + +export interface SceneJSON extends Object3DJSON { + object: SceneJSONObject; +} + +/** + * Scenes allow you to set up what and where is to be rendered by three.js + * @remarks + * This is where you place objects, lights and cameras. + * @see Example: {@link https://threejs.org/examples/#webgl_multiple_scenes_comparison | webgl multiple scenes comparison} + * @see {@link https://threejs.org/docs/index.html#manual/en/introduction/Creating-a-scene | Manual: Creating a scene} + * @see {@link https://threejs.org/docs/index.html#api/en/scenes/Scene | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/scenes/Scene.js | Source} + */ +export class Scene extends Object3D { + /** + * Create a new {@link Scene} object. + */ + constructor(); + + /** + * Read-only flag to check if a given object is of type {@link Scene}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isScene: true; + + /** + * @defaultValue `Scene` + */ + type: "Scene"; + + /** + * A {@link Fog | fog} instance defining the type of fog that affects everything rendered in the scene. + * @defaultValue `null` + */ + fog: Fog | FogExp2 | null; + + /** + * Sets the blurriness of the background. Only influences environment maps assigned to {@link THREE.Scene.background | Scene.background}. + * @defaultValue `0` + * @remarks Expects a `Float` between `0` and `1`. + */ + backgroundBlurriness: number; + + /** + * Attenuates the color of the background. Only applies to background textures. + * @defaultValue `1` + * @remarks Expects a `Float` + */ + backgroundIntensity: number; + + /** + * Forces everything in the {@link Scene} to be rendered with the defined material. + * @defaultValue `null` + */ + overrideMaterial: Material | null; + + /** + * Defines the background of the scene. + * @remarks Valid inputs are: + * - A {@link THREE.Color | Color} for defining a uniform colored background. + * - A {@link THREE.Texture | Texture} for defining a (flat) textured background. + * - Texture cubes ({@link THREE.CubeTexture | CubeTexture}) or equirectangular textures for defining a skybox. + * @defaultValue `null` + */ + background: Color | Texture | CubeTexture | null; + + /** + * The rotation of the background in radians. Only influences environment maps assigned to {@link .background}. + * Default is `(0,0,0)`. + */ + backgroundRotation: Euler; + + /** + * Sets the environment map for all physical materials in the scene. + * However, it's not possible to overwrite an existing texture assigned to {@link THREE.MeshStandardMaterial.envMap | MeshStandardMaterial.envMap}. + * @defaultValue `null` + */ + environment: Texture | null; + + /** + * Attenuates the color of the environment. Only influences environment maps assigned to {@link Scene.environment}. + * @default 1 + */ + environmentIntensity: number; + + /** + * The rotation of the environment map in radians. Only influences physical materials in the scene when + * {@link .environment} is used. Default is `(0,0,0)`. + */ + environmentRotation: Euler; + + /** + * Convert the {@link Scene} to three.js {@link https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 | JSON Object/Scene format}. + * @param meta Object containing metadata such as textures or images for the scene. + */ + toJSON(meta?: JSONMeta): SceneJSON; +} diff --git a/src-testing/src/textures/CanvasTexture.d.ts b/src-testing/src/textures/CanvasTexture.d.ts new file mode 100644 index 000000000..6445338fa --- /dev/null +++ b/src-testing/src/textures/CanvasTexture.d.ts @@ -0,0 +1,51 @@ +import { + MagnificationTextureFilter, + Mapping, + MinificationTextureFilter, + PixelFormat, + TextureDataType, + Wrapping, +} from "../constants.js"; +import { OffscreenCanvas, Texture } from "./Texture.js"; + +/** + * Creates a texture from a {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas | canvas element}. + * @remarks + * This is almost the same as the base {@link Texture | Texture} class, + * except that it sets {@link Texture.needsUpdate | needsUpdate} to `true` immediately. + * @see {@link THREE.Texture | Texture} + * @see {@link https://threejs.org/docs/index.html#api/en/textures/CanvasTexture | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/textures/CanvasTexture.js | Source} + */ +export class CanvasTexture extends Texture { + /** + * This creates a new {@link THREE.CanvasTexture | CanvasTexture} object. + * @param canvas The HTML canvas element from which to load the texture. + * @param mapping See {@link Texture.mapping | .mapping}. Default {@link THREE.Texture.DEFAULT_MAPPING} + * @param wrapS See {@link Texture.wrapS | .wrapS}. Default {@link THREE.ClampToEdgeWrapping} + * @param wrapT See {@link Texture.wrapT | .wrapT}. Default {@link THREE.ClampToEdgeWrapping} + * @param magFilter See {@link Texture.magFilter | .magFilter}. Default {@link THREE.LinearFilter} + * @param minFilter See {@link Texture.minFilter | .minFilter}. Default {@link THREE.LinearMipmapLinearFilter} + * @param format See {@link Texture.format | .format}. Default {@link THREE.RGBAFormat} + * @param type See {@link Texture.type | .type}. Default {@link THREE.UnsignedByteType} + * @param anisotropy See {@link Texture.anisotropy | .anisotropy}. Default {@link THREE.Texture.DEFAULT_ANISOTROPY} + */ + constructor( + canvas: TexImageSource | OffscreenCanvas, + mapping?: Mapping, + wrapS?: Wrapping, + wrapT?: Wrapping, + magFilter?: MagnificationTextureFilter, + minFilter?: MinificationTextureFilter, + format?: PixelFormat, + type?: TextureDataType, + anisotropy?: number, + ); + + /** + * Read-only flag to check if a given object is of type {@link CanvasTexture}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isCanvasTexture: true; +} diff --git a/src-testing/src/textures/CompressedArrayTexture.d.ts b/src-testing/src/textures/CompressedArrayTexture.d.ts new file mode 100644 index 000000000..e46c3d478 --- /dev/null +++ b/src-testing/src/textures/CompressedArrayTexture.d.ts @@ -0,0 +1,68 @@ +import { CompressedPixelFormat, TextureDataType, Wrapping } from "../constants.js"; +import { CompressedTexture, CompressedTextureMipmap } from "./CompressedTexture.js"; + +/** + * Creates an texture 2D array based on data in compressed form, for example from a + * {@link https://en.wikipedia.org/wiki/DirectDraw_Surface | DDS} file. + * @remarks For use with the {@link THREE.CompressedTextureLoader | CompressedTextureLoader}. + * @see {@link https://threejs.org/docs/index.html#api/en/textures/CompressedArrayTexture | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/textures/CompressedArrayTexture.js | Source} + */ +export class CompressedArrayTexture extends CompressedTexture { + /** + * Read-only flag to check if a given object is of type {@link CompressedArrayTexture}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isCompressedArrayTexture: true; + + /** + * Overridden with a object containing width and height. + * @override + */ + get image(): { width: number; height: number; depth: number }; + set image(value: { width: number; height: number; depth: number }); + + /** + * This defines how the texture is wrapped in the depth direction. + * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} + * @defaultValue {@link THREE.ClampToEdgeWrapping} + */ + wrapR: Wrapping; + + /** + * A set of all layers which need to be updated in the texture. See {@link CompressedArrayTexture.addLayerUpdate}. + */ + layerUpdates: Set; + + /** + * Create a new instance of {@link CompressedArrayTexture} + * @param mipmaps The mipmaps array should contain objects with data, width and height. The mipmaps should be of the + * correct format and type. + * @param width The width of the biggest mipmap. + * @param height The height of the biggest mipmap. + * @param depth The number of layers of the 2D array texture + * @param format The format used in the mipmaps. See {@link THREE.CompressedPixelFormat}. + * @param type See {@link Texture.type | .type}. Default {@link THREE.UnsignedByteType} + */ + constructor( + mipmaps: CompressedTextureMipmap[], + width: number, + height: number, + depth: number, + format: CompressedPixelFormat, + type?: TextureDataType, + ); + + /** + * Describes that a specific layer of the texture needs to be updated. Normally when {@link Texture.needsUpdate} is + * set to true, the entire compressed texture array is sent to the GPU. Marking specific layers will only transmit + * subsets of all mipmaps associated with a specific depth in the array which is often much more performant. + */ + addLayerUpdate(layerIndex: number): void; + + /** + * Resets the layer updates registry. See {@link CompressedArrayTexture.addLayerUpdate}. + */ + clearLayoutUpdates(): void; +} diff --git a/src-testing/src/textures/CompressedCubeTexture.d.ts b/src-testing/src/textures/CompressedCubeTexture.d.ts new file mode 100644 index 000000000..9c72145a0 --- /dev/null +++ b/src-testing/src/textures/CompressedCubeTexture.d.ts @@ -0,0 +1,13 @@ +import { CompressedPixelFormat, TextureDataType } from "../constants.js"; +import { CompressedTexture } from "./CompressedTexture.js"; + +export class CompressedCubeTexture extends CompressedTexture { + readonly isCompressedCubeTexture: true; + readonly isCubeTexture: true; + + constructor( + images: Array<{ width: number; height: number }>, + format?: CompressedPixelFormat, + type?: TextureDataType, + ); +} diff --git a/src-testing/src/textures/CompressedTexture.d.ts b/src-testing/src/textures/CompressedTexture.d.ts new file mode 100644 index 000000000..33ec5b17d --- /dev/null +++ b/src-testing/src/textures/CompressedTexture.d.ts @@ -0,0 +1,94 @@ +import { + CompressedPixelFormat, + MagnificationTextureFilter, + Mapping, + MinificationTextureFilter, + TextureDataType, + Wrapping, +} from "../constants.js"; +import { TypedArray } from "../core/BufferAttribute.js"; +import { Texture } from "./Texture.js"; + +export interface CompressedTextureMipmap { + data: TypedArray; + width: number; + height: number; +} + +/** + * Creates a texture based on data in compressed form, for example from a {@link https://en.wikipedia.org/wiki/DirectDraw_Surface | DDS} file. + * @remarks For use with the {@link THREE.CompressedTextureLoader | CompressedTextureLoader}. + * @see {@link https://threejs.org/docs/index.html#api/en/textures/CompressedTexture | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/textures/CompressedTexture.js | Source} + */ +export class CompressedTexture extends Texture { + /** + * This creates a new {@link THREE.CompressedTexture | CompressedTexture} object. + * @param mipmaps The mipmaps array should contain objects with data, width and height. The mipmaps should be of the + * correct format and type. + * @param width The width of the biggest mipmap. + * @param height The height of the biggest mipmap. + * @param format The format used in the mipmaps. See {@link THREE.CompressedPixelFormat}. + * @param type See {@link Texture.type | .type}. Default {@link THREE.UnsignedByteType} + * @param mapping See {@link Texture.mapping | .mapping}. Default {@link THREE.Texture.DEFAULT_MAPPING} + * @param wrapS See {@link Texture.wrapS | .wrapS}. Default {@link THREE.ClampToEdgeWrapping} + * @param wrapT See {@link Texture.wrapT | .wrapT}. Default {@link THREE.ClampToEdgeWrapping} + * @param magFilter See {@link Texture.magFilter | .magFilter}. Default {@link THREE.LinearFilter} + * @param minFilter See {@link Texture.minFilter | .minFilter}. Default {@link THREE.LinearMipmapLinearFilter} + * @param anisotropy See {@link Texture.anisotropy | .anisotropy}. Default {@link THREE.Texture.DEFAULT_ANISOTROPY} + * @param colorSpace See {@link Texture.colorSpace .colorSpace}. Default {@link NoColorSpace} + */ + constructor( + mipmaps?: CompressedTextureMipmap[], + width?: number, + height?: number, + format?: CompressedPixelFormat, + type?: TextureDataType, + mapping?: Mapping, + wrapS?: Wrapping, + wrapT?: Wrapping, + magFilter?: MagnificationTextureFilter, + minFilter?: MinificationTextureFilter, + anisotropy?: number, + colorSpace?: string, + ); + + /** + * Read-only flag to check if a given object is of type {@link CompressedTexture}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isCompressedTexture: true; + + /** + * Overridden with a object containing width and height. + * @override + */ + get image(): { width: number; height: number }; + set image(value: { width: number; height: number }); + + /** + * The mipmaps array should contain objects with data, width and height. The mipmaps should be of the correct + * format and type. + */ + mipmaps: CompressedTextureMipmap[] | undefined; + + /** + * @override + * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} + * @see {@link THREE.CompressedPixelFormat} + */ + format: CompressedPixelFormat; + + /** + * @override No flipping for cube textures. (also flipping doesn't work for compressed textures) + * @defaultValue `false` + */ + flipY: boolean; + + /** + * @override Can't generate mipmaps for compressed textures. mips must be embedded in DDS files + * @defaultValue `false` + */ + generateMipmaps: boolean; +} diff --git a/src-testing/src/textures/CubeTexture.d.ts b/src-testing/src/textures/CubeTexture.d.ts new file mode 100644 index 000000000..f5808aaf9 --- /dev/null +++ b/src-testing/src/textures/CubeTexture.d.ts @@ -0,0 +1,89 @@ +import { + CubeTextureMapping, + MagnificationTextureFilter, + MinificationTextureFilter, + PixelFormat, + TextureDataType, + Wrapping, +} from "../constants.js"; +import { Texture } from "./Texture.js"; + +/** + * Creates a cube texture made up of six images. + * @remarks + * {@link CubeTexture} is almost equivalent in functionality and usage to {@link Texture}. + * The only differences are that the images are an array of _6_ images as opposed to a single image, + * and the mapping options are {@link THREE.CubeReflectionMapping} (default) or {@link THREE.CubeRefractionMapping} + * @example + * ```typescript + * const loader = new THREE.CubeTextureLoader(); + * loader.setPath('textures/cube/pisa/'); + * const textureCube = loader.load(['px.png', 'nx.png', 'py.png', 'ny.png', 'pz.png', 'nz.png']); + * const material = new THREE.MeshBasicMaterial({ + * color: 0xffffff, + * envMap: textureCube + * }); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/textures/CubeTexture | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/textures/CubeTexture.js | Source} + */ +export class CubeTexture extends Texture { + /** + * This creates a new {@link THREE.CubeTexture | CubeTexture} object. + * @param images + * @param mapping See {@link CubeTexture.mapping | .mapping}. Default {@link THREE.CubeReflectionMapping} + * @param wrapS See {@link Texture.wrapS | .wrapS}. Default {@link THREE.ClampToEdgeWrapping} + * @param wrapT See {@link Texture.wrapT | .wrapT}. Default {@link THREE.ClampToEdgeWrapping} + * @param magFilter See {@link Texture.magFilter | .magFilter}. Default {@link THREE.LinearFilter} + * @param minFilter See {@link Texture.minFilter | .minFilter}. Default {@link THREE.LinearMipmapLinearFilter} + * @param format See {@link Texture.format | .format}. Default {@link THREE.RGBAFormat} + * @param type See {@link Texture.type | .type}. Default {@link THREE.UnsignedByteType} + * @param anisotropy See {@link Texture.anisotropy | .anisotropy}. Default {@link THREE.Texture.DEFAULT_ANISOTROPY} + * @param colorSpace See {@link Texture.colorSpace | .colorSpace}. Default {@link NoColorSpace} + */ + constructor( + images?: any[], // HTMLImageElement or HTMLCanvasElement + mapping?: CubeTextureMapping, + wrapS?: Wrapping, + wrapT?: Wrapping, + magFilter?: MagnificationTextureFilter, + minFilter?: MinificationTextureFilter, + format?: PixelFormat, + type?: TextureDataType, + anisotropy?: number, + colorSpace?: string, + ); + + /** + * Read-only flag to check if a given object is of type {@link CubeTexture}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isCubeTexture: true; + + /** + * An image object, typically created using the {@link THREE.CubeTextureLoader.load | CubeTextureLoader.load()} method. + * @see {@link Texture.image} + */ + get image(): any; + set image(data: any); + + /** + * An image object, typically created using the {@link THREE.CubeTextureLoader.load | CubeTextureLoader.load()} method. + * @see {@link Texture.image} + */ + get images(): any; + set images(data: any); + + /** + * @inheritDoc + * @defaultValue {@link THREE.CubeReflectionMapping} + */ + mapping: CubeTextureMapping; + + /** + * @inheritDoc + * @defaultValue `false` + */ + flipY: boolean; +} diff --git a/src-testing/src/textures/Data3DTexture.d.ts b/src-testing/src/textures/Data3DTexture.d.ts new file mode 100644 index 000000000..9e5986eed --- /dev/null +++ b/src-testing/src/textures/Data3DTexture.d.ts @@ -0,0 +1,96 @@ +import { MagnificationTextureFilter, MinificationTextureFilter, Wrapping } from "../constants.js"; +import { Texture } from "./Texture.js"; +import { Texture3DImageData } from "./types.js"; + +/** + * Creates a three-dimensional texture from raw data, with parameters to divide it into width, height, and depth + * @example + * ```typescript + * This creates a[name] with repeating data, 0 to 255 + * // create a buffer with some data + * const sizeX = 64; + * const sizeY = 64; + * const sizeZ = 64; + * const data = new Uint8Array(sizeX * sizeY * sizeZ); + * let i = 0; + * for (let z = 0; z & lt; sizeZ; z++) { + * for (let y = 0; y & lt; sizeY; y++) { + * for (let x = 0; x & lt; sizeX; x++) { + * data[i] = i % 256; + * i++; + * } + * } + * } + * // use the buffer to create the texture + * const texture = new THREE.Data3DTexture(data, sizeX, sizeY, sizeZ); + * texture.needsUpdate = true; + * ``` + * @see Example: {@link https://threejs.org/examples/#webgl2_materials_texture3d | WebGL2 / materials / texture3d} + * @see Example: {@link https://threejs.org/examples/#webgl2_materials_texture3d_partialupdate | WebGL2 / materials / texture3d / partialupdate} + * @see Example: {@link https://threejs.org/examples/#webgl2_volume_cloud | WebGL2 / volume / cloud} + * @see Example: {@link https://threejs.org/examples/#webgl2_volume_perlin | WebGL2 / volume / perlin} + * @see {@link https://threejs.org/docs/index.html#api/en/textures/Data3DTexture | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/textures/Data3DTexture.js | Source} + */ +export class Data3DTexture extends Texture { + /** + * Create a new instance of {@link Data3DTexture} + * @param data {@link https://developer.mozilla.org/en-US/docs/Web/API/ArrayBufferView | ArrayBufferView} of the texture. Default `null`. + * @param width Width of the texture. Default `1`. + * @param height Height of the texture. Default `1`. + * @param depth Depth of the texture. Default `1`. + */ + constructor(data?: BufferSource | null, width?: number, height?: number, depth?: number); + + /** + * Read-only flag to check if a given object is of type {@link Data3DTexture}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isData3DTexture: true; + + /** + * Overridden with a record type holding data, width and height and depth. + * @override + */ + get image(): Texture3DImageData; + set image(data: Texture3DImageData); + + /** + * @override + * @defaultValue {@link THREE.NearestFilter} + */ + magFilter: MagnificationTextureFilter; + + /** + * @override + * @defaultValue {@link THREE.NearestFilter} + */ + minFilter: MinificationTextureFilter; + + /** + * @override + * @defaultValue {@link THREE.ClampToEdgeWrapping} + */ + wrapR: Wrapping; + + /** + * @override + * @defaultValue `false` + */ + flipY: boolean; + + /** + * @override + * @defaultValue `false` + */ + generateMipmaps: boolean; + + /** + * @override + * @defaultValue `1` + */ + unpackAlignment: number; +} + +export {}; diff --git a/src-testing/src/textures/DataArrayTexture.d.ts b/src-testing/src/textures/DataArrayTexture.d.ts new file mode 100644 index 000000000..d3a82c1e8 --- /dev/null +++ b/src-testing/src/textures/DataArrayTexture.d.ts @@ -0,0 +1,123 @@ +import { MagnificationTextureFilter, MinificationTextureFilter } from "../constants.js"; +import { Texture } from "./Texture.js"; +import { Texture3DImageData } from "./types.js"; + +/** + * Creates an array of textures directly from raw data, width and height and depth + * @example + * ```typescript + * This creates a[name] where each texture has a different color. + * // create a buffer with color data + * const width = 512; + * const height = 512; + * const depth = 100; + * const size = width * height; + * const data = new Uint8Array(4 * size * depth); + * for (let i = 0; i & lt; depth; i++) { + * const color = new THREE.Color(Math.random(), Math.random(), Math.random()); + * const r = Math.floor(color.r * 255); + * const g = Math.floor(color.g * 255); + * const b = Math.floor(color.b * 255); + * for (let j = 0; j & lt; size; j++) { + * const stride = (i * size + j) * 4; + * data[stride] = r; + * data[stride + 1] = g; + * data[stride + 2] = b; + * data[stride + 3] = 255; + * } + * } + * // used the buffer to create a [name] + * const texture = new THREE.DataArrayTexture(data, width, height, depth); + * texture.needsUpdate = true; + * ``` + * @see Example: {@link https://threejs.org/examples/#webgl2_materials_texture2darray | WebGL2 / materials / texture2darray} + * @see Example: {@link https://threejs.org/examples/#webgl2_rendertarget_texture2darray | WebGL2 / rendertarget / texture2darray} + * @see {@link https://threejs.org/docs/index.html#api/en/textures/DataArrayTexture | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/textures/DataArrayTexture.js | Source} + */ +export class DataArrayTexture extends Texture { + /** + * Read-only flag to check if a given object is of type {@link DataArrayTexture}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isDataArrayTexture: true; + + /** + * Overridden with a record type holding data, width and height and depth. + * @override + */ + get image(): Texture3DImageData; + set image(data: Texture3DImageData); + + /** + * @override + * @defaultValue {@link THREE.NearestFilter} + */ + magFilter: MagnificationTextureFilter; + + /** + * @override + * @defaultValue {@link THREE.NearestFilter} + */ + minFilter: MinificationTextureFilter; + + /** + * @override + * @defaultValue {@link THREE.ClampToEdgeWrapping} + */ + wrapR: boolean; + + /** + * @override + * @defaultValue `false` + */ + generateMipmaps: boolean; + + /** + * @override + * @defaultValue `false` + */ + flipY: boolean; + + /** + * @override + * @defaultValue `1` + */ + unpackAlignment: number; + + /** + * A set of all layers which need to be updated in the texture. See {@link DataArrayTexture.addLayerUpdate}. + */ + layerUpdates: Set; + + /** + * This creates a new {@link THREE.DataArrayTexture | DataArrayTexture} object. + * @remarks The interpretation of the data depends on {@link format} and {@link type}. + * @remarks If the {@link type} is {@link THREE.UnsignedByteType}, a {@link Uint8Array} will be useful for addressing the texel data + * @remarks If the {@link format} is {@link THREE.RGBAFormat}, data needs four values for one texel; Red, Green, Blue and Alpha (typically the opacity). + * @remarks For the packed {@link type | types}, {@link THREE.UnsignedShort4444Type} and {@link THREE.UnsignedShort5551Type} + * all color components of one texel can be addressed as bitfields within an integer element of a {@link Uint16Array}. + * @remarks In order to use the {@link type | types} {@link THREE.FloatType} and {@link THREE.HalfFloatType}, + * the WebGL implementation must support the respective extensions _OES_texture_float_ and _OES_texture_half_float_ + * @remarks In order to use {@link THREE.LinearFilter} for component-wise, bilinear interpolation of the texels based on these types, + * the WebGL extensions _OES_texture_float_linear_ or _OES_texture_half_float_linear_ must also be present. + * @param data {@link https://developer.mozilla.org/en-US/docs/Web/API/ArrayBufferView | ArrayBufferView} of the texture. Default `null`. + * @param width Width of the texture. Default `1`. + * @param height Height of the texture. Default `1`. + * @param depth Depth of the texture. Default `1`. + */ + constructor(data?: BufferSource | null, width?: number, height?: number, depth?: number); + + /** + * Describes that a specific layer of the texture needs to be updated. Normally when {@link Texture.needsUpdate} is + * set to true, the entire compressed texture array is sent to the GPU. Marking specific layers will only transmit + * subsets of all mipmaps associated with a specific depth in the array which is often much more performant. + */ + addLayerUpdate(layerIndex: number): void; + + /** + * Resets the layer updates registry. See {@link DataArrayTexture.addLayerUpdate}. + */ + clearLayoutUpdates(): void; +} diff --git a/src-testing/src/textures/DataTexture.d.ts b/src-testing/src/textures/DataTexture.d.ts new file mode 100644 index 000000000..605450990 --- /dev/null +++ b/src-testing/src/textures/DataTexture.d.ts @@ -0,0 +1,112 @@ +import { + MagnificationTextureFilter, + Mapping, + MinificationTextureFilter, + PixelFormat, + TextureDataType, + Wrapping, +} from "../constants.js"; +import { Texture } from "./Texture.js"; +import { TextureImageData } from "./types.js"; + +/** + * Creates a texture directly from raw data, width and height. + * @example + * ```typescript + * // create a buffer with color data + * const width = 512; + * const height = 512; + * const size = width * height; + * const data = new Uint8Array(4 * size); + * const color = new THREE.Color(0xffffff); + * const r = Math.floor(color.r * 255); + * const g = Math.floor(color.g * 255); + * const b = Math.floor(color.b * 255); + * for (let i = 0; i & lt; size; i++) { + * const stride = i * 4; + * data[stride] = r; + * data[stride + 1] = g; + * data[stride + 2] = b; + * data[stride + 3] = 255; + * } + * // used the buffer to create a [name] + * const texture = new THREE.DataTexture(data, width, height); + * texture.needsUpdate = true; + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/textures/DataTexture | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/textures/DataTexture.js | Source} + */ +export class DataTexture extends Texture { + /** + * @param data {@link https://developer.mozilla.org/en-US/docs/Web/API/ArrayBufferView | ArrayBufferView} of the texture. Default `null`. + * @param width Width of the texture. Default `1`. + * @param height Height of the texture. Default `1`. + * @param format See {@link Texture.format | .format}. Default {@link THREE.RGBAFormat} + * @param type See {@link Texture.type | .type}. Default {@link THREE.UnsignedByteType} + * @param mapping See {@link Texture.mapping | .mapping}. Default {@link THREE.Texture.DEFAULT_MAPPING} + * @param wrapS See {@link Texture.wrapS | .wrapS}. Default {@link THREE.ClampToEdgeWrapping} + * @param wrapT See {@link Texture.wrapT | .wrapT}. Default {@link THREE.ClampToEdgeWrapping} + * @param magFilter See {@link Texture.magFilter | .magFilter}. Default {@link THREE.NearestFilter} + * @param minFilter See {@link Texture.minFilter | .minFilter}. Default {@link THREE.NearestFilter} + * @param anisotropy See {@link Texture.anisotropy | .anisotropy}. Default {@link THREE.Texture.DEFAULT_ANISOTROPY} + * @param colorSpace See {@link Texture.colorSpace | .colorSpace}. Default {@link NoColorSpace} + */ + constructor( + data?: BufferSource | null, + width?: number, + height?: number, + format?: PixelFormat, + type?: TextureDataType, + mapping?: Mapping, + wrapS?: Wrapping, + wrapT?: Wrapping, + magFilter?: MagnificationTextureFilter, + minFilter?: MinificationTextureFilter, + anisotropy?: number, + colorSpace?: string, + ); + + /** + * Read-only flag to check if a given object is of type {@link DataTexture}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isDataTexture: true; + + /** + * Overridden with a record type holding data, width and height and depth. + * @override + */ + get image(): TextureImageData; + set image(value: TextureImageData); + + /** + * @override + * @defaultValue {@link THREE.NearestFilter} + */ + magFilter: MagnificationTextureFilter; + + /** + * @override + * @defaultValue {@link THREE.NearestFilter} + */ + minFilter: MinificationTextureFilter; + + /** + * @override + * @defaultValue `false` + */ + flipY: boolean; + + /** + * @override + * @defaultValue `false` + */ + generateMipmaps: boolean; + + /** + * @override + * @defaultValue `1` + */ + unpackAlignment: number; +} diff --git a/src-testing/src/textures/DepthTexture.d.ts b/src-testing/src/textures/DepthTexture.d.ts new file mode 100644 index 000000000..f524e91cc --- /dev/null +++ b/src-testing/src/textures/DepthTexture.d.ts @@ -0,0 +1,104 @@ +import { + DepthTexturePixelFormat, + MagnificationTextureFilter, + Mapping, + MinificationTextureFilter, + TextureComparisonFunction, + TextureDataType, + Wrapping, +} from "../constants.js"; +import { Texture } from "./Texture.js"; + +/** + * This class can be used to automatically save the depth information of a rendering into a texture + * @see Example: {@link https://threejs.org/examples/#webgl_depth_texture | depth / texture} + * @see {@link https://threejs.org/docs/index.html#api/en/textures/DepthTexture | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/textures/DepthTexture.js | Source} + */ +export class DepthTexture extends Texture { + /** + * Create a new instance of {@link DepthTexture} + * @param width Width of the texture. + * @param height Height of the texture. + * @param type See {@link Texture.type | .type}. Default {@link THREE.UnsignedByteType} or {@link THREE.UnsignedInt248Type} + * @param mapping See {@link Texture.mapping | .mapping}. Default {@link THREE.Texture.DEFAULT_MAPPING} + * @param wrapS See {@link Texture.wrapS | .wrapS}. Default {@link THREE.ClampToEdgeWrapping} + * @param wrapT See {@link Texture.wrapT | .wrapT}. Default {@link THREE.ClampToEdgeWrapping} + * @param magFilter See {@link Texture.magFilter | .magFilter}. Default {@link THREE.NearestFilter} + * @param minFilter See {@link Texture.minFilter | .minFilter}. Default {@link THREE.NearestFilter} + * @param anisotropy See {@link Texture.anisotropy | .anisotropy}. Default {@link THREE.Texture.DEFAULT_ANISOTROPY} + * @param format See {@link DepthTexture.format | .format}. Default {@link THREE.DepthFormat} + */ + constructor( + width: number, + height: number, + type?: TextureDataType, + mapping?: Mapping, + wrapS?: Wrapping, + wrapT?: Wrapping, + magFilter?: MagnificationTextureFilter, + minFilter?: MinificationTextureFilter, + anisotropy?: number, + format?: DepthTexturePixelFormat, + ); + + /** + * Read-only flag to check if a given object is of type {@link DepthTexture}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isDepthTexture: true; + + /** + * Overridden with a record type holding width and height. + * @override + */ + get image(): { width: number; height: number }; + set image(value: { width: number; height: number }); + + /** + * @override + * @defaultValue `false` + */ + flipY: boolean; + + /** + * @override + * @defaultValue {@link THREE.NearestFilter} + */ + magFilter: MagnificationTextureFilter; + + /** + * @override + * @defaultValue {@link THREE.NearestFilter} + */ + minFilter: MinificationTextureFilter; + + /** + * @override Depth textures do not use mipmaps. + * @defaultValue `false` + */ + generateMipmaps: boolean; + + /** + * @override + * @see {@link Texture.format | Texture.format} + * @defaultValue {@link THREE.DepthFormat}. + */ + format: DepthTexturePixelFormat; + + /** + * @override + * @defaultValue {@link THREE.UnsignedByteType} when {@link format | .format} === {@link THREE.DepthFormat} + * @defaultValue {@link THREE.UnsignedInt248Type} when {@link format | .format} === {@link THREE.DepthStencilFormat} + */ + type: TextureDataType; + + /** + * This is used to define the comparison function used when comparing texels in the depth texture to the value in + * the depth buffer. Default is `null` which means comparison is disabled. + * + * See {@link THREE.TextureComparisonFunction} for functions. + */ + compareFunction: TextureComparisonFunction | null; +} diff --git a/src-testing/src/textures/FramebufferTexture.d.ts b/src-testing/src/textures/FramebufferTexture.d.ts new file mode 100644 index 000000000..ad54c5175 --- /dev/null +++ b/src-testing/src/textures/FramebufferTexture.d.ts @@ -0,0 +1,62 @@ +import { MagnificationTextureFilter, MinificationTextureFilter } from "../constants.js"; +import { Texture } from "./Texture.js"; + +/** + * This class can only be used in combination with {@link THREE.WebGLRenderer.copyFramebufferToTexture | WebGLRenderer.copyFramebufferToTexture()}. + * @example + * ```typescript + * const pixelRatio = window.devicePixelRatio; + * const textureSize = 128 * pixelRatio; + * + * // instantiate a framebuffer texture + * const frameTexture = new FramebufferTexture( textureSize, textureSize, RGBAFormat ); + * + * // calculate start position for copying part of the frame data + * const vector = new Vector2(); + * vector.x = ( window.innerWidth * pixelRatio / 2 ) - ( textureSize / 2 ); + * vector.y = ( window.innerHeight * pixelRatio / 2 ) - ( textureSize / 2 ); + * + * // render the scene + * renderer.clear(); + * renderer.render( scene, camera ); + * + * // copy part of the rendered frame into the framebuffer texture + * renderer.copyFramebufferToTexture( frameTexture, vector ); + * ``` + * @see Example: {@link https://threejs.org/examples/#webgl_framebuffer_texture | webgl_framebuffer_texture} + * @see {@link https://threejs.org/docs/index.html#api/en/textures/FramebufferTexture | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/textures/FramebufferTexture.js | Source} + */ +export class FramebufferTexture extends Texture { + /** + * Create a new instance of {@link FramebufferTexture} + * @param width The width of the texture. + * @param height The height of the texture. + */ + constructor(width: number, height: number); + + /** + * Read-only flag to check if a given object is of type {@link FramebufferTexture}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isFramebufferTexture: true; + + /** + * @override + * @defaultValue {@link THREE.NearestFilter} + */ + magFilter: MagnificationTextureFilter; + + /** + * @override + * @defaultValue {@link THREE.NearestFilter} + */ + minFilter: MinificationTextureFilter; + + /** + * @override + * @defaultValue `false` + */ + generateMipmaps: boolean; +} diff --git a/src-testing/src/textures/Source.d.ts b/src-testing/src/textures/Source.d.ts new file mode 100644 index 000000000..404d1d8a1 --- /dev/null +++ b/src-testing/src/textures/Source.d.ts @@ -0,0 +1,75 @@ +export type SerializedImage = + | string + | { + data: number[]; + width: number; + height: number; + type: string; + }; + +export class SourceJSON { + uuid: string; + url: SerializedImage | SerializedImage[]; +} + +/** + * Represents the data {@link Source} of a texture. + * @see {@link https://threejs.org/docs/index.html#api/en/textures/Source | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/textures/Source.js | Source} + */ +export class Source { + /** + * Create a new instance of {@link Source} + * @param data The data definition of a texture. Default `null` + */ + constructor(data: any); + + /** + * Flag to check if a given object is of type {@link Source}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isSource: true; + + readonly id: number; + + /** + * The actual data of a texture. + * @remarks The type of this property depends on the texture that uses this instance. + */ + data: any; + + /** + * This property is only relevant when {@link .needsUpdate} is set to `true` and provides more control on how + * texture data should be processed. + * When `dataReady` is set to `false`, the engine performs the memory allocation (if necessary) but does not + * transfer the data into the GPU memory. + * @default true + */ + dataReady: boolean; + + /** + * When the property is set to `true`, the engine allocates the memory for the texture (if necessary) and triggers + * the actual texture upload to the GPU next time the source is used. + */ + set needsUpdate(value: boolean); + + /** + * {@link http://en.wikipedia.org/wiki/Universally_unique_identifier | UUID} of this object instance. + * @remarks This gets automatically assigned and shouldn't be edited. + */ + uuid: string; + + /** + * This starts at `0` and counts how many times {@link needsUpdate | .needsUpdate} is set to `true`. + * @remarks Expects a `Integer` + * @defaultValue `0` + */ + version: number; + + /** + * Convert the data {@link Source} to three.js {@link https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 | JSON Object/Scene format}. + * @param meta Optional object containing metadata. + */ + toJSON(meta?: string | {}): SourceJSON; +} diff --git a/src-testing/src/textures/Texture.d.ts b/src-testing/src/textures/Texture.d.ts new file mode 100644 index 000000000..2dc33c5d1 --- /dev/null +++ b/src-testing/src/textures/Texture.d.ts @@ -0,0 +1,476 @@ +import { + AnyMapping, + AnyPixelFormat, + MagnificationTextureFilter, + Mapping, + MinificationTextureFilter, + PixelFormat, + PixelFormatGPU, + TextureDataType, + Wrapping, +} from "../constants.js"; +import { EventDispatcher } from "../core/EventDispatcher.js"; +import { Matrix3 } from "../math/Matrix3.js"; +import { Vector2 } from "../math/Vector2.js"; +import { CompressedTextureMipmap } from "./CompressedTexture.js"; +import { CubeTexture } from "./CubeTexture.js"; +import { Source } from "./Source.js"; + +export interface TextureJSON { + metadata: { version: number; type: string; generator: string }; + + uuid: string; + name: string; + + image: string; + + mapping: AnyMapping; + channel: number; + + repeat: [x: number, y: number]; + offset: [x: number, y: number]; + center: [x: number, y: number]; + rotation: number; + + wrap: [wrapS: number, wrapT: number]; + + format: AnyPixelFormat; + internalFormat: PixelFormatGPU | null; + type: TextureDataType; + colorSpace: string; + + minFilter: MinificationTextureFilter; + magFilter: MagnificationTextureFilter; + anisotropy: number; + + flipY: boolean; + + generateMipmaps: boolean; + premultiplyAlpha: boolean; + unpackAlignment: number; + + userData?: Record; +} + +/** Shim for OffscreenCanvas. */ +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface OffscreenCanvas extends EventTarget {} + +/** + * Create a {@link Texture} to apply to a surface or as a reflection or refraction map. + * @remarks + * After the initial use of a texture, its **dimensions**, {@link format}, and {@link type} cannot be changed + * Instead, call {@link dispose | .dispose()} on the {@link Texture} and instantiate a new {@link Texture}. + * @example + * ```typescript + * // load a texture, set wrap mode to repeat + * const texture = new THREE.TextureLoader().load("textures/water.jpg"); + * texture.wrapS = THREE.RepeatWrapping; + * texture.wrapT = THREE.RepeatWrapping; + * texture.repeat.set(4, 4); + * ``` + * @see Example: {@link https://threejs.org/examples/#webgl_materials_texture_filters | webgl materials texture filters} + * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} + * @see {@link https://threejs.org/docs/index.html#api/en/textures/Texture | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/Textures/Texture.js | Source} + */ +export class Texture extends EventDispatcher<{ dispose: {} }> { + /** + * This creates a new {@link THREE.Texture | Texture} object. + * @param image See {@link Texture.image | .image}. Default {@link THREE.Texture.DEFAULT_IMAGE} + * @param mapping See {@link Texture.mapping | .mapping}. Default {@link THREE.Texture.DEFAULT_MAPPING} + * @param wrapS See {@link Texture.wrapS | .wrapS}. Default {@link THREE.ClampToEdgeWrapping} + * @param wrapT See {@link Texture.wrapT | .wrapT}. Default {@link THREE.ClampToEdgeWrapping} + * @param magFilter See {@link Texture.magFilter | .magFilter}. Default {@link THREE.LinearFilter} + * @param minFilter See {@link Texture.minFilter | .minFilter}. Default {@link THREE.LinearMipmapLinearFilter} + * @param format See {@link Texture.format | .format}. Default {@link THREE.RGBAFormat} + * @param type See {@link Texture.type | .type}. Default {@link THREE.UnsignedByteType} + * @param anisotropy See {@link Texture.anisotropy | .anisotropy}. Default {@link THREE.Texture.DEFAULT_ANISOTROPY} + * @param colorSpace See {@link Texture.colorSpace | .colorSpace}. Default {@link THREE.NoColorSpace} + */ + constructor( + image?: TexImageSource | OffscreenCanvas, + mapping?: Mapping, + wrapS?: Wrapping, + wrapT?: Wrapping, + magFilter?: MagnificationTextureFilter, + minFilter?: MinificationTextureFilter, + format?: PixelFormat, + type?: TextureDataType, + anisotropy?: number, + colorSpace?: string, + ); + + /** + * @deprecated + */ + constructor( + image: TexImageSource | OffscreenCanvas, + mapping: Mapping, + wrapS: Wrapping, + wrapT: Wrapping, + magFilter: MagnificationTextureFilter, + minFilter: MinificationTextureFilter, + format: PixelFormat, + type: TextureDataType, + anisotropy: number, + ); + + /** + * Read-only flag to check if a given object is of type {@link Texture}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isTexture: true; + + /** + * Unique number for this {@link Texture} instance. + * @remarks Note that ids are assigned in chronological order: 1, 2, 3, ..., incrementing by one for each new object. + * @remarks Expects a `Integer` + */ + readonly id: number; + + /** + * {@link http://en.wikipedia.org/wiki/Universally_unique_identifier | UUID} of this object instance. + * @remarks This gets automatically assigned and shouldn't be edited. + */ + uuid: string; + + /** + * Optional name of the object + * @remarks _(doesn't need to be unique)_. + * @defaultValue `""` + */ + name: string; + + /** + * The data definition of a texture. A reference to the data source can be shared across textures. + * This is often useful in context of spritesheets where multiple textures render the same data + * but with different {@link Texture} transformations. + */ + source: Source; + + /** + * An image object, typically created using the {@link THREE.TextureLoader.load | TextureLoader.load()} method. + * @remarks This can be any image (e.g., PNG, JPG, GIF, DDS) or video (e.g., MP4, OGG/OGV) type supported by three.js. + * @remarks To use video as a {@link Texture} you need to have a playing HTML5 video element as a source + * for your {@link Texture} image and continuously update this {@link Texture} + * as long as video is playing - the {@link THREE.VideoTexture | VideoTexture} class handles this automatically. + */ + get image(): any; + set image(data: any); + + /** + * Array of user-specified mipmaps + * @defaultValue `[]` + */ + mipmaps: CompressedTextureMipmap[] | CubeTexture[] | HTMLCanvasElement[] | undefined; + + /** + * How the image is applied to the object. + * @remarks All {@link Texture} types except {@link THREE.CubeTexture} expect the _values_ be {@link THREE.Mapping} + * @remarks {@link CubeTexture} expect the _values_ be {@link THREE.CubeTextureMapping} + * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} + * @defaultValue _value of_ {@link THREE.Texture.DEFAULT_MAPPING} + */ + mapping: AnyMapping; + + /** + * Lets you select the uv attribute to map the texture to. `0` for `uv`, `1` for `uv1`, `2` for `uv2` and `3` for + * `uv3`. + */ + channel: number; + + /** + * This defines how the {@link Texture} is wrapped *horizontally* and corresponds to **U** in UV mapping. + * @remarks for **WEBGL1** - tiling of images in textures only functions if image dimensions are powers of two + * (2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, ...) in terms of pixels. + * Individual dimensions need not be equal, but each must be a power of two. This is a limitation of WebGL1, not three.js. + * **WEBGL2** does not have this limitation. + * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} + * @see {@link wrapT} + * @see {@link repeat} + * @defaultValue {@link THREE.ClampToEdgeWrapping} + */ + wrapS: Wrapping; + + /** + * This defines how the {@link Texture} is wrapped *vertically* and corresponds to **V** in UV mapping. + * @remarks for **WEBGL1** - tiling of images in textures only functions if image dimensions are powers of two + * (2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, ...) in terms of pixels. + * Individual dimensions need not be equal, but each must be a power of two. This is a limitation of WebGL1, not three.js. + * **WEBGL2** does not have this limitation. + * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} + * @see {@link wrapS} + * @see {@link repeat} + * @defaultValue {@link THREE.ClampToEdgeWrapping} + */ + wrapT: Wrapping; + + /** + * How the {@link Texture} is sampled when a texel covers more than one pixel. + * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} + * @see {@link minFilter} + * @see {@link THREE.MagnificationTextureFilter} + * @defaultValue {@link THREE.LinearFilter} + */ + magFilter: MagnificationTextureFilter; + + /** + * How the {@link Texture} is sampled when a texel covers less than one pixel. + * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} + * @see {@link magFilter} + * @see {@link THREE.MinificationTextureFilter} + * @defaultValue {@link THREE.LinearMipmapLinearFilter} + */ + minFilter: MinificationTextureFilter; + + /** + * The number of samples taken along the axis through the pixel that has the highest density of texels. + * @remarks A higher value gives a less blurry result than a basic mipmap, at the cost of more {@link Texture} samples being used. + * @remarks Use {@link THREE.WebGLCapabilities.getMaxAnisotropy() | renderer.capabilities.getMaxAnisotropy()} to find the maximum valid anisotropy value for the GPU; + * @remarks This value is usually a power of 2. + * @default _value of_ {@link THREE.Texture.DEFAULT_ANISOTROPY}. That is normally `1`. + */ + anisotropy: number; + + /** + * These define how elements of a 2D texture, or texels, are read by shaders. + * @remarks All {@link Texture} types except {@link THREE.DepthTexture} and {@link THREE.CompressedPixelFormat} expect the _values_ be {@link THREE.PixelFormat} + * @remarks {@link DepthTexture} expect the _values_ be {@link THREE.CubeTextureMapping} + * @remarks {@link CompressedPixelFormat} expect the _values_ be {@link THREE.CubeTextureMapping} + * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} + * @see {@link THREE.PixelFormat} + * @defaultValue {@link THREE.RGBAFormat}. + */ + format: AnyPixelFormat; + + /** + * This must correspond to the {@link Texture.format | .format}. + * @remarks {@link THREE.UnsignedByteType}, is the type most used by Texture formats. + * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} + * @see {@link THREE.TextureDataType} + * @defaultValue {@link THREE.UnsignedByteType} + */ + type: TextureDataType; + + /** + * The GPU Pixel Format allows the developer to specify how the data is going to be stored on the GPU. + * @remarks Compatible only with {@link WebGL2RenderingContext | WebGL 2 Rendering Context}. + * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} + * @defaultValue The default value is obtained using a combination of {@link Texture.format | .format} and {@link Texture.type | .type}. + */ + internalFormat: PixelFormatGPU | null; + + /** + * The uv-transform matrix for the texture. + * @remarks + * When {@link Texture.matrixAutoUpdate | .matrixAutoUpdate} property is `true`. + * Will be updated by the renderer from the properties: + * - {@link Texture.offset | .offset} + * - {@link Texture.repeat | .repeat} + * - {@link Texture.rotation | .rotation} + * - {@link Texture.center | .center} + * @remarks + * When {@link Texture.matrixAutoUpdate | .matrixAutoUpdate} property is `false`. + * This matrix may be set manually. + * @see {@link matrixAutoUpdate | .matrixAutoUpdate} + * @defaultValue `new THREE.Matrix3()` + */ + matrix: Matrix3; + + /** + * Whether is to update the texture's uv-transform {@link matrix | .matrix}. + * @remarks Set this to `false` if you are specifying the uv-transform {@link matrix} directly. + * @see {@link matrix | .matrix} + * @defaultValue `true` + */ + matrixAutoUpdate: boolean; + + /** + * How much a single repetition of the texture is offset from the beginning, in each direction **U** and **V**. + * @remarks Typical range is `0.0` to `1.0`. + * @defaultValue `new THREE.Vector2(0, 0)` + */ + offset: Vector2; + + /** + * How many times the texture is repeated across the surface, in each direction **U** and **V**. + * @remarks + * If repeat is set greater than `1` in either direction, the corresponding *Wrap* parameter should + * also be set to {@link THREE.RepeatWrapping} or {@link THREE.MirroredRepeatWrapping} to achieve the desired tiling effect. + * @see {@link wrapS} + * @see {@link wrapT} + * @defaultValue `new THREE.Vector2( 1, 1 )` + */ + repeat: Vector2; + + /** + * The point around which rotation occurs. + * @remarks A value of `(0.5, 0.5)` corresponds to the center of the texture. + * @defaultValue `new THREE.Vector2( 0, 0 )`, _lower left._ + */ + center: Vector2; + + /** + * How much the texture is rotated around the center point, in radians. + * @remarks Positive values are counter-clockwise. + * @defaultValue `0` + */ + rotation: number; + + /** + * Whether to generate mipmaps, _(if possible)_ for a texture. + * @remarks Set this to false if you are creating mipmaps manually. + * @defaultValue true + */ + generateMipmaps: boolean; + + /** + * If set to `true`, the alpha channel, if present, is multiplied into the color channels when the texture is uploaded to the GPU. + * @remarks + * Note that this property has no effect for {@link https://developer.mozilla.org/en-US/docs/Web/API/ImageBitmap | ImageBitmap}. + * You need to configure on bitmap creation instead. See {@link THREE.ImageBitmapLoader | ImageBitmapLoader}. + * @see {@link THREE.ImageBitmapLoader | ImageBitmapLoader}. + * @defaultValue `false` + */ + premultiplyAlpha: boolean; + + /** + * If set to `true`, the texture is flipped along the vertical axis when uploaded to the GPU. + * @remarks + * Note that this property has no effect for {@link https://developer.mozilla.org/en-US/docs/Web/API/ImageBitmap | ImageBitmap}. + * You need to configure on bitmap creation instead. See {@link THREE.ImageBitmapLoader | ImageBitmapLoader}. + * @see {@link THREE.ImageBitmapLoader | ImageBitmapLoader}. + * @defaultValue `true` + */ + flipY: boolean; + + /** + * Specifies the alignment requirements for the start of each pixel row in memory. + * @remarks + * The allowable values are: + * - `1` (byte-alignment) + * - `2` (rows aligned to even-numbered bytes) + * - `4` (word-alignment) + * - `8` (rows start on double-word boundaries). + * @see {@link http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml | glPixelStorei} for more information. + * @defaultValue `4` + */ + unpackAlignment: number; // TODO Fix typing to only allow the expected values. + + /** + * The {@link Textures | {@link Texture} constants} page for details of other color spaces. + * @remarks + * Textures containing color data should be annotated with {@link SRGBColorSpace THREE.SRGBColorSpace} or + * {@link LinearSRGBColorSpace THREE.LinearSRGBColorSpace}. + * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} + * @see {@link THREE.TextureDataType} + * @defaultValue {@link THREE.NoColorSpace} + */ + colorSpace: string; + + /** + * Indicates whether a texture belongs to a render target or not + * @defaultValue `false` + */ + isRenderTargetTexture: boolean; + + /** + * An object that can be used to store custom data about the texture. + * @remarks It should not hold references to functions as these will not be cloned. + * @defaultValue `{}` + */ + userData: Record; + + /** + * This starts at `0` and counts how many times {@link needsUpdate | .needsUpdate} is set to `true`. + * @remarks Expects a `Integer` + * @defaultValue `0` + */ + version: number; + + /** + * Indicates whether this texture should be processed by PMREMGenerator or not (only relevant for render target + * textures) + */ + pmremVersion: number; + + /** + * Set this to `true` to trigger an update next time the texture is used. Particularly important for setting the wrap mode. + */ + set needsUpdate(value: boolean); + + /** + * Indicates whether this texture should be processed by {@link THREE.PMREMGenerator} or not. + * @remarks Only relevant for render target textures. + * @defaultValue `false` + */ + set needsPMREMUpdate(value: boolean); + + /** + * The Global default value for {@link anisotropy | .anisotropy}. + * @defaultValue `1`. + */ + static DEFAULT_ANISOTROPY: number; + + /** + * The Global default value for {@link Texture.image | .image}. + * @defaultValue `null`. + */ + static DEFAULT_IMAGE: any; + + /** + * The Global default value for {@link mapping | .mapping}. + * @defaultValue {@link THREE.UVMapping} + */ + static DEFAULT_MAPPING: Mapping; + + /** + * A callback function, called when the texture is updated _(e.g., when needsUpdate has been set to true and then the texture is used)_. + */ + onUpdate: () => void; + + /** + * Transform the **UV** based on the value of this texture's + * {@link offset | .offset}, + * {@link repeat | .repeat}, + * {@link wrapS | .wrapS}, + * {@link wrapT | .wrapT} and + * {@link flipY | .flipY} properties. + * @param uv + */ + transformUv(uv: Vector2): Vector2; + + /** + * Update the texture's **UV-transform** {@link matrix | .matrix} from the texture properties + * {@link offset | .offset}, + * {@link repeat | .repeat}, + * {@link rotation | .rotation} and + * {@link center | .center}. + */ + updateMatrix(): void; + + /** + * Make copy of the texture + * @remarks Note this is not a **"deep copy"**, the image is shared + * @remarks + * Besides, cloning a texture does not automatically mark it for a texture upload + * You have to set {@link needsUpdate | .needsUpdate} to `true` as soon as it's image property (the data source) is fully loaded or ready. + */ + clone(): this; + + copy(source: Texture): this; + + /** + * Convert the texture to three.js {@link https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 | JSON Object/Scene format}. + * @param meta Optional object containing metadata. + */ + toJSON(meta?: string | {}): TextureJSON; + + /** + * Frees the GPU-related resources allocated by this instance + * @remarks Call this method whenever this instance is no longer used in your app. + */ + dispose(): void; +} diff --git a/src-testing/src/textures/VideoTexture.d.ts b/src-testing/src/textures/VideoTexture.d.ts new file mode 100644 index 000000000..31dc5d456 --- /dev/null +++ b/src-testing/src/textures/VideoTexture.d.ts @@ -0,0 +1,90 @@ +import { + MagnificationTextureFilter, + Mapping, + MinificationTextureFilter, + PixelFormat, + TextureDataType, + Wrapping, +} from "../constants.js"; +import { Texture } from "./Texture.js"; + +/** + * Creates a texture for use with a video. + * @remarks + * Note: After the initial use of a texture, the video cannot be changed + * Instead, call {@link dispose | .dispose()} on the texture and instantiate a new one. + * @example + * ```typescript + * // assuming you have created a HTML video element with id="video" + * const video = document.getElementById('video'); + * const texture = new THREE.VideoTexture(video); + * ``` + * @see Example: {@link https://threejs.org/examples/#webgl_materials_video | materials / video} + * @see Example: {@link https://threejs.org/examples/#webgl_materials_video_webcam | materials / video / webcam} + * @see Example: {@link https://threejs.org/examples/#webgl_video_kinect | video / kinect} + * @see Example: {@link https://threejs.org/examples/#webgl_video_panorama_equirectangular | video / panorama / equirectangular} + * @see Example: {@link https://threejs.org/examples/#webxr_vr_video | vr / video} + * @see {@link https://threejs.org/docs/index.html#api/en/textures/VideoTexture | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/textures/VideoTexture.js | Source} + */ +export class VideoTexture extends Texture { + /** + * Create a new instance of {@link VideoTexture} + * @param video The video element to use as the texture. + * @param mapping See {@link Texture.mapping | .mapping}. Default {@link THREE.Texture.DEFAULT_MAPPING} + * @param wrapS See {@link Texture.wrapS | .wrapS}. Default {@link THREE.ClampToEdgeWrapping} + * @param wrapT See {@link Texture.wrapT | .wrapT}. Default {@link THREE.ClampToEdgeWrapping} + * @param magFilter See {@link Texture.magFilter | .magFilter}. Default {@link THREE.LinearFilter} + * @param minFilter See {@link Texture.minFilter | .minFilter}. Default {@link THREE.LinearFilter} + * @param format See {@link Texture.format | .format}. Default {@link THREE.RGBAFormat} + * @param type See {@link Texture.type | .type}. Default {@link THREE.UnsignedByteType} + * @param anisotropy See {@link Texture.anisotropy | .anisotropy}. Default {@link THREE.Texture.DEFAULT_ANISOTROPY} + */ + constructor( + video: HTMLVideoElement, + mapping?: Mapping, + wrapS?: Wrapping, + wrapT?: Wrapping, + magFilter?: MagnificationTextureFilter, + minFilter?: MinificationTextureFilter, + format?: PixelFormat, + type?: TextureDataType, + anisotropy?: number, + ); + + /** + * Read-only flag to check if a given object is of type {@link VideoTexture}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isVideoTexture: true; + + /** + * @override + * @defaultValue {@link THREE.LinearFilter} + */ + magFilter: MagnificationTextureFilter; + + /** + * @override + * @defaultValue {@link THREE.LinearFilter} + */ + minFilter: MinificationTextureFilter; + + /** + * @override + * @defaultValue `false` + */ + generateMipmaps: boolean; + + /** + * @override + * You will **not** need to set this manually here as it is handled by the {@link update | update()} method. + */ + set needsUpdate(value: boolean); + + /** + * This is called automatically and sets {@link needsUpdate | .needsUpdate } to `true` every time a new frame is available. + */ + update(): void; +} diff --git a/src-testing/src/textures/types.d.ts b/src-testing/src/textures/types.d.ts new file mode 100644 index 000000000..86b7f2fd2 --- /dev/null +++ b/src-testing/src/textures/types.d.ts @@ -0,0 +1,9 @@ +export interface TextureImageData { + data: Uint8Array | Uint8ClampedArray; + height: number; + width: number; +} + +export interface Texture3DImageData extends TextureImageData { + depth: number; +} diff --git a/src-testing/src/utils.d.ts b/src-testing/src/utils.d.ts new file mode 100644 index 000000000..3fda1cfda --- /dev/null +++ b/src-testing/src/utils.d.ts @@ -0,0 +1,3 @@ +export function createCanvasElement(): HTMLCanvasElement; + +export function probeAsync(gl: WebGLRenderingContext, sync: WebGLSync, interval: number): Promise; From 63f7fd2dda5a5de6da29dbb3e1061ece2f83b8cc Mon Sep 17 00:00:00 2001 From: Nathan Bierema Date: Sun, 10 Nov 2024 17:18:40 -0500 Subject: [PATCH 4/7] Update patch and delete src --- src-testing/changes.patch | 21 +- src-testing/src/Three.Legacy.d.ts | 20 - src-testing/src/Three.WebGPU.Nodes.d.ts | 205 --- src-testing/src/Three.WebGPU.d.ts | 206 --- src-testing/src/Three.d.ts | 214 --- .../src/animation/AnimationAction.d.ts | 86 - src-testing/src/animation/AnimationClip.d.ts | 59 - src-testing/src/animation/AnimationMixer.d.ts | 39 - .../src/animation/AnimationObjectGroup.d.ts | 17 - src-testing/src/animation/AnimationUtils.d.ts | 60 - src-testing/src/animation/KeyframeTrack.d.ts | 55 - .../src/animation/PropertyBinding.d.ts | 43 - src-testing/src/animation/PropertyMixer.d.ts | 17 - .../tracks/BooleanKeyframeTrack.d.ts | 10 - .../animation/tracks/ColorKeyframeTrack.d.ts | 11 - .../animation/tracks/NumberKeyframeTrack.d.ts | 11 - .../tracks/QuaternionKeyframeTrack.d.ts | 11 - .../animation/tracks/StringKeyframeTrack.d.ts | 10 - .../animation/tracks/VectorKeyframeTrack.d.ts | 11 - src-testing/src/audio/Audio.d.ts | 273 ---- src-testing/src/audio/AudioAnalyser.d.ts | 58 - src-testing/src/audio/AudioContext.d.ts | 19 - src-testing/src/audio/AudioListener.d.ts | 96 -- src-testing/src/audio/PositionalAudio.d.ts | 101 -- src-testing/src/cameras/ArrayCamera.d.ts | 32 - src-testing/src/cameras/Camera.d.ts | 74 - src-testing/src/cameras/CubeCamera.d.ts | 68 - .../src/cameras/OrthographicCamera.d.ts | 174 -- .../src/cameras/PerspectiveCamera.d.ts | 254 --- src-testing/src/cameras/StereoCamera.d.ts | 50 - src-testing/src/constants.d.ts | 918 ----------- src-testing/src/core/BufferAttribute.d.ts | 622 ------- src-testing/src/core/BufferGeometry.d.ts | 433 ----- src-testing/src/core/Clock.d.ts | 72 - src-testing/src/core/EventDispatcher.d.ts | 82 - src-testing/src/core/GLBufferAttribute.d.ts | 121 -- .../src/core/InstancedBufferAttribute.d.ts | 32 - .../src/core/InstancedBufferGeometry.d.ts | 37 - .../src/core/InstancedInterleavedBuffer.d.ts | 22 - src-testing/src/core/InterleavedBuffer.d.ts | 150 -- .../src/core/InterleavedBufferAttribute.d.ts | 201 --- src-testing/src/core/Layers.d.ts | 72 - src-testing/src/core/Object3D.d.ts | 674 -------- src-testing/src/core/Raycaster.d.ts | 208 --- src-testing/src/core/RenderTarget.d.ts | 95 -- src-testing/src/core/Uniform.d.ts | 38 - src-testing/src/core/UniformsGroup.d.ts | 33 - src-testing/src/extras/Controls.d.ts | 54 - src-testing/src/extras/DataUtils.d.ts | 22 - src-testing/src/extras/Earcut.d.ts | 15 - src-testing/src/extras/ImageUtils.d.ts | 32 - src-testing/src/extras/PMREMGenerator.d.ts | 82 - src-testing/src/extras/ShapeUtils.d.ts | 25 - src-testing/src/extras/TextureUtils.d.ts | 42 - src-testing/src/extras/core/Curve.d.ts | 162 -- src-testing/src/extras/core/CurvePath.d.ts | 77 - .../src/extras/core/Interpolations.d.ts | 36 - src-testing/src/extras/core/Path.d.ts | 166 -- src-testing/src/extras/core/Shape.d.ts | 86 - src-testing/src/extras/core/ShapePath.d.ts | 98 -- src-testing/src/extras/curves/ArcCurve.d.ts | 41 - .../src/extras/curves/CatmullRomCurve3.d.ts | 77 - .../src/extras/curves/CubicBezierCurve.d.ts | 72 - .../src/extras/curves/CubicBezierCurve3.d.ts | 72 - src-testing/src/extras/curves/Curves.d.ts | 10 - .../src/extras/curves/EllipseCurve.d.ts | 115 -- src-testing/src/extras/curves/LineCurve.d.ts | 42 - src-testing/src/extras/curves/LineCurve3.d.ts | 42 - .../extras/curves/QuadraticBezierCurve.d.ts | 64 - .../extras/curves/QuadraticBezierCurve3.d.ts | 64 - .../src/extras/curves/SplineCurve.d.ts | 52 - src-testing/src/geometries/BoxGeometry.d.ts | 59 - .../src/geometries/CapsuleGeometry.d.ts | 48 - .../src/geometries/CircleGeometry.d.ts | 51 - src-testing/src/geometries/ConeGeometry.d.ts | 64 - .../src/geometries/CylinderGeometry.d.ts | 64 - .../src/geometries/DodecahedronGeometry.d.ts | 25 - src-testing/src/geometries/EdgesGeometry.d.ts | 41 - .../src/geometries/ExtrudeGeometry.d.ts | 152 -- src-testing/src/geometries/Geometries.d.ts | 21 - .../src/geometries/IcosahedronGeometry.d.ts | 26 - src-testing/src/geometries/LatheGeometry.d.ts | 55 - .../src/geometries/OctahedronGeometry.d.ts | 25 - src-testing/src/geometries/PlaneGeometry.d.ts | 48 - .../src/geometries/PolyhedronGeometry.d.ts | 54 - src-testing/src/geometries/RingGeometry.d.ts | 59 - src-testing/src/geometries/ShapeGeometry.d.ts | 53 - .../src/geometries/SphereGeometry.d.ts | 67 - .../src/geometries/TetrahedronGeometry.d.ts | 25 - src-testing/src/geometries/TorusGeometry.d.ts | 49 - .../src/geometries/TorusKnotGeometry.d.ts | 59 - src-testing/src/geometries/TubeGeometry.d.ts | 86 - .../src/geometries/WireframeGeometry.d.ts | 40 - src-testing/src/helpers/ArrowHelper.d.ts | 93 -- src-testing/src/helpers/AxesHelper.d.ts | 50 - src-testing/src/helpers/Box3Helper.d.ts | 44 - src-testing/src/helpers/BoxHelper.d.ts | 64 - src-testing/src/helpers/CameraHelper.d.ts | 80 - .../src/helpers/DirectionalLightHelper.d.ts | 81 - src-testing/src/helpers/GridHelper.d.ts | 47 - .../src/helpers/HemisphereLightHelper.d.ts | 72 - src-testing/src/helpers/PlaneHelper.d.ts | 50 - src-testing/src/helpers/PointLightHelper.d.ts | 73 - src-testing/src/helpers/PolarGridHelper.d.ts | 55 - src-testing/src/helpers/SkeletonHelper.d.ts | 78 - src-testing/src/helpers/SpotLightHelper.d.ts | 77 - src-testing/src/lights/AmbientLight.d.ts | 36 - src-testing/src/lights/DirectionalLight.d.ts | 103 -- .../src/lights/DirectionalLightShadow.d.ts | 73 - src-testing/src/lights/HemisphereLight.d.ts | 61 - src-testing/src/lights/Light.d.ts | 82 - src-testing/src/lights/LightProbe.d.ts | 47 - src-testing/src/lights/LightShadow.d.ts | 169 -- src-testing/src/lights/PointLight.d.ts | 102 -- src-testing/src/lights/PointLightShadow.d.ts | 22 - src-testing/src/lights/RectAreaLight.d.ts | 82 - src-testing/src/lights/SpotLight.d.ts | 164 -- src-testing/src/lights/SpotLightShadow.d.ts | 72 - .../src/lights/webgpu/IESSpotLight.d.ts | 6 - src-testing/src/loaders/AnimationLoader.d.ts | 9 - src-testing/src/loaders/AudioLoader.d.ts | 6 - .../src/loaders/BufferGeometryLoader.d.ts | 10 - src-testing/src/loaders/Cache.d.ts | 21 - .../src/loaders/CompressedTextureLoader.d.ts | 14 - .../src/loaders/CubeTextureLoader.d.ts | 14 - .../src/loaders/DataTextureLoader.d.ts | 14 - src-testing/src/loaders/FileLoader.d.ts | 19 - .../src/loaders/ImageBitmapLoader.d.ts | 22 - src-testing/src/loaders/ImageLoader.d.ts | 17 - src-testing/src/loaders/Loader.d.ts | 50 - src-testing/src/loaders/LoaderUtils.d.ts | 10 - src-testing/src/loaders/LoadingManager.d.ts | 69 - src-testing/src/loaders/MaterialLoader.d.ts | 21 - src-testing/src/loaders/ObjectLoader.d.ts | 35 - src-testing/src/loaders/TextureLoader.d.ts | 18 - src-testing/src/loaders/nodes/NodeLoader.d.ts | 21 - .../src/loaders/nodes/NodeMaterialLoader.d.ts | 11 - .../src/loaders/nodes/NodeObjectLoader.d.ts | 22 - .../src/materials/LineBasicMaterial.d.ts | 55 - .../src/materials/LineDashedMaterial.d.ts | 35 - src-testing/src/materials/Material.d.ts | 629 -------- src-testing/src/materials/Materials.d.ts | 18 - .../src/materials/MeshBasicMaterial.d.ts | 134 -- .../src/materials/MeshDepthMaterial.d.ts | 71 - .../src/materials/MeshDistanceMaterial.d.ts | 57 - .../src/materials/MeshLambertMaterial.d.ts | 199 --- .../src/materials/MeshMatcapMaterial.d.ts | 112 -- .../src/materials/MeshNormalMaterial.d.ts | 88 - .../src/materials/MeshPhongMaterial.d.ts | 223 --- .../src/materials/MeshPhysicalMaterial.d.ts | 231 --- .../src/materials/MeshStandardMaterial.d.ts | 213 --- .../src/materials/MeshToonMaterial.d.ts | 173 -- src-testing/src/materials/PointsMaterial.d.ts | 56 - .../src/materials/RawShaderMaterial.d.ts | 12 - src-testing/src/materials/ShaderMaterial.d.ts | 162 -- src-testing/src/materials/ShadowMaterial.d.ts | 34 - src-testing/src/materials/SpriteMaterial.d.ts | 61 - .../nodes/InstancedPointsNodeMaterial.d.ts | 33 - .../materials/nodes/Line2NodeMaterial.d.ts | 53 - .../nodes/LineBasicNodeMaterial.d.ts | 22 - .../nodes/LineDashedNodeMaterial.d.ts | 29 - .../nodes/MeshBasicNodeMaterial.d.ts | 36 - .../nodes/MeshLambertNodeMaterial.d.ts | 49 - .../nodes/MeshMatcapNodeMaterial.d.ts | 32 - .../nodes/MeshNormalNodeMaterial.d.ts | 28 - .../nodes/MeshPhongNodeMaterial.d.ts | 56 - .../nodes/MeshPhysicalNodeMaterial.d.ts | 93 -- .../materials/nodes/MeshSSSNodeMaterial.d.ts | 16 - .../nodes/MeshStandardNodeMaterial.d.ts | 56 - .../materials/nodes/MeshToonNodeMaterial.d.ts | 42 - .../src/materials/nodes/NodeMaterial.ts | 535 ------- .../src/materials/nodes/NodeMaterials.d.ts | 18 - .../materials/nodes/PointsNodeMaterial.d.ts | 21 - .../materials/nodes/ShadowNodeMaterial.d.ts | 17 - .../materials/nodes/SpriteNodeMaterial.d.ts | 26 - .../materials/nodes/VolumeNodeMaterial.d.ts | 10 - .../nodes/manager/NodeMaterialObserver.ts | 308 ---- src-testing/src/math/Box2.d.ts | 48 - src-testing/src/math/Box3.d.ts | 66 - src-testing/src/math/Color.d.ts | 375 ----- src-testing/src/math/ColorManagement.d.ts | 49 - src-testing/src/math/Cylindrical.d.ts | 26 - src-testing/src/math/Euler.d.ts | 50 - src-testing/src/math/Frustum.d.ts | 30 - src-testing/src/math/Interpolant.d.ts | 10 - src-testing/src/math/Line3.d.ts | 29 - src-testing/src/math/MathUtils.d.ts | 137 -- src-testing/src/math/Matrix2.d.ts | 53 - src-testing/src/math/Matrix3.d.ts | 184 --- src-testing/src/math/Matrix4.d.ts | 284 ---- src-testing/src/math/Plane.d.ts | 47 - src-testing/src/math/Quaternion.d.ts | 189 --- src-testing/src/math/Ray.d.ts | 60 - src-testing/src/math/Sphere.d.ts | 47 - src-testing/src/math/Spherical.d.ts | 27 - src-testing/src/math/SphericalHarmonics3.d.ts | 50 - src-testing/src/math/Triangle.d.ts | 110 -- src-testing/src/math/Vector2.d.ts | 321 ---- src-testing/src/math/Vector3.d.ts | 301 ---- src-testing/src/math/Vector4.d.ts | 239 --- .../math/interpolants/CubicInterpolant.d.ts | 7 - .../interpolants/DiscreteInterpolant.d.ts | 7 - .../math/interpolants/LinearInterpolant.d.ts | 7 - .../QuaternionLinearInterpolant.d.ts | 7 - src-testing/src/nodes/Nodes.ts | 144 -- src-testing/src/nodes/TSL.d.ts | 156 -- .../src/nodes/accessors/AccessorsUtils.d.ts | 9 - .../src/nodes/accessors/BatchNode.d.ts | 13 - .../src/nodes/accessors/Bitangent.d.ts | 9 - .../nodes/accessors/BufferAttributeNode.ts | 135 -- .../src/nodes/accessors/BufferNode.d.ts | 17 - src-testing/src/nodes/accessors/Camera.d.ts | 14 - .../src/nodes/accessors/ClippingNode.d.ts | 16 - .../src/nodes/accessors/CubeTextureNode.d.ts | 28 - .../src/nodes/accessors/InstanceNode.d.ts | 13 - .../src/nodes/accessors/MaterialNode.d.ts | 129 -- .../nodes/accessors/MaterialProperties.d.ts | 4 - .../accessors/MaterialReferenceNode.d.ts | 15 - .../src/nodes/accessors/ModelNode.d.ts | 24 - .../accessors/ModelViewProjectionNode.d.ts | 8 - .../src/nodes/accessors/MorphNode.d.ts | 15 - src-testing/src/nodes/accessors/Normal.d.ts | 25 - .../src/nodes/accessors/Object3DNode.d.ts | 22 - .../src/nodes/accessors/PointUVNode.d.ts | 10 - src-testing/src/nodes/accessors/Position.d.ts | 10 - .../nodes/accessors/ReferenceBaseNode.d.ts | 27 - .../src/nodes/accessors/ReferenceNode.d.ts | 29 - .../src/nodes/accessors/ReflectVector.d.ts | 9 - .../accessors/RendererReferenceNode.d.ts | 15 - .../src/nodes/accessors/SceneNode.d.ts | 20 - .../src/nodes/accessors/SkinningNode.d.ts | 30 - .../nodes/accessors/StorageBufferNode.d.ts | 38 - .../nodes/accessors/StorageTextureNode.d.ts | 40 - src-testing/src/nodes/accessors/Tangent.d.ts | 12 - .../src/nodes/accessors/Texture3DNode.d.ts | 17 - .../src/nodes/accessors/TextureBicubic.d.ts | 4 - .../src/nodes/accessors/TextureNode.ts | 370 ----- .../src/nodes/accessors/TextureSizeNode.d.ts | 18 - src-testing/src/nodes/accessors/UV.d.ts | 4 - .../src/nodes/accessors/UniformArrayNode.d.ts | 30 - .../src/nodes/accessors/UserDataNode.d.ts | 15 - .../src/nodes/accessors/VelocityNode.d.ts | 20 - .../src/nodes/accessors/VertexColorNode.d.ts | 12 - src-testing/src/nodes/code/CodeNode.ts | 68 - .../src/nodes/code/ExpressionNode.d.ts | 9 - .../src/nodes/code/FunctionCallNode.d.ts | 25 - src-testing/src/nodes/code/FunctionNode.ts | 87 - .../src/nodes/code/ScriptableNode.d.ts | 22 - .../src/nodes/code/ScriptableValueNode.d.ts | 10 - src-testing/src/nodes/core/AssignNode.d.ts | 18 - src-testing/src/nodes/core/AttributeNode.d.ts | 16 - src-testing/src/nodes/core/BypassNode.d.ts | 18 - src-testing/src/nodes/core/CacheNode.d.ts | 20 - src-testing/src/nodes/core/ConstNode.d.ts | 9 - src-testing/src/nodes/core/ContextNode.ts | 61 - src-testing/src/nodes/core/IndexNode.d.ts | 28 - src-testing/src/nodes/core/InputNode.ts | 67 - src-testing/src/nodes/core/LightingModel.d.ts | 46 - src-testing/src/nodes/core/MRTNode.d.ts | 24 - src-testing/src/nodes/core/Node.ts | 401 ----- src-testing/src/nodes/core/NodeAttribute.ts | 11 - src-testing/src/nodes/core/NodeBuilder.ts | 1208 -------------- src-testing/src/nodes/core/NodeCache.ts | 26 - src-testing/src/nodes/core/NodeCode.ts | 11 - src-testing/src/nodes/core/NodeFrame.ts | 127 -- src-testing/src/nodes/core/NodeFunction.ts | 16 - .../src/nodes/core/NodeFunctionInput.d.ts | 7 - src-testing/src/nodes/core/NodeParser.ts | 7 - src-testing/src/nodes/core/NodeUniform.ts | 27 - src-testing/src/nodes/core/NodeUtils.ts | 171 -- src-testing/src/nodes/core/NodeVar.ts | 10 - src-testing/src/nodes/core/NodeVarying.ts | 13 - .../src/nodes/core/OutputStructNode.d.ts | 12 - src-testing/src/nodes/core/ParameterNode.d.ts | 12 - src-testing/src/nodes/core/PropertyNode.d.ts | 43 - src-testing/src/nodes/core/StackNode.ts | 89 - src-testing/src/nodes/core/StructTypeNode.ts | 20 - src-testing/src/nodes/core/TempNode.d.ts | 10 - src-testing/src/nodes/core/UniformGroup.d.ts | 7 - .../src/nodes/core/UniformGroupNode.ts | 47 - src-testing/src/nodes/core/UniformNode.ts | 91 -- src-testing/src/nodes/core/VarNode.d.ts | 31 - src-testing/src/nodes/core/VaryingNode.d.ts | 21 - src-testing/src/nodes/core/constants.ts | 28 - src-testing/src/nodes/display/BlendMode.d.ts | 10 - .../src/nodes/display/BumpMapNode.d.ts | 16 - .../src/nodes/display/ColorAdjustment.d.ts | 56 - .../nodes/display/ColorSpaceFunctions.d.ts | 6 - .../src/nodes/display/ColorSpaceNode.d.ts | 60 - .../src/nodes/display/FrontFacingNode.d.ts | 12 - .../src/nodes/display/NormalMapNode.d.ts | 17 - src-testing/src/nodes/display/PassNode.d.ts | 71 - .../src/nodes/display/PosterizeNode.d.ts | 14 - .../src/nodes/display/RenderOutputNode.d.ts | 28 - src-testing/src/nodes/display/ScreenNode.d.ts | 48 - .../nodes/display/ToneMappingFunctions.d.ts | 14 - .../src/nodes/display/ToneMappingNode.d.ts | 32 - .../nodes/display/ToonOutlinePassNode.d.ts | 24 - .../src/nodes/display/ViewportDepthNode.d.ts | 36 - .../display/ViewportDepthTextureNode.d.ts | 14 - .../display/ViewportSharedTextureNode.d.ts | 14 - .../nodes/display/ViewportTextureNode.d.ts | 28 - src-testing/src/nodes/fog/FogExp2Node.d.ts | 14 - src-testing/src/nodes/fog/FogNode.ts | 38 - src-testing/src/nodes/fog/FogRangeNode.d.ts | 19 - .../src/nodes/functions/BSDF/BRDF_GGX.d.ts | 15 - .../nodes/functions/BSDF/BRDF_Lambert.d.ts | 7 - .../src/nodes/functions/BSDF/BRDF_Sheen.d.ts | 7 - .../src/nodes/functions/BSDF/DFGApprox.d.ts | 11 - .../src/nodes/functions/BSDF/D_GGX.d.ts | 10 - .../functions/BSDF/D_GGX_Anisotropic.d.ts | 10 - .../src/nodes/functions/BSDF/F_Schlick.d.ts | 7 - src-testing/src/nodes/functions/BSDF/LTC.d.ts | 9 - .../nodes/functions/BSDF/Schlick_to_F0.d.ts | 10 - .../functions/BSDF/V_GGX_SmithCorrelated.d.ts | 11 - .../V_GGX_SmithCorrelated_Anisotropic.d.ts | 16 - .../nodes/functions/BasicLightingModel.d.ts | 7 - .../nodes/functions/PhongLightingModel.d.ts | 7 - .../functions/PhysicalLightingModel.d.ts | 30 - .../src/nodes/functions/ShadowMaskModel.d.ts | 9 - .../nodes/functions/ToonLightingModel.d.ts | 4 - .../material/getGeometryRoughness.d.ts | 6 - .../functions/material/getRoughness.d.ts | 7 - .../functions/material/getShIrradianceAt.d.ts | 6 - src-testing/src/nodes/geometry/RangeNode.d.ts | 19 - src-testing/src/nodes/gpgpu/ComputeNode.ts | 75 - src-testing/src/nodes/lighting/AONode.d.ts | 8 - .../src/nodes/lighting/AmbientLightNode.d.ts | 8 - .../src/nodes/lighting/AnalyticLightNode.d.ts | 8 - .../nodes/lighting/BasicEnvironmentNode.d.ts | 10 - .../src/nodes/lighting/BasicLightMapNode.d.ts | 8 - .../nodes/lighting/DirectionalLightNode.d.ts | 8 - .../src/nodes/lighting/EnvironmentNode.ts | 114 -- .../nodes/lighting/HemisphereLightNode.d.ts | 13 - .../src/nodes/lighting/IESSpotLightNode.d.ts | 5 - .../src/nodes/lighting/IrradianceNode.d.ts | 8 - src-testing/src/nodes/lighting/LightNode.d.ts | 18 - .../src/nodes/lighting/LightProbeNode.d.ts | 11 - .../src/nodes/lighting/LightUtils.d.ts | 9 - .../src/nodes/lighting/LightingContextNode.ts | 57 - .../src/nodes/lighting/LightingNode.d.ts | 7 - src-testing/src/nodes/lighting/LightsNode.ts | 200 --- .../src/nodes/lighting/PointLightNode.d.ts | 20 - .../src/nodes/lighting/RectAreaLightNode.d.ts | 21 - .../src/nodes/lighting/ShadowNode.d.ts | 12 - .../src/nodes/lighting/SpotLightNode.d.ts | 15 - .../src/nodes/materialx/MaterialXNodes.d.ts | 107 -- .../src/nodes/materialx/lib/mx_hsv.d.ts | 6 - .../src/nodes/materialx/lib/mx_noise.d.ts | 359 ----- .../materialx/lib/mx_transform_color.d.ts | 4 - .../src/nodes/math/ConditionalNode.d.ts | 39 - src-testing/src/nodes/math/Hash.d.ts | 4 - src-testing/src/nodes/math/MathNode.d.ts | 273 ---- src-testing/src/nodes/math/MathUtils.d.ts | 6 - src-testing/src/nodes/math/OperatorNode.d.ts | 97 -- src-testing/src/nodes/math/TriNoise3D.d.ts | 12 - .../src/nodes/parsers/GLSLNodeFunction.d.ts | 9 - .../src/nodes/parsers/GLSLNodeParser.d.ts | 8 - src-testing/src/nodes/pmrem/PMREMNode.d.ts | 22 - src-testing/src/nodes/pmrem/PMREMUtils.d.ts | 28 - src-testing/src/nodes/procedural/Checker.d.ts | 4 - src-testing/src/nodes/tsl/TSLBase.d.ts | 21 - src-testing/src/nodes/tsl/TSLCore.ts | 533 ------ .../src/nodes/utils/ArrayElementNode.d.ts | 9 - src-testing/src/nodes/utils/ConvertNode.d.ts | 7 - src-testing/src/nodes/utils/CubeMapNode.d.ts | 13 - src-testing/src/nodes/utils/Discard.d.ts | 11 - .../src/nodes/utils/EquirectUVNode.d.ts | 8 - .../nodes/utils/FunctionOverloadingNode.d.ts | 13 - src-testing/src/nodes/utils/JoinNode.d.ts | 10 - src-testing/src/nodes/utils/LoopNode.d.ts | 22 - src-testing/src/nodes/utils/MatcapUVNode.d.ts | 8 - .../src/nodes/utils/MaxMipLevelNode.d.ts | 14 - src-testing/src/nodes/utils/Oscillators.d.ts | 7 - src-testing/src/nodes/utils/Packing.d.ts | 5 - .../src/nodes/utils/PostProcessingUtils.d.ts | 45 - src-testing/src/nodes/utils/RTTNode.d.ts | 45 - .../src/nodes/utils/ReflectorNode.d.ts | 45 - src-testing/src/nodes/utils/RemapNode.d.ts | 36 - src-testing/src/nodes/utils/RotateNode.d.ts | 15 - src-testing/src/nodes/utils/SetNode.d.ts | 11 - src-testing/src/nodes/utils/SplitNode.d.ts | 15 - .../src/nodes/utils/SpriteSheetUVNode.d.ts | 16 - src-testing/src/nodes/utils/SpriteUtils.d.ts | 6 - .../nodes/utils/StorageArrayElementNode.d.ts | 19 - src-testing/src/nodes/utils/Timer.d.ts | 21 - .../nodes/utils/TriplanarTexturesNode.d.ts | 36 - src-testing/src/nodes/utils/UVUtils.d.ts | 14 - .../src/nodes/utils/ViewportUtils.d.ts | 4 - src-testing/src/objects/BatchedMesh.d.ts | 275 ---- src-testing/src/objects/Bone.d.ts | 36 - src-testing/src/objects/Group.d.ts | 37 - src-testing/src/objects/InstancedMesh.d.ts | 179 --- src-testing/src/objects/LOD.d.ts | 111 -- src-testing/src/objects/Line.d.ts | 87 - src-testing/src/objects/LineLoop.d.ts | 40 - src-testing/src/objects/LineSegments.d.ts | 41 - src-testing/src/objects/Mesh.d.ts | 94 -- src-testing/src/objects/Points.d.ts | 66 - src-testing/src/objects/Skeleton.d.ts | 120 -- src-testing/src/objects/SkinnedMesh.d.ts | 160 -- src-testing/src/objects/Sprite.d.ts | 65 - .../src/renderers/WebGL3DRenderTarget.d.ts | 29 - .../src/renderers/WebGLArrayRenderTarget.d.ts | 29 - .../src/renderers/WebGLCubeRenderTarget.d.ts | 18 - .../src/renderers/WebGLRenderTarget.d.ts | 8 - src-testing/src/renderers/WebGLRenderer.d.ts | 558 ------- src-testing/src/renderers/common/Animation.ts | 38 - .../src/renderers/common/Attributes.ts | 56 - src-testing/src/renderers/common/Backend.ts | 170 -- .../src/renderers/common/Background.ts | 133 -- src-testing/src/renderers/common/BindGroup.ts | 14 - src-testing/src/renderers/common/Binding.ts | 17 - src-testing/src/renderers/common/Bindings.ts | 160 -- src-testing/src/renderers/common/Buffer.ts | 28 - .../src/renderers/common/BufferUtils.ts | 23 - .../src/renderers/common/BundleGroup.ts | 20 - src-testing/src/renderers/common/ChainMap.ts | 43 - .../src/renderers/common/ClippingContext.ts | 136 -- src-testing/src/renderers/common/Color4.ts | 27 - .../src/renderers/common/ComputePipeline.ts | 13 - src-testing/src/renderers/common/Constants.ts | 15 - .../src/renderers/common/CubeRenderTarget.ts | 71 - src-testing/src/renderers/common/DataMap.ts | 38 - .../src/renderers/common/Geometries.ts | 199 --- .../IndirectStorageBufferAttribute.d.ts | 10 - src-testing/src/renderers/common/Info.ts | 95 -- .../src/renderers/common/Lighting.d.ts | 15 - src-testing/src/renderers/common/Pipeline.ts | 9 - src-testing/src/renderers/common/Pipelines.ts | 270 ---- .../src/renderers/common/PostProcessing.d.ts | 21 - .../renderers/common/PostProcessingUtils.d.ts | 66 - .../src/renderers/common/ProgrammableStage.ts | 16 - .../src/renderers/common/QuadMesh.d.ts | 16 - .../src/renderers/common/RenderBundle.ts | 12 - .../src/renderers/common/RenderBundles.ts | 28 - .../src/renderers/common/RenderContext.ts | 56 - .../src/renderers/common/RenderContexts.ts | 47 - .../src/renderers/common/RenderList.ts | 142 -- .../src/renderers/common/RenderLists.ts | 30 - .../src/renderers/common/RenderObject.ts | 350 ---- .../src/renderers/common/RenderObjects.ts | 107 -- .../src/renderers/common/RenderPipeline.ts | 12 - src-testing/src/renderers/common/Renderer.ts | 1425 ----------------- .../src/renderers/common/SampledTexture.ts | 68 - src-testing/src/renderers/common/Sampler.ts | 14 - .../src/renderers/common/StorageBuffer.ts | 13 - .../common/StorageBufferAttribute.d.ts | 7 - .../StorageInstancedBufferAttribute.d.ts | 8 - .../src/renderers/common/StorageTexture.d.ts | 5 - src-testing/src/renderers/common/Textures.ts | 294 ---- src-testing/src/renderers/common/Uniform.ts | 105 -- .../src/renderers/common/UniformBuffer.ts | 11 - .../src/renderers/common/UniformsGroup.ts | 277 ---- .../renderers/common/extras/PMREMGenerator.ts | 657 -------- .../common/nodes/NodeBuilderState.ts | 55 - .../src/renderers/common/nodes/NodeLibrary.ts | 76 - .../common/nodes/NodeSampledTexture.d.ts | 29 - .../renderers/common/nodes/NodeSampler.d.ts | 12 - .../src/renderers/common/nodes/NodeUniform.ts | 103 -- .../common/nodes/NodeUniformsGroup.ts | 30 - .../src/renderers/common/nodes/Nodes.ts | 433 ----- .../common/nodes/StandardNodeLibrary.d.ts | 5 - .../src/renderers/shaders/ShaderChunk.d.ts | 143 -- .../src/renderers/shaders/ShaderLib.d.ts | 29 - .../src/renderers/shaders/UniformsLib.d.ts | 189 --- .../src/renderers/shaders/UniformsUtils.d.ts | 14 - .../renderers/webgl-fallback/WebGLBackend.ts | 1349 ---------------- .../webgl-fallback/nodes/GLSLNodeBuilder.ts | 812 ---------- .../src/renderers/webgl/WebGLAttributes.d.ts | 21 - .../renderers/webgl/WebGLBindingStates.d.ts | 26 - .../renderers/webgl/WebGLBufferRenderer.d.ts | 21 - .../renderers/webgl/WebGLCapabilities.d.ts | 48 - .../src/renderers/webgl/WebGLClipping.d.ts | 26 - .../src/renderers/webgl/WebGLCubeMaps.d.ts | 8 - .../src/renderers/webgl/WebGLCubeUVMaps.d.ts | 9 - .../src/renderers/webgl/WebGLExtensions.d.ts | 7 - .../src/renderers/webgl/WebGLGeometries.d.ts | 13 - .../webgl/WebGLIndexedBufferRenderer.d.ts | 15 - .../src/renderers/webgl/WebGLInfo.d.ts | 39 - .../src/renderers/webgl/WebGLLights.d.ts | 49 - .../src/renderers/webgl/WebGLObjects.d.ts | 6 - .../src/renderers/webgl/WebGLProgram.d.ts | 30 - .../src/renderers/webgl/WebGLPrograms.d.ts | 233 --- .../src/renderers/webgl/WebGLProperties.d.ts | 9 - .../src/renderers/webgl/WebGLRenderLists.d.ts | 66 - .../src/renderers/webgl/WebGLShader.d.ts | 1 - .../src/renderers/webgl/WebGLShadowMap.d.ts | 38 - .../src/renderers/webgl/WebGLState.d.ts | 116 -- .../src/renderers/webgl/WebGLTextures.d.ts | 30 - .../src/renderers/webgl/WebGLUniforms.d.ts | 12 - .../renderers/webgl/WebGLUniformsGroups.d.ts | 17 - .../src/renderers/webgl/WebGLUtils.d.ts | 11 - .../src/renderers/webgpu/WebGPUBackend.ts | 1297 --------------- .../webgpu/WebGPURenderer.Nodes.d.ts | 12 - .../src/renderers/webgpu/WebGPURenderer.ts | 46 - .../webgpu/nodes/BasicNodeLibrary.ts | 61 - .../webgpu/nodes/StandardNodeLibrary.ts | 107 -- .../renderers/webgpu/nodes/WGSLNodeBuilder.ts | 1178 -------------- .../webgpu/nodes/WGSLNodeFunction.ts | 142 -- .../renderers/webgpu/nodes/WGSLNodeParser.ts | 10 - .../webgpu/utils/WebGPUConstants.d.ts | 328 ---- .../src/renderers/webxr/WebXRController.d.ts | 63 - .../renderers/webxr/WebXRDepthSensing.d.ts | 22 - .../src/renderers/webxr/WebXRManager.d.ts | 85 - src-testing/src/scenes/Fog.d.ts | 77 - src-testing/src/scenes/FogExp2.d.ts | 66 - src-testing/src/scenes/Scene.d.ts | 118 -- src-testing/src/textures/CanvasTexture.d.ts | 51 - .../src/textures/CompressedArrayTexture.d.ts | 68 - .../src/textures/CompressedCubeTexture.d.ts | 13 - .../src/textures/CompressedTexture.d.ts | 94 -- src-testing/src/textures/CubeTexture.d.ts | 89 - src-testing/src/textures/Data3DTexture.d.ts | 96 -- .../src/textures/DataArrayTexture.d.ts | 123 -- src-testing/src/textures/DataTexture.d.ts | 112 -- src-testing/src/textures/DepthTexture.d.ts | 104 -- .../src/textures/FramebufferTexture.d.ts | 62 - src-testing/src/textures/Source.d.ts | 75 - src-testing/src/textures/Texture.d.ts | 476 ------ src-testing/src/textures/VideoTexture.d.ts | 90 -- src-testing/src/textures/types.d.ts | 9 - src-testing/src/utils.d.ts | 3 - 523 files changed, 5 insertions(+), 42366 deletions(-) delete mode 100644 src-testing/src/Three.Legacy.d.ts delete mode 100644 src-testing/src/Three.WebGPU.Nodes.d.ts delete mode 100644 src-testing/src/Three.WebGPU.d.ts delete mode 100644 src-testing/src/Three.d.ts delete mode 100644 src-testing/src/animation/AnimationAction.d.ts delete mode 100644 src-testing/src/animation/AnimationClip.d.ts delete mode 100644 src-testing/src/animation/AnimationMixer.d.ts delete mode 100644 src-testing/src/animation/AnimationObjectGroup.d.ts delete mode 100644 src-testing/src/animation/AnimationUtils.d.ts delete mode 100644 src-testing/src/animation/KeyframeTrack.d.ts delete mode 100644 src-testing/src/animation/PropertyBinding.d.ts delete mode 100644 src-testing/src/animation/PropertyMixer.d.ts delete mode 100644 src-testing/src/animation/tracks/BooleanKeyframeTrack.d.ts delete mode 100644 src-testing/src/animation/tracks/ColorKeyframeTrack.d.ts delete mode 100644 src-testing/src/animation/tracks/NumberKeyframeTrack.d.ts delete mode 100644 src-testing/src/animation/tracks/QuaternionKeyframeTrack.d.ts delete mode 100644 src-testing/src/animation/tracks/StringKeyframeTrack.d.ts delete mode 100644 src-testing/src/animation/tracks/VectorKeyframeTrack.d.ts delete mode 100644 src-testing/src/audio/Audio.d.ts delete mode 100644 src-testing/src/audio/AudioAnalyser.d.ts delete mode 100644 src-testing/src/audio/AudioContext.d.ts delete mode 100644 src-testing/src/audio/AudioListener.d.ts delete mode 100644 src-testing/src/audio/PositionalAudio.d.ts delete mode 100644 src-testing/src/cameras/ArrayCamera.d.ts delete mode 100644 src-testing/src/cameras/Camera.d.ts delete mode 100644 src-testing/src/cameras/CubeCamera.d.ts delete mode 100644 src-testing/src/cameras/OrthographicCamera.d.ts delete mode 100644 src-testing/src/cameras/PerspectiveCamera.d.ts delete mode 100644 src-testing/src/cameras/StereoCamera.d.ts delete mode 100644 src-testing/src/constants.d.ts delete mode 100644 src-testing/src/core/BufferAttribute.d.ts delete mode 100644 src-testing/src/core/BufferGeometry.d.ts delete mode 100644 src-testing/src/core/Clock.d.ts delete mode 100644 src-testing/src/core/EventDispatcher.d.ts delete mode 100644 src-testing/src/core/GLBufferAttribute.d.ts delete mode 100644 src-testing/src/core/InstancedBufferAttribute.d.ts delete mode 100644 src-testing/src/core/InstancedBufferGeometry.d.ts delete mode 100644 src-testing/src/core/InstancedInterleavedBuffer.d.ts delete mode 100644 src-testing/src/core/InterleavedBuffer.d.ts delete mode 100644 src-testing/src/core/InterleavedBufferAttribute.d.ts delete mode 100644 src-testing/src/core/Layers.d.ts delete mode 100644 src-testing/src/core/Object3D.d.ts delete mode 100644 src-testing/src/core/Raycaster.d.ts delete mode 100644 src-testing/src/core/RenderTarget.d.ts delete mode 100644 src-testing/src/core/Uniform.d.ts delete mode 100644 src-testing/src/core/UniformsGroup.d.ts delete mode 100644 src-testing/src/extras/Controls.d.ts delete mode 100644 src-testing/src/extras/DataUtils.d.ts delete mode 100644 src-testing/src/extras/Earcut.d.ts delete mode 100644 src-testing/src/extras/ImageUtils.d.ts delete mode 100644 src-testing/src/extras/PMREMGenerator.d.ts delete mode 100644 src-testing/src/extras/ShapeUtils.d.ts delete mode 100644 src-testing/src/extras/TextureUtils.d.ts delete mode 100644 src-testing/src/extras/core/Curve.d.ts delete mode 100644 src-testing/src/extras/core/CurvePath.d.ts delete mode 100644 src-testing/src/extras/core/Interpolations.d.ts delete mode 100644 src-testing/src/extras/core/Path.d.ts delete mode 100644 src-testing/src/extras/core/Shape.d.ts delete mode 100644 src-testing/src/extras/core/ShapePath.d.ts delete mode 100644 src-testing/src/extras/curves/ArcCurve.d.ts delete mode 100644 src-testing/src/extras/curves/CatmullRomCurve3.d.ts delete mode 100644 src-testing/src/extras/curves/CubicBezierCurve.d.ts delete mode 100644 src-testing/src/extras/curves/CubicBezierCurve3.d.ts delete mode 100644 src-testing/src/extras/curves/Curves.d.ts delete mode 100644 src-testing/src/extras/curves/EllipseCurve.d.ts delete mode 100644 src-testing/src/extras/curves/LineCurve.d.ts delete mode 100644 src-testing/src/extras/curves/LineCurve3.d.ts delete mode 100644 src-testing/src/extras/curves/QuadraticBezierCurve.d.ts delete mode 100644 src-testing/src/extras/curves/QuadraticBezierCurve3.d.ts delete mode 100644 src-testing/src/extras/curves/SplineCurve.d.ts delete mode 100644 src-testing/src/geometries/BoxGeometry.d.ts delete mode 100644 src-testing/src/geometries/CapsuleGeometry.d.ts delete mode 100644 src-testing/src/geometries/CircleGeometry.d.ts delete mode 100644 src-testing/src/geometries/ConeGeometry.d.ts delete mode 100644 src-testing/src/geometries/CylinderGeometry.d.ts delete mode 100644 src-testing/src/geometries/DodecahedronGeometry.d.ts delete mode 100644 src-testing/src/geometries/EdgesGeometry.d.ts delete mode 100644 src-testing/src/geometries/ExtrudeGeometry.d.ts delete mode 100644 src-testing/src/geometries/Geometries.d.ts delete mode 100644 src-testing/src/geometries/IcosahedronGeometry.d.ts delete mode 100644 src-testing/src/geometries/LatheGeometry.d.ts delete mode 100644 src-testing/src/geometries/OctahedronGeometry.d.ts delete mode 100644 src-testing/src/geometries/PlaneGeometry.d.ts delete mode 100644 src-testing/src/geometries/PolyhedronGeometry.d.ts delete mode 100644 src-testing/src/geometries/RingGeometry.d.ts delete mode 100644 src-testing/src/geometries/ShapeGeometry.d.ts delete mode 100644 src-testing/src/geometries/SphereGeometry.d.ts delete mode 100644 src-testing/src/geometries/TetrahedronGeometry.d.ts delete mode 100644 src-testing/src/geometries/TorusGeometry.d.ts delete mode 100644 src-testing/src/geometries/TorusKnotGeometry.d.ts delete mode 100644 src-testing/src/geometries/TubeGeometry.d.ts delete mode 100644 src-testing/src/geometries/WireframeGeometry.d.ts delete mode 100644 src-testing/src/helpers/ArrowHelper.d.ts delete mode 100644 src-testing/src/helpers/AxesHelper.d.ts delete mode 100644 src-testing/src/helpers/Box3Helper.d.ts delete mode 100644 src-testing/src/helpers/BoxHelper.d.ts delete mode 100644 src-testing/src/helpers/CameraHelper.d.ts delete mode 100644 src-testing/src/helpers/DirectionalLightHelper.d.ts delete mode 100644 src-testing/src/helpers/GridHelper.d.ts delete mode 100644 src-testing/src/helpers/HemisphereLightHelper.d.ts delete mode 100644 src-testing/src/helpers/PlaneHelper.d.ts delete mode 100644 src-testing/src/helpers/PointLightHelper.d.ts delete mode 100644 src-testing/src/helpers/PolarGridHelper.d.ts delete mode 100644 src-testing/src/helpers/SkeletonHelper.d.ts delete mode 100644 src-testing/src/helpers/SpotLightHelper.d.ts delete mode 100644 src-testing/src/lights/AmbientLight.d.ts delete mode 100644 src-testing/src/lights/DirectionalLight.d.ts delete mode 100644 src-testing/src/lights/DirectionalLightShadow.d.ts delete mode 100644 src-testing/src/lights/HemisphereLight.d.ts delete mode 100644 src-testing/src/lights/Light.d.ts delete mode 100644 src-testing/src/lights/LightProbe.d.ts delete mode 100644 src-testing/src/lights/LightShadow.d.ts delete mode 100644 src-testing/src/lights/PointLight.d.ts delete mode 100644 src-testing/src/lights/PointLightShadow.d.ts delete mode 100644 src-testing/src/lights/RectAreaLight.d.ts delete mode 100644 src-testing/src/lights/SpotLight.d.ts delete mode 100644 src-testing/src/lights/SpotLightShadow.d.ts delete mode 100644 src-testing/src/lights/webgpu/IESSpotLight.d.ts delete mode 100644 src-testing/src/loaders/AnimationLoader.d.ts delete mode 100644 src-testing/src/loaders/AudioLoader.d.ts delete mode 100644 src-testing/src/loaders/BufferGeometryLoader.d.ts delete mode 100644 src-testing/src/loaders/Cache.d.ts delete mode 100644 src-testing/src/loaders/CompressedTextureLoader.d.ts delete mode 100644 src-testing/src/loaders/CubeTextureLoader.d.ts delete mode 100644 src-testing/src/loaders/DataTextureLoader.d.ts delete mode 100644 src-testing/src/loaders/FileLoader.d.ts delete mode 100644 src-testing/src/loaders/ImageBitmapLoader.d.ts delete mode 100644 src-testing/src/loaders/ImageLoader.d.ts delete mode 100644 src-testing/src/loaders/Loader.d.ts delete mode 100644 src-testing/src/loaders/LoaderUtils.d.ts delete mode 100644 src-testing/src/loaders/LoadingManager.d.ts delete mode 100644 src-testing/src/loaders/MaterialLoader.d.ts delete mode 100644 src-testing/src/loaders/ObjectLoader.d.ts delete mode 100644 src-testing/src/loaders/TextureLoader.d.ts delete mode 100644 src-testing/src/loaders/nodes/NodeLoader.d.ts delete mode 100644 src-testing/src/loaders/nodes/NodeMaterialLoader.d.ts delete mode 100644 src-testing/src/loaders/nodes/NodeObjectLoader.d.ts delete mode 100644 src-testing/src/materials/LineBasicMaterial.d.ts delete mode 100644 src-testing/src/materials/LineDashedMaterial.d.ts delete mode 100644 src-testing/src/materials/Material.d.ts delete mode 100644 src-testing/src/materials/Materials.d.ts delete mode 100644 src-testing/src/materials/MeshBasicMaterial.d.ts delete mode 100644 src-testing/src/materials/MeshDepthMaterial.d.ts delete mode 100644 src-testing/src/materials/MeshDistanceMaterial.d.ts delete mode 100644 src-testing/src/materials/MeshLambertMaterial.d.ts delete mode 100644 src-testing/src/materials/MeshMatcapMaterial.d.ts delete mode 100644 src-testing/src/materials/MeshNormalMaterial.d.ts delete mode 100644 src-testing/src/materials/MeshPhongMaterial.d.ts delete mode 100644 src-testing/src/materials/MeshPhysicalMaterial.d.ts delete mode 100644 src-testing/src/materials/MeshStandardMaterial.d.ts delete mode 100644 src-testing/src/materials/MeshToonMaterial.d.ts delete mode 100644 src-testing/src/materials/PointsMaterial.d.ts delete mode 100644 src-testing/src/materials/RawShaderMaterial.d.ts delete mode 100644 src-testing/src/materials/ShaderMaterial.d.ts delete mode 100644 src-testing/src/materials/ShadowMaterial.d.ts delete mode 100644 src-testing/src/materials/SpriteMaterial.d.ts delete mode 100644 src-testing/src/materials/nodes/InstancedPointsNodeMaterial.d.ts delete mode 100644 src-testing/src/materials/nodes/Line2NodeMaterial.d.ts delete mode 100644 src-testing/src/materials/nodes/LineBasicNodeMaterial.d.ts delete mode 100644 src-testing/src/materials/nodes/LineDashedNodeMaterial.d.ts delete mode 100644 src-testing/src/materials/nodes/MeshBasicNodeMaterial.d.ts delete mode 100644 src-testing/src/materials/nodes/MeshLambertNodeMaterial.d.ts delete mode 100644 src-testing/src/materials/nodes/MeshMatcapNodeMaterial.d.ts delete mode 100644 src-testing/src/materials/nodes/MeshNormalNodeMaterial.d.ts delete mode 100644 src-testing/src/materials/nodes/MeshPhongNodeMaterial.d.ts delete mode 100644 src-testing/src/materials/nodes/MeshPhysicalNodeMaterial.d.ts delete mode 100644 src-testing/src/materials/nodes/MeshSSSNodeMaterial.d.ts delete mode 100644 src-testing/src/materials/nodes/MeshStandardNodeMaterial.d.ts delete mode 100644 src-testing/src/materials/nodes/MeshToonNodeMaterial.d.ts delete mode 100644 src-testing/src/materials/nodes/NodeMaterial.ts delete mode 100644 src-testing/src/materials/nodes/NodeMaterials.d.ts delete mode 100644 src-testing/src/materials/nodes/PointsNodeMaterial.d.ts delete mode 100644 src-testing/src/materials/nodes/ShadowNodeMaterial.d.ts delete mode 100644 src-testing/src/materials/nodes/SpriteNodeMaterial.d.ts delete mode 100644 src-testing/src/materials/nodes/VolumeNodeMaterial.d.ts delete mode 100644 src-testing/src/materials/nodes/manager/NodeMaterialObserver.ts delete mode 100644 src-testing/src/math/Box2.d.ts delete mode 100644 src-testing/src/math/Box3.d.ts delete mode 100644 src-testing/src/math/Color.d.ts delete mode 100644 src-testing/src/math/ColorManagement.d.ts delete mode 100644 src-testing/src/math/Cylindrical.d.ts delete mode 100644 src-testing/src/math/Euler.d.ts delete mode 100644 src-testing/src/math/Frustum.d.ts delete mode 100644 src-testing/src/math/Interpolant.d.ts delete mode 100644 src-testing/src/math/Line3.d.ts delete mode 100644 src-testing/src/math/MathUtils.d.ts delete mode 100644 src-testing/src/math/Matrix2.d.ts delete mode 100644 src-testing/src/math/Matrix3.d.ts delete mode 100644 src-testing/src/math/Matrix4.d.ts delete mode 100644 src-testing/src/math/Plane.d.ts delete mode 100644 src-testing/src/math/Quaternion.d.ts delete mode 100644 src-testing/src/math/Ray.d.ts delete mode 100644 src-testing/src/math/Sphere.d.ts delete mode 100644 src-testing/src/math/Spherical.d.ts delete mode 100644 src-testing/src/math/SphericalHarmonics3.d.ts delete mode 100644 src-testing/src/math/Triangle.d.ts delete mode 100644 src-testing/src/math/Vector2.d.ts delete mode 100644 src-testing/src/math/Vector3.d.ts delete mode 100644 src-testing/src/math/Vector4.d.ts delete mode 100644 src-testing/src/math/interpolants/CubicInterpolant.d.ts delete mode 100644 src-testing/src/math/interpolants/DiscreteInterpolant.d.ts delete mode 100644 src-testing/src/math/interpolants/LinearInterpolant.d.ts delete mode 100644 src-testing/src/math/interpolants/QuaternionLinearInterpolant.d.ts delete mode 100644 src-testing/src/nodes/Nodes.ts delete mode 100644 src-testing/src/nodes/TSL.d.ts delete mode 100644 src-testing/src/nodes/accessors/AccessorsUtils.d.ts delete mode 100644 src-testing/src/nodes/accessors/BatchNode.d.ts delete mode 100644 src-testing/src/nodes/accessors/Bitangent.d.ts delete mode 100644 src-testing/src/nodes/accessors/BufferAttributeNode.ts delete mode 100644 src-testing/src/nodes/accessors/BufferNode.d.ts delete mode 100644 src-testing/src/nodes/accessors/Camera.d.ts delete mode 100644 src-testing/src/nodes/accessors/ClippingNode.d.ts delete mode 100644 src-testing/src/nodes/accessors/CubeTextureNode.d.ts delete mode 100644 src-testing/src/nodes/accessors/InstanceNode.d.ts delete mode 100644 src-testing/src/nodes/accessors/MaterialNode.d.ts delete mode 100644 src-testing/src/nodes/accessors/MaterialProperties.d.ts delete mode 100644 src-testing/src/nodes/accessors/MaterialReferenceNode.d.ts delete mode 100644 src-testing/src/nodes/accessors/ModelNode.d.ts delete mode 100644 src-testing/src/nodes/accessors/ModelViewProjectionNode.d.ts delete mode 100644 src-testing/src/nodes/accessors/MorphNode.d.ts delete mode 100644 src-testing/src/nodes/accessors/Normal.d.ts delete mode 100644 src-testing/src/nodes/accessors/Object3DNode.d.ts delete mode 100644 src-testing/src/nodes/accessors/PointUVNode.d.ts delete mode 100644 src-testing/src/nodes/accessors/Position.d.ts delete mode 100644 src-testing/src/nodes/accessors/ReferenceBaseNode.d.ts delete mode 100644 src-testing/src/nodes/accessors/ReferenceNode.d.ts delete mode 100644 src-testing/src/nodes/accessors/ReflectVector.d.ts delete mode 100644 src-testing/src/nodes/accessors/RendererReferenceNode.d.ts delete mode 100644 src-testing/src/nodes/accessors/SceneNode.d.ts delete mode 100644 src-testing/src/nodes/accessors/SkinningNode.d.ts delete mode 100644 src-testing/src/nodes/accessors/StorageBufferNode.d.ts delete mode 100644 src-testing/src/nodes/accessors/StorageTextureNode.d.ts delete mode 100644 src-testing/src/nodes/accessors/Tangent.d.ts delete mode 100644 src-testing/src/nodes/accessors/Texture3DNode.d.ts delete mode 100644 src-testing/src/nodes/accessors/TextureBicubic.d.ts delete mode 100644 src-testing/src/nodes/accessors/TextureNode.ts delete mode 100644 src-testing/src/nodes/accessors/TextureSizeNode.d.ts delete mode 100644 src-testing/src/nodes/accessors/UV.d.ts delete mode 100644 src-testing/src/nodes/accessors/UniformArrayNode.d.ts delete mode 100644 src-testing/src/nodes/accessors/UserDataNode.d.ts delete mode 100644 src-testing/src/nodes/accessors/VelocityNode.d.ts delete mode 100644 src-testing/src/nodes/accessors/VertexColorNode.d.ts delete mode 100644 src-testing/src/nodes/code/CodeNode.ts delete mode 100644 src-testing/src/nodes/code/ExpressionNode.d.ts delete mode 100644 src-testing/src/nodes/code/FunctionCallNode.d.ts delete mode 100644 src-testing/src/nodes/code/FunctionNode.ts delete mode 100644 src-testing/src/nodes/code/ScriptableNode.d.ts delete mode 100644 src-testing/src/nodes/code/ScriptableValueNode.d.ts delete mode 100644 src-testing/src/nodes/core/AssignNode.d.ts delete mode 100644 src-testing/src/nodes/core/AttributeNode.d.ts delete mode 100644 src-testing/src/nodes/core/BypassNode.d.ts delete mode 100644 src-testing/src/nodes/core/CacheNode.d.ts delete mode 100644 src-testing/src/nodes/core/ConstNode.d.ts delete mode 100644 src-testing/src/nodes/core/ContextNode.ts delete mode 100644 src-testing/src/nodes/core/IndexNode.d.ts delete mode 100644 src-testing/src/nodes/core/InputNode.ts delete mode 100644 src-testing/src/nodes/core/LightingModel.d.ts delete mode 100644 src-testing/src/nodes/core/MRTNode.d.ts delete mode 100644 src-testing/src/nodes/core/Node.ts delete mode 100644 src-testing/src/nodes/core/NodeAttribute.ts delete mode 100644 src-testing/src/nodes/core/NodeBuilder.ts delete mode 100644 src-testing/src/nodes/core/NodeCache.ts delete mode 100644 src-testing/src/nodes/core/NodeCode.ts delete mode 100644 src-testing/src/nodes/core/NodeFrame.ts delete mode 100644 src-testing/src/nodes/core/NodeFunction.ts delete mode 100644 src-testing/src/nodes/core/NodeFunctionInput.d.ts delete mode 100644 src-testing/src/nodes/core/NodeParser.ts delete mode 100644 src-testing/src/nodes/core/NodeUniform.ts delete mode 100644 src-testing/src/nodes/core/NodeUtils.ts delete mode 100644 src-testing/src/nodes/core/NodeVar.ts delete mode 100644 src-testing/src/nodes/core/NodeVarying.ts delete mode 100644 src-testing/src/nodes/core/OutputStructNode.d.ts delete mode 100644 src-testing/src/nodes/core/ParameterNode.d.ts delete mode 100644 src-testing/src/nodes/core/PropertyNode.d.ts delete mode 100644 src-testing/src/nodes/core/StackNode.ts delete mode 100644 src-testing/src/nodes/core/StructTypeNode.ts delete mode 100644 src-testing/src/nodes/core/TempNode.d.ts delete mode 100644 src-testing/src/nodes/core/UniformGroup.d.ts delete mode 100644 src-testing/src/nodes/core/UniformGroupNode.ts delete mode 100644 src-testing/src/nodes/core/UniformNode.ts delete mode 100644 src-testing/src/nodes/core/VarNode.d.ts delete mode 100644 src-testing/src/nodes/core/VaryingNode.d.ts delete mode 100644 src-testing/src/nodes/core/constants.ts delete mode 100644 src-testing/src/nodes/display/BlendMode.d.ts delete mode 100644 src-testing/src/nodes/display/BumpMapNode.d.ts delete mode 100644 src-testing/src/nodes/display/ColorAdjustment.d.ts delete mode 100644 src-testing/src/nodes/display/ColorSpaceFunctions.d.ts delete mode 100644 src-testing/src/nodes/display/ColorSpaceNode.d.ts delete mode 100644 src-testing/src/nodes/display/FrontFacingNode.d.ts delete mode 100644 src-testing/src/nodes/display/NormalMapNode.d.ts delete mode 100644 src-testing/src/nodes/display/PassNode.d.ts delete mode 100644 src-testing/src/nodes/display/PosterizeNode.d.ts delete mode 100644 src-testing/src/nodes/display/RenderOutputNode.d.ts delete mode 100644 src-testing/src/nodes/display/ScreenNode.d.ts delete mode 100644 src-testing/src/nodes/display/ToneMappingFunctions.d.ts delete mode 100644 src-testing/src/nodes/display/ToneMappingNode.d.ts delete mode 100644 src-testing/src/nodes/display/ToonOutlinePassNode.d.ts delete mode 100644 src-testing/src/nodes/display/ViewportDepthNode.d.ts delete mode 100644 src-testing/src/nodes/display/ViewportDepthTextureNode.d.ts delete mode 100644 src-testing/src/nodes/display/ViewportSharedTextureNode.d.ts delete mode 100644 src-testing/src/nodes/display/ViewportTextureNode.d.ts delete mode 100644 src-testing/src/nodes/fog/FogExp2Node.d.ts delete mode 100644 src-testing/src/nodes/fog/FogNode.ts delete mode 100644 src-testing/src/nodes/fog/FogRangeNode.d.ts delete mode 100644 src-testing/src/nodes/functions/BSDF/BRDF_GGX.d.ts delete mode 100644 src-testing/src/nodes/functions/BSDF/BRDF_Lambert.d.ts delete mode 100644 src-testing/src/nodes/functions/BSDF/BRDF_Sheen.d.ts delete mode 100644 src-testing/src/nodes/functions/BSDF/DFGApprox.d.ts delete mode 100644 src-testing/src/nodes/functions/BSDF/D_GGX.d.ts delete mode 100644 src-testing/src/nodes/functions/BSDF/D_GGX_Anisotropic.d.ts delete mode 100644 src-testing/src/nodes/functions/BSDF/F_Schlick.d.ts delete mode 100644 src-testing/src/nodes/functions/BSDF/LTC.d.ts delete mode 100644 src-testing/src/nodes/functions/BSDF/Schlick_to_F0.d.ts delete mode 100644 src-testing/src/nodes/functions/BSDF/V_GGX_SmithCorrelated.d.ts delete mode 100644 src-testing/src/nodes/functions/BSDF/V_GGX_SmithCorrelated_Anisotropic.d.ts delete mode 100644 src-testing/src/nodes/functions/BasicLightingModel.d.ts delete mode 100644 src-testing/src/nodes/functions/PhongLightingModel.d.ts delete mode 100644 src-testing/src/nodes/functions/PhysicalLightingModel.d.ts delete mode 100644 src-testing/src/nodes/functions/ShadowMaskModel.d.ts delete mode 100644 src-testing/src/nodes/functions/ToonLightingModel.d.ts delete mode 100644 src-testing/src/nodes/functions/material/getGeometryRoughness.d.ts delete mode 100644 src-testing/src/nodes/functions/material/getRoughness.d.ts delete mode 100644 src-testing/src/nodes/functions/material/getShIrradianceAt.d.ts delete mode 100644 src-testing/src/nodes/geometry/RangeNode.d.ts delete mode 100644 src-testing/src/nodes/gpgpu/ComputeNode.ts delete mode 100644 src-testing/src/nodes/lighting/AONode.d.ts delete mode 100644 src-testing/src/nodes/lighting/AmbientLightNode.d.ts delete mode 100644 src-testing/src/nodes/lighting/AnalyticLightNode.d.ts delete mode 100644 src-testing/src/nodes/lighting/BasicEnvironmentNode.d.ts delete mode 100644 src-testing/src/nodes/lighting/BasicLightMapNode.d.ts delete mode 100644 src-testing/src/nodes/lighting/DirectionalLightNode.d.ts delete mode 100644 src-testing/src/nodes/lighting/EnvironmentNode.ts delete mode 100644 src-testing/src/nodes/lighting/HemisphereLightNode.d.ts delete mode 100644 src-testing/src/nodes/lighting/IESSpotLightNode.d.ts delete mode 100644 src-testing/src/nodes/lighting/IrradianceNode.d.ts delete mode 100644 src-testing/src/nodes/lighting/LightNode.d.ts delete mode 100644 src-testing/src/nodes/lighting/LightProbeNode.d.ts delete mode 100644 src-testing/src/nodes/lighting/LightUtils.d.ts delete mode 100644 src-testing/src/nodes/lighting/LightingContextNode.ts delete mode 100644 src-testing/src/nodes/lighting/LightingNode.d.ts delete mode 100644 src-testing/src/nodes/lighting/LightsNode.ts delete mode 100644 src-testing/src/nodes/lighting/PointLightNode.d.ts delete mode 100644 src-testing/src/nodes/lighting/RectAreaLightNode.d.ts delete mode 100644 src-testing/src/nodes/lighting/ShadowNode.d.ts delete mode 100644 src-testing/src/nodes/lighting/SpotLightNode.d.ts delete mode 100644 src-testing/src/nodes/materialx/MaterialXNodes.d.ts delete mode 100644 src-testing/src/nodes/materialx/lib/mx_hsv.d.ts delete mode 100644 src-testing/src/nodes/materialx/lib/mx_noise.d.ts delete mode 100644 src-testing/src/nodes/materialx/lib/mx_transform_color.d.ts delete mode 100644 src-testing/src/nodes/math/ConditionalNode.d.ts delete mode 100644 src-testing/src/nodes/math/Hash.d.ts delete mode 100644 src-testing/src/nodes/math/MathNode.d.ts delete mode 100644 src-testing/src/nodes/math/MathUtils.d.ts delete mode 100644 src-testing/src/nodes/math/OperatorNode.d.ts delete mode 100644 src-testing/src/nodes/math/TriNoise3D.d.ts delete mode 100644 src-testing/src/nodes/parsers/GLSLNodeFunction.d.ts delete mode 100644 src-testing/src/nodes/parsers/GLSLNodeParser.d.ts delete mode 100644 src-testing/src/nodes/pmrem/PMREMNode.d.ts delete mode 100644 src-testing/src/nodes/pmrem/PMREMUtils.d.ts delete mode 100644 src-testing/src/nodes/procedural/Checker.d.ts delete mode 100644 src-testing/src/nodes/tsl/TSLBase.d.ts delete mode 100644 src-testing/src/nodes/tsl/TSLCore.ts delete mode 100644 src-testing/src/nodes/utils/ArrayElementNode.d.ts delete mode 100644 src-testing/src/nodes/utils/ConvertNode.d.ts delete mode 100644 src-testing/src/nodes/utils/CubeMapNode.d.ts delete mode 100644 src-testing/src/nodes/utils/Discard.d.ts delete mode 100644 src-testing/src/nodes/utils/EquirectUVNode.d.ts delete mode 100644 src-testing/src/nodes/utils/FunctionOverloadingNode.d.ts delete mode 100644 src-testing/src/nodes/utils/JoinNode.d.ts delete mode 100644 src-testing/src/nodes/utils/LoopNode.d.ts delete mode 100644 src-testing/src/nodes/utils/MatcapUVNode.d.ts delete mode 100644 src-testing/src/nodes/utils/MaxMipLevelNode.d.ts delete mode 100644 src-testing/src/nodes/utils/Oscillators.d.ts delete mode 100644 src-testing/src/nodes/utils/Packing.d.ts delete mode 100644 src-testing/src/nodes/utils/PostProcessingUtils.d.ts delete mode 100644 src-testing/src/nodes/utils/RTTNode.d.ts delete mode 100644 src-testing/src/nodes/utils/ReflectorNode.d.ts delete mode 100644 src-testing/src/nodes/utils/RemapNode.d.ts delete mode 100644 src-testing/src/nodes/utils/RotateNode.d.ts delete mode 100644 src-testing/src/nodes/utils/SetNode.d.ts delete mode 100644 src-testing/src/nodes/utils/SplitNode.d.ts delete mode 100644 src-testing/src/nodes/utils/SpriteSheetUVNode.d.ts delete mode 100644 src-testing/src/nodes/utils/SpriteUtils.d.ts delete mode 100644 src-testing/src/nodes/utils/StorageArrayElementNode.d.ts delete mode 100644 src-testing/src/nodes/utils/Timer.d.ts delete mode 100644 src-testing/src/nodes/utils/TriplanarTexturesNode.d.ts delete mode 100644 src-testing/src/nodes/utils/UVUtils.d.ts delete mode 100644 src-testing/src/nodes/utils/ViewportUtils.d.ts delete mode 100644 src-testing/src/objects/BatchedMesh.d.ts delete mode 100644 src-testing/src/objects/Bone.d.ts delete mode 100644 src-testing/src/objects/Group.d.ts delete mode 100644 src-testing/src/objects/InstancedMesh.d.ts delete mode 100644 src-testing/src/objects/LOD.d.ts delete mode 100644 src-testing/src/objects/Line.d.ts delete mode 100644 src-testing/src/objects/LineLoop.d.ts delete mode 100644 src-testing/src/objects/LineSegments.d.ts delete mode 100644 src-testing/src/objects/Mesh.d.ts delete mode 100644 src-testing/src/objects/Points.d.ts delete mode 100644 src-testing/src/objects/Skeleton.d.ts delete mode 100644 src-testing/src/objects/SkinnedMesh.d.ts delete mode 100644 src-testing/src/objects/Sprite.d.ts delete mode 100644 src-testing/src/renderers/WebGL3DRenderTarget.d.ts delete mode 100644 src-testing/src/renderers/WebGLArrayRenderTarget.d.ts delete mode 100644 src-testing/src/renderers/WebGLCubeRenderTarget.d.ts delete mode 100644 src-testing/src/renderers/WebGLRenderTarget.d.ts delete mode 100644 src-testing/src/renderers/WebGLRenderer.d.ts delete mode 100644 src-testing/src/renderers/common/Animation.ts delete mode 100644 src-testing/src/renderers/common/Attributes.ts delete mode 100644 src-testing/src/renderers/common/Backend.ts delete mode 100644 src-testing/src/renderers/common/Background.ts delete mode 100644 src-testing/src/renderers/common/BindGroup.ts delete mode 100644 src-testing/src/renderers/common/Binding.ts delete mode 100644 src-testing/src/renderers/common/Bindings.ts delete mode 100644 src-testing/src/renderers/common/Buffer.ts delete mode 100644 src-testing/src/renderers/common/BufferUtils.ts delete mode 100644 src-testing/src/renderers/common/BundleGroup.ts delete mode 100644 src-testing/src/renderers/common/ChainMap.ts delete mode 100644 src-testing/src/renderers/common/ClippingContext.ts delete mode 100644 src-testing/src/renderers/common/Color4.ts delete mode 100644 src-testing/src/renderers/common/ComputePipeline.ts delete mode 100644 src-testing/src/renderers/common/Constants.ts delete mode 100644 src-testing/src/renderers/common/CubeRenderTarget.ts delete mode 100644 src-testing/src/renderers/common/DataMap.ts delete mode 100644 src-testing/src/renderers/common/Geometries.ts delete mode 100644 src-testing/src/renderers/common/IndirectStorageBufferAttribute.d.ts delete mode 100644 src-testing/src/renderers/common/Info.ts delete mode 100644 src-testing/src/renderers/common/Lighting.d.ts delete mode 100644 src-testing/src/renderers/common/Pipeline.ts delete mode 100644 src-testing/src/renderers/common/Pipelines.ts delete mode 100644 src-testing/src/renderers/common/PostProcessing.d.ts delete mode 100644 src-testing/src/renderers/common/PostProcessingUtils.d.ts delete mode 100644 src-testing/src/renderers/common/ProgrammableStage.ts delete mode 100644 src-testing/src/renderers/common/QuadMesh.d.ts delete mode 100644 src-testing/src/renderers/common/RenderBundle.ts delete mode 100644 src-testing/src/renderers/common/RenderBundles.ts delete mode 100644 src-testing/src/renderers/common/RenderContext.ts delete mode 100644 src-testing/src/renderers/common/RenderContexts.ts delete mode 100644 src-testing/src/renderers/common/RenderList.ts delete mode 100644 src-testing/src/renderers/common/RenderLists.ts delete mode 100644 src-testing/src/renderers/common/RenderObject.ts delete mode 100644 src-testing/src/renderers/common/RenderObjects.ts delete mode 100644 src-testing/src/renderers/common/RenderPipeline.ts delete mode 100644 src-testing/src/renderers/common/Renderer.ts delete mode 100644 src-testing/src/renderers/common/SampledTexture.ts delete mode 100644 src-testing/src/renderers/common/Sampler.ts delete mode 100644 src-testing/src/renderers/common/StorageBuffer.ts delete mode 100644 src-testing/src/renderers/common/StorageBufferAttribute.d.ts delete mode 100644 src-testing/src/renderers/common/StorageInstancedBufferAttribute.d.ts delete mode 100644 src-testing/src/renderers/common/StorageTexture.d.ts delete mode 100644 src-testing/src/renderers/common/Textures.ts delete mode 100644 src-testing/src/renderers/common/Uniform.ts delete mode 100644 src-testing/src/renderers/common/UniformBuffer.ts delete mode 100644 src-testing/src/renderers/common/UniformsGroup.ts delete mode 100644 src-testing/src/renderers/common/extras/PMREMGenerator.ts delete mode 100644 src-testing/src/renderers/common/nodes/NodeBuilderState.ts delete mode 100644 src-testing/src/renderers/common/nodes/NodeLibrary.ts delete mode 100644 src-testing/src/renderers/common/nodes/NodeSampledTexture.d.ts delete mode 100644 src-testing/src/renderers/common/nodes/NodeSampler.d.ts delete mode 100644 src-testing/src/renderers/common/nodes/NodeUniform.ts delete mode 100644 src-testing/src/renderers/common/nodes/NodeUniformsGroup.ts delete mode 100644 src-testing/src/renderers/common/nodes/Nodes.ts delete mode 100644 src-testing/src/renderers/common/nodes/StandardNodeLibrary.d.ts delete mode 100644 src-testing/src/renderers/shaders/ShaderChunk.d.ts delete mode 100644 src-testing/src/renderers/shaders/ShaderLib.d.ts delete mode 100644 src-testing/src/renderers/shaders/UniformsLib.d.ts delete mode 100644 src-testing/src/renderers/shaders/UniformsUtils.d.ts delete mode 100644 src-testing/src/renderers/webgl-fallback/WebGLBackend.ts delete mode 100644 src-testing/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.ts delete mode 100644 src-testing/src/renderers/webgl/WebGLAttributes.d.ts delete mode 100644 src-testing/src/renderers/webgl/WebGLBindingStates.d.ts delete mode 100644 src-testing/src/renderers/webgl/WebGLBufferRenderer.d.ts delete mode 100644 src-testing/src/renderers/webgl/WebGLCapabilities.d.ts delete mode 100644 src-testing/src/renderers/webgl/WebGLClipping.d.ts delete mode 100644 src-testing/src/renderers/webgl/WebGLCubeMaps.d.ts delete mode 100644 src-testing/src/renderers/webgl/WebGLCubeUVMaps.d.ts delete mode 100644 src-testing/src/renderers/webgl/WebGLExtensions.d.ts delete mode 100644 src-testing/src/renderers/webgl/WebGLGeometries.d.ts delete mode 100644 src-testing/src/renderers/webgl/WebGLIndexedBufferRenderer.d.ts delete mode 100644 src-testing/src/renderers/webgl/WebGLInfo.d.ts delete mode 100644 src-testing/src/renderers/webgl/WebGLLights.d.ts delete mode 100644 src-testing/src/renderers/webgl/WebGLObjects.d.ts delete mode 100644 src-testing/src/renderers/webgl/WebGLProgram.d.ts delete mode 100644 src-testing/src/renderers/webgl/WebGLPrograms.d.ts delete mode 100644 src-testing/src/renderers/webgl/WebGLProperties.d.ts delete mode 100644 src-testing/src/renderers/webgl/WebGLRenderLists.d.ts delete mode 100644 src-testing/src/renderers/webgl/WebGLShader.d.ts delete mode 100644 src-testing/src/renderers/webgl/WebGLShadowMap.d.ts delete mode 100644 src-testing/src/renderers/webgl/WebGLState.d.ts delete mode 100644 src-testing/src/renderers/webgl/WebGLTextures.d.ts delete mode 100644 src-testing/src/renderers/webgl/WebGLUniforms.d.ts delete mode 100644 src-testing/src/renderers/webgl/WebGLUniformsGroups.d.ts delete mode 100644 src-testing/src/renderers/webgl/WebGLUtils.d.ts delete mode 100644 src-testing/src/renderers/webgpu/WebGPUBackend.ts delete mode 100644 src-testing/src/renderers/webgpu/WebGPURenderer.Nodes.d.ts delete mode 100644 src-testing/src/renderers/webgpu/WebGPURenderer.ts delete mode 100644 src-testing/src/renderers/webgpu/nodes/BasicNodeLibrary.ts delete mode 100644 src-testing/src/renderers/webgpu/nodes/StandardNodeLibrary.ts delete mode 100644 src-testing/src/renderers/webgpu/nodes/WGSLNodeBuilder.ts delete mode 100644 src-testing/src/renderers/webgpu/nodes/WGSLNodeFunction.ts delete mode 100644 src-testing/src/renderers/webgpu/nodes/WGSLNodeParser.ts delete mode 100644 src-testing/src/renderers/webgpu/utils/WebGPUConstants.d.ts delete mode 100644 src-testing/src/renderers/webxr/WebXRController.d.ts delete mode 100644 src-testing/src/renderers/webxr/WebXRDepthSensing.d.ts delete mode 100644 src-testing/src/renderers/webxr/WebXRManager.d.ts delete mode 100644 src-testing/src/scenes/Fog.d.ts delete mode 100644 src-testing/src/scenes/FogExp2.d.ts delete mode 100644 src-testing/src/scenes/Scene.d.ts delete mode 100644 src-testing/src/textures/CanvasTexture.d.ts delete mode 100644 src-testing/src/textures/CompressedArrayTexture.d.ts delete mode 100644 src-testing/src/textures/CompressedCubeTexture.d.ts delete mode 100644 src-testing/src/textures/CompressedTexture.d.ts delete mode 100644 src-testing/src/textures/CubeTexture.d.ts delete mode 100644 src-testing/src/textures/Data3DTexture.d.ts delete mode 100644 src-testing/src/textures/DataArrayTexture.d.ts delete mode 100644 src-testing/src/textures/DataTexture.d.ts delete mode 100644 src-testing/src/textures/DepthTexture.d.ts delete mode 100644 src-testing/src/textures/FramebufferTexture.d.ts delete mode 100644 src-testing/src/textures/Source.d.ts delete mode 100644 src-testing/src/textures/Texture.d.ts delete mode 100644 src-testing/src/textures/VideoTexture.d.ts delete mode 100644 src-testing/src/textures/types.d.ts delete mode 100644 src-testing/src/utils.d.ts diff --git a/src-testing/changes.patch b/src-testing/changes.patch index dd501907e..7020a9c2e 100644 --- a/src-testing/changes.patch +++ b/src-testing/changes.patch @@ -6705,10 +6705,10 @@ index 520a3c91..524d188c 100644 } else { bindings.push(instanceGroup); diff --git a/src-testing/src/renderers/common/nodes/NodeLibrary.ts b/src-testing/src/renderers/common/nodes/NodeLibrary.ts -index 15931016..2128aa79 100644 +index b6738b95..6c1eaf57 100644 --- a/src-testing/src/renderers/common/nodes/NodeLibrary.ts +++ b/src-testing/src/renderers/common/nodes/NodeLibrary.ts -@@ -1,4 +1,21 @@ +@@ -1,12 +1,29 @@ +import { Material } from '../../../materials/Material.js'; +import NodeMaterial from '../../../materials/nodes/NodeMaterial.js'; +import { ToneMapping } from '../../../constants.js'; @@ -6730,8 +6730,7 @@ index 15931016..2128aa79 100644 constructor() { this.lightNodes = new WeakMap(); this.materialNodes = new Map(); -@@ -6,8 +23,8 @@ class NodeLibrary { - this.colorSpaceNodes = new Map(); + this.toneMappingNodes = new Map(); } - fromMaterial(material) { @@ -6741,20 +6740,10 @@ index 15931016..2128aa79 100644 let nodeMaterial = null; -@@ -24,39 +41,52 @@ class NodeLibrary { +@@ -23,31 +40,44 @@ class NodeLibrary { return nodeMaterial; } -- addColorSpace(colorSpaceNode, colorSpace) { -+ addColorSpace(colorSpaceNode: (color: NodeRepresentation) => ShaderNodeObject, colorSpace: ColorSpaceMethod) { - this.addType(colorSpaceNode, colorSpace, this.colorSpaceNodes); - } - -- getColorSpaceFunction(colorSpace) { -+ getColorSpaceFunction(colorSpace: ColorSpaceMethod) { - return this.colorSpaceNodes.get(colorSpace) || null; - } - - addToneMapping(toneMappingNode, toneMapping) { + addToneMapping( + toneMappingNode: (color: NodeRepresentation, exposure: NodeRepresentation) => ShaderNodeObject, @@ -6804,7 +6793,7 @@ index 15931016..2128aa79 100644 if (library.has(type)) { console.warn(`Redefinition of node ${type}`); return; -@@ -69,7 +99,11 @@ class NodeLibrary { +@@ -60,7 +90,11 @@ class NodeLibrary { library.set(type, nodeClass); } diff --git a/src-testing/src/Three.Legacy.d.ts b/src-testing/src/Three.Legacy.d.ts deleted file mode 100644 index 07f4743b9..000000000 --- a/src-testing/src/Three.Legacy.d.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { RenderTargetOptions } from "./core/RenderTarget.js"; -import { WebGLRenderTarget } from "./renderers/WebGLRenderTarget.js"; -import { Texture } from "./textures/Texture.js"; - -/** - * @deprecated THREE.WebGLMultipleRenderTargets has been deprecated and will be removed in r172. Use THREE.WebGLRenderTarget and set the "count" parameter to enable MRT. - */ -export class WebGLMultipleRenderTargets extends WebGLRenderTarget { - readonly isWebGLMultipleRenderTargets: true; - - /** - * @deprecated THREE.WebGLMultipleRenderTargets has been deprecated and will be removed in r172. Use THREE.WebGLRenderTarget and set the "count" parameter to enable MRT. - * @param width The width of the render target. - * @param height The height of the render target. - * @param count The number of render targets. - * @param options object that holds texture parameters for an auto-generated target texture and depthBuffer/stencilBuffer booleans. - * For an explanation of the texture parameters see {@link Texture}. - */ - constructor(width?: number, height?: number, count?: number, options?: RenderTargetOptions); -} diff --git a/src-testing/src/Three.WebGPU.Nodes.d.ts b/src-testing/src/Three.WebGPU.Nodes.d.ts deleted file mode 100644 index ac876f6fe..000000000 --- a/src-testing/src/Three.WebGPU.Nodes.d.ts +++ /dev/null @@ -1,205 +0,0 @@ -export * from "./animation/AnimationAction.js"; -export * from "./animation/AnimationClip.js"; -export * from "./animation/AnimationMixer.js"; -export * from "./animation/AnimationObjectGroup.js"; -export { AnimationUtils } from "./animation/AnimationUtils.js"; -export * from "./animation/KeyframeTrack.js"; -export * from "./animation/PropertyBinding.js"; -export * from "./animation/PropertyMixer.js"; -export * from "./animation/tracks/BooleanKeyframeTrack.js"; -export * from "./animation/tracks/ColorKeyframeTrack.js"; -export * from "./animation/tracks/NumberKeyframeTrack.js"; -export * from "./animation/tracks/QuaternionKeyframeTrack.js"; -export * from "./animation/tracks/StringKeyframeTrack.js"; -export * from "./animation/tracks/VectorKeyframeTrack.js"; -export * from "./audio/Audio.js"; -export * from "./audio/AudioAnalyser.js"; -export * from "./audio/AudioContext.js"; -export * from "./audio/AudioListener.js"; -export * from "./audio/PositionalAudio.js"; -export * from "./cameras/ArrayCamera.js"; -export * from "./cameras/Camera.js"; -export * from "./cameras/CubeCamera.js"; -export * from "./cameras/OrthographicCamera.js"; -export * from "./cameras/PerspectiveCamera.js"; -export * from "./cameras/StereoCamera.js"; -export * from "./constants.js"; -export * from "./core/BufferAttribute.js"; -export * from "./core/BufferGeometry.js"; -export * from "./core/Clock.js"; -export * from "./core/EventDispatcher.js"; -export * from "./core/GLBufferAttribute.js"; -export * from "./core/InstancedBufferAttribute.js"; -export * from "./core/InstancedBufferGeometry.js"; -export * from "./core/InstancedInterleavedBuffer.js"; -export * from "./core/InterleavedBuffer.js"; -export * from "./core/InterleavedBufferAttribute.js"; -export * from "./core/Layers.js"; -export * from "./core/Object3D.js"; -export * from "./core/Raycaster.js"; -export * from "./core/RenderTarget.js"; -export * from "./core/Uniform.js"; -export * from "./core/UniformsGroup.js"; -export * from "./extras/Controls.js"; -export * from "./extras/core/Curve.js"; -export * from "./extras/core/CurvePath.js"; -export * from "./extras/core/Path.js"; -export * from "./extras/core/Shape.js"; -export * from "./extras/core/ShapePath.js"; -export * from "./extras/curves/Curves.js"; -export { DataUtils } from "./extras/DataUtils.js"; -export * from "./extras/ImageUtils.js"; -// export * from "./extras/PMREMGenerator.js"; -export * from "./extras/ShapeUtils.js"; -export { TextureUtils } from "./extras/TextureUtils.js"; -export * from "./geometries/Geometries.js"; -export * from "./helpers/ArrowHelper.js"; -export * from "./helpers/AxesHelper.js"; -export * from "./helpers/Box3Helper.js"; -export * from "./helpers/BoxHelper.js"; -export * from "./helpers/CameraHelper.js"; -export * from "./helpers/DirectionalLightHelper.js"; -export * from "./helpers/GridHelper.js"; -export * from "./helpers/HemisphereLightHelper.js"; -export * from "./helpers/PlaneHelper.js"; -export * from "./helpers/PointLightHelper.js"; -export * from "./helpers/PolarGridHelper.js"; -export * from "./helpers/SkeletonHelper.js"; -export * from "./helpers/SpotLightHelper.js"; -export * from "./lights/AmbientLight.js"; -export * from "./lights/DirectionalLight.js"; -export type { DirectionalLightShadow } from "./lights/DirectionalLightShadow.js"; -export * from "./lights/HemisphereLight.js"; -export * from "./lights/Light.js"; -export * from "./lights/LightProbe.js"; -export type { LightShadow, LightShadowJSON } from "./lights/LightShadow.js"; -export * from "./lights/PointLight.js"; -export type { PointLightShadow } from "./lights/PointLightShadow.js"; -export * from "./lights/RectAreaLight.js"; -export * from "./lights/SpotLight.js"; -export type { SpotLightShadow } from "./lights/SpotLightShadow.js"; -export * from "./loaders/AnimationLoader.js"; -export * from "./loaders/AudioLoader.js"; -export * from "./loaders/BufferGeometryLoader.js"; -export * from "./loaders/Cache.js"; -export * from "./loaders/CompressedTextureLoader.js"; -export * from "./loaders/CubeTextureLoader.js"; -export * from "./loaders/DataTextureLoader.js"; -export * from "./loaders/FileLoader.js"; -export * from "./loaders/ImageBitmapLoader.js"; -export * from "./loaders/ImageLoader.js"; -export * from "./loaders/Loader.js"; -export * from "./loaders/LoaderUtils.js"; -export * from "./loaders/LoadingManager.js"; -export * from "./loaders/MaterialLoader.js"; -export * from "./loaders/ObjectLoader.js"; -export * from "./loaders/TextureLoader.js"; -export * from "./materials/Materials.js"; -export * from "./materials/nodes/NodeMaterials.js"; -export * from "./math/Box2.js"; -export * from "./math/Box3.js"; -export * from "./math/Color.js"; -export { ColorManagement, ColorSpaceDefinition } from "./math/ColorManagement.js"; -export * from "./math/Cylindrical.js"; -export * from "./math/Euler.js"; -export * from "./math/Frustum.js"; -export * from "./math/Interpolant.js"; -export * from "./math/interpolants/CubicInterpolant.js"; -export * from "./math/interpolants/DiscreteInterpolant.js"; -export * from "./math/interpolants/LinearInterpolant.js"; -export * from "./math/interpolants/QuaternionLinearInterpolant.js"; -export * from "./math/Line3.js"; -export { MathUtils } from "./math/MathUtils.js"; -export * from "./math/Matrix2.js"; -export * from "./math/Matrix3.js"; -export * from "./math/Matrix4.js"; -export * from "./math/Plane.js"; -export * from "./math/Quaternion.js"; -export * from "./math/Ray.js"; -export * from "./math/Sphere.js"; -export * from "./math/Spherical.js"; -export * from "./math/SphericalHarmonics3.js"; -export * from "./math/Triangle.js"; -export * from "./math/Vector2.js"; -export * from "./math/Vector3.js"; -export * from "./math/Vector4.js"; -export * from "./objects/BatchedMesh.js"; -export * from "./objects/Bone.js"; -export * from "./objects/Group.js"; -export * from "./objects/InstancedMesh.js"; -export * from "./objects/Line.js"; -export * from "./objects/LineLoop.js"; -export * from "./objects/LineSegments.js"; -export * from "./objects/LOD.js"; -export * from "./objects/Mesh.js"; -export * from "./objects/Points.js"; -export * from "./objects/Skeleton.js"; -export * from "./objects/SkinnedMesh.js"; -export * from "./objects/Sprite.js"; -// export * from "./renderers/shaders/ShaderChunk.js"; -// export * from "./renderers/shaders/ShaderLib.js"; -// export * from "./renderers/shaders/UniformsLib.js"; -// export { UniformsUtils } from './renderers/shaders/UniformsUtils.js'; -export type { WebGLProgramParameters, WebGLProgramParametersWithUniforms } from "./renderers/webgl/WebGLPrograms.js"; -export type { WebGLShadowMap } from "./renderers/webgl/WebGLShadowMap.js"; -// export * from "./renderers/webgl/WebGLUtils.js"; -export * from "./renderers/WebGL3DRenderTarget.js"; -export * from "./renderers/WebGLArrayRenderTarget.js"; -export * from "./renderers/WebGLCubeRenderTarget.js"; -// export * from "./renderers/WebGLRenderer.js"; -export * from "./renderers/WebGLRenderTarget.js"; -export type { - WebXRController, - WebXRSpaceEventMap, - XRControllerEventType, - XRGripSpace, - XRHandInputState, - XRHandJoints, - XRHandSpace, - XRJointSpace, - XRTargetRaySpace, -} from "./renderers/webxr/WebXRController.js"; -export type { WebXRDepthSensing } from "./renderers/webxr/WebXRDepthSensing.js"; -export type { - WebXRArrayCamera, - WebXRCamera, - WebXRManager, - WebXRManagerEventMap, -} from "./renderers/webxr/WebXRManager.js"; -export * from "./scenes/Fog.js"; -export * from "./scenes/FogExp2.js"; -export * from "./scenes/Scene.js"; -export * from "./textures/CanvasTexture.js"; -export * from "./textures/CompressedArrayTexture.js"; -export * from "./textures/CompressedCubeTexture.js"; -export * from "./textures/CompressedTexture.js"; -export * from "./textures/CubeTexture.js"; -export * from "./textures/Data3DTexture.js"; -export * from "./textures/DataArrayTexture.js"; -export * from "./textures/DataTexture.js"; -export * from "./textures/DepthTexture.js"; -export * from "./textures/FramebufferTexture.js"; -export * from "./textures/Source.js"; -export * from "./textures/Texture.js"; -export * from "./textures/VideoTexture.js"; -export * from "./Three.Legacy.js"; -export { createCanvasElement } from "./utils.js"; - -export { default as IESSpotLight } from "./lights/webgpu/IESSpotLight.js"; -export { default as NodeLoader } from "./loaders/nodes/NodeLoader.js"; -export { default as NodeMaterialLoader } from "./loaders/nodes/NodeMaterialLoader.js"; -export { default as NodeObjectLoader } from "./loaders/nodes/NodeObjectLoader.js"; -export * from "./nodes/Nodes.js"; -export * from "./nodes/TSL.js"; -export { default as PMREMGenerator } from "./renderers/common/extras/PMREMGenerator.js"; -export { default as PostProcessing } from "./renderers/common/PostProcessing.js"; -import * as PostProcessingUtils from "./renderers/common/PostProcessingUtils.js"; -export { PostProcessingUtils }; -export { default as IndirectStorageBufferAttribute } from "./renderers/common/IndirectStorageBufferAttribute.js"; -export { default as Lighting } from "./renderers/common/Lighting.js"; -export { default as QuadMesh } from "./renderers/common/QuadMesh.js"; -export type { default as Renderer } from "./renderers/common/Renderer.js"; -export { default as StorageBufferAttribute } from "./renderers/common/StorageBufferAttribute.js"; -export { default as StorageInstancedBufferAttribute } from "./renderers/common/StorageInstancedBufferAttribute.js"; -export { default as StorageTexture } from "./renderers/common/StorageTexture.js"; -export { default as WebGPURenderer } from "./renderers/webgpu/WebGPURenderer.Nodes.js"; diff --git a/src-testing/src/Three.WebGPU.d.ts b/src-testing/src/Three.WebGPU.d.ts deleted file mode 100644 index 254ef5332..000000000 --- a/src-testing/src/Three.WebGPU.d.ts +++ /dev/null @@ -1,206 +0,0 @@ -export * from "./animation/AnimationAction.js"; -export * from "./animation/AnimationClip.js"; -export * from "./animation/AnimationMixer.js"; -export * from "./animation/AnimationObjectGroup.js"; -export { AnimationUtils } from "./animation/AnimationUtils.js"; -export * from "./animation/KeyframeTrack.js"; -export * from "./animation/PropertyBinding.js"; -export * from "./animation/PropertyMixer.js"; -export * from "./animation/tracks/BooleanKeyframeTrack.js"; -export * from "./animation/tracks/ColorKeyframeTrack.js"; -export * from "./animation/tracks/NumberKeyframeTrack.js"; -export * from "./animation/tracks/QuaternionKeyframeTrack.js"; -export * from "./animation/tracks/StringKeyframeTrack.js"; -export * from "./animation/tracks/VectorKeyframeTrack.js"; -export * from "./audio/Audio.js"; -export * from "./audio/AudioAnalyser.js"; -export * from "./audio/AudioContext.js"; -export * from "./audio/AudioListener.js"; -export * from "./audio/PositionalAudio.js"; -export * from "./cameras/ArrayCamera.js"; -export * from "./cameras/Camera.js"; -export * from "./cameras/CubeCamera.js"; -export * from "./cameras/OrthographicCamera.js"; -export * from "./cameras/PerspectiveCamera.js"; -export * from "./cameras/StereoCamera.js"; -export * from "./constants.js"; -export * from "./core/BufferAttribute.js"; -export * from "./core/BufferGeometry.js"; -export * from "./core/Clock.js"; -export * from "./core/EventDispatcher.js"; -export * from "./core/GLBufferAttribute.js"; -export * from "./core/InstancedBufferAttribute.js"; -export * from "./core/InstancedBufferGeometry.js"; -export * from "./core/InstancedInterleavedBuffer.js"; -export * from "./core/InterleavedBuffer.js"; -export * from "./core/InterleavedBufferAttribute.js"; -export * from "./core/Layers.js"; -export * from "./core/Object3D.js"; -export * from "./core/Raycaster.js"; -export * from "./core/RenderTarget.js"; -export * from "./core/Uniform.js"; -export * from "./core/UniformsGroup.js"; -export * from "./extras/Controls.js"; -export * from "./extras/core/Curve.js"; -export * from "./extras/core/CurvePath.js"; -export * from "./extras/core/Path.js"; -export * from "./extras/core/Shape.js"; -export * from "./extras/core/ShapePath.js"; -export * from "./extras/curves/Curves.js"; -export { DataUtils } from "./extras/DataUtils.js"; -export * from "./extras/ImageUtils.js"; -// export * from "./extras/PMREMGenerator.js"; -export * from "./extras/ShapeUtils.js"; -export { TextureUtils } from "./extras/TextureUtils.js"; -export * from "./geometries/Geometries.js"; -export * from "./helpers/ArrowHelper.js"; -export * from "./helpers/AxesHelper.js"; -export * from "./helpers/Box3Helper.js"; -export * from "./helpers/BoxHelper.js"; -export * from "./helpers/CameraHelper.js"; -export * from "./helpers/DirectionalLightHelper.js"; -export * from "./helpers/GridHelper.js"; -export * from "./helpers/HemisphereLightHelper.js"; -export * from "./helpers/PlaneHelper.js"; -export * from "./helpers/PointLightHelper.js"; -export * from "./helpers/PolarGridHelper.js"; -export * from "./helpers/SkeletonHelper.js"; -export * from "./helpers/SpotLightHelper.js"; -export * from "./lights/AmbientLight.js"; -export * from "./lights/DirectionalLight.js"; -export type { DirectionalLightShadow } from "./lights/DirectionalLightShadow.js"; -export * from "./lights/HemisphereLight.js"; -export * from "./lights/Light.js"; -export * from "./lights/LightProbe.js"; -export type { LightShadow, LightShadowJSON } from "./lights/LightShadow.js"; -export * from "./lights/PointLight.js"; -export type { PointLightShadow } from "./lights/PointLightShadow.js"; -export * from "./lights/RectAreaLight.js"; -export * from "./lights/SpotLight.js"; -export type { SpotLightShadow } from "./lights/SpotLightShadow.js"; -export * from "./loaders/AnimationLoader.js"; -export * from "./loaders/AudioLoader.js"; -export * from "./loaders/BufferGeometryLoader.js"; -export * from "./loaders/Cache.js"; -export * from "./loaders/CompressedTextureLoader.js"; -export * from "./loaders/CubeTextureLoader.js"; -export * from "./loaders/DataTextureLoader.js"; -export * from "./loaders/FileLoader.js"; -export * from "./loaders/ImageBitmapLoader.js"; -export * from "./loaders/ImageLoader.js"; -export * from "./loaders/Loader.js"; -export * from "./loaders/LoaderUtils.js"; -export * from "./loaders/LoadingManager.js"; -export * from "./loaders/MaterialLoader.js"; -export * from "./loaders/ObjectLoader.js"; -export * from "./loaders/TextureLoader.js"; -export * from "./materials/Materials.js"; -export * from "./math/Box2.js"; -export * from "./math/Box3.js"; -export * from "./math/Color.js"; -export { ColorManagement, ColorSpaceDefinition } from "./math/ColorManagement.js"; -export * from "./math/Cylindrical.js"; -export * from "./math/Euler.js"; -export * from "./math/Frustum.js"; -export * from "./math/Interpolant.js"; -export * from "./math/interpolants/CubicInterpolant.js"; -export * from "./math/interpolants/DiscreteInterpolant.js"; -export * from "./math/interpolants/LinearInterpolant.js"; -export * from "./math/interpolants/QuaternionLinearInterpolant.js"; -export * from "./math/Line3.js"; -export { MathUtils } from "./math/MathUtils.js"; -export * from "./math/Matrix2.js"; -export * from "./math/Matrix3.js"; -export * from "./math/Matrix4.js"; -export * from "./math/Plane.js"; -export * from "./math/Quaternion.js"; -export * from "./math/Ray.js"; -export * from "./math/Sphere.js"; -export * from "./math/Spherical.js"; -export * from "./math/SphericalHarmonics3.js"; -export * from "./math/Triangle.js"; -export * from "./math/Vector2.js"; -export * from "./math/Vector3.js"; -export * from "./math/Vector4.js"; -export * from "./objects/BatchedMesh.js"; -export * from "./objects/Bone.js"; -export * from "./objects/Group.js"; -export * from "./objects/InstancedMesh.js"; -export * from "./objects/Line.js"; -export * from "./objects/LineLoop.js"; -export * from "./objects/LineSegments.js"; -export * from "./objects/LOD.js"; -export * from "./objects/Mesh.js"; -export * from "./objects/Points.js"; -export * from "./objects/Skeleton.js"; -export * from "./objects/SkinnedMesh.js"; -export * from "./objects/Sprite.js"; -// export * from "./renderers/shaders/ShaderChunk.js"; -// export * from "./renderers/shaders/ShaderLib.js"; -// export * from "./renderers/shaders/UniformsLib.js"; -// export { UniformsUtils } from './renderers/shaders/UniformsUtils.js'; -export type { WebGLProgramParameters, WebGLProgramParametersWithUniforms } from "./renderers/webgl/WebGLPrograms.js"; -export type { WebGLShadowMap } from "./renderers/webgl/WebGLShadowMap.js"; -// export * from "./renderers/webgl/WebGLUtils.js"; -export * from "./renderers/WebGL3DRenderTarget.js"; -export * from "./renderers/WebGLArrayRenderTarget.js"; -export * from "./renderers/WebGLCubeRenderTarget.js"; -// export * from "./renderers/WebGLRenderer.js"; -export * from "./renderers/WebGLRenderTarget.js"; -export type { - WebXRController, - WebXRSpaceEventMap, - XRControllerEventType, - XRGripSpace, - XRHandInputState, - XRHandJoints, - XRHandSpace, - XRJointSpace, - XRTargetRaySpace, -} from "./renderers/webxr/WebXRController.js"; -export type { WebXRDepthSensing } from "./renderers/webxr/WebXRDepthSensing.js"; -export type { - WebXRArrayCamera, - WebXRCamera, - WebXRManager, - WebXRManagerEventMap, -} from "./renderers/webxr/WebXRManager.js"; -export * from "./scenes/Fog.js"; -export * from "./scenes/FogExp2.js"; -export * from "./scenes/Scene.js"; -export * from "./textures/CanvasTexture.js"; -export * from "./textures/CompressedArrayTexture.js"; -export * from "./textures/CompressedCubeTexture.js"; -export * from "./textures/CompressedTexture.js"; -export * from "./textures/CubeTexture.js"; -export * from "./textures/Data3DTexture.js"; -export * from "./textures/DataArrayTexture.js"; -export * from "./textures/DataTexture.js"; -export * from "./textures/DepthTexture.js"; -export * from "./textures/FramebufferTexture.js"; -export * from "./textures/Source.js"; -export * from "./textures/Texture.js"; -export * from "./textures/VideoTexture.js"; -export * from "./Three.Legacy.js"; -export { createCanvasElement } from "./utils.js"; - -export { default as IESSpotLight } from "./lights/webgpu/IESSpotLight.js"; -export { default as NodeLoader } from "./loaders/nodes/NodeLoader.js"; -export { default as NodeMaterialLoader } from "./loaders/nodes/NodeMaterialLoader.js"; -export { default as NodeObjectLoader } from "./loaders/nodes/NodeObjectLoader.js"; -export * from "./materials/nodes/NodeMaterials.js"; -export * from "./nodes/Nodes.js"; -export * from "./nodes/TSL.js"; -export { default as BundleGroup } from "./renderers/common/BundleGroup.js"; -export { default as PMREMGenerator } from "./renderers/common/extras/PMREMGenerator.js"; -export { default as PostProcessing } from "./renderers/common/PostProcessing.js"; -import * as PostProcessingUtils from "./renderers/common/PostProcessingUtils.js"; -export { PostProcessingUtils }; -export { default as IndirectStorageBufferAttribute } from "./renderers/common/IndirectStorageBufferAttribute.js"; -export { default as Lighting } from "./renderers/common/Lighting.js"; -export { default as QuadMesh } from "./renderers/common/QuadMesh.js"; -export type { default as Renderer } from "./renderers/common/Renderer.js"; -export { default as StorageBufferAttribute } from "./renderers/common/StorageBufferAttribute.js"; -export { default as StorageInstancedBufferAttribute } from "./renderers/common/StorageInstancedBufferAttribute.js"; -export { default as StorageTexture } from "./renderers/common/StorageTexture.js"; -export { default as WebGPURenderer } from "./renderers/webgpu/WebGPURenderer.js"; diff --git a/src-testing/src/Three.d.ts b/src-testing/src/Three.d.ts deleted file mode 100644 index ade1c92b9..000000000 --- a/src-testing/src/Three.d.ts +++ /dev/null @@ -1,214 +0,0 @@ -export * from "./animation/AnimationAction.js"; -export * from "./animation/AnimationClip.js"; -export * from "./animation/AnimationMixer.js"; -export * from "./animation/AnimationObjectGroup.js"; -export { AnimationUtils } from "./animation/AnimationUtils.js"; -export * from "./animation/KeyframeTrack.js"; -export * from "./animation/PropertyBinding.js"; -export * from "./animation/PropertyMixer.js"; -export * from "./animation/tracks/BooleanKeyframeTrack.js"; -export * from "./animation/tracks/ColorKeyframeTrack.js"; -export * from "./animation/tracks/NumberKeyframeTrack.js"; -export * from "./animation/tracks/QuaternionKeyframeTrack.js"; -export * from "./animation/tracks/StringKeyframeTrack.js"; -export * from "./animation/tracks/VectorKeyframeTrack.js"; -export * from "./audio/Audio.js"; -export * from "./audio/AudioAnalyser.js"; -export * from "./audio/AudioContext.js"; -export * from "./audio/AudioListener.js"; -export * from "./audio/PositionalAudio.js"; -export * from "./cameras/ArrayCamera.js"; -export * from "./cameras/Camera.js"; -export * from "./cameras/CubeCamera.js"; -export * from "./cameras/OrthographicCamera.js"; -export * from "./cameras/PerspectiveCamera.js"; -export * from "./cameras/StereoCamera.js"; -export * from "./constants.js"; -export * from "./core/BufferAttribute.js"; -export * from "./core/BufferGeometry.js"; -export * from "./core/Clock.js"; -export * from "./core/EventDispatcher.js"; -export * from "./core/GLBufferAttribute.js"; -export * from "./core/InstancedBufferAttribute.js"; -export * from "./core/InstancedBufferGeometry.js"; -export * from "./core/InstancedInterleavedBuffer.js"; -export * from "./core/InterleavedBuffer.js"; -export * from "./core/InterleavedBufferAttribute.js"; -export * from "./core/Layers.js"; -export * from "./core/Object3D.js"; -export * from "./core/Raycaster.js"; -export * from "./core/RenderTarget.js"; -export * from "./core/Uniform.js"; -export * from "./core/UniformsGroup.js"; -export * from "./extras/Controls.js"; -export * from "./extras/core/Curve.js"; -export * from "./extras/core/CurvePath.js"; -export * from "./extras/core/Path.js"; -export * from "./extras/core/Shape.js"; -export * from "./extras/core/ShapePath.js"; -export * from "./extras/curves/Curves.js"; -export { DataUtils } from "./extras/DataUtils.js"; -export * from "./extras/ImageUtils.js"; -export * from "./extras/PMREMGenerator.js"; -export * from "./extras/ShapeUtils.js"; -export { TextureUtils } from "./extras/TextureUtils.js"; -export * from "./geometries/Geometries.js"; -export * from "./helpers/ArrowHelper.js"; -export * from "./helpers/AxesHelper.js"; -export * from "./helpers/Box3Helper.js"; -export * from "./helpers/BoxHelper.js"; -export * from "./helpers/CameraHelper.js"; -export * from "./helpers/DirectionalLightHelper.js"; -export * from "./helpers/GridHelper.js"; -export * from "./helpers/HemisphereLightHelper.js"; -export * from "./helpers/PlaneHelper.js"; -export * from "./helpers/PointLightHelper.js"; -export * from "./helpers/PolarGridHelper.js"; -export * from "./helpers/SkeletonHelper.js"; -export * from "./helpers/SpotLightHelper.js"; -export * from "./lights/AmbientLight.js"; -export * from "./lights/DirectionalLight.js"; -export type { DirectionalLightShadow } from "./lights/DirectionalLightShadow.js"; -export * from "./lights/HemisphereLight.js"; -export * from "./lights/Light.js"; -export * from "./lights/LightProbe.js"; -export type { LightShadow, LightShadowJSON } from "./lights/LightShadow.js"; -export * from "./lights/PointLight.js"; -export type { PointLightShadow } from "./lights/PointLightShadow.js"; -export * from "./lights/RectAreaLight.js"; -export * from "./lights/SpotLight.js"; -export type { SpotLightShadow } from "./lights/SpotLightShadow.js"; -export * from "./loaders/AnimationLoader.js"; -export * from "./loaders/AudioLoader.js"; -export * from "./loaders/BufferGeometryLoader.js"; -export * from "./loaders/Cache.js"; -export * from "./loaders/CompressedTextureLoader.js"; -export * from "./loaders/CubeTextureLoader.js"; -export * from "./loaders/DataTextureLoader.js"; -export * from "./loaders/FileLoader.js"; -export * from "./loaders/ImageBitmapLoader.js"; -export * from "./loaders/ImageLoader.js"; -export * from "./loaders/Loader.js"; -export * from "./loaders/LoaderUtils.js"; -export * from "./loaders/LoadingManager.js"; -export * from "./loaders/MaterialLoader.js"; -export * from "./loaders/ObjectLoader.js"; -export * from "./loaders/TextureLoader.js"; -export * from "./materials/Materials.js"; -export * from "./math/Box2.js"; -export * from "./math/Box3.js"; -export * from "./math/Color.js"; -export { ColorManagement, ColorSpaceDefinition } from "./math/ColorManagement.js"; -export * from "./math/Cylindrical.js"; -export * from "./math/Euler.js"; -export * from "./math/Frustum.js"; -export * from "./math/Interpolant.js"; -export * from "./math/interpolants/CubicInterpolant.js"; -export * from "./math/interpolants/DiscreteInterpolant.js"; -export * from "./math/interpolants/LinearInterpolant.js"; -export * from "./math/interpolants/QuaternionLinearInterpolant.js"; -export * from "./math/Line3.js"; -export { MathUtils } from "./math/MathUtils.js"; -export * from "./math/Matrix2.js"; -export * from "./math/Matrix3.js"; -export * from "./math/Matrix4.js"; -export * from "./math/Plane.js"; -export * from "./math/Quaternion.js"; -export * from "./math/Ray.js"; -export * from "./math/Sphere.js"; -export * from "./math/Spherical.js"; -export * from "./math/SphericalHarmonics3.js"; -export * from "./math/Triangle.js"; -export * from "./math/Vector2.js"; -export * from "./math/Vector3.js"; -export * from "./math/Vector4.js"; -export * from "./objects/BatchedMesh.js"; -export * from "./objects/Bone.js"; -export * from "./objects/Group.js"; -export * from "./objects/InstancedMesh.js"; -export * from "./objects/Line.js"; -export * from "./objects/LineLoop.js"; -export * from "./objects/LineSegments.js"; -export * from "./objects/LOD.js"; -export * from "./objects/Mesh.js"; -export * from "./objects/Points.js"; -export * from "./objects/Skeleton.js"; -export * from "./objects/SkinnedMesh.js"; -export * from "./objects/Sprite.js"; -export * from "./renderers/shaders/ShaderChunk.js"; -export * from "./renderers/shaders/ShaderLib.js"; -export * from "./renderers/shaders/UniformsLib.js"; -export { UniformsUtils } from "./renderers/shaders/UniformsUtils.js"; -export type { WebGLAttributes } from "./renderers/webgl/WebGLAttributes.js"; -export type { WebGLBindingStates } from "./renderers/webgl/WebGLBindingStates.js"; -export type { WebGLBufferRenderer } from "./renderers/webgl/WebGLBufferRenderer.js"; -export type { WebGLCapabilities, WebGLCapabilitiesParameters } from "./renderers/webgl/WebGLCapabilities.js"; -export type { WebGLClipping } from "./renderers/webgl/WebGLClipping.js"; -export type { WebGLCubeMaps } from "./renderers/webgl/WebGLCubeMaps.js"; -export type { WebGLCubeUVMaps } from "./renderers/webgl/WebGLCubeUVMaps.js"; -export type { WebGLExtensions } from "./renderers/webgl/WebGLExtensions.js"; -export type { WebGLGeometries } from "./renderers/webgl/WebGLGeometries.js"; -export type { WebGLIndexedBufferRenderer } from "./renderers/webgl/WebGLIndexedBufferRenderer.js"; -export type { WebGLInfo } from "./renderers/webgl/WebGLInfo.js"; -export type { WebGLLights, WebGLLightsState } from "./renderers/webgl/WebGLLights.js"; -export type { WebGLObjects } from "./renderers/webgl/WebGLObjects.js"; -export type { WebGLProgram } from "./renderers/webgl/WebGLProgram.js"; -export type { - WebGLProgramParameters, - WebGLProgramParametersWithUniforms, - WebGLPrograms, -} from "./renderers/webgl/WebGLPrograms.js"; -export type { WebGLProperties } from "./renderers/webgl/WebGLProperties.js"; -export type { RenderItem, WebGLRenderList, WebGLRenderLists } from "./renderers/webgl/WebGLRenderLists.js"; -export type { WebGLShader } from "./renderers/webgl/WebGLShader.js"; -export type { WebGLShadowMap } from "./renderers/webgl/WebGLShadowMap.js"; -export type { - WebGLColorBuffer, - WebGLDepthBuffer, - WebGLState, - WebGLStencilBuffer, -} from "./renderers/webgl/WebGLState.js"; -export type { WebGLTextures } from "./renderers/webgl/WebGLTextures.js"; -export type { WebGLUniforms } from "./renderers/webgl/WebGLUniforms.js"; -export * from "./renderers/webgl/WebGLUtils.js"; -export * from "./renderers/WebGL3DRenderTarget.js"; -export * from "./renderers/WebGLArrayRenderTarget.js"; -export * from "./renderers/WebGLCubeRenderTarget.js"; -export * from "./renderers/WebGLRenderer.js"; -export * from "./renderers/WebGLRenderTarget.js"; -export type { - WebXRController, - WebXRSpaceEventMap, - XRControllerEventType, - XRGripSpace, - XRHandInputState, - XRHandJoints, - XRHandSpace, - XRJointSpace, - XRTargetRaySpace, -} from "./renderers/webxr/WebXRController.js"; -export type { WebXRDepthSensing } from "./renderers/webxr/WebXRDepthSensing.js"; -export type { - WebXRArrayCamera, - WebXRCamera, - WebXRManager, - WebXRManagerEventMap, -} from "./renderers/webxr/WebXRManager.js"; -export * from "./scenes/Fog.js"; -export * from "./scenes/FogExp2.js"; -export * from "./scenes/Scene.js"; -export * from "./textures/CanvasTexture.js"; -export * from "./textures/CompressedArrayTexture.js"; -export * from "./textures/CompressedCubeTexture.js"; -export * from "./textures/CompressedTexture.js"; -export * from "./textures/CubeTexture.js"; -export * from "./textures/Data3DTexture.js"; -export * from "./textures/DataArrayTexture.js"; -export * from "./textures/DataTexture.js"; -export * from "./textures/DepthTexture.js"; -export * from "./textures/FramebufferTexture.js"; -export * from "./textures/Source.js"; -export * from "./textures/Texture.js"; -export * from "./textures/VideoTexture.js"; -export * from "./Three.Legacy.js"; -export { createCanvasElement } from "./utils.js"; diff --git a/src-testing/src/animation/AnimationAction.d.ts b/src-testing/src/animation/AnimationAction.d.ts deleted file mode 100644 index 3fa3852a2..000000000 --- a/src-testing/src/animation/AnimationAction.d.ts +++ /dev/null @@ -1,86 +0,0 @@ -import { AnimationActionLoopStyles, AnimationBlendMode } from "../constants.js"; -import { Object3D } from "../core/Object3D.js"; -import { AnimationClip } from "./AnimationClip.js"; -import { AnimationMixer } from "./AnimationMixer.js"; -// Animation //////////////////////////////////////////////////////////////////////////////////////// - -export class AnimationAction { - constructor(mixer: AnimationMixer, clip: AnimationClip, localRoot?: Object3D, blendMode?: AnimationBlendMode); - - blendMode: AnimationBlendMode; - - /** - * @default THREE.LoopRepeat - */ - loop: AnimationActionLoopStyles; - - /** - * @default 0 - */ - time: number; - - /** - * @default 1 - */ - timeScale: number; - - /** - * @default 1 - */ - weight: number; - - /** - * @default Infinity - */ - repetitions: number; - - /** - * @default false - */ - paused: boolean; - - /** - * @default true - */ - enabled: boolean; - - /** - * @default false - */ - clampWhenFinished: boolean; - - /** - * @default true - */ - zeroSlopeAtStart: boolean; - - /** - * @default true - */ - zeroSlopeAtEnd: boolean; - - play(): AnimationAction; - stop(): AnimationAction; - reset(): AnimationAction; - isRunning(): boolean; - isScheduled(): boolean; - startAt(time: number): AnimationAction; - setLoop(mode: AnimationActionLoopStyles, repetitions: number): AnimationAction; - setEffectiveWeight(weight: number): AnimationAction; - getEffectiveWeight(): number; - fadeIn(duration: number): AnimationAction; - fadeOut(duration: number): AnimationAction; - crossFadeFrom(fadeOutAction: AnimationAction, duration: number, warp: boolean): AnimationAction; - crossFadeTo(fadeInAction: AnimationAction, duration: number, warp: boolean): AnimationAction; - stopFading(): AnimationAction; - setEffectiveTimeScale(timeScale: number): AnimationAction; - getEffectiveTimeScale(): number; - setDuration(duration: number): AnimationAction; - syncWith(action: AnimationAction): AnimationAction; - halt(duration: number): AnimationAction; - warp(statTimeScale: number, endTimeScale: number, duration: number): AnimationAction; - stopWarping(): AnimationAction; - getMixer(): AnimationMixer; - getClip(): AnimationClip; - getRoot(): Object3D; -} diff --git a/src-testing/src/animation/AnimationClip.d.ts b/src-testing/src/animation/AnimationClip.d.ts deleted file mode 100644 index 4efc3df72..000000000 --- a/src-testing/src/animation/AnimationClip.d.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { AnimationBlendMode } from "../constants.js"; -import { Vector3 } from "../math/Vector3.js"; -import { Bone } from "../objects/Bone.js"; -import { KeyframeTrack, KeyframeTrackJSON } from "./KeyframeTrack.js"; - -export interface AnimationClipJSON { - name: string; - duration: number; - tracks: KeyframeTrackJSON[]; - uuid: string; - blendMode: AnimationBlendMode; -} - -export interface MorphTarget { - name: string; - vertices: Vector3[]; -} - -export class AnimationClip { - constructor(name?: string, duration?: number, tracks?: KeyframeTrack[], blendMode?: AnimationBlendMode); - - name: string; - tracks: KeyframeTrack[]; - - /** - * @default THREE.NormalAnimationBlendMode - */ - blendMode: AnimationBlendMode; - - /** - * @default -1 - */ - duration: number; - uuid: string; - results: any[]; - - resetDuration(): AnimationClip; - trim(): AnimationClip; - validate(): boolean; - optimize(): AnimationClip; - clone(): this; - toJSON(clip: AnimationClip): any; - - static CreateFromMorphTargetSequence( - name: string, - morphTargetSequence: MorphTarget[], - fps: number, - noLoop: boolean, - ): AnimationClip; - static findByName(clipArray: AnimationClip[], name: string): AnimationClip; - static CreateClipsFromMorphTargetSequences( - morphTargets: MorphTarget[], - fps: number, - noLoop: boolean, - ): AnimationClip[]; - static parse(json: AnimationClipJSON): AnimationClip; - static parseAnimation(animation: AnimationClipJSON, bones: Bone[]): AnimationClip; - static toJSON(clip: AnimationClip): AnimationClipJSON; -} diff --git a/src-testing/src/animation/AnimationMixer.d.ts b/src-testing/src/animation/AnimationMixer.d.ts deleted file mode 100644 index 95712d893..000000000 --- a/src-testing/src/animation/AnimationMixer.d.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { AnimationBlendMode } from "../constants.js"; -import { EventDispatcher } from "../core/EventDispatcher.js"; -import { Object3D } from "../core/Object3D.js"; -import { AnimationAction } from "./AnimationAction.js"; -import { AnimationClip } from "./AnimationClip.js"; -import { AnimationObjectGroup } from "./AnimationObjectGroup.js"; - -export interface AnimationMixerEventMap { - loop: { action: AnimationAction; loopDelta: number }; - finished: { action: AnimationAction; direction: number }; -} - -export class AnimationMixer extends EventDispatcher { - constructor(root: Object3D | AnimationObjectGroup); - - /** - * @default 0 - */ - time: number; - - /** - * @default 1.0 - */ - timeScale: number; - - clipAction( - clip: AnimationClip, - root?: Object3D | AnimationObjectGroup, - blendMode?: AnimationBlendMode, - ): AnimationAction; - existingAction(clip: AnimationClip, root?: Object3D | AnimationObjectGroup): AnimationAction | null; - stopAllAction(): AnimationMixer; - update(deltaTime: number): AnimationMixer; - setTime(timeInSeconds: number): AnimationMixer; - getRoot(): Object3D | AnimationObjectGroup; - uncacheClip(clip: AnimationClip): void; - uncacheRoot(root: Object3D | AnimationObjectGroup): void; - uncacheAction(clip: AnimationClip, root?: Object3D | AnimationObjectGroup): void; -} diff --git a/src-testing/src/animation/AnimationObjectGroup.d.ts b/src-testing/src/animation/AnimationObjectGroup.d.ts deleted file mode 100644 index 9d4f29ca9..000000000 --- a/src-testing/src/animation/AnimationObjectGroup.d.ts +++ /dev/null @@ -1,17 +0,0 @@ -export class AnimationObjectGroup { - constructor(...args: any[]); - - uuid: string; - stats: { - bindingsPerObject: number; - objects: { - total: number; - inUse: number; - }; - }; - readonly isAnimationObjectGroup: true; - - add(...args: any[]): void; - remove(...args: any[]): void; - uncache(...args: any[]): void; -} diff --git a/src-testing/src/animation/AnimationUtils.d.ts b/src-testing/src/animation/AnimationUtils.d.ts deleted file mode 100644 index 4a712ed30..000000000 --- a/src-testing/src/animation/AnimationUtils.d.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { AnimationClip } from "./AnimationClip.js"; - -declare function convertArray(array: any, type: any, forceClone: boolean): any; - -declare function isTypedArray(object: any): boolean; - -declare function getKeyframeOrder(times: number[]): number[]; - -declare function sortedArray(values: any[], stride: number, order: number[]): any[]; - -declare function flattenJSON(jsonKeys: string[], times: any[], values: any[], valuePropertyName: string): void; - -/** - * @param sourceClip - * @param name - * @param startFrame - * @param endFrame - * @param [fps=30] - */ -declare function subclip( - sourceClip: AnimationClip, - name: string, - startFrame: number, - endFrame: number, - fps?: number, -): AnimationClip; - -/** - * @param targetClip - * @param [referenceFrame=0] - * @param [referenceClip=targetClip] - * @param [fps=30] - */ -declare function makeClipAdditive( - targetClip: AnimationClip, - referenceFrame?: number, - referenceClip?: AnimationClip, - fps?: number, -): AnimationClip; - -declare const AnimationUtils: { - convertArray: typeof convertArray; - isTypedArray: typeof isTypedArray; - getKeyframeOrder: typeof getKeyframeOrder; - sortedArray: typeof sortedArray; - flattenJSON: typeof flattenJSON; - subclip: typeof subclip; - makeClipAdditive: typeof makeClipAdditive; -}; - -export { - AnimationUtils, - convertArray, - flattenJSON, - getKeyframeOrder, - isTypedArray, - makeClipAdditive, - sortedArray, - subclip, -}; diff --git a/src-testing/src/animation/KeyframeTrack.d.ts b/src-testing/src/animation/KeyframeTrack.d.ts deleted file mode 100644 index 2a48e2651..000000000 --- a/src-testing/src/animation/KeyframeTrack.d.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { InterpolationModes } from "../constants.js"; -import { Interpolant } from "../math/Interpolant.js"; -import { CubicInterpolant } from "../math/interpolants/CubicInterpolant.js"; -import { DiscreteInterpolant } from "../math/interpolants/DiscreteInterpolant.js"; -import { LinearInterpolant } from "../math/interpolants/LinearInterpolant.js"; - -export interface KeyframeTrackJSON { - name: string; - times: number[]; - values: number[]; - interpolation?: InterpolationModes; - type: string; -} - -export class KeyframeTrack { - /** - * @param name - * @param times - * @param values - * @param [interpolation=THREE.InterpolateLinear] - */ - constructor(name: string, times: ArrayLike, values: ArrayLike, interpolation?: InterpolationModes); - - name: string; - times: Float32Array; - values: Float32Array; - - ValueTypeName: string; - TimeBufferType: Float32Array; - ValueBufferType: Float32Array; - - /** - * @default THREE.InterpolateLinear - */ - DefaultInterpolation: InterpolationModes; - - InterpolantFactoryMethodDiscrete(result: any): DiscreteInterpolant; - InterpolantFactoryMethodLinear(result: any): LinearInterpolant; - InterpolantFactoryMethodSmooth(result: any): CubicInterpolant; - - setInterpolation(interpolation: InterpolationModes): KeyframeTrack; - getInterpolation(): InterpolationModes; - createInterpolant(): Interpolant; - - getValueSize(): number; - - shift(timeOffset: number): KeyframeTrack; - scale(timeScale: number): KeyframeTrack; - trim(startTime: number, endTime: number): KeyframeTrack; - validate(): boolean; - optimize(): KeyframeTrack; - clone(): this; - - static toJSON(track: KeyframeTrack): KeyframeTrackJSON; -} diff --git a/src-testing/src/animation/PropertyBinding.d.ts b/src-testing/src/animation/PropertyBinding.d.ts deleted file mode 100644 index fec777634..000000000 --- a/src-testing/src/animation/PropertyBinding.d.ts +++ /dev/null @@ -1,43 +0,0 @@ -export interface ParseTrackNameResults { - nodeName: string; - objectName: string; - objectIndex: string; - propertyName: string; - propertyIndex: string; -} - -declare class Composite { - constructor(targetGroup: any, path: any, parsedPath?: any); - - getValue(array: any, offset: number): any; - setValue(array: any, offset: number): void; - bind(): void; - unbind(): void; -} - -declare class PropertyBinding { - constructor(rootNode: any, path: string, parsedPath?: any); - - path: string; - parsedPath: any; - node: any; - rootNode: any; - - getValue(targetArray: any, offset: number): any; - setValue(sourceArray: any, offset: number): void; - bind(): void; - unbind(): void; - - BindingType: { [bindingType: string]: number }; - Versioning: { [versioning: string]: number }; - - GetterByBindingType: Array<() => void>; - SetterByBindingTypeAndVersioning: Array void>>; - - static create(root: any, path: any, parsedPath?: any): PropertyBinding | Composite; - static sanitizeNodeName(name: string): string; - static parseTrackName(trackName: string): ParseTrackNameResults; - static findNode(root: any, nodeName: string): any; -} - -export { PropertyBinding }; diff --git a/src-testing/src/animation/PropertyMixer.d.ts b/src-testing/src/animation/PropertyMixer.d.ts deleted file mode 100644 index f413291fa..000000000 --- a/src-testing/src/animation/PropertyMixer.d.ts +++ /dev/null @@ -1,17 +0,0 @@ -export class PropertyMixer { - constructor(binding: any, typeName: string, valueSize: number); - - binding: any; - valueSize: number; - buffer: any; - cumulativeWeight: number; - cumulativeWeightAdditive: number; - useCount: number; - referenceCount: number; - - accumulate(accuIndex: number, weight: number): void; - accumulateAdditive(weight: number): void; - apply(accuIndex: number): void; - saveOriginalState(): void; - restoreOriginalState(): void; -} diff --git a/src-testing/src/animation/tracks/BooleanKeyframeTrack.d.ts b/src-testing/src/animation/tracks/BooleanKeyframeTrack.d.ts deleted file mode 100644 index 45b65448a..000000000 --- a/src-testing/src/animation/tracks/BooleanKeyframeTrack.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { KeyframeTrack } from "../KeyframeTrack.js"; - -export class BooleanKeyframeTrack extends KeyframeTrack { - constructor(name: string, times: ArrayLike, values: ArrayLike); - - /** - * @default 'bool' - */ - ValueTypeName: string; -} diff --git a/src-testing/src/animation/tracks/ColorKeyframeTrack.d.ts b/src-testing/src/animation/tracks/ColorKeyframeTrack.d.ts deleted file mode 100644 index 60d0fe9f7..000000000 --- a/src-testing/src/animation/tracks/ColorKeyframeTrack.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { InterpolationModes } from "../../constants.js"; -import { KeyframeTrack } from "../KeyframeTrack.js"; - -export class ColorKeyframeTrack extends KeyframeTrack { - constructor(name: string, times: ArrayLike, values: ArrayLike, interpolation?: InterpolationModes); - - /** - * @default 'color' - */ - ValueTypeName: string; -} diff --git a/src-testing/src/animation/tracks/NumberKeyframeTrack.d.ts b/src-testing/src/animation/tracks/NumberKeyframeTrack.d.ts deleted file mode 100644 index e27ff0337..000000000 --- a/src-testing/src/animation/tracks/NumberKeyframeTrack.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { InterpolationModes } from "../../constants.js"; -import { KeyframeTrack } from "../KeyframeTrack.js"; - -export class NumberKeyframeTrack extends KeyframeTrack { - constructor(name: string, times: ArrayLike, values: ArrayLike, interpolation?: InterpolationModes); - - /** - * @default 'number' - */ - ValueTypeName: string; -} diff --git a/src-testing/src/animation/tracks/QuaternionKeyframeTrack.d.ts b/src-testing/src/animation/tracks/QuaternionKeyframeTrack.d.ts deleted file mode 100644 index 29942bad5..000000000 --- a/src-testing/src/animation/tracks/QuaternionKeyframeTrack.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { InterpolationModes } from "../../constants.js"; -import { KeyframeTrack } from "../KeyframeTrack.js"; - -export class QuaternionKeyframeTrack extends KeyframeTrack { - constructor(name: string, times: ArrayLike, values: ArrayLike, interpolation?: InterpolationModes); - - /** - * @default 'quaternion' - */ - ValueTypeName: string; -} diff --git a/src-testing/src/animation/tracks/StringKeyframeTrack.d.ts b/src-testing/src/animation/tracks/StringKeyframeTrack.d.ts deleted file mode 100644 index 9bbfd2027..000000000 --- a/src-testing/src/animation/tracks/StringKeyframeTrack.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { KeyframeTrack } from "../KeyframeTrack.js"; - -export class StringKeyframeTrack extends KeyframeTrack { - constructor(name: string, times: ArrayLike, values: ArrayLike); - - /** - * @default 'string' - */ - ValueTypeName: string; -} diff --git a/src-testing/src/animation/tracks/VectorKeyframeTrack.d.ts b/src-testing/src/animation/tracks/VectorKeyframeTrack.d.ts deleted file mode 100644 index 0909d4493..000000000 --- a/src-testing/src/animation/tracks/VectorKeyframeTrack.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { InterpolationModes } from "../../constants.js"; -import { KeyframeTrack } from "../KeyframeTrack.js"; - -export class VectorKeyframeTrack extends KeyframeTrack { - constructor(name: string, times: ArrayLike, values: ArrayLike, interpolation?: InterpolationModes); - - /** - * @default 'vector' - */ - ValueTypeName: string; -} diff --git a/src-testing/src/audio/Audio.d.ts b/src-testing/src/audio/Audio.d.ts deleted file mode 100644 index 63a944b5e..000000000 --- a/src-testing/src/audio/Audio.d.ts +++ /dev/null @@ -1,273 +0,0 @@ -import { Object3D } from "../core/Object3D.js"; -import { AudioContext } from "./AudioContext.js"; -import { AudioListener } from "./AudioListener.js"; - -// Extras / Audio ///////////////////////////////////////////////////////////////////// - -/** - * Create a non-positional ( global ) {@link Audio} object. - * This uses the {@link https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API | Web {@link Audio} API}. - * @example - * ```typescript - * // create an AudioListener and add it to the camera - * const listener = new THREE.AudioListener(); - * camera.add(listener); - * // create a global {@link Audio} source - * const sound = new THREE.Audio(listener); - * // load a sound and set it as the {@link Audio} object's buffer - * const audioLoader = new THREE.AudioLoader(); - * audioLoader.load('sounds/ambient.ogg', function (buffer) { - * sound.setBuffer(buffer); - * sound.setLoop(true); - * sound.setVolume(0.5); - * sound.play(); - * }); - * ``` - * @see Example: {@link https://threejs.org/examples/#webaudio_sandbox | webaudio / sandbox } - * @see Example: {@link https://threejs.org/examples/#webaudio_visualizer | webaudio / visualizer } - * @see {@link https://threejs.org/docs/index.html#api/en/audio/Audio | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/audio/Audio.js | Source} - */ -export class Audio extends Object3D { - /** - * Create a new instance of {@link Audio} - * @param listener (required) {@link AudioListener | AudioListener} instance. - */ - constructor(listener: AudioListener); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `Audio` - */ - readonly type: string | "Audio"; - - /** - * A reference to the listener object of this audio. - */ - listener: AudioListener; - - /** - * The {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioContext | AudioContext} of the {@link AudioListener | listener} given in the constructor. - */ - context: AudioContext; - - /** - * A {@link https://developer.mozilla.org/en-US/docs/Web/API/GainNode | GainNode} created using - * {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioContext/createGain | AudioContext.createGain}(). - */ - gain: GainNode; - - /** - * Whether to start playback automatically. - * @defaultValue `false` - */ - autoplay: boolean; - - buffer: AudioBuffer | null; - - /** - * Modify pitch, measured in cents. +/- 100 is a semitone. +/- 1200 is an octave. - * @defaultValue `0` - */ - detune: number; - - /** - * @default false - */ - loop: boolean; - - /** - * @default 0 - */ - loopStart: number; - - /** - * @default 0 - */ - loopEnd: number; - - /** - * An offset to the time within the {@link Audio} buffer that playback should begin. - * Same as the {@link Audio.offset | offset} parameter of {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/start | AudioBufferSourceNode.start()}. - * @defaultValue `0` - */ - offset: number; - - /** - * Overrides the duration of the audio. Same as the {@link Audio.duration | duration} parameter of - * {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/start | AudioBufferSourceNode.start()}. - * @defaultValue `undefined` _to play the whole buffer_. - */ - duration: number | undefined; - - /** - * Speed of playback. - * @defaultValue `1` - */ - playbackRate: number; - - /** - * Whether the {@link Audio} is currently playing. - * @defaultValue `false` - */ - isPlaying: boolean; - - /** - * Whether playback can be controlled using the {@link Audio.play | play}(), {@link Audio.pause | pause}() etc. methods. - * @defaultValue `true` - */ - hasPlaybackControl: boolean; - - /** - * Type of the {@link Audio} source. - * @defaultValue 'empty'. - */ - sourceType: string; - - /** - * An {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode | AudioBufferSourceNode} created using - * {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioContext/createBufferSource | AudioContext.createBufferSource()}. - */ - source: AudioScheduledSourceNode | null; - - /** - * Represents an array of {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioNode | AudioNodes}. - * Can be used to apply a variety of low-order filters to create more complex sound effects. - * In most cases, the array contains instances of {@link https://developer.mozilla.org/en-US/docs/Web/API/BiquadFilterNode | BiquadFilterNodes}. - * Filters are set via {@link THREE.Audio.setFilter | Audio.setFilter} or {@link THREE.Audio.setFilters | Audio.setFilters}. - * @defaultValue `[]` - */ - filters: AudioNode[]; - - /** - * Return the {@link Audio.gain | gainNode}. - */ - getOutput(): NodeType; - - /** - * Setup the {@link Audio.source | source} to the audioBuffer, and sets {@link Audio.sourceType | sourceType} to 'audioNode'. - * @remarks Also sets {@link Audio.hasPlaybackControl | hasPlaybackControl} to false. - */ - setNodeSource(audioNode: AudioScheduledSourceNode): this; - - /** - * Applies the given object of type {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement | HTMLMediaElement} as the source of this audio. - * @remarks Also sets {@link Audio.hasPlaybackControl | hasPlaybackControl} to false. - */ - setMediaElementSource(mediaElement: HTMLMediaElement): this; - - /** - * Applies the given object of type {@link https://developer.mozilla.org/en-US/docs/Web/API/MediaStream | MediaStream} as the source of this audio. - * @remarks Also sets {@link Audio.hasPlaybackControl | hasPlaybackControl} to false. - */ - setMediaStreamSource(mediaStream: MediaStream): this; - - /** - * Setup the {@link Audio.source | source} to the audioBuffer, and sets {@link Audio.sourceType | sourceType} to 'buffer'. - * @remarks If {@link Audio.autoplay | autoplay}, also starts playback. - */ - setBuffer(audioBuffer: AudioBuffer): this; - - /** - * If {@link Audio.hasPlaybackControl | hasPlaybackControl} is true, starts playback. - */ - play(delay?: number): this; - - /** - * If {@link Audio.hasPlaybackControl | hasPlaybackControl} is true, pauses playback. - */ - pause(): this; - - /** - * If {@link Audio.hasPlaybackControl | hasPlaybackControl} is enabled, stops playback. - * @param delay (optional) - The delay, in seconds, at which the audio should start playing. - */ - stop(delay?: number): this; - - /** - * Called automatically when playback finished. - */ - onEnded(): void; - - /** - * Connect to the {@link THREE.Audio.source | Audio.source} - * @remarks This is used internally on initialisation and when setting / removing filters. - */ - connect(): this; - /** - * Disconnect from the {@link THREE.Audio.source | Audio.source} - * @remarks This is used internally when setting / removing filters. - */ - disconnect(): this; - - /** - * Returns the detuning of oscillation in cents. - */ - getDetune(): number; - /** - * Defines the detuning of oscillation in cents. - * @param value Expects a `Float` - */ - setDetune(value: number): this; - - /** - * Returns the first element of the {@link Audio.filters | filters} array. - */ - getFilter(): AudioNode; - /** - * Applies a single filter node to the audio. - */ - setFilter(filter: AudioNode): this; - - /** - * Returns the {@link Audio.filters | filters} array. - */ - getFilters(): AudioNode[]; - /** - * Applies an array of filter nodes to the audio. - * @param value Arrays of filters. - */ - setFilters(value: AudioNode[]): this; - - /** - * Return the value of {@link Audio.playbackRate | playbackRate}. - */ - getPlaybackRate(): number; - /** - * If {@link Audio.hasPlaybackControl | hasPlaybackControl} is enabled, set the {@link Audio.playbackRate | playbackRate} to `value`. - * @param value Expects a `Float` - */ - setPlaybackRate(value: number): this; - - /** - * Return the value of {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/loop | source.loop} (whether playback should loop). - */ - getLoop(): boolean; - /** - * Set {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/loop | source.loop} to `value` (whether playback should loop). - * @param value - */ - setLoop(value: boolean): this; - - /** - * Set {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/loopStart | source.loopStart} to `value`. - * @param value Expects a `Float` - */ - setLoopStart(value: number): this; - /** - * Set {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/loopEnd | source.loopEnd} to `value`. - * @param value Expects a `Float` - */ - setLoopEnd(value: number): this; - - /** - * Return the current volume. - */ - getVolume(): number; - /** - * Set the volume. - * @param value Expects a `Float` - */ - setVolume(value: number): this; -} diff --git a/src-testing/src/audio/AudioAnalyser.d.ts b/src-testing/src/audio/AudioAnalyser.d.ts deleted file mode 100644 index 474583ec7..000000000 --- a/src-testing/src/audio/AudioAnalyser.d.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { Audio } from "./Audio.js"; - -/** - * Create a {@link AudioAnalyser} object, which uses an {@link https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode | AnalyserNode} to analyse audio data. - * This uses the {@link https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API | Web Audio API}. - * @example - * ```typescript - * // create an AudioListener and add it to the camera - * const listener = new THREE.AudioListener(); - * camera.add(listener); - * // create an Audio source - * const sound = new THREE.Audio(listener); - * // load a sound and set it as the Audio object's buffer - * const audioLoader = new THREE.AudioLoader(); - * audioLoader.load('sounds/ambient.ogg', function (buffer) { - * sound.setBuffer(buffer); - * sound.setLoop(true); - * sound.setVolume(0.5); - * sound.play(); - * }); - * // create an AudioAnalyser, passing in the sound and desired fftSize - * const analyser = new THREE.AudioAnalyser(sound, 32); - * // get the average frequency of the sound - * const data = analyser.getAverageFrequency(); - * ``` - * @see Example: {@link https://threejs.org/examples/#webaudio_sandbox | webaudio / sandbox } - * @see Example: {@link https://threejs.org/examples/#webaudio_visualizer | webaudio / visualizer } - * @see {@link https://threejs.org/docs/index.html#api/en/audio/AudioAnalyser | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/audio/AudioAnalyser.js | Source} - */ -export class AudioAnalyser { - /** - * Create a new {@link {@link AudioAnalyser} | AudioAnalyser}. - * @param audio - * @param fftSize See {@link https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode/fftSize | AnalyserNode.fftSize }. Expects a `unsigned integer`. Default `2048`. - */ - constructor(audio: Audio, fftSize?: number); - - /** - * An {@link https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode | AnalyserNode} used to analyze audio. - */ - analyser: AnalyserNode; - - /** - * A Uint8Array with size determined by {@link https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode/frequencyBinCount | analyser.frequencyBinCount} used to hold analysis data. - */ - data: Uint8Array; - - /** - * Uses the Web Audio's {@link https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode/getByteFrequencyData | getByteFrequencyData} method - */ - getFrequencyData(): Uint8Array; - - /** - * Get the average of the frequencies returned by the {@link AudioAnalyser.getFrequencyData | getFrequencyData} method. - */ - getAverageFrequency(): number; -} diff --git a/src-testing/src/audio/AudioContext.d.ts b/src-testing/src/audio/AudioContext.d.ts deleted file mode 100644 index 50a7f3d6e..000000000 --- a/src-testing/src/audio/AudioContext.d.ts +++ /dev/null @@ -1,19 +0,0 @@ -/** - * This contains methods for setting up an {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioContext | AudioContext}. - * Used internally by the {@link AudioListener | AudioListener} and {@link AudioLoader | AudioLoader} classes. - * This uses the {@link https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API | Web Audio API}. - * @see {@link https://threejs.org/docs/index.html#api/en/audio/AudioContext | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/audio/AudioContext.js | Source} - */ -export namespace AudioContext { - /** - * Return the value of the variable `context` in the outer scope, if defined, otherwise set it to a new {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioContext | AudioContext}. - */ - function getContext(): AudioContext; - - /** - * Set the variable `context` in the outer scope to `value`. - * @param value - */ - function setContext(context: AudioContext): void; -} diff --git a/src-testing/src/audio/AudioListener.d.ts b/src-testing/src/audio/AudioListener.d.ts deleted file mode 100644 index a49e4d5c7..000000000 --- a/src-testing/src/audio/AudioListener.d.ts +++ /dev/null @@ -1,96 +0,0 @@ -import { Object3D } from "../core/Object3D.js"; -import { AudioContext } from "./AudioContext.js"; - -/** - * The {@link AudioListener} represents a virtual {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioListener | listener} of the all positional and non-positional audio effects in the scene. - * A three.js application usually creates a single instance of {@link AudioListener} * @remarks - * It is a mandatory construtor parameter for audios entities like {@link Audio | Audio} and {@link PositionalAudio | PositionalAudio}. - * In most cases, the listener object is a child of the camera - * So the 3D transformation of the camera represents the 3D transformation of the listener. - * @example - * ```typescript - * // create an {@link AudioListener} and add it to the camera - * const listener = new THREE.AudioListener(); - * camera.add(listener); - * // create a global audio source - * const sound = new THREE.Audio(listener); - * // load a sound and set it as the Audio object's buffer - * const audioLoader = new THREE.AudioLoader(); - * audioLoader.load('sounds/ambient.ogg', function (buffer) { - * sound.setBuffer(buffer); - * sound.setLoop(true); - * sound.setVolume(0.5); - * sound.play(); - * }); - * ``` - * @see Example: {@link https://threejs.org/examples/#webaudio_sandbox | webaudio / sandbox } - * @see Example: {@link https://threejs.org/examples/#webaudio_timing | webaudio / timing } - * @see Example: {@link https://threejs.org/examples/#webaudio_visualizer | webaudio / visualizer } - * @see {@link https://threejs.org/docs/index.html#api/en/audio/AudioListener | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/audio/AudioListener.js | Source} - */ -export class AudioListener extends Object3D { - /** - * Create a new AudioListener. - */ - constructor(); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `AudioListener` - */ - readonly type: string | "AudioListener"; - - /** - * The {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioContext | AudioContext} of the {@link {@link AudioListener} | listener} given in the constructor. - */ - context: AudioContext; - - /** - * A {@link https://developer.mozilla.org/en-US/docs/Web/API/GainNode | GainNode} created using - * {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioContext/createGain | AudioContext.createGain()}. - */ - gain: GainNode; - - /** - * @defaultValue `null` - */ - filter: AudioNode; - - /** - * Time delta value for audio entities. Use in context of {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioParam/linearRampToValueAtTime | AudioParam.linearRampToValueAtTimeDefault()}. - * @defaultValue `0` - */ - timeDelta: number; - - /** - * Return the {@link AudioListener.gain | gainNode}. - */ - getInput(): GainNode; - /** - * Set the {@link AudioListener.filter | filter} property to `null`. - */ - removeFilter(): this; - - /** - * Returns the value of the {@link AudioListener.filter | filter} property. - */ - getFilter(): AudioNode; - /** - * Set the {@link AudioListener.filter | filter} property to `value`. - * @param value - */ - setFilter(value: AudioNode): this; - - /** - * Return the volume. - */ - getMasterVolume(): number; - - /** - * Set the volume. - * @param value - */ - setMasterVolume(value: number): this; -} diff --git a/src-testing/src/audio/PositionalAudio.d.ts b/src-testing/src/audio/PositionalAudio.d.ts deleted file mode 100644 index d72d10674..000000000 --- a/src-testing/src/audio/PositionalAudio.d.ts +++ /dev/null @@ -1,101 +0,0 @@ -import { Audio } from "./Audio.js"; -import { AudioListener } from "./AudioListener.js"; - -/** - * Create a positional audio object. - * This uses the {@link https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API | Web Audio API}. - * @example - * ```typescript - * // create an AudioListener and add it to the camera - * const listener = new THREE.AudioListener(); - * camera.add(listener); - * // create the {@link PositionalAudio} object (passing in the listener) - * const sound = new THREE.PositionalAudio(listener); - * // load a sound and set it as the {@link PositionalAudio} object's buffer - * const audioLoader = new THREE.AudioLoader(); - * audioLoader.load('sounds/song.ogg', function (buffer) { - * sound.setBuffer(buffer); - * sound.setRefDistance(20); - * sound.play(); - * }); - * // create an object for the sound to play from - * const sphere = new THREE.SphereGeometry(20, 32, 16); - * const material = new THREE.MeshPhongMaterial({ - * color: 0xff2200 - * }); - * const mesh = new THREE.Mesh(sphere, material); - * scene.add(mesh); - * // finally add the sound to the mesh - * mesh.add(sound); - * ``` - * @see Example: {@link https://threejs.org/examples/#webaudio_orientation | webaudio / orientation } - * @see Example: {@link https://threejs.org/examples/#webaudio_sandbox | webaudio / sandbox } - * @see Example: {@link https://threejs.org/examples/#webaudio_timing | webaudio / timing } - * @see {@link https://threejs.org/docs/index.html#api/en/audio/PositionalAudio | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/audio/PositionalAudio.js | Source} - */ -export class PositionalAudio extends Audio { - /** - * Create a new instance of {@link PositionalAudio} - * @param listener (required) {@link AudioListener | AudioListener} instance. - */ - constructor(listener: AudioListener); - - /** - * The PositionalAudio's {@link https://developer.mozilla.org/en-US/docs/Web/API/PannerNode | PannerNode}. - */ - panner: PannerNode; - - /** - * Returns the {@link PositionalAudio.panner | panner}. - */ - getOutput(): PannerNode; - - /** - * Returns the value of {@link https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/refDistance | panner.refDistance}. - */ - getRefDistance(): number; - /** - * Sets the value of {@link https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/refDistance | panner.refDistance}. - * @param value Expects a `Float` - */ - setRefDistance(value: number): this; - - /** - * Returns the value of {@link https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/rolloffFactor | panner.rolloffFactor}. - */ - getRolloffFactor(): number; - /** - * Sets the value of {@link https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/rolloffFactor | panner.rolloffFactor}. - * @param value Expects a `Float` - */ - setRolloffFactor(value: number): this; - - /** - * Returns the value of {@link https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/distanceModel | panner.distanceModel}. - */ - getDistanceModel(): string; - /** - * Sets the value of {@link https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/distanceModel | panner.distanceModel}. - * @param value - */ - setDistanceModel(value: string): this; - - /** - * Returns the value of {@link https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/maxDistance | panner.maxDistance}. - */ - getMaxDistance(): number; - /** - * Sets the value of {@link https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/maxDistance | panner.maxDistance}. - * @param value Expects a `Float` - */ - setMaxDistance(value: number): this; - - /** - * This method can be used in order to transform an omnidirectional sound into a {@link https://developer.mozilla.org/en-US/docs/Web/API/PannerNode | directional sound}. - * @param coneInnerAngle Expects a `Float` - * @param coneOuterAngle Expects a `Float` - * @param coneOuterGain Expects a `Float` - */ - setDirectionalCone(coneInnerAngle: number, coneOuterAngle: number, coneOuterGain: number): this; -} diff --git a/src-testing/src/cameras/ArrayCamera.d.ts b/src-testing/src/cameras/ArrayCamera.d.ts deleted file mode 100644 index e9e9a221d..000000000 --- a/src-testing/src/cameras/ArrayCamera.d.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { PerspectiveCamera } from "./PerspectiveCamera.js"; - -/** - * {@link ArrayCamera} can be used in order to efficiently render a scene with a predefined set of cameras - * @remarks - * This is an important performance aspect for rendering VR scenes. - * An instance of {@link ArrayCamera} always has an array of sub cameras - * It's mandatory to define for each sub camera the `viewport` property which determines the part of the viewport that is rendered with this camera. - * @see Example: {@link https://threejs.org/examples/#webgl_camera_array | camera / array } - * @see {@link https://threejs.org/docs/index.html#api/en/cameras/ArrayCamera | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/cameras/ArrayCamera.js | Source} - */ -export class ArrayCamera extends PerspectiveCamera { - /** - * An array of cameras. - * @param array. Default `[]`. - */ - constructor(cameras?: PerspectiveCamera[]); - - /** - * Read-only flag to check if a given object is of type {@link ArrayCamera}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isArrayCamera: true; - - /** - * An array of cameras. - * @defaultValue `[]` - */ - cameras: PerspectiveCamera[]; -} diff --git a/src-testing/src/cameras/Camera.d.ts b/src-testing/src/cameras/Camera.d.ts deleted file mode 100644 index b49add52e..000000000 --- a/src-testing/src/cameras/Camera.d.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { CoordinateSystem } from "../constants.js"; -import { Layers } from "../core/Layers.js"; -import { Object3D } from "../core/Object3D.js"; -import { Matrix4 } from "../math/Matrix4.js"; -import { Vector3 } from "../math/Vector3.js"; -import { Vector4 } from "../math/Vector4.js"; - -/** - * Abstract base class for cameras - * @remarks - * This class should always be inherited when you build a new camera. - * @see {@link https://threejs.org/docs/index.html#api/en/cameras/Camera | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/cameras/Camera.js | Source} - */ -export class Camera extends Object3D { - /** - * @remarks - * Note that this class is not intended to be called directly; you probably want a - * {@link THREE.PerspectiveCamera | PerspectiveCamera} or - * {@link THREE.OrthographicCamera | OrthographicCamera} instead. - */ - constructor(); - - /** - * Read-only flag to check if a given object is of type {@link Camera}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isCamera: true; - - /** - * @override - * @defaultValue `Camera` - */ - override readonly type: string | "Camera"; - - /** - * @override - * The {@link THREE.Layers | layers} that the {@link Camera} is a member of. - * @remarks Objects must share at least one layer with the {@link Camera} to be n when the camera's viewpoint is rendered. - * @defaultValue `new THREE.Layers()` - */ - override layers: Layers; - - /** - * This is the inverse of matrixWorld. - * @remarks MatrixWorld contains the Matrix which has the world transform of the {@link Camera} . - * @defaultValue {@link THREE.Matrix4 | `new THREE.Matrix4()`} - */ - matrixWorldInverse: Matrix4; - - /** - * This is the matrix which contains the projection. - * @defaultValue {@link THREE.Matrix4 | `new THREE.Matrix4()`} - */ - projectionMatrix: Matrix4; - - /** - * This is the inverse of projectionMatrix. - * @defaultValue {@link THREE.Matrix4 | `new THREE.Matrix4()`} - */ - projectionMatrixInverse: Matrix4; - - coordinateSystem: CoordinateSystem; - - viewport?: Vector4; - - /** - * Returns a {@link THREE.Vector3 | Vector3} representing the world space direction in which the {@link Camera} is looking. - * @remarks Note: A {@link Camera} looks down its local, negative z-axis. - * @param target The result will be copied into this Vector3. - */ - getWorldDirection(target: Vector3): Vector3; -} diff --git a/src-testing/src/cameras/CubeCamera.d.ts b/src-testing/src/cameras/CubeCamera.d.ts deleted file mode 100644 index e6e82fb19..000000000 --- a/src-testing/src/cameras/CubeCamera.d.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { CoordinateSystem } from "../constants.js"; -import { Object3D } from "../core/Object3D.js"; -import { WebGLCubeRenderTarget } from "../renderers/WebGLCubeRenderTarget.js"; -import { WebGLRenderer } from "../renderers/WebGLRenderer.js"; - -/** - * Creates **6** {@link THREE.PerspectiveCamera | cameras} that render to a {@link THREE.WebGLCubeRenderTarget | WebGLCubeRenderTarget}. - * @remarks The cameras are added to the {@link children} array. - * @example - * ```typescript - * // Create cube render target - * const cubeRenderTarget = new THREE.WebGLCubeRenderTarget( 128, { generateMipmaps: true, minFilter: THREE.LinearMipmapLinearFilter } ); - * - * // Create cube camera - * const cubeCamera = new THREE.CubeCamera( 1, 100000, cubeRenderTarget ); - * scene.add( cubeCamera ); - * - * // Create car - * const chromeMaterial = new THREE.MeshLambertMaterial( { color: 0xffffff, envMap: cubeRenderTarget.texture } ); - * const car = new THREE.Mesh( carGeometry, chromeMaterial ); - * scene.add( car ); - * - * // Update the render target cube - * car.visible = false; - * cubeCamera.position.copy( car.position ); - * cubeCamera.update( renderer, scene ); - * - * // Render the scene - * car.visible = true; - * renderer.render( scene, camera ); - * ``` - * @see Example: {@link https://threejs.org/examples/#webgl_materials_cubemap_dynamic | materials / cubemap / dynamic } - * @see {@link https://threejs.org/docs/index.html#api/en/cameras/CubeCamera | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/cameras/CubeCamera.js | Source} - */ -export class CubeCamera extends Object3D { - /** - * Constructs a {@link CubeCamera} that contains 6 {@link PerspectiveCamera | PerspectiveCameras} that render to a {@link THREE.WebGLCubeRenderTarget | WebGLCubeRenderTarget}. - * @param near The near clipping distance. - * @param far The far clipping distance. - * @param renderTarget The destination cube render target. - */ - constructor(near: number, far: number, renderTarget: WebGLCubeRenderTarget); - - /** - * @override - * @defaultValue `CubeCamera` - */ - override readonly type: string | "CubeCamera"; - - /** - * The destination cube render target. - */ - renderTarget: WebGLCubeRenderTarget; - - coordinateSystem: CoordinateSystem; - - activeMipmapLevel: number; - - updateCoordinateSystem(): void; - - /** - * Call this to update the {@link CubeCamera.renderTarget | renderTarget}. - * @param renderer The current WebGL renderer - * @param scene The current scene - */ - update(renderer: WebGLRenderer, scene: Object3D): void; -} diff --git a/src-testing/src/cameras/OrthographicCamera.d.ts b/src-testing/src/cameras/OrthographicCamera.d.ts deleted file mode 100644 index 745d11416..000000000 --- a/src-testing/src/cameras/OrthographicCamera.d.ts +++ /dev/null @@ -1,174 +0,0 @@ -import { JSONMeta, Object3DJSON, Object3DJSONObject } from "../core/Object3D.js"; -import { Camera } from "./Camera.js"; - -export interface OrthographicCameraJSONObject extends Object3DJSONObject { - zoom: number; - left: number; - right: number; - top: number; - bottom: number; - near: number; - far: number; - - view?: { - enabled: boolean; - fullWidth: number; - fullHeight: number; - offsetX: number; - offsetY: number; - width: number; - height: number; - }; -} - -export interface OrthographicCameraJSON extends Object3DJSON { - object: OrthographicCameraJSONObject; -} - -/** - * Camera that uses {@link https://en.wikipedia.org/wiki/Orthographic_projection | orthographic projection}. - * In this projection mode, an object's size in the rendered image stays constant regardless of its distance from the camera. - * This can be useful for rendering 2D scenes and UI elements, amongst other things. - * @example - * ```typescript - * const camera = new THREE.OrthographicCamera(width / -2, width / 2, height / 2, height / -2, 1, 1000); - * scene.add(camera); - * ``` - * @see Example: {@link https://threejs.org/examples/#webgl_camera | camera } - * @see Example: {@link https://threejs.org/examples/#webgl_interactive_cubes_ortho | interactive / cubes / ortho } - * @see Example: {@link https://threejs.org/examples/#webgl_materials_cubemap_dynamic | materials / cubemap / dynamic } - * @see Example: {@link https://threejs.org/examples/#webgl_postprocessing_advanced | postprocessing / advanced } - * @see Example: {@link https://threejs.org/examples/#webgl_postprocessing_dof2 | postprocessing / dof2 } - * @see Example: {@link https://threejs.org/examples/#webgl_postprocessing_godrays | postprocessing / godrays } - * @see Example: {@link https://threejs.org/examples/#webgl_rtt | rtt } - * @see Example: {@link https://threejs.org/examples/#webgl_shaders_tonemapping | shaders / tonemapping } - * @see Example: {@link https://threejs.org/examples/#webgl_shadowmap | shadowmap } - * @see {@link https://threejs.org/docs/index.html#api/en/cameras/OrthographicCamera | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/cameras/OrthographicCamera.js | Source} - */ -export class OrthographicCamera extends Camera { - /** - * Creates a new {@link OrthographicCamera}. - * @remarks Together these define the camera's {@link https://en.wikipedia.org/wiki/Viewing_frustum | viewing frustum}. - * @param left Camera frustum left plane. Default `-1`. - * @param right Camera frustum right plane. Default `1`. - * @param top Camera frustum top plane. Default `1`. - * @param bottom Camera frustum bottom plane. Default `-1`. - * @param near Camera frustum near plane. Default `0.1`. - * @param far Camera frustum far plane. Default `2000`. - */ - constructor(left?: number, right?: number, top?: number, bottom?: number, near?: number, far?: number); - - /** - * Read-only flag to check if a given object is of type {@link OrthographicCamera}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isOrthographicCamera: true; - - /** - * @override - * @defaultValue `OrthographicCamera` - */ - override readonly type: string | "OrthographicCamera"; - - /** - * Gets or sets the zoom factor of the camera. - * @defaultValue `1` - */ - zoom: number; - - /** - * Set by {@link setViewOffset | .setViewOffset()}. - * @defaultValue `null` - */ - view: null | { - enabled: boolean; - fullWidth: number; - fullHeight: number; - offsetX: number; - offsetY: number; - width: number; - height: number; - }; - - /** - * Camera frustum left plane. - * @remarks Expects a `Float` - * @defaultValue `-1` - */ - left: number; - - /** - * Camera frustum right plane. - * @remarks Expects a `Float` - * @defaultValue `1` - */ - right: number; - - /** - * Camera frustum top plane. - * @remarks Expects a `Float` - * @defaultValue `1` - */ - top: number; - - /** - * Camera frustum bottom plane. - * @remarks Expects a `Float`. - * @defaultValue `-1` - */ - bottom: number; - - /** - * Camera frustum near plane.`. - * @remarks The valid range is between `0` and the current value of the {@link far | .far} plane. - * @remarks Note that, unlike for the {@link THREE.PerspectiveCamera | PerspectiveCamera}, `0` is a valid value for an {@link THREE.OrthographicCamera | OrthographicCamera's} near plane. - * @remarks Expects a `Float` - * @defaultValue `0.1` - */ - near: number; - - /** - * Camera frustum far plane. - * @remarks Must be greater than the current value of {@link near | .near} plane. - * @remarks Expects a `Float` - * @defaultValue `2000` - */ - far: number; - - /** - * Updates the camera projection matrix - * @remarks Must be called after any change of parameters. - */ - updateProjectionMatrix(): void; - - /** - * Sets an offset in a larger {@link https://en.wikipedia.org/wiki/Viewing_frustum | viewing frustum} - * @remarks - * This is useful for multi-window or multi-monitor/multi-machine setups - * For an example on how to use it see {@link PerspectiveCamera.setViewOffset | PerspectiveCamera}. - * @see {@link THREE.PerspectiveCamera.setViewOffset | PerspectiveCamera}. - * @param fullWidth Full width of multiview setup Expects a `Float`. - * @param fullHeight Full height of multiview setup Expects a `Float`. - * @param x Horizontal offset of subcamera Expects a `Float`. - * @param y Vertical offset of subcamera Expects a `Float`. - * @param width Width of subcamera Expects a `Float`. - * @param height Height of subcamera Expects a `Float`. - */ - setViewOffset( - fullWidth: number, - fullHeight: number, - offsetX: number, - offsetY: number, - width: number, - height: number, - ): void; - - /** - * Removes any offset set by the {@link setViewOffset | .setViewOffset} method. - */ - clearViewOffset(): void; - - toJSON(meta?: JSONMeta): OrthographicCameraJSON; -} diff --git a/src-testing/src/cameras/PerspectiveCamera.d.ts b/src-testing/src/cameras/PerspectiveCamera.d.ts deleted file mode 100644 index 60567105f..000000000 --- a/src-testing/src/cameras/PerspectiveCamera.d.ts +++ /dev/null @@ -1,254 +0,0 @@ -import { JSONMeta, Object3DJSON, Object3DJSONObject } from "../core/Object3D.js"; -import { Vector2 } from "../math/Vector2.js"; -import { Camera } from "./Camera.js"; - -export interface PerspectiveCameraJSONObject extends Object3DJSONObject { - fov: number; - zoom: number; - - near: number; - far: number; - focus: number; - - aspect: number; - - view?: { - enabled: boolean; - fullWidth: number; - fullHeight: number; - offsetX: number; - offsetY: number; - width: number; - height: number; - }; - - filmGauge: number; - filmOffset: number; -} - -export interface PerspectiveCameraJSON extends Object3DJSON { - object: PerspectiveCameraJSONObject; -} - -/** - * Camera that uses {@link https://en.wikipedia.org/wiki/Perspective_(graphical) | perspective projection}. - * This projection mode is designed to mimic the way the human eye sees - * @remarks - * It is the most common projection mode used for rendering a 3D scene. - * @example - * ```typescript - * const camera = new THREE.PerspectiveCamera(45, width / height, 1, 1000); - * scene.add(camera); - * ``` - * @see Example: {@link https://threejs.org/examples/#webgl_animation_skinning_blending | animation / skinning / blending } - * @see Example: {@link https://threejs.org/examples/#webgl_animation_skinning_morph | animation / skinning / morph } - * @see Example: {@link https://threejs.org/examples/#webgl_effects_stereo | effects / stereo } - * @see Example: {@link https://threejs.org/examples/#webgl_interactive_cubes | interactive / cubes } - * @see Example: {@link https://threejs.org/examples/#webgl_loader_collada_skinning | loader / collada / skinning } - * @see {@link https://threejs.org/docs/index.html#api/en/cameras/PerspectiveCamera | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/cameras/PerspectiveCamera.js | Source} - */ -export class PerspectiveCamera extends Camera { - /** - * Creates a new {@link PerspectiveCamera}. - * @remarks Together these define the camera's {@link https://en.wikipedia.org/wiki/Viewing_frustum | viewing frustum}. - * @param fov Camera frustum vertical field of view. Default `50`. - * @param aspect Camera frustum aspect ratio. Default `1`. - * @param near Camera frustum near plane. Default `0.1`. - * @param far Camera frustum far plane. Default `2000`. - */ - constructor(fov?: number, aspect?: number, near?: number, far?: number); - - /** - * Read-only flag to check if a given object is of type {@link Camera}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isPerspectiveCamera: true; - - /** - * @override - * @defaultValue `PerspectiveCamera` - */ - override readonly type: string | "PerspectiveCamera"; - - /** - * Gets or sets the zoom factor of the camera. - * @defaultValue `1` - */ - zoom: number; - - /** - * Camera frustum vertical field of view, from bottom to top of view, in degrees. - * @remarks Expects a `Float` - * @defaultValue `50` - */ - fov: number; - - /** - * Camera frustum aspect ratio, usually the canvas width / canvas height. - * @remarks Expects a `Float` - * @defaultValue `1`, _(square canvas)_. - */ - aspect: number; - - /** - * Camera frustum near plane. - * @remarks The valid range is greater than `0` and less than the current value of the {@link far | .far} plane. - * @remarks Note that, unlike for the {@link THREE.OrthographicCamera | OrthographicCamera}, `0` is **not** a valid value for a {@link PerspectiveCamera |PerspectiveCamera's}. near plane. - * @defaultValue `0.1` - * @remarks Expects a `Float` - */ - near: number; - - /** - * Camera frustum far plane. - * @remarks Must be greater than the current value of {@link near | .near} plane. - * @remarks Expects a `Float` - * @defaultValue `2000` - */ - far: number; - - /** - * Object distance used for stereoscopy and depth-of-field effects. - * @remarks This parameter does not influence the projection matrix unless a {@link THREE.StereoCamera | StereoCamera} is being used. - * @remarks Expects a `Float` - * @defaultValue `10` - */ - focus: number; - - /** - * Frustum window specification or null. - * This is set using the {@link setViewOffset | .setViewOffset} method and cleared using {@link clearViewOffset | .clearViewOffset}. - * @defaultValue `null` - */ - view: null | { - enabled: boolean; - fullWidth: number; - fullHeight: number; - offsetX: number; - offsetY: number; - width: number; - height: number; - }; - - /** - * Film size used for the larger axis. - * This parameter does not influence the projection matrix unless {@link filmOffset | .filmOffset} is set to a nonzero value. - * @remarks Expects a `Float` - * @defaultValue `35`, _millimeters_. - */ - filmGauge: number; - - /** - * Horizontal off-center offset in the same unit as {@link filmGauge | .filmGauge}. - * @remarks Expects a `Float` - * @defaultValue `0` - */ - filmOffset: number; - - /** - * Returns the focal length of the current {@link .fov | fov} in respect to {@link filmGauge | .filmGauge}. - */ - getFocalLength(): number; - - /** - * Sets the FOV by focal length in respect to the current {@link filmGauge | .filmGauge}. - * @remarks By default, the focal length is specified for a `35mm` (full frame) camera. - * @param focalLength Expects a `Float` - */ - setFocalLength(focalLength: number): void; - - /** - * Returns the current vertical field of view angle in degrees considering {@link zoom | .zoom}. - */ - getEffectiveFOV(): number; - - /** - * Returns the width of the image on the film - * @remarks - * If {@link aspect | .aspect}. is greater than or equal to one (landscape format), the result equals {@link filmGauge | .filmGauge}. - */ - getFilmWidth(): number; - - /** - * Returns the height of the image on the film - * @remarks - * If {@link aspect | .aspect}. is less than or equal to one (portrait format), the result equals {@link filmGauge | .filmGauge}. - */ - getFilmHeight(): number; - - /** - * Computes the 2D bounds of the camera's viewable rectangle at a given distance along the viewing direction. - * Sets minTarget and maxTarget to the coordinates of the lower-left and upper-right corners of the view rectangle. - */ - getViewBounds(distance: number, minTarget: Vector2, maxTarget: Vector2): void; - - /** - * Computes the width and height of the camera's viewable rectangle at a given distance along the viewing direction. - * Copies the result into the target Vector2, where x is width and y is height. - */ - getViewSize(distance: number, target: Vector2): Vector2; - - /** - * Sets an offset in a larger frustum. - * @remarks - * This is useful for multi-window or multi-monitor/multi-machine setups. - * - * For example, if you have 3x2 monitors and each monitor is _1920x1080_ and - * the monitors are in grid like this - * ``` - * ┌───┬───┬───┐ - * │ A │ B │ C │ - * ├───┼───┼───┤ - * │ D │ E │ F │ - * └───┴───┴───┘ - * ``` - * then for each monitor you would call it like this - * ```typescript - * const w = 1920; - * const h = 1080; - * const fullWidth = w * 3; - * const fullHeight = h * 2; - * - * // Monitor - A - * camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 0, w, h ); - * // Monitor - B - * camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 0, w, h ); - * // Monitor - C - * camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 0, w, h ); - * // Monitor - D - * camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 1, w, h ); - * // Monitor - E - * camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 1, w, h ); - * // Monitor - F - * camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 1, w, h ); - * ``` - * Note there is no reason monitors have to be the same size or in a grid. - * @param fullWidth Full width of multiview setup Expects a `Float`. - * @param fullHeight Full height of multiview setup Expects a `Float`. - * @param x Horizontal offset of subcamera Expects a `Float`. - * @param y Vertical offset of subcamera Expects a `Float`. - * @param width Width of subcamera Expects a `Float`. - * @param height Height of subcamera Expects a `Float`. - */ - setViewOffset(fullWidth: number, fullHeight: number, x: number, y: number, width: number, height: number): void; - - /** - * Removes any offset set by the {@link setViewOffset | .setViewOffset} method. - */ - clearViewOffset(): void; - - /** - * Updates the camera projection matrix - * @remarks Must be called after any change of parameters. - */ - updateProjectionMatrix(): void; - - /** - * @deprecated Use {@link PerspectiveCamera.setFocalLength | .setFocalLength()} and {@link PerspectiveCamera.filmGauge | .filmGauge} instead. - */ - setLens(focalLength: number, frameHeight?: number): void; - - toJSON(meta?: JSONMeta): PerspectiveCameraJSON; -} diff --git a/src-testing/src/cameras/StereoCamera.d.ts b/src-testing/src/cameras/StereoCamera.d.ts deleted file mode 100644 index 3f359e3e0..000000000 --- a/src-testing/src/cameras/StereoCamera.d.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { Camera } from "./Camera.js"; -import { PerspectiveCamera } from "./PerspectiveCamera.js"; - -/** - * Dual {@link PerspectiveCamera | PerspectiveCamera}s used for effects such as - * {@link https://en.wikipedia.org/wiki/Anaglyph_3D | 3D Anaglyph} or - * {@link https://en.wikipedia.org/wiki/parallax_barrier | Parallax Barrier}. - * @see Example: {@link https://threejs.org/examples/#webgl_effects_anaglyph | effects / anaglyph } - * @see Example: {@link https://threejs.org/examples/#webgl_effects_parallaxbarrier | effects / parallaxbarrier } - * @see Example: {@link https://threejs.org/examples/#webgl_effects_stereo | effects / stereo } - * @see {@link https://threejs.org/docs/index.html#api/en/cameras/StereoCamera | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/cameras/StereoCamera.js | Source} - */ -export class StereoCamera extends Camera { - constructor(); - - type: "StereoCamera"; - - /** - * @remarks Expects a `Float` - * @defaultValue `1` - */ - aspect: number; - - /** - * @remarks Expects a `Float` - * @defaultValue `0.064` - */ - eyeSep: number; - - /** - * The Left camera. - * A {@link PerspectiveCamera } added to {@link THREE.PerspectiveCamera.layers | layer 1} - * @remarks Objects to be rendered by the **left** camera must also be added to this layer. - */ - cameraL: PerspectiveCamera; - - /** - * The Right camera. - * A {@link PerspectiveCamera } added to {@link THREE.PerspectiveCamera.layers | layer 2} - * @remarks Objects to be rendered by the **right** camera must also be added to this layer. - */ - cameraR: PerspectiveCamera; - - /** - * Update the stereo cameras based on the camera passed in. - * @param camera - */ - update(camera: PerspectiveCamera): void; -} diff --git a/src-testing/src/constants.d.ts b/src-testing/src/constants.d.ts deleted file mode 100644 index f5d26b42a..000000000 --- a/src-testing/src/constants.d.ts +++ /dev/null @@ -1,918 +0,0 @@ -export const REVISION: string; - -// https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent.button -export enum MOUSE { - LEFT = 0, - MIDDLE = 1, - RIGHT = 2, - ROTATE = 0, - DOLLY = 1, - PAN = 2, -} - -export enum TOUCH { - ROTATE = 0, - PAN = 1, - DOLLY_PAN = 2, - DOLLY_ROTATE = 3, -} - -// GL STATE CONSTANTS -export const CullFaceNone: 0; -export const CullFaceBack: 1; -export const CullFaceFront: 2; -export const CullFaceFrontBack: 3; -export type CullFace = typeof CullFaceNone | typeof CullFaceBack | typeof CullFaceFront | typeof CullFaceFrontBack; - -// Shadowing Type -export const BasicShadowMap: 0; -export const PCFShadowMap: 1; -export const PCFSoftShadowMap: 2; -export const VSMShadowMap: 3; -export type ShadowMapType = typeof BasicShadowMap | typeof PCFShadowMap | typeof PCFSoftShadowMap | typeof VSMShadowMap; - -// MATERIAL CONSTANTS - -// side -export const FrontSide: 0; -export const BackSide: 1; -export const DoubleSide: 2; -/** - * Defines which side of faces will be rendered - front, back or both. - * Default is {@link FrontSide}. - */ -export type Side = typeof FrontSide | typeof BackSide | typeof DoubleSide; - -// blending modes -export const NoBlending: 0; -export const NormalBlending: 1; -export const AdditiveBlending: 2; -export const SubtractiveBlending: 3; -export const MultiplyBlending: 4; -export const CustomBlending: 5; -export type Blending = - | typeof NoBlending - | typeof NormalBlending - | typeof AdditiveBlending - | typeof SubtractiveBlending - | typeof MultiplyBlending - | typeof CustomBlending; - -// custom blending equations -// (numbers start from 100 not to clash with other -// mappings to OpenGL constants defined in Texture.js) -export const AddEquation: 100; -export const SubtractEquation: 101; -export const ReverseSubtractEquation: 102; -export const MinEquation: 103; -export const MaxEquation: 104; -export type BlendingEquation = - | typeof AddEquation - | typeof SubtractEquation - | typeof ReverseSubtractEquation - | typeof MinEquation - | typeof MaxEquation; - -// custom blending factors -export const ZeroFactor: 200; -export const OneFactor: 201; -export const SrcColorFactor: 202; -export const OneMinusSrcColorFactor: 203; -export const SrcAlphaFactor: 204; -export const OneMinusSrcAlphaFactor: 205; -export const DstAlphaFactor: 206; -export const OneMinusDstAlphaFactor: 207; -export const DstColorFactor: 208; -export const OneMinusDstColorFactor: 209; -export const SrcAlphaSaturateFactor: 210; -export const ConstantColorFactor: 211; -export const OneMinusConstantColorFactor: 212; -export const ConstantAlphaFactor: 213; -export const OneMinusConstantAlphaFactor: 214; -export type BlendingDstFactor = - | typeof ZeroFactor - | typeof OneFactor - | typeof SrcColorFactor - | typeof OneMinusSrcColorFactor - | typeof SrcAlphaFactor - | typeof OneMinusSrcAlphaFactor - | typeof DstAlphaFactor - | typeof OneMinusDstAlphaFactor - | typeof DstColorFactor - | typeof OneMinusDstColorFactor - | typeof ConstantColorFactor - | typeof OneMinusConstantColorFactor - | typeof ConstantAlphaFactor - | typeof OneMinusConstantAlphaFactor; -export type BlendingSrcFactor = BlendingDstFactor | typeof SrcAlphaSaturateFactor; - -// depth modes -export const NeverDepth: 0; -export const AlwaysDepth: 1; -export const LessDepth: 2; -export const LessEqualDepth: 3; -export const EqualDepth: 4; -export const GreaterEqualDepth: 5; -export const GreaterDepth: 6; -export const NotEqualDepth: 7; -export type DepthModes = - | typeof NeverDepth - | typeof AlwaysDepth - | typeof LessDepth - | typeof LessEqualDepth - | typeof EqualDepth - | typeof GreaterEqualDepth - | typeof GreaterDepth - | typeof NotEqualDepth; - -// TEXTURE CONSTANTS -// Operations -export const MultiplyOperation: 0; -export const MixOperation: 1; -export const AddOperation: 2; -export type Combine = typeof MultiplyOperation | typeof MixOperation | typeof AddOperation; - -// Tone Mapping modes -export const NoToneMapping: 0; -export const LinearToneMapping: 1; -export const ReinhardToneMapping: 2; -export const CineonToneMapping: 3; -export const ACESFilmicToneMapping: 4; -export const CustomToneMapping: 5; -export const AgXToneMapping: 6; -export const NeutralToneMapping: 7; -export type ToneMapping = - | typeof NoToneMapping - | typeof LinearToneMapping - | typeof ReinhardToneMapping - | typeof CineonToneMapping - | typeof ACESFilmicToneMapping - | typeof CustomToneMapping - | typeof AgXToneMapping - | typeof NeutralToneMapping; - -// Bind modes -export const AttachedBindMode: "attached"; -export const DetachedBindMode: "detached"; -export type BindMode = typeof AttachedBindMode | typeof DetachedBindMode; - -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// -// Mapping modes - -/** - * Maps the texture using the mesh's UV coordinates. - * @remarks This is the _default_ value and behaver for Texture Mapping. - */ -export const UVMapping: 300; - -/** - * @remarks This is the _default_ value and behaver for Cube Texture Mapping. - */ -export const CubeReflectionMapping: 301; -export const CubeRefractionMapping: 302; -export const CubeUVReflectionMapping: 306; - -export const EquirectangularReflectionMapping: 303; -export const EquirectangularRefractionMapping: 304; - -/** - * Texture Mapping Modes for non-cube Textures - * @remarks {@link UVMapping} is the _default_ value and behaver for Texture Mapping. - * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} - */ -export type Mapping = - | typeof UVMapping - | typeof EquirectangularReflectionMapping - | typeof EquirectangularRefractionMapping; - -/** - * Texture Mapping Modes for cube Textures - * @remarks {@link CubeReflectionMapping} is the _default_ value and behaver for Cube Texture Mapping. - * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} - */ -export type CubeTextureMapping = - | typeof CubeReflectionMapping - | typeof CubeRefractionMapping - | typeof CubeUVReflectionMapping; - -/** - * Texture Mapping Modes for any type of Textures - * @see {@link Mapping} and {@link CubeTextureMapping} - * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} - */ -export type AnyMapping = Mapping | CubeTextureMapping; - -/////////////////////////////////////////////////////////////////////////////// -// Wrapping modes - -/** With {@link RepeatWrapping} the texture will simply repeat to infinity. */ -export const RepeatWrapping: 1000; -/** - * With {@link ClampToEdgeWrapping} the last pixel of the texture stretches to the edge of the mesh. - * @remarks This is the _default_ value and behaver for Wrapping Mapping. - */ -export const ClampToEdgeWrapping: 1001; -/** With {@link MirroredRepeatWrapping} the texture will repeats to infinity, mirroring on each repeat. */ -export const MirroredRepeatWrapping: 1002; - -/** - * Texture Wrapping Modes - * @remarks {@link ClampToEdgeWrapping} is the _default_ value and behaver for Wrapping Mapping. - * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} - */ -export type Wrapping = typeof RepeatWrapping | typeof ClampToEdgeWrapping | typeof MirroredRepeatWrapping; - -/////////////////////////////////////////////////////////////////////////////// -// Filters - -/** {@link NearestFilter} returns the value of the texture element that is nearest (in Manhattan distance) to the specified texture coordinates. */ -export const NearestFilter: 1003; - -/** - * {@link NearestMipmapNearestFilter} chooses the mipmap that most closely matches the size of the pixel being textured - * and uses the {@link NearestFilter} criterion (the texel nearest to the center of the pixel) to produce a texture value. - */ -export const NearestMipmapNearestFilter: 1004; -/** - * {@link NearestMipmapNearestFilter} chooses the mipmap that most closely matches the size of the pixel being textured - * and uses the {@link NearestFilter} criterion (the texel nearest to the center of the pixel) to produce a texture value. - */ -export const NearestMipMapNearestFilter: 1004; - -/** - * {@link NearestMipmapLinearFilter} chooses the two mipmaps that most closely match the size of the pixel being textured - * and uses the {@link NearestFilter} criterion to produce a texture value from each mipmap. - * The final texture value is a weighted average of those two values. - */ -export const NearestMipmapLinearFilter: 1005; -/** - * {@link NearestMipMapLinearFilter} chooses the two mipmaps that most closely match the size of the pixel being textured - * and uses the {@link NearestFilter} criterion to produce a texture value from each mipmap. - * The final texture value is a weighted average of those two values. - */ -export const NearestMipMapLinearFilter: 1005; - -/** - * {@link LinearFilter} returns the weighted average of the four texture elements that are closest to the specified texture coordinates, - * and can include items wrapped or repeated from other parts of a texture, - * depending on the values of {@link THREE.Texture.wrapS | wrapS} and {@link THREE.Texture.wrapT | wrapT}, and on the exact mapping. - */ -export const LinearFilter: 1006; - -/** - * {@link LinearMipmapNearestFilter} chooses the mipmap that most closely matches the size of the pixel being textured and - * uses the {@link LinearFilter} criterion (a weighted average of the four texels that are closest to the center of the pixel) to produce a texture value. - */ -export const LinearMipmapNearestFilter: 1007; -/** - * {@link LinearMipMapNearestFilter} chooses the mipmap that most closely matches the size of the pixel being textured and - * uses the {@link LinearFilter} criterion (a weighted average of the four texels that are closest to the center of the pixel) to produce a texture value. - */ -export const LinearMipMapNearestFilter: 1007; - -/** - * {@link LinearMipmapLinearFilter} is the default and chooses the two mipmaps that most closely match the size of the pixel being textured and - * uses the {@link LinearFilter} criterion to produce a texture value from each mipmap. - * The final texture value is a weighted average of those two values. - */ -export const LinearMipmapLinearFilter: 1008; - -/** - * {@link LinearMipMapLinearFilter} is the default and chooses the two mipmaps that most closely match the size of the pixel being textured and - * uses the {@link LinearFilter} criterion to produce a texture value from each mipmap. - * The final texture value is a weighted average of those two values. - */ -export const LinearMipMapLinearFilter: 1008; - -/** - * Texture Magnification Filter Modes. - * For use with a texture's {@link THREE.Texture.magFilter | magFilter} property, - * these define the texture magnification function to be used when the pixel being textured maps to an area less than or equal to one texture element (texel). - * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} - * @see {@link https://sbcode.net/threejs/mipmaps/ | Texture Mipmaps (non-official)} - */ -export type MagnificationTextureFilter = typeof NearestFilter | typeof LinearFilter; - -/** - * Texture Minification Filter Modes. - * For use with a texture's {@link THREE.Texture.minFilter | minFilter} property, - * these define the texture minifying function that is used whenever the pixel being textured maps to an area greater than one texture element (texel). - * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} - * @see {@link https://sbcode.net/threejs/mipmaps/ | Texture Mipmaps (non-official)} - */ -export type MinificationTextureFilter = - | typeof NearestFilter - | typeof NearestMipmapNearestFilter - | typeof NearestMipMapNearestFilter - | typeof NearestMipmapLinearFilter - | typeof NearestMipMapLinearFilter - | typeof LinearFilter - | typeof LinearMipmapNearestFilter - | typeof LinearMipMapNearestFilter - | typeof LinearMipmapLinearFilter - | typeof LinearMipMapLinearFilter; - -/** - * Texture all Magnification and Minification Filter Modes. - * @see {@link MagnificationTextureFilter} and {@link MinificationTextureFilter} - * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} - * @see {@link https://sbcode.net/threejs/mipmaps/ | Texture Mipmaps (non-official)} - */ -export type TextureFilter = MagnificationTextureFilter | MinificationTextureFilter; - -/////////////////////////////////////////////////////////////////////////////// -// Data types - -export const UnsignedByteType: 1009; -export const ByteType: 1010; -export const ShortType: 1011; -export const UnsignedShortType: 1012; -export const IntType: 1013; -export const UnsignedIntType: 1014; -export const FloatType: 1015; -export const HalfFloatType: 1016; -export const UnsignedShort4444Type: 1017; -export const UnsignedShort5551Type: 1018; -export const UnsignedInt248Type: 1020; -export const UnsignedInt5999Type: 35902; - -export type AttributeGPUType = typeof FloatType | typeof IntType; - -/** - * Texture Types. - * @remarks Must correspond to the correct {@link PixelFormat | format}. - * @see {@link THREE.Texture.type} - * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} - */ -export type TextureDataType = - | typeof UnsignedByteType - | typeof ByteType - | typeof ShortType - | typeof UnsignedShortType - | typeof IntType - | typeof UnsignedIntType - | typeof FloatType - | typeof HalfFloatType - | typeof UnsignedShort4444Type - | typeof UnsignedShort5551Type - | typeof UnsignedInt248Type - | typeof UnsignedInt5999Type; - -/////////////////////////////////////////////////////////////////////////////// -// Pixel formats - -/** {@link AlphaFormat} discards the red, green and blue components and reads just the alpha component. */ -export const AlphaFormat: 1021; - -export const RGBFormat: 1022; - -/** {@link RGBAFormat} is the default and reads the red, green, blue and alpha components. */ -export const RGBAFormat: 1023; - -/** - * {@link LuminanceFormat} reads each element as a single luminance component. - * This is then converted to a floating point, clamped to the range `[0,1]`, and then assembled into an RGBA element by - * placing the luminance value in the red, green and blue channels, and attaching `1.0` to the alpha channel. - */ -export const LuminanceFormat: 1024; - -/** - * {@link LuminanceAlphaFormat} reads each element as a luminance/alpha double. - * The same process occurs as for the {@link LuminanceFormat}, except that the alpha channel may have values other than `1.0`. - */ -export const LuminanceAlphaFormat: 1025; - -/** - * {@link DepthFormat} reads each element as a single depth value, converts it to floating point, and clamps to the range `[0,1]`. - * @remarks This is the default for {@link THREE.DepthTexture}. - */ -export const DepthFormat: 1026; - -/** - * {@link DepthStencilFormat} reads each element is a pair of depth and stencil values. - * The depth component of the pair is interpreted as in {@link DepthFormat}. - * The stencil component is interpreted based on the depth + stencil internal format. - */ -export const DepthStencilFormat: 1027; - -/** - * {@link RedFormat} discards the green and blue components and reads just the red component. - */ -export const RedFormat: 1028; - -/** - * {@link RedIntegerFormat} discards the green and blue components and reads just the red component. - * The texels are read as integers instead of floating point. - */ -export const RedIntegerFormat: 1029; - -/** - * {@link RGFormat} discards the alpha, and blue components and reads the red, and green components. - */ -export const RGFormat: 1030; - -/** - * {@link RGIntegerFormat} discards the alpha, and blue components and reads the red, and green components. - * The texels are read as integers instead of floating point. - */ -export const RGIntegerFormat: 1031; - -/** - * {@link RGBIntegerFormat} discrads the alpha components and reads the red, green, and blue components. - */ -export const RGBIntegerFormat: 1032; - -/** - * {@link RGBAIntegerFormat} reads the red, green, blue and alpha component - * @remarks This is the default for {@link THREE.Texture}. - */ -export const RGBAIntegerFormat: 1033; - -/** - * All Texture Pixel Formats Modes. - * @remarks Note that the texture must have the correct {@link THREE.Texture.type} set, as described in {@link TextureDataType}. - * @see {@link WebGLRenderingContext.texImage2D} for details. - * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} - */ -export type PixelFormat = - | typeof AlphaFormat - | typeof RGBFormat - | typeof RGBAFormat - | typeof LuminanceFormat - | typeof LuminanceAlphaFormat - | typeof DepthFormat - | typeof DepthStencilFormat - | typeof RedFormat - | typeof RedIntegerFormat - | typeof RGFormat - | typeof RGIntegerFormat - | typeof RGBIntegerFormat - | typeof RGBAIntegerFormat; - -/** - * All Texture Pixel Formats Modes for {@link THREE.DepthTexture}. - * @see {@link WebGLRenderingContext.texImage2D} for details. - * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} - */ -export type DepthTexturePixelFormat = typeof DepthFormat | typeof DepthStencilFormat; - -/////////////////////////////////////////////////////////////////////////////// -// Compressed texture formats -// DDS / ST3C Compressed texture formats - -/** - * A DXT1-compressed image in an RGB image format. - * @remarks Require support for the _WEBGL_compressed_texture_s3tc_ WebGL extension. - */ -export const RGB_S3TC_DXT1_Format: 33776; -/** - * A DXT1-compressed image in an RGB image format with a simple on/off alpha value. - * @remarks Require support for the _WEBGL_compressed_texture_s3tc_ WebGL extension. - */ -export const RGBA_S3TC_DXT1_Format: 33777; -/** - * A DXT3-compressed image in an RGBA image format. Compared to a 32-bit RGBA texture, it offers 4:1 compression. - * @remarks Require support for the _WEBGL_compressed_texture_s3tc_ WebGL extension. - */ -export const RGBA_S3TC_DXT3_Format: 33778; -/** - * A DXT5-compressed image in an RGBA image format. It also provides a 4:1 compression, but differs to the DXT3 compression in how the alpha compression is done. - * @remarks Require support for the _WEBGL_compressed_texture_s3tc_ WebGL extension. - */ -export const RGBA_S3TC_DXT5_Format: 33779; - -// PVRTC compressed './texture formats - -/** - * RGB compression in 4-bit mode. One block for each 4×4 pixels. - * @remarks Require support for the _WEBGL_compressed_texture_pvrtc_ WebGL extension. - */ -export const RGB_PVRTC_4BPPV1_Format: 35840; -/** - * RGB compression in 2-bit mode. One block for each 8×4 pixels. - * @remarks Require support for the _WEBGL_compressed_texture_pvrtc_ WebGL extension. - */ -export const RGB_PVRTC_2BPPV1_Format: 35841; -/** - * RGBA compression in 4-bit mode. One block for each 4×4 pixels. - * @remarks Require support for the _WEBGL_compressed_texture_pvrtc_ WebGL extension. - */ -export const RGBA_PVRTC_4BPPV1_Format: 35842; -/** - * RGBA compression in 2-bit mode. One block for each 8×4 pixels. - * @remarks Require support for the _WEBGL_compressed_texture_pvrtc_ WebGL extension. - */ -export const RGBA_PVRTC_2BPPV1_Format: 35843; - -// ETC compressed texture formats - -/** - * @remarks Require support for the _WEBGL_compressed_texture_etc1_ (ETC1) or _WEBGL_compressed_texture_etc_ (ETC2) WebGL extension. - */ -export const RGB_ETC1_Format: 36196; -/** - * @remarks Require support for the _WEBGL_compressed_texture_etc1_ (ETC1) or _WEBGL_compressed_texture_etc_ (ETC2) WebGL extension. - */ -export const RGB_ETC2_Format: 37492; -/** - * @remarks Require support for the _WEBGL_compressed_texture_etc1_ (ETC1) or _WEBGL_compressed_texture_etc_ (ETC2) WebGL extension. - */ -export const RGBA_ETC2_EAC_Format: 37496; - -// ASTC compressed texture formats - -/** - * @remarks Require support for the _WEBGL_compressed_texture_astc_ WebGL extension. - */ -export const RGBA_ASTC_4x4_Format: 37808; -/** - * @remarks Require support for the _WEBGL_compressed_texture_astc_ WebGL extension. - */ -export const RGBA_ASTC_5x4_Format: 37809; -/** - * @remarks Require support for the _WEBGL_compressed_texture_astc_ WebGL extension. - */ -export const RGBA_ASTC_5x5_Format: 37810; -/** - * @remarks Require support for the _WEBGL_compressed_texture_astc_ WebGL extension. - */ -export const RGBA_ASTC_6x5_Format: 37811; -/** - * @remarks Require support for the _WEBGL_compressed_texture_astc_ WebGL extension. - */ -export const RGBA_ASTC_6x6_Format: 37812; -/** - * @remarks Require support for the _WEBGL_compressed_texture_astc_ WebGL extension. - */ -export const RGBA_ASTC_8x5_Format: 37813; -/** - * @remarks Require support for the _WEBGL_compressed_texture_astc_ WebGL extension. - */ -export const RGBA_ASTC_8x6_Format: 37814; -/** - * @remarks Require support for the _WEBGL_compressed_texture_astc_ WebGL extension. - */ -export const RGBA_ASTC_8x8_Format: 37815; -/** - * @remarks Require support for the _WEBGL_compressed_texture_astc_ WebGL extension. - */ -export const RGBA_ASTC_10x5_Format: 37816; -/** - * @remarks Require support for the _WEBGL_compressed_texture_astc_ WebGL extension. - */ -export const RGBA_ASTC_10x6_Format: 37817; -/** - * @remarks Require support for the _WEBGL_compressed_texture_astc_ WebGL extension. - */ -export const RGBA_ASTC_10x8_Format: 37818; -/** - * @remarks Require support for the _WEBGL_compressed_texture_astc_ WebGL extension. - */ -export const RGBA_ASTC_10x10_Format: 37819; -/** - * @remarks Require support for the _WEBGL_compressed_texture_astc_ WebGL extension. - */ -export const RGBA_ASTC_12x10_Format: 37820; -/** - * @remarks Require support for the _WEBGL_compressed_texture_astc_ WebGL extension. - */ -export const RGBA_ASTC_12x12_Format: 37821; - -// BPTC compressed texture formats - -/** - * @remarks Require support for the _EXT_texture_compression_bptc_ WebGL extension. - */ -export const RGBA_BPTC_Format: 36492; -export const RGB_BPTC_SIGNED_Format = 36494; -export const RGB_BPTC_UNSIGNED_Format = 36495; - -// RGTC compressed texture formats -export const RED_RGTC1_Format: 36283; -export const SIGNED_RED_RGTC1_Format: 36284; -export const RED_GREEN_RGTC2_Format: 36285; -export const SIGNED_RED_GREEN_RGTC2_Format: 36286; - -/** - * For use with a {@link THREE.CompressedTexture}'s {@link THREE.CompressedTexture.format | .format} property. - * @remarks Compressed Require support for correct WebGL extension. - */ -export type CompressedPixelFormat = - | typeof RGB_S3TC_DXT1_Format - | typeof RGBA_S3TC_DXT1_Format - | typeof RGBA_S3TC_DXT3_Format - | typeof RGBA_S3TC_DXT5_Format - | typeof RGB_PVRTC_4BPPV1_Format - | typeof RGB_PVRTC_2BPPV1_Format - | typeof RGBA_PVRTC_4BPPV1_Format - | typeof RGBA_PVRTC_2BPPV1_Format - | typeof RGB_ETC1_Format - | typeof RGB_ETC2_Format - | typeof RGBA_ETC2_EAC_Format - | typeof RGBA_ASTC_4x4_Format - | typeof RGBA_ASTC_5x4_Format - | typeof RGBA_ASTC_5x5_Format - | typeof RGBA_ASTC_6x5_Format - | typeof RGBA_ASTC_6x6_Format - | typeof RGBA_ASTC_8x5_Format - | typeof RGBA_ASTC_8x6_Format - | typeof RGBA_ASTC_8x8_Format - | typeof RGBA_ASTC_10x5_Format - | typeof RGBA_ASTC_10x6_Format - | typeof RGBA_ASTC_10x8_Format - | typeof RGBA_ASTC_10x10_Format - | typeof RGBA_ASTC_12x10_Format - | typeof RGBA_ASTC_12x12_Format - | typeof RGBA_BPTC_Format - | typeof RGB_BPTC_SIGNED_Format - | typeof RGB_BPTC_UNSIGNED_Format - | typeof RED_RGTC1_Format - | typeof SIGNED_RED_RGTC1_Format - | typeof RED_GREEN_RGTC2_Format - | typeof SIGNED_RED_GREEN_RGTC2_Format; - -/////////////////////////////////////////////////////////////////////////////// - -/** - * All Possible Texture Pixel Formats Modes. For any Type or SubType of Textures. - * @remarks Note that the texture must have the correct {@link THREE.Texture.type} set, as described in {@link TextureDataType}. - * @see {@link WebGLRenderingContext.texImage2D} for details. - * @see {@link PixelFormat} and {@link DepthTexturePixelFormat} and {@link CompressedPixelFormat} - * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} - */ -export type AnyPixelFormat = PixelFormat | DepthTexturePixelFormat | CompressedPixelFormat; - -/////////////////////////////////////////////////////////////////////////////// -// Loop styles for AnimationAction -export const LoopOnce: 2200; -export const LoopRepeat: 2201; -export const LoopPingPong: 2202; -export type AnimationActionLoopStyles = typeof LoopOnce | typeof LoopRepeat | typeof LoopPingPong; - -// Interpolation -export const InterpolateDiscrete: 2300; -export const InterpolateLinear: 2301; -export const InterpolateSmooth: 2302; -export type InterpolationModes = typeof InterpolateDiscrete | typeof InterpolateLinear | typeof InterpolateSmooth; - -// Interpolant ending modes -export const ZeroCurvatureEnding: 2400; -export const ZeroSlopeEnding: 2401; -export const WrapAroundEnding: 2402; -export type InterpolationEndingModes = typeof ZeroCurvatureEnding | typeof ZeroSlopeEnding | typeof WrapAroundEnding; - -// Animation blending modes -export const NormalAnimationBlendMode: 2500; -export const AdditiveAnimationBlendMode: 2501; -export type AnimationBlendMode = typeof NormalAnimationBlendMode | typeof AdditiveAnimationBlendMode; - -// Triangle Draw modes -export const TrianglesDrawMode: 0; -export const TriangleStripDrawMode: 1; -export const TriangleFanDrawMode: 2; -export type TrianglesDrawModes = typeof TrianglesDrawMode | typeof TriangleStripDrawMode | typeof TriangleFanDrawMode; - -/////////////////////////////////////////////////////////////////////////////// -// Depth packing strategies - -export const BasicDepthPacking: 3200; -export const RGBADepthPacking: 3201; -export const RGBDepthPacking: 3202; -export const RGDepthPacking: 3203; -export type DepthPackingStrategies = - | typeof BasicDepthPacking - | typeof RGBADepthPacking - | typeof RGBDepthPacking - | typeof RGDepthPacking; - -/////////////////////////////////////////////////////////////////////////////// -// Normal Map types - -export const TangentSpaceNormalMap: 0; -export const ObjectSpaceNormalMap: 1; -export type NormalMapTypes = typeof TangentSpaceNormalMap | typeof ObjectSpaceNormalMap; - -export const NoColorSpace: ""; -export const SRGBColorSpace: "srgb"; -export const LinearSRGBColorSpace: "srgb-linear"; -export type ColorSpace = - | typeof NoColorSpace - | typeof SRGBColorSpace - | typeof LinearSRGBColorSpace; - -export const LinearTransfer: "linear"; -export const SRGBTransfer: "srgb"; -export type ColorSpaceTransfer = typeof LinearTransfer | typeof SRGBTransfer; - -// Stencil Op types -export const ZeroStencilOp: 0; -export const KeepStencilOp: 7680; -export const ReplaceStencilOp: 7681; -export const IncrementStencilOp: 7682; -export const DecrementStencilOp: 7283; -export const IncrementWrapStencilOp: 34055; -export const DecrementWrapStencilOp: 34056; -export const InvertStencilOp: 5386; -export type StencilOp = - | typeof ZeroStencilOp - | typeof KeepStencilOp - | typeof ReplaceStencilOp - | typeof IncrementStencilOp - | typeof DecrementStencilOp - | typeof IncrementWrapStencilOp - | typeof DecrementWrapStencilOp - | typeof InvertStencilOp; - -// Stencil Func types -export const NeverStencilFunc: 512; -export const LessStencilFunc: 513; -export const EqualStencilFunc: 514; -export const LessEqualStencilFunc: 515; -export const GreaterStencilFunc: 516; -export const NotEqualStencilFunc: 517; -export const GreaterEqualStencilFunc: 518; -export const AlwaysStencilFunc: 519; -export type StencilFunc = - | typeof NeverStencilFunc - | typeof LessStencilFunc - | typeof EqualStencilFunc - | typeof LessEqualStencilFunc - | typeof GreaterStencilFunc - | typeof NotEqualStencilFunc - | typeof GreaterEqualStencilFunc - | typeof AlwaysStencilFunc; - -export const NeverCompare: 512; -export const LessCompare: 513; -export const EqualCompare: 514; -export const LessEqualCompare: 515; -export const GreaterCompare: 516; -export const NotEqualCompare: 517; -export const GreaterEqualCompare: 518; -export const AlwaysCompare: 519; -export type TextureComparisonFunction = - | typeof NeverCompare - | typeof LessCompare - | typeof EqualCompare - | typeof LessEqualCompare - | typeof GreaterCompare - | typeof NotEqualCompare - | typeof GreaterEqualCompare - | typeof AlwaysCompare; - -// usage types -export const StaticDrawUsage: 35044; -export const DynamicDrawUsage: 35048; -export const StreamDrawUsage: 35040; -export const StaticReadUsage: 35045; -export const DynamicReadUsage: 35049; -export const StreamReadUsage: 35041; -export const StaticCopyUsage: 35046; -export const DynamicCopyUsage: 35050; -export const StreamCopyUsage: 35042; -export type Usage = - | typeof StaticDrawUsage - | typeof DynamicDrawUsage - | typeof StreamDrawUsage - | typeof StaticReadUsage - | typeof DynamicReadUsage - | typeof StreamReadUsage - | typeof StaticCopyUsage - | typeof DynamicCopyUsage - | typeof StreamCopyUsage; - -export const GLSL1: "100"; -export const GLSL3: "300 es"; -export type GLSLVersion = typeof GLSL1 | typeof GLSL3; - -export const WebGLCoordinateSystem: 2000; -export const WebGPUCoordinateSystem: 2001; -export type CoordinateSystem = typeof WebGLCoordinateSystem | typeof WebGPUCoordinateSystem; - -/////////////////////////////////////////////////////////////////////////////// -// Texture - Internal Pixel Formats - -/** - * For use with a texture's {@link THREE.Texture.internalFormat} property, these define how elements of a {@link THREE.Texture}, or texels, are stored on the GPU. - * - `R8` stores the red component on 8 bits. - * - `R8_SNORM` stores the red component on 8 bits. The component is stored as normalized. - * - `R8I` stores the red component on 8 bits. The component is stored as an integer. - * - `R8UI` stores the red component on 8 bits. The component is stored as an unsigned integer. - * - `R16I` stores the red component on 16 bits. The component is stored as an integer. - * - `R16UI` stores the red component on 16 bits. The component is stored as an unsigned integer. - * - `R16F` stores the red component on 16 bits. The component is stored as floating point. - * - `R32I` stores the red component on 32 bits. The component is stored as an integer. - * - `R32UI` stores the red component on 32 bits. The component is stored as an unsigned integer. - * - `R32F` stores the red component on 32 bits. The component is stored as floating point. - * - `RG8` stores the red and green components on 8 bits each. - * - `RG8_SNORM` stores the red and green components on 8 bits each. Every component is stored as normalized. - * - `RG8I` stores the red and green components on 8 bits each. Every component is stored as an integer. - * - `RG8UI` stores the red and green components on 8 bits each. Every component is stored as an unsigned integer. - * - `RG16I` stores the red and green components on 16 bits each. Every component is stored as an integer. - * - `RG16UI` stores the red and green components on 16 bits each. Every component is stored as an unsigned integer. - * - `RG16F` stores the red and green components on 16 bits each. Every component is stored as floating point. - * - `RG32I` stores the red and green components on 32 bits each. Every component is stored as an integer. - * - `RG32UI` stores the red and green components on 32 bits. Every component is stored as an unsigned integer. - * - `RG32F` stores the red and green components on 32 bits. Every component is stored as floating point. - * - `RGB8` stores the red, green, and blue components on 8 bits each. RGB8_SNORM` stores the red, green, and blue components on 8 bits each. Every component is stored as normalized. - * - `RGB8I` stores the red, green, and blue components on 8 bits each. Every component is stored as an integer. - * - `RGB8UI` stores the red, green, and blue components on 8 bits each. Every component is stored as an unsigned integer. - * - `RGB16I` stores the red, green, and blue components on 16 bits each. Every component is stored as an integer. - * - `RGB16UI` stores the red, green, and blue components on 16 bits each. Every component is stored as an unsigned integer. - * - `RGB16F` stores the red, green, and blue components on 16 bits each. Every component is stored as floating point - * - `RGB32I` stores the red, green, and blue components on 32 bits each. Every component is stored as an integer. - * - `RGB32UI` stores the red, green, and blue components on 32 bits each. Every component is stored as an unsigned integer. - * - `RGB32F` stores the red, green, and blue components on 32 bits each. Every component is stored as floating point - * - `R11F_G11F_B10F` stores the red, green, and blue components respectively on 11 bits, 11 bits, and 10bits. Every component is stored as floating point. - * - `RGB565` stores the red, green, and blue components respectively on 5 bits, 6 bits, and 5 bits. - * - `RGB9_E5` stores the red, green, and blue components on 9 bits each. - * - `RGBA8` stores the red, green, blue, and alpha components on 8 bits each. - * - `RGBA8_SNORM` stores the red, green, blue, and alpha components on 8 bits. Every component is stored as normalized. - * - `RGBA8I` stores the red, green, blue, and alpha components on 8 bits each. Every component is stored as an integer. - * - `RGBA8UI` stores the red, green, blue, and alpha components on 8 bits. Every component is stored as an unsigned integer. - * - `RGBA16I` stores the red, green, blue, and alpha components on 16 bits. Every component is stored as an integer. - * - `RGBA16UI` stores the red, green, blue, and alpha components on 16 bits. Every component is stored as an unsigned integer. - * - `RGBA16F` stores the red, green, blue, and alpha components on 16 bits. Every component is stored as floating point. - * - `RGBA32I` stores the red, green, blue, and alpha components on 32 bits. Every component is stored as an integer. - * - `RGBA32UI` stores the red, green, blue, and alpha components on 32 bits. Every component is stored as an unsigned integer. - * - `RGBA32F` stores the red, green, blue, and alpha components on 32 bits. Every component is stored as floating point. - * - `RGB5_A1` stores the red, green, blue, and alpha components respectively on 5 bits, 5 bits, 5 bits, and 1 bit. - * - `RGB10_A2` stores the red, green, blue, and alpha components respectively on 10 bits, 10 bits, 10 bits and 2 bits. - * - `RGB10_A2UI` stores the red, green, blue, and alpha components respectively on 10 bits, 10 bits, 10 bits and 2 bits. Every component is stored as an unsigned integer. - * - `SRGB8` stores the red, green, and blue components on 8 bits each. - * - `SRGB8_ALPHA8` stores the red, green, blue, and alpha components on 8 bits each. - * - `DEPTH_COMPONENT16` stores the depth component on 16bits. - * - `DEPTH_COMPONENT24` stores the depth component on 24bits. - * - `DEPTH_COMPONENT32F` stores the depth component on 32bits. The component is stored as floating point. - * - `DEPTH24_STENCIL8` stores the depth, and stencil components respectively on 24 bits and 8 bits. The stencil component is stored as an unsigned integer. - * - `DEPTH32F_STENCIL8` stores the depth, and stencil components respectively on 32 bits and 8 bits. The depth component is stored as floating point, and the stencil component as an unsigned integer. - * @remark Note that the texture must have the correct {@link THREE.Texture.type} set, as well as the correct {@link THREE.Texture.format}. - * @see {@link WebGLRenderingContext.texImage2D} and {@link WebGLRenderingContext.texImage3D} for more details regarding the possible combination - * of {@link THREE.Texture.format}, {@link THREE.Texture.internalFormat}, and {@link THREE.Texture.type}. - * @see {@link https://registry.khronos.org/webgl/specs/latest/2.0/ | WebGL2 Specification} and - * {@link https://registry.khronos.org/OpenGL/specs/es/3.0/es_spec_3.0.pdf | OpenGL ES 3.0 Specification} For more in-depth information regarding internal formats. - */ -export type PixelFormatGPU = - | "ALPHA" - | "RGB" - | "RGBA" - | "LUMINANCE" - | "LUMINANCE_ALPHA" - | "RED_INTEGER" - | "R8" - | "R8_SNORM" - | "R8I" - | "R8UI" - | "R16I" - | "R16UI" - | "R16F" - | "R32I" - | "R32UI" - | "R32F" - | "RG8" - | "RG8_SNORM" - | "RG8I" - | "RG8UI" - | "RG16I" - | "RG16UI" - | "RG16F" - | "RG32I" - | "RG32UI" - | "RG32F" - | "RGB565" - | "RGB8" - | "RGB8_SNORM" - | "RGB8I" - | "RGB8UI" - | "RGB16I" - | "RGB16UI" - | "RGB16F" - | "RGB32I" - | "RGB32UI" - | "RGB32F" - | "RGB9_E5" - | "SRGB8" - | "R11F_G11F_B10F" - | "RGBA4" - | "RGBA8" - | "RGBA8_SNORM" - | "RGBA8I" - | "RGBA8UI" - | "RGBA16I" - | "RGBA16UI" - | "RGBA16F" - | "RGBA32I" - | "RGBA32UI" - | "RGBA32F" - | "RGB5_A1" - | "RGB10_A2" - | "RGB10_A2UI" - | "SRGB8_ALPHA8" - | "SRGB8" - | "DEPTH_COMPONENT16" - | "DEPTH_COMPONENT24" - | "DEPTH_COMPONENT32F" - | "DEPTH24_STENCIL8" - | "DEPTH32F_STENCIL8"; diff --git a/src-testing/src/core/BufferAttribute.d.ts b/src-testing/src/core/BufferAttribute.d.ts deleted file mode 100644 index 01e8e882d..000000000 --- a/src-testing/src/core/BufferAttribute.d.ts +++ /dev/null @@ -1,622 +0,0 @@ -import { AttributeGPUType, Usage } from "../constants.js"; -import { Matrix3 } from "../math/Matrix3.js"; -import { Matrix4 } from "../math/Matrix4.js"; - -export type TypedArray = - | Int8Array - | Uint8Array - | Uint8ClampedArray - | Int16Array - | Uint16Array - | Int32Array - | Uint32Array - | Float32Array - | Float64Array; - -export interface BufferAttributeJSON { - itemSize: number; - type: string; - array: number[]; - normalized: boolean; - - name?: string; - usage?: Usage; -} - -/** - * This class stores data for an attribute (such as vertex positions, face indices, normals, colors, UVs, and any custom attributes ) - * associated with a {@link THREE.BufferGeometry | BufferGeometry}, which allows for more efficient passing of data to the GPU - * @remarks - * When working with _vector-like_ data, the _`.fromBufferAttribute( attribute, index )`_ helper methods on - * {@link THREE.Vector2.fromBufferAttribute | Vector2}, - * {@link THREE.Vector3.fromBufferAttribute | Vector3}, - * {@link THREE.Vector4.fromBufferAttribute | Vector4}, and - * {@link THREE.Color.fromBufferAttribute | Color} classes may be helpful. - * @see {@link THREE.BufferGeometry | BufferGeometry} for details and a usage examples. - * @see Example: {@link https://threejs.org/examples/#webgl_buffergeometry | WebGL / BufferGeometry - Clean up Memory} - * @see {@link https://threejs.org/docs/index.html#api/en/core/BufferAttribute | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/BufferAttribute.js | Source} - */ -export class BufferAttribute { - /** - * This creates a new {@link THREE.GLBufferAttribute | GLBufferAttribute} object. - * @param array Must be a `TypedArray`. Used to instantiate the buffer. - * This array should have `itemSize * numVertices` elements, where numVertices is the number of vertices in the associated {@link THREE.BufferGeometry | BufferGeometry}. - * @param itemSize the number of values of the {@link array} that should be associated with a particular vertex. - * For instance, if this attribute is storing a 3-component vector (such as a _position_, _normal_, or _color_), - * then itemSize should be `3`. - * @param normalized Applies to integer data only. - * Indicates how the underlying data in the buffer maps to the values in the GLSL code. - * For instance, if {@link array} is an instance of `UInt16Array`, and {@link normalized} is true, - * the values `0` - `+65535` in the array data will be mapped to `0.0f` - `+1.0f` in the GLSL attribute. - * An `Int16Array` (signed) would map from `-32768` - `+32767` to `-1.0f` - `+1.0f`. - * If normalized is false, the values will be converted to floats unmodified, - * i.e. `32767` becomes `32767.0f`. - * Default `false`. - * @throws `TypeError` When the {@link array} is not a `TypedArray`; - */ - constructor(array: TypedArray, itemSize: number, normalized?: boolean); - - /** - * Optional name for this attribute instance. - * @defaultValue '' - */ - name: string; - - /** - * The {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray | TypedArray} holding data stored in the buffer. - * @returns `TypedArray` - */ - array: TypedArray; - - /** - * The length of vectors that are being stored in the {@link BufferAttribute.array | array}. - * @remarks Expects a `Integer` - */ - itemSize: number; - - /** - * Defines the intended usage pattern of the data store for optimization purposes. - * Corresponds to the {@link BufferAttribute.usage | usage} parameter of - * {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/bufferData | WebGLRenderingContext.bufferData}. - * @remarks - * After the initial use of a buffer, its usage cannot be changed. Instead, instantiate a new one and set the desired usage before the next render. - * @see {@link https://threejs.org/docs/index.html#api/en/constants/BufferAttributeUsage | Buffer Attribute Usage Constants} for all possible values. - * @see {@link BufferAttribute.setUsage | setUsage} - * @defaultValue {@link THREE.StaticDrawUsage | THREE.StaticDrawUsage}. - */ - usage: Usage; - - /** - * Configures the bound GPU type for use in shaders. Either {@link FloatType} or {@link IntType}, default is {@link FloatType}. - * - * Note: this only has an effect for integer arrays and is not configurable for float arrays. For lower precision - * float types, see https://threejs.org/docs/#api/en/core/bufferAttributeTypes/BufferAttributeTypes. - */ - gpuType: AttributeGPUType; - - /** - * This can be used to only update some components of stored vectors (for example, just the component related to - * color). Use the {@link .addUpdateRange} function to add ranges to this array. - */ - updateRanges: Array<{ - /** - * Position at which to start update. - */ - start: number; - /** - * The number of components to update. - */ - count: number; - }>; - - /** - * A version number, incremented every time the {@link BufferAttribute.needsUpdate | needsUpdate} property is set to true. - * @remarks Expects a `Integer` - * @defaultValue `0` - */ - version: number; - - /** - * Indicates how the underlying data in the buffer maps to the values in the GLSL shader code. - * @see `constructor` above for details. - * @defaultValue `false` - */ - normalized: boolean; - - /** - * Represents the number of items this buffer attribute stores. It is internally computed by dividing the - * {@link BufferAttribute.array | array}'s length by the {@link BufferAttribute.itemSize | itemSize}. Read-only - * property. - */ - readonly count: number; - - /** - * Flag to indicate that this attribute has changed and should be re-sent to the GPU. - * Set this to true when you modify the value of the array. - * @remarks Setting this to true also increments the {@link BufferAttribute.version | version}. - * @remarks _set-only property_. - */ - set needsUpdate(value: boolean); - - /** - * Read-only flag to check if a given object is of type {@link BufferAttribute}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isBufferAttribute: true; - - /** - * A callback function that is executed after the Renderer has transferred the attribute array data to the GPU. - */ - onUploadCallback: () => void; - - /** - * Sets the value of the {@link onUploadCallback} property. - * @see Example: {@link https://threejs.org/examples/#webgl_buffergeometry | WebGL / BufferGeometry} this is used to free memory after the buffer has been transferred to the GPU. - * @see {@link onUploadCallback} - * @param callback function that is executed after the Renderer has transferred the attribute array data to the GPU. - */ - onUpload(callback: () => void): this; - - /** - * Set {@link BufferAttribute.usage | usage} - * @remarks - * After the initial use of a buffer, its usage cannot be changed. Instead, instantiate a new one and set the desired usage before the next render. - * @see {@link https://threejs.org/docs/index.html#api/en/constants/BufferAttributeUsage | Buffer Attribute Usage Constants} for all possible values. - * @see {@link BufferAttribute.usage | usage} - * @param value Corresponds to the {@link BufferAttribute.usage | usage} parameter of - * {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/bufferData | WebGLRenderingContext.bufferData}. - */ - setUsage(usage: Usage): this; - - /** - * Adds a range of data in the data array to be updated on the GPU. Adds an object describing the range to the - * {@link .updateRanges} array. - */ - addUpdateRange(start: number, count: number): void; - - /** - * Clears the {@link .updateRanges} array. - */ - clearUpdateRanges(): void; - - /** - * @returns a copy of this {@link BufferAttribute}. - */ - clone(): BufferAttribute; - - /** - * Copies another {@link BufferAttribute} to this {@link BufferAttribute}. - * @param bufferAttribute - */ - copy(source: BufferAttribute): this; - - /** - * Copy a vector from bufferAttribute[index2] to {@link BufferAttribute.array | array}[index1]. - * @param index1 - * @param bufferAttribute - * @param index2 - */ - copyAt(index1: number, attribute: BufferAttribute, index2: number): this; - - /** - * Copy the array given here (which can be a normal array or `TypedArray`) into {@link BufferAttribute.array | array}. - * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set | TypedArray.set} for notes on requirements if copying a `TypedArray`. - */ - copyArray(array: ArrayLike): this; - - /** - * Applies matrix {@link Matrix3 | m} to every Vector3 element of this {@link BufferAttribute}. - * @param m - */ - applyMatrix3(m: Matrix3): this; - - /** - * Applies matrix {@link Matrix4 | m} to every Vector3 element of this {@link BufferAttribute}. - * @param m - */ - applyMatrix4(m: Matrix4): this; - - /** - * Applies normal matrix {@link Matrix3 | m} to every Vector3 element of this {@link BufferAttribute}. - * @param m - */ - applyNormalMatrix(m: Matrix3): this; - - /** - * Applies matrix {@link Matrix4 | m} to every Vector3 element of this {@link BufferAttribute}, interpreting the elements as a direction vectors. - * @param m - */ - transformDirection(m: Matrix4): this; - - /** - * Calls {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set | TypedArray.set}( {@link value}, {@link offset} ) - * on the {@link BufferAttribute.array | array}. - * @param value {@link Array | Array} or `TypedArray` from which to copy values. - * @param offset index of the {@link BufferAttribute.array | array} at which to start copying. Expects a `Integer`. Default `0`. - * @throws `RangeError` When {@link offset} is negative or is too large. - */ - set(value: ArrayLike | ArrayBufferView, offset?: number): this; - - /** - * Returns the given component of the vector at the given index. - */ - getComponent(index: number, component: number): number; - - /** - * Sets the given component of the vector at the given index. - */ - setComponent(index: number, component: number, value: number): void; - - /** - * Returns the x component of the vector at the given index. - * @param index Expects a `Integer` - */ - getX(index: number): number; - - /** - * Sets the x component of the vector at the given index. - * @param index Expects a `Integer` - * @param x - */ - setX(index: number, x: number): this; - - /** - * Returns the y component of the vector at the given index. - * @param index Expects a `Integer` - */ - getY(index: number): number; - - /** - * Sets the y component of the vector at the given index. - * @param index Expects a `Integer` - * @param y - */ - setY(index: number, y: number): this; - - /** - * Returns the z component of the vector at the given index. - * @param index Expects a `Integer` - */ - getZ(index: number): number; - - /** - * Sets the z component of the vector at the given index. - * @param index Expects a `Integer` - * @param z - */ - setZ(index: number, z: number): this; - - /** - * Returns the w component of the vector at the given index. - * @param index Expects a `Integer` - */ - getW(index: number): number; - - /** - * Sets the w component of the vector at the given index. - * @param index Expects a `Integer` - * @param w - */ - setW(index: number, z: number): this; - - /** - * Sets the x and y components of the vector at the given index. - * @param index Expects a `Integer` - * @param x - * @param y - */ - setXY(index: number, x: number, y: number): this; - - /** - * Sets the x, y and z components of the vector at the given index. - * @param index Expects a `Integer` - * @param x - * @param y - * @param z - */ - setXYZ(index: number, x: number, y: number, z: number): this; - - /** - * Sets the x, y, z and w components of the vector at the given index. - * @param index Expects a `Integer` - * @param x - * @param y - * @param z - * @param w - */ - setXYZW(index: number, x: number, y: number, z: number, w: number): this; - - /** - * Convert this object to three.js to the `data.attributes` part of {@link https://github.com/mrdoob/three.js/wiki/JSON-Geometry-format-4 | JSON Geometry format v4}, - */ - toJSON(): BufferAttributeJSON; -} - -/** - * A {@link THREE.BufferAttribute | BufferAttribute} for {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Int8Array: Int8Array} - * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray#typedarray_objects | TypedArray} - * @see {@link THREE.BufferAttribute | BufferAttribute} for details and for inherited methods and properties. - * @see {@link https://threejs.org/docs/index.html#api/en/core/bufferAttributeTypes/BufferAttributeTypes | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/BufferAttribute.js | Source} - */ -export class Int8BufferAttribute extends BufferAttribute { - /** - * This creates a new {@link THREE.Int8BufferAttribute | Int8BufferAttribute} object. - * @param array This can be a typed or untyped (normal) array or an integer length. An array value will be converted to `Int8Array`. - * If a length is given a new `TypedArray` will created, initialized with all elements set to zero. - * @param itemSize the number of values of the {@link array} that should be associated with a particular vertex. - * For instance, if this attribute is storing a 3-component vector (such as a _position_, _normal_, or _color_), - * then itemSize should be `3`. - * @param normalized Applies to integer data only. - * Indicates how the underlying data in the buffer maps to the values in the GLSL code. - * For instance, if {@link array} is an instance of `UInt16Array`, and {@link normalized} is true, - * the values `0` - `+65535` in the array data will be mapped to `0.0f` - `+1.0f` in the GLSL attribute. - * An `Int16Array` (signed) would map from `-32768` - `+32767` to `-1.0f` - `+1.0f`. - * If normalized is false, the values will be converted to floats unmodified, - * i.e. `32767` becomes `32767.0f`. - * Default `false`. - */ - constructor( - array: Iterable | ArrayLike | ArrayBuffer | number, - itemSize: number, - normalized?: boolean, - ); -} - -/** - * A {@link THREE.BufferAttribute | BufferAttribute} for {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array: Uint8Array} - * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray#typedarray_objects | TypedArray} - * @see {@link THREE.BufferAttribute | BufferAttribute} for details and for inherited methods and properties. - * @see {@link https://threejs.org/docs/index.html#api/en/core/bufferAttributeTypes/BufferAttributeTypes | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/BufferAttribute.js | Source} - */ -export class Uint8BufferAttribute extends BufferAttribute { - /** - * This creates a new {@link THREE.Uint8BufferAttribute | Uint8BufferAttribute} object. - * @param array This can be a typed or untyped (normal) array or an integer length. An array value will be converted to `Uint8Array`. - * If a length is given a new `TypedArray` will created, initialized with all elements set to zero. - * @param itemSize the number of values of the {@link array} that should be associated with a particular vertex. - * For instance, if this attribute is storing a 3-component vector (such as a _position_, _normal_, or _color_), - * then itemSize should be `3`. - * @param normalized Applies to integer data only. - * Indicates how the underlying data in the buffer maps to the values in the GLSL code. - * For instance, if {@link array} is an instance of `UInt16Array`, and {@link normalized} is true, - * the values `0` - `+65535` in the array data will be mapped to `0.0f` - `+1.0f` in the GLSL attribute. - * An `Int16Array` (signed) would map from `-32768` - `+32767` to `-1.0f` - `+1.0f`. - * If normalized is false, the values will be converted to floats unmodified, - * i.e. `32767` becomes `32767.0f`. - * Default `false`. - * @see {@link THREE.BufferAttribute | BufferAttribute} - */ - constructor( - array: Iterable | ArrayLike | ArrayBuffer | number, - itemSize: number, - normalized?: boolean, - ); -} - -/** - * A {@link THREE.BufferAttribute | BufferAttribute} for {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8ClampedArray: Uint8ClampedArray} - * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray#typedarray_objects | TypedArray} - * @see {@link THREE.BufferAttribute | BufferAttribute} for details and for inherited methods and properties. - * @see {@link https://threejs.org/docs/index.html#api/en/core/bufferAttributeTypes/BufferAttributeTypes | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/BufferAttribute.js | Source} - */ -export class Uint8ClampedBufferAttribute extends BufferAttribute { - /** - * This creates a new {@link THREE.Uint8ClampedBufferAttribute | Uint8ClampedBufferAttribute} object. - * @param array This can be a typed or untyped (normal) array or an integer length. An array value will be converted to `Uint8ClampedArray`. - * If a length is given a new `TypedArray` will created, initialized with all elements set to zero. - * @param itemSize the number of values of the {@link array} that should be associated with a particular vertex. - * For instance, if this attribute is storing a 3-component vector (such as a _position_, _normal_, or _color_), - * then itemSize should be `3`. - * @param normalized Applies to integer data only. - * Indicates how the underlying data in the buffer maps to the values in the GLSL code. - * For instance, if {@link array} is an instance of `UInt16Array`, and {@link normalized} is true, - * the values `0` - `+65535` in the array data will be mapped to `0.0f` - `+1.0f` in the GLSL attribute. - * An `Int16Array` (signed) would map from `-32768` - `+32767` to `-1.0f` - `+1.0f`. - * If normalized is false, the values will be converted to floats unmodified, - * i.e. `32767` becomes `32767.0f`. - * Default `false`. - * @see {@link THREE.BufferAttribute | BufferAttribute} - */ - constructor( - array: Iterable | ArrayLike | ArrayBuffer | number, - itemSize: number, - normalized?: boolean, - ); -} - -/** - * A {@link THREE.BufferAttribute | BufferAttribute} for {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Int16Array: Int16Array} - * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray#typedarray_objects | TypedArray} - * @see {@link THREE.BufferAttribute | BufferAttribute} for details and for inherited methods and properties. - * @see {@link https://threejs.org/docs/index.html#api/en/core/bufferAttributeTypes/BufferAttributeTypes | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/BufferAttribute.js | Source} - */ -export class Int16BufferAttribute extends BufferAttribute { - /** - * This creates a new {@link THREE.Int16BufferAttribute | Int16BufferAttribute} object. - * @param array This can be a typed or untyped (normal) array or an integer length. An array value will be converted to `Int16Array`. - * If a length is given a new `TypedArray` will created, initialized with all elements set to zero. - * @param itemSize the number of values of the {@link array} that should be associated with a particular vertex. - * For instance, if this attribute is storing a 3-component vector (such as a _position_, _normal_, or _color_), - * then itemSize should be `3`. - * @param normalized Applies to integer data only. - * Indicates how the underlying data in the buffer maps to the values in the GLSL code. - * For instance, if {@link array} is an instance of `UInt16Array`, and {@link normalized} is true, - * the values `0` - `+65535` in the array data will be mapped to `0.0f` - `+1.0f` in the GLSL attribute. - * An `Int16Array` (signed) would map from `-32768` - `+32767` to `-1.0f` - `+1.0f`. - * If normalized is false, the values will be converted to floats unmodified, - * i.e. `32767` becomes `32767.0f`. - * Default `false`. - * @see {@link THREE.BufferAttribute | BufferAttribute} - */ - constructor( - array: Iterable | ArrayLike | ArrayBuffer | number, - itemSize: number, - normalized?: boolean, - ); -} - -/** - * A {@link THREE.BufferAttribute | BufferAttribute} for {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint16Array: Uint16Array} - * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray#typedarray_objects | TypedArray} - * @see {@link THREE.BufferAttribute | BufferAttribute} for details and for inherited methods and properties. - * @see {@link https://threejs.org/docs/index.html#api/en/core/bufferAttributeTypes/BufferAttributeTypes | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/BufferAttribute.js | Source} - */ -export class Uint16BufferAttribute extends BufferAttribute { - /** - * This creates a new {@link THREE.Uint16BufferAttribute | Uint16BufferAttribute} object. - * @param array This can be a typed or untyped (normal) array or an integer length. An array value will be converted to `Uint16Array`. - * If a length is given a new `TypedArray` will created, initialized with all elements set to zero. - * @param itemSize the number of values of the {@link array} that should be associated with a particular vertex. - * For instance, if this attribute is storing a 3-component vector (such as a _position_, _normal_, or _color_), - * then itemSize should be `3`. - * @param normalized Applies to integer data only. - * Indicates how the underlying data in the buffer maps to the values in the GLSL code. - * For instance, if {@link array} is an instance of `UInt16Array`, and {@link normalized} is true, - * the values `0` - `+65535` in the array data will be mapped to `0.0f` - `+1.0f` in the GLSL attribute. - * An `Int16Array` (signed) would map from `-32768` - `+32767` to `-1.0f` - `+1.0f`. - * If normalized is false, the values will be converted to floats unmodified, - * i.e. `32767` becomes `32767.0f`. - * Default `false`. - * @see {@link THREE.BufferAttribute | BufferAttribute} - */ - constructor( - array: Iterable | ArrayLike | ArrayBuffer | number, - itemSize: number, - normalized?: boolean, - ); -} - -/** - * A {@link THREE.BufferAttribute | BufferAttribute} for {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Int32Array: Int32Array} - * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray#typedarray_objects | TypedArray} - * @see {@link THREE.BufferAttribute | BufferAttribute} for details and for inherited methods and properties. - * @see {@link https://threejs.org/docs/index.html#api/en/core/bufferAttributeTypes/BufferAttributeTypes | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/BufferAttribute.js | Source} - */ -export class Int32BufferAttribute extends BufferAttribute { - /** - * This creates a new {@link THREE.Int32BufferAttribute | Int32BufferAttribute} object. - * @param array This can be a typed or untyped (normal) array or an integer length. An array value will be converted to `Int32Array`. - * If a length is given a new `TypedArray` will created, initialized with all elements set to zero. - * @param itemSize the number of values of the {@link array} that should be associated with a particular vertex. - * For instance, if this attribute is storing a 3-component vector (such as a _position_, _normal_, or _color_), - * then itemSize should be `3`. - * @param normalized Applies to integer data only. - * Indicates how the underlying data in the buffer maps to the values in the GLSL code. - * For instance, if {@link array} is an instance of `UInt16Array`, and {@link normalized} is true, - * the values `0` - `+65535` in the array data will be mapped to `0.0f` - `+1.0f` in the GLSL attribute. - * An `Int16Array` (signed) would map from `-32768` - `+32767` to `-1.0f` - `+1.0f`. - * If normalized is false, the values will be converted to floats unmodified, - * i.e. `32767` becomes `32767.0f`. - * Default `false`. - * @see {@link THREE.BufferAttribute | BufferAttribute} - */ - constructor( - array: Iterable | ArrayLike | ArrayBuffer | number, - itemSize: number, - normalized?: boolean, - ); -} - -/** - * A {@link THREE.BufferAttribute | BufferAttribute} for {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint32Array: Uint32Array} - * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray#typedarray_objects | TypedArray} - * @see {@link THREE.BufferAttribute | BufferAttribute} for details and for inherited methods and properties. - * @see {@link https://threejs.org/docs/index.html#api/en/core/bufferAttributeTypes/BufferAttributeTypes | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/BufferAttribute.js | Source} - */ -export class Uint32BufferAttribute extends BufferAttribute { - /** - * This creates a new {@link THREE.Uint32BufferAttribute | Uint32BufferAttribute} object. - * @param array This can be a typed or untyped (normal) array or an integer length. An array value will be converted to `Uint32Array`. - * If a length is given a new `TypedArray` will created, initialized with all elements set to zero. - * @param itemSize the number of values of the {@link array} that should be associated with a particular vertex. - * For instance, if this attribute is storing a 3-component vector (such as a _position_, _normal_, or _color_), - * then itemSize should be `3`. - * @param normalized Applies to integer data only. - * Indicates how the underlying data in the buffer maps to the values in the GLSL code. - * For instance, if {@link array} is an instance of `UInt16Array`, and {@link normalized} is true, - * the values `0` - `+65535` in the array data will be mapped to `0.0f` - `+1.0f` in the GLSL attribute. - * An `Int16Array` (signed) would map from `-32768` - `+32767` to `-1.0f` - `+1.0f`. - * If normalized is false, the values will be converted to floats unmodified, - * i.e. `32767` becomes `32767.0f`. - * Default `false`. - * @see {@link THREE.BufferAttribute | BufferAttribute} - */ - constructor( - array: Iterable | ArrayLike | ArrayBuffer | number, - itemSize: number, - normalized?: boolean, - ); -} - -/** - * A {@link THREE.BufferAttribute | BufferAttribute} for {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint16Array: Uint16Array} - * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray#typedarray_objects | TypedArray} - * @see {@link THREE.BufferAttribute | BufferAttribute} for details and for inherited methods and properties. - * @see {@link https://threejs.org/docs/index.html#api/en/core/bufferAttributeTypes/BufferAttributeTypes | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/BufferAttribute.js | Source} - */ -export class Float16BufferAttribute extends BufferAttribute { - /** - * This creates a new {@link THREE.Float16BufferAttribute | Float16BufferAttribute} object. - * @param array This can be a typed or untyped (normal) array or an integer length. An array value will be converted to `Uint16Array`. - * If a length is given a new `TypedArray` will created, initialized with all elements set to zero. - * @param itemSize the number of values of the {@link array} that should be associated with a particular vertex. - * For instance, if this attribute is storing a 3-component vector (such as a _position_, _normal_, or _color_), - * then itemSize should be `3`. - * @param normalized Applies to integer data only. - * Indicates how the underlying data in the buffer maps to the values in the GLSL code. - * For instance, if {@link array} is an instance of `UInt16Array`, and {@link normalized} is true, - * the values `0` - `+65535` in the array data will be mapped to `0.0f` - `+1.0f` in the GLSL attribute. - * An `Int16Array` (signed) would map from `-32768` - `+32767` to `-1.0f` - `+1.0f`. - * If normalized is false, the values will be converted to floats unmodified, - * i.e. `32767` becomes `32767.0f`. - * Default `false`. - * @see {@link THREE.BufferAttribute | BufferAttribute} - */ - constructor( - array: Iterable | ArrayLike | ArrayBuffer | number, - itemSize: number, - normalized?: boolean, - ); -} - -/** - * A {@link THREE.BufferAttribute | BufferAttribute} for {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float32Array: Float32Array} - * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray#typedarray_objects | TypedArray} - * @see {@link THREE.BufferAttribute | BufferAttribute} for details and for inherited methods and properties. - * @see {@link https://threejs.org/docs/index.html#api/en/core/bufferAttributeTypes/BufferAttributeTypes | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/BufferAttribute.js | Source} - */ -export class Float32BufferAttribute extends BufferAttribute { - /** - * This creates a new {@link THREE.Float32BufferAttribute | Float32BufferAttribute} object. - * @param array This can be a typed or untyped (normal) array or an integer length. An array value will be converted to `Float32Array`. - * If a length is given a new `TypedArray` will created, initialized with all elements set to zero. - * @param itemSize the number of values of the {@link array} that should be associated with a particular vertex. - * For instance, if this attribute is storing a 3-component vector (such as a _position_, _normal_, or _color_), - * then itemSize should be `3`. - * @param normalized Applies to integer data only. - * Indicates how the underlying data in the buffer maps to the values in the GLSL code. - * For instance, if {@link array} is an instance of `UInt16Array`, and {@link normalized} is true, - * the values `0` - `+65535` in the array data will be mapped to `0.0f` - `+1.0f` in the GLSL attribute. - * An `Int16Array` (signed) would map from `-32768` - `+32767` to `-1.0f` - `+1.0f`. - * If normalized is false, the values will be converted to floats unmodified, - * i.e. `32767` becomes `32767.0f`. - * Default `false`. - * @see {@link THREE.BufferAttribute | BufferAttribute} - */ - constructor( - array: Iterable | ArrayLike | ArrayBuffer | number, - itemSize: number, - normalized?: boolean, - ); -} diff --git a/src-testing/src/core/BufferGeometry.d.ts b/src-testing/src/core/BufferGeometry.d.ts deleted file mode 100644 index 516d5f765..000000000 --- a/src-testing/src/core/BufferGeometry.d.ts +++ /dev/null @@ -1,433 +0,0 @@ -import { Box3 } from "../math/Box3.js"; -import { Matrix4 } from "../math/Matrix4.js"; -import { Quaternion } from "../math/Quaternion.js"; -import { Sphere } from "../math/Sphere.js"; -import { Vector2 } from "../math/Vector2.js"; -import { Vector3, Vector3Tuple } from "../math/Vector3.js"; -import IndirectStorageBufferAttribute from "../renderers/common/IndirectStorageBufferAttribute.js"; -import { BufferAttribute, BufferAttributeJSON } from "./BufferAttribute.js"; -import { EventDispatcher } from "./EventDispatcher.js"; -import { GLBufferAttribute } from "./GLBufferAttribute.js"; -import { InterleavedBufferAttribute } from "./InterleavedBufferAttribute.js"; - -export type NormalBufferAttributes = Record; -export type NormalOrGLBufferAttributes = Record< - string, - BufferAttribute | InterleavedBufferAttribute | GLBufferAttribute ->; - -export interface BufferGeometryJSON { - metadata?: { version: number; type: string; generator: string }; - - uuid: string; - type: string; - - name?: string; - userData?: Record; - - data?: { - attributes: Record; - - index?: { type: string; array: number[] }; - - morphAttributes?: Record; - morphTargetsRelative?: boolean; - - groups?: GeometryGroup[]; - - boundingSphere?: { center: Vector3Tuple; radius: number }; - }; -} - -export interface GeometryGroup { - /** - * Specifies the first element in this draw call – the first vertex for non-indexed geometry, otherwise the first triangle index. - * @remarks Expects a `Integer` - */ - start: number; - /** - * Specifies how many vertices (or indices) are included. - * @remarks Expects a `Integer` - */ - count: number; - /** - * Specifies the material array index to use. - * @remarks Expects a `Integer` - */ - materialIndex?: number | undefined; -} - -/** - * A representation of mesh, line, or point geometry - * Includes vertex positions, face indices, normals, colors, UVs, and custom attributes within buffers, reducing the cost of passing all this data to the GPU. - * @remarks - * To read and edit data in BufferGeometry attributes, see {@link THREE.BufferAttribute | BufferAttribute} documentation. - * @example - * ```typescript - * const geometry = new THREE.BufferGeometry(); - * - * // create a simple square shape. We duplicate the top left and bottom right - * // vertices because each vertex needs to appear once per triangle. - * const vertices = new Float32Array( [ - * -1.0, -1.0, 1.0, // v0 - * 1.0, -1.0, 1.0, // v1 - * 1.0, 1.0, 1.0, // v2 - * - * 1.0, 1.0, 1.0, // v3 - * -1.0, 1.0, 1.0, // v4 - * -1.0, -1.0, 1.0 // v5 - * ] ); - * - * // itemSize = 3 because there are 3 values (components) per vertex - * geometry.setAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) ); - * const material = new THREE.MeshBasicMaterial( { color: 0xff0000 } ); - * const mesh = new THREE.Mesh( geometry, material ); - * ``` - * @example - * ```typescript - * const geometry = new THREE.BufferGeometry(); - * - * const vertices = new Float32Array( [ - * -1.0, -1.0, 1.0, // v0 - * 1.0, -1.0, 1.0, // v1 - * 1.0, 1.0, 1.0, // v2 - * -1.0, 1.0, 1.0, // v3 - * ] ); - * geometry.setAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) ); - * - * const indices = [ - * 0, 1, 2, - * 2, 3, 0, - * ]; - * - * geometry.setIndex( indices ); - * geometry.setAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) ); - * - * const material = new THREE.MeshBasicMaterial( { color: 0xff0000 } ); - * const mesh = new THREE.Mesh( geometry, material ); - * ``` - * @see Example: {@link https://threejs.org/examples/#webgl_buffergeometry | Mesh with non-indexed faces} - * @see Example: {@link https://threejs.org/examples/#webgl_buffergeometry_indexed | Mesh with indexed faces} - * @see Example: {@link https://threejs.org/examples/#webgl_buffergeometry_lines | Lines} - * @see Example: {@link https://threejs.org/examples/#webgl_buffergeometry_lines_indexed | Indexed Lines} - * @see Example: {@link https://threejs.org/examples/#webgl_buffergeometry_custom_attributes_particles | Particles} - * @see Example: {@link https://threejs.org/examples/#webgl_buffergeometry_rawshader | Raw Shaders} - * @see {@link https://threejs.org/docs/index.html#api/en/core/BufferGeometry | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/BufferGeometry.js | Source} - */ -export class BufferGeometry< - Attributes extends NormalOrGLBufferAttributes = NormalBufferAttributes, -> extends EventDispatcher<{ dispose: {} }> { - /** - * This creates a new {@link THREE.BufferGeometry | BufferGeometry} object. - */ - constructor(); - - /** - * Unique number for this {@link THREE.BufferGeometry | BufferGeometry} instance. - * @remarks Expects a `Integer` - */ - id: number; - - /** - * {@link http://en.wikipedia.org/wiki/Universally_unique_identifier | UUID} of this object instance. - * @remarks This gets automatically assigned and shouldn't be edited. - */ - uuid: string; - - /** - * Optional name for this {@link THREE.BufferGeometry | BufferGeometry} instance. - * @defaultValue `''` - */ - name: string; - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `BufferGeometry` - */ - readonly type: string | "BufferGeometry"; - - /** - * Allows for vertices to be re-used across multiple triangles; this is called using "indexed triangles". - * Each triangle is associated with the indices of three vertices. This attribute therefore stores the index of each vertex for each triangular face. - * If this attribute is not set, the {@link THREE.WebGLRenderer | renderer} assumes that each three contiguous positions represent a single triangle. - * @defaultValue `null` - */ - index: BufferAttribute | null; - - indirect: IndirectStorageBufferAttribute | null; - - /** - * This hashmap has as id the name of the attribute to be set and as value the {@link THREE.BufferAttribute | buffer} to set it to. Rather than accessing this property directly, - * use {@link setAttribute | .setAttribute} and {@link getAttribute | .getAttribute} to access attributes of this geometry. - * @defaultValue `{}` - */ - attributes: Attributes; - - /** - * Hashmap of {@link THREE.BufferAttribute | BufferAttributes} holding details of the geometry's morph targets. - * @remarks - * Once the geometry has been rendered, the morph attribute data cannot be changed. - * You will have to call {@link dispose | .dispose}(), and create a new instance of {@link THREE.BufferGeometry | BufferGeometry}. - * @defaultValue `{}` - */ - morphAttributes: { - [name: string]: Array; // TODO Replace for 'Record<>' - }; - - /** - * Used to control the morph target behavior; when set to true, the morph target data is treated as relative offsets, rather than as absolute positions/normals. - * @defaultValue `false` - */ - morphTargetsRelative: boolean; - - /** - * Split the geometry into groups, each of which will be rendered in a separate WebGL draw call. This allows an array of materials to be used with the geometry. - * @remarks Every vertex and index must belong to exactly one group — groups must not share vertices or indices, and must not leave vertices or indices unused. - * @remarks Use {@link addGroup | .addGroup} to add groups, rather than modifying this array directly. - * @defaultValue `[]` - */ - groups: GeometryGroup[]; - - /** - * Bounding box for the {@link THREE.BufferGeometry | BufferGeometry}, which can be calculated with {@link computeBoundingBox | .computeBoundingBox()}. - * @remarks Bounding boxes aren't computed by default. They need to be explicitly computed, otherwise they are `null`. - * @defaultValue `null` - */ - boundingBox: Box3 | null; - - /** - * Bounding sphere for the {@link THREE.BufferGeometry | BufferGeometry}, which can be calculated with {@link computeBoundingSphere | .computeBoundingSphere()}. - * @remarks bounding spheres aren't computed by default. They need to be explicitly computed, otherwise they are `null`. - * @defaultValue `null` - */ - boundingSphere: Sphere | null; - - /** - * Determines the part of the geometry to render. This should not be set directly, instead use {@link setDrawRange | .setDrawRange(...)}. - * @remarks For non-indexed {@link THREE.BufferGeometry | BufferGeometry}, count is the number of vertices to render. - * @remarks For indexed {@link THREE.BufferGeometry | BufferGeometry}, count is the number of indices to render. - * @defaultValue `{ start: 0, count: Infinity }` - */ - drawRange: { start: number; count: number }; - - /** - * An object that can be used to store custom data about the BufferGeometry. It should not hold references to functions as these will not be cloned. - * @defaultValue `{}` - */ - userData: Record; - - /** - * Read-only flag to check if a given object is of type {@link BufferGeometry}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isBufferGeometry: true; - - /** - * Return the {@link index | .index} buffer. - */ - getIndex(): BufferAttribute | null; - - /** - * Set the {@link THREE.BufferGeometry.index | .index} buffer. - * @param index - */ - setIndex(index: BufferAttribute | number[] | null): this; - - setIndirect(indirect: IndirectStorageBufferAttribute | null): this; - - getIndirect(): IndirectStorageBufferAttribute | null; - - /** - * Sets an {@link attributes | attribute} to this geometry with the specified name. - * @remarks - * Use this rather than the attributes property, because an internal hashmap of {@link attributes | .attributes} is maintained to speed up iterating over attributes. - * @param name - * @param attribute - */ - setAttribute(name: K, attribute: Attributes[K]): this; - - /** - * Returns the {@link attributes | attribute} with the specified name. - * @param name - */ - getAttribute(name: K): Attributes[K]; - - /** - * Deletes the {@link attributes | attribute} with the specified name. - * @param name - */ - deleteAttribute(name: keyof Attributes): this; - - /** - * Returns true if the {@link attributes | attribute} with the specified name exists. - * @param name - */ - hasAttribute(name: keyof Attributes): boolean; - - /** - * Adds a group to this geometry - * @see the {@link BufferGeometry.groups | groups} property for details. - * @param start - * @param count - * @param materialIndex - */ - addGroup(start: number, count: number, materialIndex?: number): void; - - /** - * Clears all groups. - */ - clearGroups(): void; - - /** - * Set the {@link drawRange | .drawRange} property - * @remarks For non-indexed BufferGeometry, count is the number of vertices to render - * @remarks For indexed BufferGeometry, count is the number of indices to render. - * @param start - * @param count is the number of vertices or indices to render. Expects a `Integer` - */ - setDrawRange(start: number, count: number): void; - - /** - * Applies the matrix transform to the geometry. - * @param matrix - */ - applyMatrix4(matrix: Matrix4): this; - - /** - * Applies the rotation represented by the quaternion to the geometry. - * @param quaternion - */ - applyQuaternion(quaternion: Quaternion): this; - - /** - * Rotate the geometry about the X axis. This is typically done as a one time operation, and not during a loop. - * @remarks Use {@link THREE.Object3D.rotation | Object3D.rotation} for typical real-time mesh rotation. - * @param angle radians. Expects a `Float` - */ - rotateX(angle: number): this; - - /** - * Rotate the geometry about the Y axis. - * @remarks This is typically done as a one time operation, and not during a loop. - * @remarks Use {@link THREE.Object3D.rotation | Object3D.rotation} for typical real-time mesh rotation. - * @param angle radians. Expects a `Float` - */ - rotateY(angle: number): this; - - /** - * Rotate the geometry about the Z axis. - * @remarks This is typically done as a one time operation, and not during a loop. - * @remarks Use {@link THREE.Object3D.rotation | Object3D.rotation} for typical real-time mesh rotation. - * @param angle radians. Expects a `Float` - */ - rotateZ(angle: number): this; - - /** - * Translate the geometry. - * @remarks This is typically done as a one time operation, and not during a loop. - * @remarks Use {@link THREE.Object3D.position | Object3D.position} for typical real-time mesh rotation. - * @param x Expects a `Float` - * @param y Expects a `Float` - * @param z Expects a `Float` - */ - translate(x: number, y: number, z: number): this; - - /** - * Scale the geometry data. - * @remarks This is typically done as a one time operation, and not during a loop. - * @remarks Use {@link THREE.Object3D.scale | Object3D.scale} for typical real-time mesh scaling. - * @param x Expects a `Float` - * @param y Expects a `Float` - * @param z Expects a `Float` - */ - scale(x: number, y: number, z: number): this; - - /** - * Rotates the geometry to face a point in space. - * @remarks This is typically done as a one time operation, and not during a loop. - * @remarks Use {@link THREE.Object3D.lookAt | Object3D.lookAt} for typical real-time mesh usage. - * @param vector A world vector to look at. - */ - lookAt(vector: Vector3): this; - - /** - * Center the geometry based on the bounding box. - */ - center(): this; - - /** - * Defines a geometry by creating a `position` attribute based on the given array of points. The array can hold - * instances of {@link Vector2} or {@link Vector3}. When using two-dimensional data, the `z` coordinate for all - * vertices is set to `0`. - * - * If the method is used with an existing `position` attribute, the vertex data are overwritten with the data from - * the array. The length of the array must match the vertex count. - */ - setFromPoints(points: Vector3[] | Vector2[]): this; - - /** - * Computes the bounding box of the geometry, and updates the {@link .boundingBox} attribute. The bounding box is - * not computed by the engine; it must be computed by your app. You may need to recompute the bounding box if the - * geometry vertices are modified. - */ - computeBoundingBox(): void; - - /** - * Computes the bounding sphere of the geometry, and updates the {@link .boundingSphere} attribute. The engine - * automatically computes the bounding sphere when it is needed, e.g., for ray casting or view frustum culling. You - * may need to recompute the bounding sphere if the geometry vertices are modified. - */ - computeBoundingSphere(): void; - - /** - * Calculates and adds a tangent attribute to this geometry. - * The computation is only supported for indexed geometries and if position, normal, and uv attributes are defined - * @remarks - * When using a tangent space normal map, prefer the MikkTSpace algorithm provided by - * {@link BufferGeometryUtils.computeMikkTSpaceTangents} instead. - */ - computeTangents(): void; - - /** - * Computes vertex normals for the given vertex data. For indexed geometries, the method sets each vertex normal to - * be the average of the face normals of the faces that share that vertex. For non-indexed geometries, vertices are - * not shared, and the method sets each vertex normal to be the same as the face normal. - */ - computeVertexNormals(): void; - - /** - * Every normal vector in a geometry will have a magnitude of 1 - * @remarks This will correct lighting on the geometry surfaces. - */ - normalizeNormals(): void; - - /** - * Return a non-index version of an indexed BufferGeometry. - */ - toNonIndexed(): BufferGeometry; - - /** - * Convert the buffer geometry to three.js {@link https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 | JSON Object/Scene format}. - */ - toJSON(): BufferGeometryJSON; - - /** - * Creates a clone of this BufferGeometry - */ - clone(): this; - - /** - * Copies another BufferGeometry to this BufferGeometry. - * @param source - */ - copy(source: BufferGeometry): this; - - /** - * Frees the GPU-related resources allocated by this instance. - * @remarks Call this method whenever this instance is no longer used in your app. - */ - dispose(): void; -} diff --git a/src-testing/src/core/Clock.d.ts b/src-testing/src/core/Clock.d.ts deleted file mode 100644 index 05307083c..000000000 --- a/src-testing/src/core/Clock.d.ts +++ /dev/null @@ -1,72 +0,0 @@ -/** - * Object for keeping track of time - * @remarks - * This uses {@link https://developer.mozilla.org/en-US/docs/Web/API/Performance/now | performance.now} if it is available, - * otherwise it reverts to the less accurate {@link https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Date/now | Date.now}. - * @see {@link https://threejs.org/docs/index.html#api/en/core/Clock | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/Clock.js | Source} - */ -export class Clock { - /** - * Create a new instance of {@link THREE.Clock | Clock} - * @param autoStart - Whether to automatically start the clock when {@link getDelta | .getDelta()} is called for the first time. Default `true` - */ - constructor(autoStart?: boolean); - - /** - * If set, starts the clock automatically when {@link getDelta | .getDelta()} is called for the first time. - * @defaultValue `true` - */ - autoStart: boolean; - - /** - * Holds the time at which the clock's {@link start | .start()} method was last called. - * @defaultValue `0` - */ - startTime: number; - - /** - * Holds the time at which the clock's {@link start | .start()}, {@link getElapsedTime | .getElapsedTime()} or {@link getDelta | .getDelta()} methods were last called. - * @defaultValue `0` - */ - oldTime: number; - - /** - * Keeps track of the total time that the clock has been running. - * @defaultValue `0` - */ - elapsedTime: number; - - /** - * Whether the clock is running or not. - * @defaultValue `false` - */ - running: boolean; - - /** - * Starts clock. - * @remarks - * Also sets the {@link startTime | .startTime} and {@link oldTime | .oldTime} to the current time, - * sets {@link elapsedTime | .elapsedTime} to `0` and {@link running | .running} to `true`. - */ - start(): void; - - /** - * Stops clock and sets {@link oldTime | oldTime} to the current time. - */ - stop(): void; - - /** - * Get the seconds passed since the clock started and sets {@link oldTime | .oldTime} to the current time. - * @remarks - * If {@link autoStart | .autoStart} is `true` and the clock is not running, also starts the clock. - */ - getElapsedTime(): number; - - /** - * Get the seconds passed since the time {@link oldTime | .oldTime} was set and sets {@link oldTime | .oldTime} to the current time. - * @remarks - * If {@link autoStart | .autoStart} is `true` and the clock is not running, also starts the clock. - */ - getDelta(): number; -} diff --git a/src-testing/src/core/EventDispatcher.d.ts b/src-testing/src/core/EventDispatcher.d.ts deleted file mode 100644 index 403dd1c2e..000000000 --- a/src-testing/src/core/EventDispatcher.d.ts +++ /dev/null @@ -1,82 +0,0 @@ -/** - * The minimal basic Event that can be dispatched by a {@link EventDispatcher<>}. - */ -export interface BaseEvent { - readonly type: TEventType; -} - -/** - * The minimal expected contract of a fired Event that was dispatched by a {@link EventDispatcher<>}. - */ -export interface Event { - readonly type: TEventType; - readonly target: TTarget; -} - -export type EventListener = ( - event: TEventData & Event, -) => void; - -/** - * JavaScript events for custom objects - * @example - * ```typescript - * // Adding events to a custom object - * class Car extends EventDispatcher { - * start() { - * this.dispatchEvent( { type: 'start', message: 'vroom vroom!' } ); - * } - * }; - * // Using events with the custom object - * const car = new Car(); - * car.addEventListener( 'start', ( event ) => { - * alert( event.message ); - * } ); - * car.start(); - * ``` - * @see {@link https://github.com/mrdoob/eventdispatcher.js | mrdoob EventDispatcher on GitHub} - * @see {@link https://threejs.org/docs/index.html#api/en/core/EventDispatcher | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/EventDispatcher.js | Source} - */ -export class EventDispatcher { - /** - * Creates {@link THREE.EventDispatcher | EventDispatcher} object. - */ - constructor(); - - /** - * Adds a listener to an event type. - * @param type The type of event to listen to. - * @param listener The function that gets called when the event is fired. - */ - addEventListener>( - type: T, - listener: EventListener, - ): void; - - /** - * Checks if listener is added to an event type. - * @param type The type of event to listen to. - * @param listener The function that gets called when the event is fired. - */ - hasEventListener>( - type: T, - listener: EventListener, - ): boolean; - - /** - * Removes a listener from an event type. - * @param type The type of the listener that gets removed. - * @param listener The listener function that gets removed. - */ - removeEventListener>( - type: T, - listener: EventListener, - ): void; - - /** - * Fire an event type. - * @param event The event that gets fired. - */ - dispatchEvent>(event: BaseEvent & TEventMap[T]): void; -} diff --git a/src-testing/src/core/GLBufferAttribute.d.ts b/src-testing/src/core/GLBufferAttribute.d.ts deleted file mode 100644 index c549518dd..000000000 --- a/src-testing/src/core/GLBufferAttribute.d.ts +++ /dev/null @@ -1,121 +0,0 @@ -/** - * This buffer attribute class does not construct a VBO. - * Instead, it uses whatever VBO is passed in constructor and can later be altered via the {@link buffer | .buffer} property. - * @remarks - * It is required to pass additional params alongside the VBO - * Those are: the GL context, the GL data type, the number of components per vertex, the number of bytes per component, and the number of vertices. - * @remarks - * The most common use case for this class is when some kind of GPGPU calculation interferes or even produces the VBOs in question. - * @see Example: {@link https://threejs.org/examples/#webgl_buffergeometry_glbufferattribute | WebGL / buffergeometry / glbufferattribute} - * @see {@link https://threejs.org/docs/index.html#api/en/core/GLBufferAttribute | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/GLBufferAttribute.js | Source} - */ -export class GLBufferAttribute { - /** - * This creates a new GLBufferAttribute object. - * @param buffer Must be a {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGLBuffer | WebGLBuffer}. See {@link GLBufferAttribute.buffer | .buffer} - * @param type One of {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Constants#Data_types | WebGL Data Types}. See {@link GLBufferAttribute.type | .type} - * @param itemSize How many values make up each item (vertex). See {@link GLBufferAttribute.itemSize | .itemSize} - * @param elementSize `1`, `2` or `4`. The corresponding size (in bytes) for the given {@link type} param. See {@link GLBufferAttribute.elementSize | .elementSize} - * @param count The expected number of vertices in VBO. See {@link GLBufferAttribute.count | .count} - */ - constructor(buffer: WebGLBuffer, type: GLenum, itemSize: number, elementSize: 1 | 2 | 4, count: number); - - /** - * Read-only flag to check if a given object is of type {@link GLBufferAttribute}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isGLBufferAttribute: true; - - /** - * Optional name for this attribute instance. - * @defaultValue `""` - */ - name: string; - - /** - * The current {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGLBuffer | WebGLBuffer} instance. - */ - buffer: WebGLBuffer; - - /** - * A {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Constants#Data_types | WebGL Data Type} describing the underlying VBO contents. - * - * #### WebGL Data Type (`GLenum`) - * - gl.BYTE: 0x1400 - * - gl.UNSIGNED_BYTE: 0x1401 - * - gl.SHORT: 0x1402 - * - gl.UNSIGNED_SHORT: 0x1403 - * - gl.INT: 0x1404 - * - gl.UNSIGNED_INT: 0x1405 - * - gl.FLOAT: 0x1406 - * @remarks Set this property together with {@link elementSize | .elementSize}. The recommended way is using the {@link setType | .setType()} method. - * @remarks Expects a `DataType` `GLenum` _possible values:_ `0x1400` `0x1401` `0x1402` `0x1403` `0x1404` `0x1405` `0x1406` - */ - type: GLenum; - - /** - * How many values make up each item (vertex). - * @remarks The number of values of the array that should be associated with a particular vertex. - * For instance, if this attribute is storing a 3-component vector (such as a position, normal, or color), then itemSize should be 3. - * @remarks Expects a `Integer` - */ - itemSize: number; - - /** - * Stores the corresponding size in bytes for the current {@link type | .type} property value. - * - * The corresponding size (_in bytes_) for the given "type" param. - * #### WebGL Data Type (`GLenum`) - * - gl.BYTE: 1 - * - gl.UNSIGNED_BYTE: 1 - * - gl.SHORT: 2 - * - gl.UNSIGNED_SHORT: 2 - * - gl.INT: 4 - * - gl.UNSIGNED_INT: 4 - * - gl.FLOAT: 4 - * @remarks Set this property together with {@link type | .type}. The recommended way is using the {@link setType | .setType} method. - * @see `constructor`` for a list of known type sizes. - * @remarks Expects a `1`, `2` or `4` - */ - elementSize: 1 | 2 | 4; - - /** - * The expected number of vertices in VBO. - * @remarks Expects a `Integer` - */ - count: number; - - /** - * A version number, incremented every time the needsUpdate property is set to true. - * @remarks Expects a `Integer` - */ - version: number; - - /** - * Setting this to true increments {@link version | .version}. - * @remarks _set-only property_. - */ - set needsUpdate(value: boolean); - - /** - * Sets the {@link buffer | .buffer} property. - */ - setBuffer(buffer: WebGLBuffer): this; - - /** - * Sets the both {@link GLBufferAttribute.type | type} and {@link GLBufferAttribute.elementSize | elementSize} properties. - */ - setType(type: GLenum, elementSize: 1 | 2 | 4): this; - - /** - * Sets the {@link GLBufferAttribute.itemSize | itemSize} property. - */ - setItemSize(itemSize: number): this; - - /** - * Sets the {@link GLBufferAttribute.count | count} property. - */ - setCount(count: number): this; -} diff --git a/src-testing/src/core/InstancedBufferAttribute.d.ts b/src-testing/src/core/InstancedBufferAttribute.d.ts deleted file mode 100644 index fde083b81..000000000 --- a/src-testing/src/core/InstancedBufferAttribute.d.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { BufferAttribute, TypedArray } from "./BufferAttribute.js"; - -/** - * An instanced version of {@link THREE.BufferAttribute | BufferAttribute}. - * @see {@link https://threejs.org/docs/index.html#api/en/core/InstancedBufferAttribute | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/InstancedBufferAttribute.js | Source} - */ -export class InstancedBufferAttribute extends BufferAttribute { - /** - * Create a new instance of {@link THREE.InstancedBufferAttribute | InstancedBufferAttribute} - * @param array - * @param itemSize - * @param normalized - * @param meshPerAttribute - */ - constructor(array: TypedArray, itemSize: number, normalized?: boolean, meshPerAttribute?: number); - - /** - * Defines how often a value of this buffer attribute should be repeated. - * A value of one means that each value of the instanced attribute is used for a single instance. - * A value of two means that each value is used for two consecutive instances (and so on). - * @defaultValue `1` - */ - meshPerAttribute: number; - - /** - * Read-only flag to check if a given object is of type {@link InstancedBufferAttribute}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isInstancedBufferAttribute: true; -} diff --git a/src-testing/src/core/InstancedBufferGeometry.d.ts b/src-testing/src/core/InstancedBufferGeometry.d.ts deleted file mode 100644 index 421294c49..000000000 --- a/src-testing/src/core/InstancedBufferGeometry.d.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { BufferGeometry } from "./BufferGeometry.js"; - -/** - * An instanced version of {@link THREE.BufferGeometry | BufferGeometry}. - * @see {@link https://threejs.org/docs/index.html#api/en/core/InstancedBufferGeometry | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/InstancedBufferGeometry.js | Source} - */ -export class InstancedBufferGeometry extends BufferGeometry { - /** - * Create a new instance of {@link InstancedBufferGeometry} - */ - constructor(); - - /** - * @defaultValue `InstancedBufferGeometry` - */ - type: string; - - /** - * Read-only flag to check if a given object is of type {@link InstancedBufferGeometry}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isInstancedBufferGeometry: true; - - /** - * @defaultValue `Infinity` - */ - instanceCount: number; - - /** - * Copies the given {@link InstancedBufferGeometry} to this instance. - * @param source - * @override - */ - copy(source: InstancedBufferGeometry): this; -} diff --git a/src-testing/src/core/InstancedInterleavedBuffer.d.ts b/src-testing/src/core/InstancedInterleavedBuffer.d.ts deleted file mode 100644 index 3c78beae4..000000000 --- a/src-testing/src/core/InstancedInterleavedBuffer.d.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { TypedArray } from "./BufferAttribute.js"; -import { InterleavedBuffer } from "./InterleavedBuffer.js"; - -/** - * An instanced version of {@link THREE.InterleavedBuffer | InterleavedBuffer}. - * @see {@link https://threejs.org/docs/index.html#api/en/core/InstancedInterleavedBuffer | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/InstancedInterleavedBuffer.js | Source} - */ -export class InstancedInterleavedBuffer extends InterleavedBuffer { - /** - * Create a new instance of {@link InstancedInterleavedBuffer} - * @param array - * @param itemSize - * @param meshPerAttribute - */ - constructor(array: TypedArray, stride: number, meshPerAttribute?: number); - - /** - * @defaultValue `1` - */ - meshPerAttribute: number; -} diff --git a/src-testing/src/core/InterleavedBuffer.d.ts b/src-testing/src/core/InterleavedBuffer.d.ts deleted file mode 100644 index 89819f6c2..000000000 --- a/src-testing/src/core/InterleavedBuffer.d.ts +++ /dev/null @@ -1,150 +0,0 @@ -import { Usage } from "../constants.js"; -import { TypedArray } from "./BufferAttribute.js"; -import { InterleavedBufferAttribute } from "./InterleavedBufferAttribute.js"; - -/** - * **"Interleaved"** means that multiple attributes, possibly of different types, (e.g., _position, normal, uv, color_) are packed into a single array buffer. - * An introduction into interleaved arrays can be found here: {@link https://blog.tojicode.com/2011/05/interleaved-array-basics.html | Interleaved array basics} - * @see Example: {@link https://threejs.org/examples/#webgl_buffergeometry_points_interleaved | webgl / buffergeometry / points / interleaved} - * @see {@link https://threejs.org/docs/index.html#api/en/core/InterleavedBuffer | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/InterleavedBuffer.js | Source} - */ -export class InterleavedBuffer { - readonly isInterleavedBuffer: true; - - /** - * Create a new instance of {@link InterleavedBuffer} - * @param array A {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray | TypedArray} with a shared buffer. Stores the geometry data. - * @param stride The number of typed-array elements per vertex. Expects a `Integer` - */ - constructor(array: TypedArray, stride: number); - - /** - * A {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray | TypedArray} with a shared buffer. Stores the geometry data. - */ - array: TypedArray; - - /** - * The number of {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray | TypedArray} elements per vertex. - * @remarks Expects a `Integer` - */ - stride: number; - - /** - * Defines the intended usage pattern of the data store for optimization purposes. - * Corresponds to the {@link BufferAttribute.usage | usage} parameter of - * {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/bufferData | WebGLRenderingContext.bufferData}. - * @remarks - * After the initial use of a buffer, its usage cannot be changed. Instead, instantiate a new one and set the desired usage before the next render. - * @see {@link https://threejs.org/docs/index.html#api/en/constants/BufferAttributeUsage | Buffer Attribute Usage Constants} for all possible values. - * @see {@link BufferAttribute.setUsage | setUsage} - * @defaultValue {@link THREE.StaticDrawUsage | THREE.StaticDrawUsage}. - */ - usage: Usage; - - /** - * This can be used to only update some components of stored data. Use the {@link .addUpdateRange} function to add - * ranges to this array. - */ - updateRanges: Array<{ - /** - * Position at which to start update. - */ - start: number; - /** - * The number of components to update. - */ - count: number; - }>; - - /** - * A version number, incremented every time the {@link BufferAttribute.needsUpdate | needsUpdate} property is set to true. - * @remarks Expects a `Integer` - * @defaultValue `0` - */ - version: number; - - /** - * Gives the total number of elements in the array. - * @remarks Expects a `Integer` - * @defaultValue 0 - */ - count: number; - - /** - * Flag to indicate that this attribute has changed and should be re-sent to the GPU. - * Set this to true when you modify the value of the array. - * @remarks Setting this to true also increments the {@link BufferAttribute.version | version}. - * @remarks _set-only property_. - */ - set needsUpdate(value: boolean); - - /** - * {@link http://en.wikipedia.org/wiki/Universally_unique_identifier | UUID} of this object instance. - * @remarks This gets automatically assigned and shouldn't be edited. - */ - uuid: string; - - /** - * Calls {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set | TypedArray.set}( {@link value}, {@link offset} ) - * on the {@link BufferAttribute.array | array}. - * @param value The source `TypedArray`. - * @param offset index of the {@link BufferAttribute.array | array} at which to start copying. Expects a `Integer`. Default `0`. - * @throws `RangeError` When {@link offset} is negative or is too large. - */ - set(value: ArrayLike, offset: number): this; - - /** - * Set {@link BufferAttribute.usage | usage} - * @remarks - * After the initial use of a buffer, its usage cannot be changed. Instead, instantiate a new one and set the desired usage before the next render. - * @see {@link https://threejs.org/docs/index.html#api/en/constants/BufferAttributeUsage | Buffer Attribute Usage Constants} for all possible values. - * @see {@link BufferAttribute.usage | usage} - * @param value Corresponds to the {@link BufferAttribute.usage | usage} parameter of - * {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/bufferData | WebGLRenderingContext.bufferData}. - */ - setUsage(value: Usage): this; - - /** - * Adds a range of data in the data array to be updated on the GPU. Adds an object describing the range to the - * {@link .updateRanges} array. - */ - addUpdateRange(start: number, count: number): void; - - /** - * Clears the {@link .updateRanges} array. - */ - clearUpdateRanges(): void; - - /** - * Copies another {@link InterleavedBuffer} to this {@link InterleavedBuffer} instance. - * @param source - */ - copy(source: InterleavedBuffer): this; - - /** - * Copies data from {@link attribute}[{@link index2}] to {@link InterleavedBuffer.array | array}[{@link index1}]. - * @param index1 Expects a `Integer` - * @param attribute - * @param index2 Expects a `Integer` - */ - copyAt(index1: number, attribute: InterleavedBufferAttribute, index2: number): this; - - /** - * Creates a clone of this {@link InterleavedBuffer}. - * @param data This object holds shared array buffers required for properly cloning geometries with interleaved attributes. - */ - clone(data: {}): InterleavedBuffer; - - /** - * Serializes this {@link InterleavedBuffer}. - * Converting to {@link https://github.com/mrdoob/three.js/wiki/JSON-Geometry-format-4 | JSON Geometry format v4}, - * @param data This object holds shared array buffers required for properly serializing geometries with interleaved attributes. - */ - toJSON(data: {}): { - uuid: string; - buffer: string; - type: string; - stride: number; - }; -} diff --git a/src-testing/src/core/InterleavedBufferAttribute.d.ts b/src-testing/src/core/InterleavedBufferAttribute.d.ts deleted file mode 100644 index 955049938..000000000 --- a/src-testing/src/core/InterleavedBufferAttribute.d.ts +++ /dev/null @@ -1,201 +0,0 @@ -import { Matrix3 } from "../math/Matrix3.js"; -import { Matrix4 } from "../math/Matrix4.js"; -import { BufferAttribute, TypedArray } from "./BufferAttribute.js"; -import { InterleavedBuffer } from "./InterleavedBuffer.js"; - -/** - * @see {@link https://threejs.org/docs/index.html#api/en/core/InterleavedBufferAttribute | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/InterleavedBufferAttribute.js | Source} - */ -export class InterleavedBufferAttribute { - /** - * Create a new instance of {@link THREE.InterleavedBufferAttribute | InterleavedBufferAttribute}. - * @param interleavedBuffer - * @param itemSize - * @param offset - * @param normalized Default `false`. - */ - constructor(interleavedBuffer: InterleavedBuffer, itemSize: number, offset: number, normalized?: boolean); - - /** - * Optional name for this attribute instance. - * @defaultValue `''` - */ - name: string; - - /** - * The {@link InterleavedBuffer | InterleavedBuffer} instance passed in the constructor. - */ - data: InterleavedBuffer; - - /** - * How many values make up each item. - * @remarks Expects a `Integer` - */ - itemSize: number; - - /** - * The offset in the underlying array buffer where an item starts. - * @remarks Expects a `Integer` - */ - offset: number; - - /** - * @defaultValue `false` - */ - normalized: boolean; - - /** - * The value of {@link data | .data}.{@link InterleavedBuffer.count | count}. - * If the buffer is storing a 3-component item (such as a _position, normal, or color_), then this will count the number of such items stored. - * @remarks _get-only property_. - * @remarks Expects a `Integer` - */ - get count(): number; - - /** - * The value of {@link InterleavedBufferAttribute.data | data}.{@link InterleavedBuffer.array | array}. - * @remarks _get-only property_. - */ - get array(): TypedArray; - - /** - * Flag to indicate that the {@link data | .data} ({@link InterleavedBuffer}) attribute has changed and should be re-sent to the GPU. - * @remarks Setting this to have the same result of setting true also increments the {@link InterleavedBuffer.needsUpdate | InterleavedBuffer.needsUpdate} of {@link data | .data}. - * @remarks Setting this to true also increments the {@link InterleavedBuffer.version | InterleavedBuffer.version}. - * @remarks _set-only property_. - */ - set needsUpdate(value: boolean); - - /** - * Read-only flag to check if a given object is of type {@link InterleavedBufferAttribute}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isInterleavedBufferAttribute: true; - - /** - * Applies matrix {@link Matrix4 | m} to every Vector3 element of this InterleavedBufferAttribute. - * @param m - */ - applyMatrix4(m: Matrix4): this; - - /** - * Applies normal matrix {@link Matrix3 | m} to every Vector3 element of this InterleavedBufferAttribute. - * @param m - */ - applyNormalMatrix(m: Matrix3): this; - - /** - * Applies matrix {@link Matrix4 | m} to every Vector3 element of this InterleavedBufferAttribute, interpreting the elements as a direction vectors. - * @param m - */ - transformDirection(m: Matrix4): this; - - /** - * Returns the given component of the vector at the given index. - */ - getComponent(index: number, component: number): number; - - /** - * Sets the given component of the vector at the given index. - */ - setComponent(index: number, component: number, value: number): this; - - /** - * Returns the x component of the item at the given index. - * @param index Expects a `Integer` - */ - getX(index: number): number; - - /** - * Sets the x component of the item at the given index. - * @param index Expects a `Integer` - * @param x Expects a `Float` - */ - setX(index: number, x: number): this; - - /** - * Returns the y component of the item at the given index. - * @param index Expects a `Integer` - */ - getY(index: number): number; - - /** - * Sets the y component of the item at the given index. - * @param index Expects a `Integer` - * @param y Expects a `Float` - */ - setY(index: number, y: number): this; - - /** - * Returns the z component of the item at the given index. - * @param index Expects a `Integer` - */ - getZ(index: number): number; - - /** - * Sets the z component of the item at the given index. - * @param index Expects a `Integer` - * @param z Expects a `Float` - */ - setZ(index: number, z: number): this; - - /** - * Returns the w component of the item at the given index. - * @param index Expects a `Integer` - */ - getW(index: number): number; - - /** - * Sets the w component of the item at the given index. - * @param index Expects a `Integer` - * @param w Expects a `Float` - */ - setW(index: number, z: number): this; - - /** - * Sets the x and y components of the item at the given index. - * @param index Expects a `Integer` - * @param x Expects a `Float` - * @param y Expects a `Float` - */ - setXY(index: number, x: number, y: number): this; - /** - * Sets the x, y and z components of the item at the given index. - * @param index Expects a `Integer` - * @param x Expects a `Float` - * @param y Expects a `Float` - * @param z Expects a `Float` - */ - setXYZ(index: number, x: number, y: number, z: number): this; - - /** - * Sets the x, y, z and w components of the item at the given index. - * @param index Expects a `Integer` - * @param x Expects a `Float` - * @param y Expects a `Float` - * @param z Expects a `Float` - * @param w Expects a `Float` - */ - setXYZW(index: number, x: number, y: number, z: number, w: number): this; - - /** - * Creates a clone of this {@link InterleavedBufferAttribute}. - * @param data This object holds shared array buffers required for properly cloning geometries with interleaved attributes. - */ - clone(data?: {}): BufferAttribute; - - /** - * Serializes this {@link InterleavedBufferAttribute}. - * Converting to {@link https://github.com/mrdoob/three.js/wiki/JSON-Geometry-format-4 | JSON Geometry format v4}, - * @param data This object holds shared array buffers required for properly serializing geometries with interleaved attributes. - */ - toJSON(data?: {}): { - isInterleavedBufferAttribute: true; - itemSize: number; - data: string; - offset: number; - normalized: boolean; - }; -} diff --git a/src-testing/src/core/Layers.d.ts b/src-testing/src/core/Layers.d.ts deleted file mode 100644 index ad95f892d..000000000 --- a/src-testing/src/core/Layers.d.ts +++ /dev/null @@ -1,72 +0,0 @@ -/** - * A {@link THREE.Layers | Layers} object assigns an {@link THREE.Object3D | Object3D} to 1 or more of 32 layers numbered `0` to `31` - internally the - * layers are stored as a {@link https://en.wikipedia.org/wiki/Mask_(computing) | bit mask}, and - * by default all Object3Ds are a member of layer `0`. - * @remarks - * This can be used to control visibility - an object must share a layer with a {@link Camera | camera} to be visible when that camera's view is rendered. - * @remarks - * All classes that inherit from {@link THREE.Object3D | Object3D} have an {@link THREE.Object3D.layers | Object3D.layers} property which is an instance of this class. - * @see Example: {@link https://threejs.org/examples/#webgl_layers | WebGL / layers} - * @see Example: {@link https://threejs.org/examples/#webxr_vr_layers | Webxr / vr / layers} - * @see {@link https://threejs.org/docs/index.html#api/en/core/Layers | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/Layers.js | Source} - */ -export class Layers { - /** - * Create a new Layers object, with membership initially set to layer 0. - */ - constructor(); - - /** - * A bit mask storing which of the 32 layers this layers object is currently a member of. - * @defaultValue `1 | 0` - * @remarks Expects a `Integer` - */ - mask: number; - - /** - * Set membership to `layer`, and remove membership all other layers. - * @param layer An integer from 0 to 31. - */ - set(layer: number): void; - - /** - * Add membership of this `layer`. - * @param layer An integer from 0 to 31. - */ - enable(layer: number): void; - - /** - * Add membership to all layers. - */ - enableAll(): void; - - /** - * Toggle membership of `layer`. - * @param layer An integer from 0 to 31. - */ - toggle(layer: number): void; - - /** - * Remove membership of this `layer`. - * @param layer An integer from 0 to 31. - */ - disable(layer: number): void; - - /** - * Remove membership from all layers. - */ - disableAll(): void; - - /** - * Returns true if this and the passed `layers` object have at least one layer in common. - * @param layers A Layers object - */ - test(layers: Layers): boolean; - - /** - * Returns true if the given layer is enabled. - * @param layer An integer from 0 to 31. - */ - isEnabled(layer: number): boolean; -} diff --git a/src-testing/src/core/Object3D.d.ts b/src-testing/src/core/Object3D.d.ts deleted file mode 100644 index 20bba57ce..000000000 --- a/src-testing/src/core/Object3D.d.ts +++ /dev/null @@ -1,674 +0,0 @@ -import { AnimationClip, AnimationClipJSON } from "../animation/AnimationClip.js"; -import { Camera } from "../cameras/Camera.js"; -import { ShapeJSON } from "../extras/core/Shape.js"; -import { Material, MaterialJSON } from "../materials/Material.js"; -import { Euler } from "../math/Euler.js"; -import { Matrix3 } from "../math/Matrix3.js"; -import { Matrix4, Matrix4Tuple } from "../math/Matrix4.js"; -import { Quaternion } from "../math/Quaternion.js"; -import { Vector3, Vector3Tuple } from "../math/Vector3.js"; -import { Group } from "../objects/Group.js"; -import { SkeletonJSON } from "../objects/Skeleton.js"; -import { WebGLRenderer } from "../renderers/WebGLRenderer.js"; -import { Scene } from "../scenes/Scene.js"; -import { SourceJSON } from "../textures/Source.js"; -import { TextureJSON } from "../textures/Texture.js"; -import { BufferGeometry, BufferGeometryJSON } from "./BufferGeometry.js"; -import { EventDispatcher } from "./EventDispatcher.js"; -import { Layers } from "./Layers.js"; -import { Intersection, Raycaster } from "./Raycaster.js"; - -export interface Object3DJSONObject { - uuid: string; - type: string; - - name?: string; - castShadow?: boolean; - receiveShadow?: boolean; - visible?: boolean; - frustumCulled?: boolean; - renderOrder?: number; - userData?: Record; - - layers: number; - matrix: Matrix4Tuple; - up: Vector3Tuple; - - matrixAutoUpdate?: boolean; - - material?: string | string[]; - - children?: string[]; - - animations?: string[]; -} - -export interface Object3DJSON { - metadata?: { version: number; type: string; generator: string }; - object: Object3DJSONObject; -} - -export interface JSONMeta { - geometries: Record; - materials: Record; - textures: Record; - images: Record; - shapes: Record; - skeletons: Record; - animations: Record; - nodes: Record; -} - -export interface Object3DEventMap { - /** - * Fires when the object has been added to its parent object. - */ - added: {}; - - /** - * Fires when the object has been removed from its parent object. - */ - removed: {}; - - /** - * Fires when a new child object has been added. - */ - childadded: { child: Object3D }; - - /** - * Fires when a new child object has been removed. - */ - childremoved: { child: Object3D }; -} - -/** - * This is the base class for most objects in three.js and provides a set of properties and methods for manipulating objects in 3D space. - * @remarks Note that this can be used for grouping objects via the {@link THREE.Object3D.add | .add()} method which adds the object as a child, - * however it is better to use {@link THREE.Group | Group} for this. - * @see {@link https://threejs.org/docs/index.html#api/en/core/Object3D | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/Object3D.js | Source} - */ -export class Object3D extends EventDispatcher { - /** - * This creates a new {@link Object3D} object. - */ - constructor(); - - /** - * Flag to check if a given object is of type {@link Object3D}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isObject3D: true; - - /** - * Unique number for this {@link Object3D} instance. - * @remarks Note that ids are assigned in chronological order: 1, 2, 3, ..., incrementing by one for each new object. - * Expects a `Integer` - */ - readonly id: number; - - /** - * {@link http://en.wikipedia.org/wiki/Universally_unique_identifier | UUID} of this object instance. - * @remarks This gets automatically assigned and shouldn't be edited. - */ - uuid: string; - - /** - * Optional name of the object - * @remarks _(doesn't need to be unique)_. - * @defaultValue `""` - */ - name: string; - - /** - * A Read-only _string_ to check `this` object type. - * @remarks This can be used to find a specific type of Object3D in a scene. - * Sub-classes will update this value. - * @defaultValue `Object3D` - */ - readonly type: string; - - /** - * Object's parent in the {@link https://en.wikipedia.org/wiki/Scene_graph | scene graph}. - * @remarks An object can have at most one parent. - * @defaultValue `null` - */ - parent: Object3D | null; - - /** - * Array with object's children. - * @see {@link THREE.Object3DGroup | Group} for info on manually grouping objects. - * @defaultValue `[]` - */ - - children: Object3D[]; - - /** - * This is used by the {@link lookAt | lookAt} method, for example, to determine the orientation of the result. - * @defaultValue {@link DEFAULT_UP | Object3D.DEFAULT_UP} - that is `(0, 1, 0)`. - */ - up: Vector3; - - /** - * Object's local position. - * @defaultValue `new THREE.Vector3()` - that is `(0, 0, 0)`. - */ - readonly position: Vector3; - - /** - * Object's local rotation ({@link https://en.wikipedia.org/wiki/Euler_angles | Euler angles}), in radians. - * @defaultValue `new THREE.Euler()` - that is `(0, 0, 0, Euler.DEFAULT_ORDER)`. - */ - readonly rotation: Euler; - - /** - * Object's local rotation as a {@link THREE.Quaternion | Quaternion}. - * @defaultValue `new THREE.Quaternion()` - that is `(0, 0, 0, 1)`. - */ - readonly quaternion: Quaternion; - - /** - * The object's local scale. - * @defaultValue `new THREE.Vector3( 1, 1, 1 )` - */ - readonly scale: Vector3; - - /** - * @defaultValue `new THREE.Matrix4()` - */ - readonly modelViewMatrix: Matrix4; - - /** - * @defaultValue `new THREE.Matrix3()` - */ - readonly normalMatrix: Matrix3; - - /** - * The local transform matrix. - * @defaultValue `new THREE.Matrix4()` - */ - matrix: Matrix4; - - /** - * The global transform of the object. - * @remarks If the {@link Object3D} has no parent, then it's identical to the local transform {@link THREE.Object3D.matrix | .matrix}. - * @defaultValue `new THREE.Matrix4()` - */ - matrixWorld: Matrix4; - - /** - * When this is set, it calculates the matrix of position, (rotation or quaternion) and - * scale every frame and also recalculates the matrixWorld property. - * @defaultValue {@link DEFAULT_MATRIX_AUTO_UPDATE} - that is `(true)`. - */ - matrixAutoUpdate: boolean; - - /** - * If set, then the renderer checks every frame if the object and its children need matrix updates. - * When it isn't, then you have to maintain all matrices in the object and its children yourself. - * @defaultValue {@link DEFAULT_MATRIX_WORLD_AUTO_UPDATE} - that is `(true)`. - */ - matrixWorldAutoUpdate: boolean; - - /** - * When this is set, it calculates the matrixWorld in that frame and resets this property to false. - * @defaultValue `false` - */ - matrixWorldNeedsUpdate: boolean; - - /** - * The layer membership of the object. - * @remarks The object is only visible if it has at least one layer in common with the {@link THREE.Object3DCamera | Camera} in use. - * This property can also be used to filter out unwanted objects in ray-intersection tests when using {@link THREE.Raycaster | Raycaster}. - * @defaultValue `new THREE.Layers()` - */ - layers: Layers; - - /** - * Object gets rendered if `true`. - * @defaultValue `true` - */ - visible: boolean; - - /** - * Whether the object gets rendered into shadow map. - * @defaultValue `false` - */ - castShadow: boolean; - - /** - * Whether the material receives shadows. - * @defaultValue `false` - */ - receiveShadow: boolean; - - /** - * When this is set, it checks every frame if the object is in the frustum of the camera before rendering the object. - * If set to `false` the object gets rendered every frame even if it is not in the frustum of the camera. - * @defaultValue `true` - */ - frustumCulled: boolean; - - /** - * This value allows the default rendering order of {@link https://en.wikipedia.org/wiki/Scene_graph | scene graph} - * objects to be overridden although opaque and transparent objects remain sorted independently. - * @remarks When this property is set for an instance of {@link Group | Group}, all descendants objects will be sorted and rendered together. - * Sorting is from lowest to highest renderOrder. - * @defaultValue `0` - */ - renderOrder: number; - - /** - * Array with object's animation clips. - * @defaultValue `[]` - */ - animations: AnimationClip[]; - - /** - * An object that can be used to store custom data about the {@link Object3D}. - * @remarks It should not hold references to _functions_ as these **will not** be cloned. - * @default `{}` - */ - userData: Record; - - /** - * Custom depth material to be used when rendering to the depth map. - * @remarks Can only be used in context of meshes. - * When shadow-casting with a {@link THREE.DirectionalLight | DirectionalLight} or {@link THREE.SpotLight | SpotLight}, - * if you are modifying vertex positions in the vertex shader you must specify a customDepthMaterial for proper shadows. - * @defaultValue `undefined` - */ - customDepthMaterial?: Material | undefined; - - /** - * Same as {@link customDepthMaterial}, but used with {@link THREE.Object3DPointLight | PointLight}. - * @defaultValue `undefined` - */ - customDistanceMaterial?: Material | undefined; - - /** - * An optional callback that is executed immediately before a 3D object is rendered to a shadow map. - * @remarks This function is called with the following parameters: renderer, scene, camera, shadowCamera, geometry, - * depthMaterial, group. - * Please notice that this callback is only executed for `renderable` 3D objects. Meaning 3D objects which - * define their visual appearance with geometries and materials like instances of {@link Mesh}, {@link Line}, - * {@link Points} or {@link Sprite}. Instances of {@link Object3D}, {@link Group} or {@link Bone} are not renderable - * and thus this callback is not executed for such objects. - */ - onBeforeShadow( - renderer: WebGLRenderer, - scene: Scene, - camera: Camera, - shadowCamera: Camera, - geometry: BufferGeometry, - depthMaterial: Material, - group: Group, - ): void; - - /** - * An optional callback that is executed immediately after a 3D object is rendered to a shadow map. - * @remarks This function is called with the following parameters: renderer, scene, camera, shadowCamera, geometry, - * depthMaterial, group. - * Please notice that this callback is only executed for `renderable` 3D objects. Meaning 3D objects which - * define their visual appearance with geometries and materials like instances of {@link Mesh}, {@link Line}, - * {@link Points} or {@link Sprite}. Instances of {@link Object3D}, {@link Group} or {@link Bone} are not renderable - * and thus this callback is not executed for such objects. - */ - onAfterShadow( - renderer: WebGLRenderer, - scene: Scene, - camera: Camera, - shadowCamera: Camera, - geometry: BufferGeometry, - depthMaterial: Material, - group: Group, - ): void; - - /** - * An optional callback that is executed immediately before a 3D object is rendered. - * @remarks This function is called with the following parameters: renderer, scene, camera, geometry, material, group. - * Please notice that this callback is only executed for `renderable` 3D objects. Meaning 3D objects which - * define their visual appearance with geometries and materials like instances of {@link Mesh}, {@link Line}, - * {@link Points} or {@link Sprite}. Instances of {@link Object3D}, {@link Group} or {@link Bone} are not renderable - * and thus this callback is not executed for such objects. - */ - onBeforeRender( - renderer: WebGLRenderer, - scene: Scene, - camera: Camera, - geometry: BufferGeometry, - material: Material, - group: Group, - ): void; - - /** - * An optional callback that is executed immediately after a 3D object is rendered. - * @remarks This function is called with the following parameters: renderer, scene, camera, geometry, material, group. - * Please notice that this callback is only executed for `renderable` 3D objects. Meaning 3D objects which - * define their visual appearance with geometries and materials like instances of {@link Mesh}, {@link Line}, - * {@link Points} or {@link Sprite}. Instances of {@link Object3D}, {@link Group} or {@link Bone} are not renderable - * and thus this callback is not executed for such objects. - */ - onAfterRender( - renderer: WebGLRenderer, - scene: Scene, - camera: Camera, - geometry: BufferGeometry, - material: Material, - group: Group, - ): void; - - /** - * The default {@link up} direction for objects, also used as the default position for {@link THREE.DirectionalLight | DirectionalLight}, - * {@link THREE.HemisphereLight | HemisphereLight} and {@link THREE.Spotlight | Spotlight} (which creates lights shining from the top down). - * @defaultValue `new THREE.Vector3( 0, 1, 0)` - */ - static DEFAULT_UP: Vector3; - - /** - * The default setting for {@link matrixAutoUpdate} for newly created Object3Ds. - * @defaultValue `true` - */ - static DEFAULT_MATRIX_AUTO_UPDATE: boolean; - - /** - * The default setting for {@link matrixWorldAutoUpdate} for newly created Object3Ds. - * @defaultValue `true` - */ - static DEFAULT_MATRIX_WORLD_AUTO_UPDATE: boolean; - - /** - * Applies the matrix transform to the object and updates the object's position, rotation and scale. - * @param matrix - */ - applyMatrix4(matrix: Matrix4): void; - - /** - * Applies the rotation represented by the quaternion to the object. - * @param quaternion - */ - applyQuaternion(quaternion: Quaternion): this; - - /** - * Calls {@link THREE.Quaternion.setFromAxisAngle | setFromAxisAngle}({@link axis}, {@link angle}) on the {@link quaternion | .quaternion}. - * @param axis A normalized vector in object space. - * @param angle Angle in radians. Expects a `Float` - */ - setRotationFromAxisAngle(axis: Vector3, angle: number): void; - - /** - * Calls {@link THREE.Quaternion.setFromEuler | setFromEuler}({@link euler}) on the {@link quaternion | .quaternion}. - * @param euler Euler angle specifying rotation amount. - */ - setRotationFromEuler(euler: Euler): void; - - /** - * Calls {@link THREE.Quaternion.setFromRotationMatrix | setFromRotationMatrix}({@link m}) on the {@link quaternion | .quaternion}. - * @remarks Note that this assumes that the upper 3x3 of m is a pure rotation matrix (i.e, unscaled). - * @param m Rotate the quaternion by the rotation component of the matrix. - */ - setRotationFromMatrix(m: Matrix4): void; - - /** - * Copy the given {@link THREE.Quaternion | Quaternion} into {@link quaternion | .quaternion}. - * @param q Normalized Quaternion. - */ - setRotationFromQuaternion(q: Quaternion): void; - - /** - * Rotate an object along an axis in object space. - * @remarks The axis is assumed to be normalized. - * @param axis A normalized vector in object space. - * @param angle The angle in radians. Expects a `Float` - */ - rotateOnAxis(axis: Vector3, angle: number): this; - - /** - * Rotate an object along an axis in world space. - * @remarks The axis is assumed to be normalized - * Method Assumes no rotated parent. - * @param axis A normalized vector in world space. - * @param angle The angle in radians. Expects a `Float` - */ - rotateOnWorldAxis(axis: Vector3, angle: number): this; - - /** - * Rotates the object around _x_ axis in local space. - * @param rad The angle to rotate in radians. Expects a `Float` - */ - rotateX(angle: number): this; - - /** - * Rotates the object around _y_ axis in local space. - * @param rad The angle to rotate in radians. Expects a `Float` - */ - rotateY(angle: number): this; - - /** - * Rotates the object around _z_ axis in local space. - * @param rad The angle to rotate in radians. Expects a `Float` - */ - rotateZ(angle: number): this; - - /** - * Translate an object by distance along an axis in object space - * @remarks The axis is assumed to be normalized. - * @param axis A normalized vector in object space. - * @param distance The distance to translate. Expects a `Float` - */ - translateOnAxis(axis: Vector3, distance: number): this; - - /** - * Translates object along x axis in object space by {@link distance} units. - * @param distance Expects a `Float` - */ - translateX(distance: number): this; - - /** - * Translates object along _y_ axis in object space by {@link distance} units. - * @param distance Expects a `Float` - */ - translateY(distance: number): this; - - /** - * Translates object along _z_ axis in object space by {@link distance} units. - * @param distance Expects a `Float` - */ - translateZ(distance: number): this; - - /** - * Converts the vector from this object's local space to world space. - * @param vector A vector representing a position in this object's local space. - */ - localToWorld(vector: Vector3): Vector3; - - /** - * Converts the vector from world space to this object's local space. - * @param vector A vector representing a position in world space. - */ - worldToLocal(vector: Vector3): Vector3; - - /** - * Rotates the object to face a point in world space. - * @remarks This method does not support objects having non-uniformly-scaled parent(s). - * @param vector A vector representing a position in world space to look at. - */ - lookAt(vector: Vector3): void; - /** - * Rotates the object to face a point in world space. - * @remarks This method does not support objects having non-uniformly-scaled parent(s). - * @param x Expects a `Float` - * @param y Expects a `Float` - * @param z Expects a `Float` - */ - lookAt(x: number, y: number, z: number): void; - - /** - * Adds another {@link Object3D} as child of this {@link Object3D}. - * @remarks An arbitrary number of objects may be added - * Any current parent on an {@link object} passed in here will be removed, since an {@link Object3D} can have at most one parent. - * @see {@link attach} - * @see {@link THREE.Group | Group} for info on manually grouping objects. - * @param object - */ - add(...object: Object3D[]): this; - - /** - * Removes a {@link Object3D} as child of this {@link Object3D}. - * @remarks An arbitrary number of objects may be removed. - * @see {@link THREE.Group | Group} for info on manually grouping objects. - * @param object - */ - remove(...object: Object3D[]): this; - - /** - * Removes this object from its current parent. - */ - removeFromParent(): this; - - /** - * Removes all child objects. - */ - clear(): this; - - /** - * Adds a {@link Object3D} as a child of this, while maintaining the object's world transform. - * @remarks Note: This method does not support scene graphs having non-uniformly-scaled nodes(s). - * @see {@link add} - * @param object - */ - attach(object: Object3D): this; - - /** - * Searches through an object and its children, starting with the object itself, and returns the first with a matching id. - * @remarks Note that ids are assigned in chronological order: 1, 2, 3, ..., incrementing by one for each new object. - * @see {@link id} - * @param id Unique number of the object instance. Expects a `Integer` - */ - getObjectById(id: number): Object3D | undefined; - - /** - * Searches through an object and its children, starting with the object itself, and returns the first with a matching name. - * @remarks Note that for most objects the name is an empty string by default - * You will have to set it manually to make use of this method. - * @param name String to match to the children's Object3D.name property. - */ - getObjectByName(name: string): Object3D | undefined; - - /** - * Searches through an object and its children, starting with the object itself, - * and returns the first with a property that matches the value given. - * - * @param name - the property name to search for. - * @param value - value of the given property. - */ - getObjectByProperty(name: string, value: any): Object3D | undefined; - - /** - * Searches through an object and its children, starting with the object itself, - * and returns the first with a property that matches the value given. - * @param name The property name to search for. - * @param value Value of the given property. - * @param optionalTarget target to set the result. Otherwise a new Array is instantiated. If set, you must clear - * this array prior to each call (i.e., array.length = 0;). - */ - getObjectsByProperty(name: string, value: any, optionalTarget?: Object3D[]): Object3D[]; - - /** - * Returns a vector representing the position of the object in world space. - * @param target The result will be copied into this Vector3. - */ - getWorldPosition(target: Vector3): Vector3; - - /** - * Returns a quaternion representing the rotation of the object in world space. - * @param target The result will be copied into this Quaternion. - */ - getWorldQuaternion(target: Quaternion): Quaternion; - - /** - * Returns a vector of the scaling factors applied to the object for each axis in world space. - * @param target The result will be copied into this Vector3. - */ - getWorldScale(target: Vector3): Vector3; - - /** - * Returns a vector representing the direction of object's positive z-axis in world space. - * @param target The result will be copied into this Vector3. - */ - getWorldDirection(target: Vector3): Vector3; - - /** - * Abstract (empty) method to get intersections between a casted ray and this object - * @remarks Subclasses such as {@link THREE.Mesh | Mesh}, {@link THREE.Line | Line}, and {@link THREE.Points | Points} implement this method in order to use raycasting. - * @see {@link THREE.Raycaster | Raycaster} - * @param raycaster - * @param intersects - * @defaultValue `() => {}` - */ - raycast(raycaster: Raycaster, intersects: Intersection[]): void; - - /** - * Executes the callback on this object and all descendants. - * @remarks Note: Modifying the scene graph inside the callback is discouraged. - * @param callback A function with as first argument an {@link Object3D} object. - */ - traverse(callback: (object: Object3D) => any): void; - - /** - * Like traverse, but the callback will only be executed for visible objects - * @remarks Descendants of invisible objects are not traversed. - * Note: Modifying the scene graph inside the callback is discouraged. - * @param callback A function with as first argument an {@link Object3D} object. - */ - traverseVisible(callback: (object: Object3D) => any): void; - - /** - * Executes the callback on all ancestors. - * @remarks Note: Modifying the scene graph inside the callback is discouraged. - * @param callback A function with as first argument an {@link Object3D} object. - */ - traverseAncestors(callback: (object: Object3D) => any): void; - - /** - * Updates local transform. - */ - updateMatrix(): void; - - /** - * Updates the global transform of the object. - * And will update the object descendants if {@link matrixWorldNeedsUpdate | .matrixWorldNeedsUpdate} is set to true or if the {@link force} parameter is set to `true`. - * @param force A boolean that can be used to bypass {@link matrixWorldAutoUpdate | .matrixWorldAutoUpdate}, to recalculate the world matrix of the object and descendants on the current frame. - * Useful if you cannot wait for the renderer to update it on the next frame, assuming {@link matrixWorldAutoUpdate | .matrixWorldAutoUpdate} set to `true`. - */ - updateMatrixWorld(force?: boolean): void; - - /** - * Updates the global transform of the object. - * @param updateParents Recursively updates global transform of ancestors. - * @param updateChildren Recursively updates global transform of descendants. - */ - updateWorldMatrix(updateParents: boolean, updateChildren: boolean): void; - - /** - * Convert the object to three.js {@link https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 | JSON Object/Scene format}. - * @param meta Object containing metadata such as materials, textures or images for the object. - */ - toJSON(meta?: JSONMeta): Object3DJSON; - - /** - * Returns a clone of `this` object and optionally all descendants. - * @param recursive If true, descendants of the object are also cloned. Default `true` - */ - clone(recursive?: boolean): this; - - /** - * Copies the given object into this object. - * @remarks Event listeners and user-defined callbacks ({@link .onAfterRender} and {@link .onBeforeRender}) are not copied. - * @param object - * @param recursive If set to `true`, descendants of the object are copied next to the existing ones. If set to - * `false`, descendants are left unchanged. Default is `true`. - */ - copy(object: Object3D, recursive?: boolean): this; -} diff --git a/src-testing/src/core/Raycaster.d.ts b/src-testing/src/core/Raycaster.d.ts deleted file mode 100644 index 4b6d3746e..000000000 --- a/src-testing/src/core/Raycaster.d.ts +++ /dev/null @@ -1,208 +0,0 @@ -import { Camera } from "../cameras/Camera.js"; -import { Ray } from "../math/Ray.js"; -import { Vector2 } from "../math/Vector2.js"; -import { Vector3 } from "../math/Vector3.js"; -import { XRTargetRaySpace } from "../renderers/webxr/WebXRController.js"; -import { Layers } from "./Layers.js"; -import { Object3D } from "./Object3D.js"; - -export interface Face { - a: number; - b: number; - c: number; - normal: Vector3; - materialIndex: number; -} - -export interface Intersection { - /** Distance between the origin of the ray and the intersection */ - distance: number; - distanceToRay?: number | undefined; - /** Point of intersection, in world coordinates */ - point: Vector3; - index?: number | undefined; - /** Intersected face */ - face?: Face | null | undefined; - /** Index of the intersected face */ - faceIndex?: number | null | undefined; - barycoord?: Vector3 | null; - /** The intersected object */ - object: TIntersected; - uv?: Vector2 | undefined; - uv1?: Vector2 | undefined; - normal?: Vector3; - /** The index number of the instance where the ray intersects the {@link THREE.InstancedMesh | InstancedMesh } */ - instanceId?: number | undefined; - pointOnLine?: Vector3; - batchId?: number; -} - -export interface RaycasterParameters { - Mesh: any; - Line: { threshold: number }; - Line2?: { threshold: number }; - LOD: any; - Points: { threshold: number }; - Sprite: any; -} - -/** - * This class is designed to assist with {@link https://en.wikipedia.org/wiki/Ray_casting | raycasting} - * @remarks - * Raycasting is used for mouse picking (working out what objects in the 3d space the mouse is over) amongst other things. - * @example - * ```typescript - * const raycaster = new THREE.Raycaster(); - * const pointer = new THREE.Vector2(); - * - * function onPointerMove(event) { - * // calculate pointer position in normalized device coordinates (-1 to +1) for both components - * pointer.x = (event.clientX / window.innerWidth) * 2 - 1; - * pointer.y = -(event.clientY / window.innerHeight) * 2 + 1; - * } - * - * function render() { - * // update the picking ray with the camera and pointer position - * raycaster.setFromCamera(pointer, camera); - * // calculate objects intersecting the picking ray - * const intersects = raycaster.intersectObjects(scene.children); - * for (let i = 0; i & lt; intersects.length; i++) { - * intersects[i].object.material.color.set(0xff0000); - * } - * renderer.render(scene, camera); - * } - * window.addEventListener('pointermove', onPointerMove); - * window.requestAnimationFrame(render); - * ``` - * @see Example: {@link https://threejs.org/examples/#webgl_interactive_cubes | Raycasting to a Mesh} - * @see Example: {@link https://threejs.org/examples/#webgl_interactive_cubes_ortho | Raycasting to a Mesh in using an OrthographicCamera} - * @see Example: {@link https://threejs.org/examples/#webgl_interactive_buffergeometry | Raycasting to a Mesh with BufferGeometry} - * @see Example: {@link https://threejs.org/examples/#webgl_instancing_raycast | Raycasting to a InstancedMesh} - * @see Example: {@link https://threejs.org/examples/#webgl_interactive_lines | Raycasting to a Line} - * @see Example: {@link https://threejs.org/examples/#webgl_interactive_raycasting_points | Raycasting to Points} - * @see Example: {@link https://threejs.org/examples/#webgl_geometry_terrain_raycast | Terrain raycasting} - * @see Example: {@link https://threejs.org/examples/#webgl_interactive_voxelpainter | Raycasting to paint voxels} - * @see Example: {@link https://threejs.org/examples/#webgl_raycaster_texture | Raycast to a Texture} - * @see {@link https://threejs.org/docs/index.html#api/en/core/Raycaster | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/Raycaster.js | Source} - */ -export class Raycaster { - /** - * This creates a new {@link Raycaster} object. - * @param origin The origin vector where the ray casts from. Default `new Vector3()` - * @param direction The direction vector that gives direction to the ray. Should be normalized. Default `new Vector3(0, 0, -1)` - * @param near All results returned are further away than near. Near can't be negative. Expects a `Float`. Default `0` - * @param far All results returned are closer than far. Far can't be lower than near. Expects a `Float`. Default `Infinity` - */ - constructor(origin?: Vector3, direction?: Vector3, near?: number, far?: number); - - /** - * The {@link THREE.RaycasterRay | Ray} used for the raycasting. - */ - ray: Ray; - - /** - * The near factor of the raycaster. This value indicates which objects can be discarded based on the distance. - * This value shouldn't be negative and should be smaller than the far property. - * @remarks Expects a `Float` - * @defaultValue `0` - */ - near: number; - - /** - * The far factor of the raycaster. This value indicates which objects can be discarded based on the distance. - * This value shouldn't be negative and should be larger than the near property. - * @remarks Expects a `Float` - * @defaultValue `Infinity` - */ - far: number; - - /** - * The camera to use when raycasting against view-dependent objects such as billboarded objects like {@link THREE.Sprites | Sprites}. - * This field can be set manually or is set when calling {@link setFromCamera}. - * @defaultValue `null` - */ - camera: Camera; - - /** - * Used by {@link Raycaster} to selectively ignore 3D objects when performing intersection tests. - * The following code example ensures that only 3D objects on layer `1` will be honored by the instance of Raycaster. - * ``` - * raycaster.layers.set( 1 ); - * object.layers.enable( 1 ); - * ``` - * @defaultValue `new THREE.Layers()` - See {@link THREE.Layers | Layers}. - */ - layers: Layers; - - /** - * An data object where threshold is the precision of the {@link Raycaster} when intersecting objects, in world units. - * @defaultValue `{ Mesh: {}, Line: { threshold: 1 }, LOD: {}, Points: { threshold: 1 }, Sprite: {} }` - */ - params: RaycasterParameters; - - /** - * Updates the ray with a new origin and direction - * @remarks - * Please note that this method only copies the values from the arguments. - * @param origin The origin vector where the ray casts from. - * @param direction The normalized direction vector that gives direction to the ray. - */ - set(origin: Vector3, direction: Vector3): void; - - /** - * Updates the ray with a new origin and direction. - * @param coords 2D coordinates of the mouse, in normalized device coordinates (NDC)---X and Y components should be between -1 and 1. - * @param camera camera from which the ray should originate - */ - setFromCamera(coords: Vector2, camera: Camera): void; - - /** - * Updates the ray with a new origin and direction. - * @param controller The controller to copy the position and direction from. - */ - setFromXRController(controller: XRTargetRaySpace): this; - - /** - * Checks all intersection between the ray and the object with or without the descendants - * @remarks Intersections are returned sorted by distance, closest first - * @remarks {@link Raycaster} delegates to the {@link Object3D.raycast | raycast} method of the passed object, when evaluating whether the ray intersects the object or not - * This allows {@link THREE.Mesh | meshes} to respond differently to ray casting than {@link THREE.Line | lines} and {@link THREE.Points | pointclouds}. - * **Note** that for meshes, faces must be pointed towards the origin of the {@link Raycaster.ray | ray} in order to be detected; - * intersections of the ray passing through the back of a face will not be detected - * To raycast against both faces of an object, you'll want to set the {@link Mesh.material | material}'s {@link Material.side | side} property to `THREE.DoubleSide`. - * @see {@link intersectObjects | .intersectObjects()}. - * @param object The object to check for intersection with the ray. - * @param recursive If true, it also checks all descendants. Otherwise it only checks intersection with the object. Default `true` - * @param optionalTarget Target to set the result. Otherwise a new {@link Array | Array} is instantiated. - * If set, you must clear this array prior to each call (i.e., array.length = 0;). Default `[]` - * @returns An array of intersections is returned. - */ - intersectObject( - object: Object3D, - recursive?: boolean, - optionalTarget?: Array>, - ): Array>; - - /** - * Checks all intersection between the ray and the objects with or without the descendants - * @remarks Intersections are returned sorted by distance, closest first - * @remarks Intersections are of the same form as those returned by {@link intersectObject | .intersectObject()}. - * @remarks {@link Raycaster} delegates to the {@link Object3D.raycast | raycast} method of the passed object, when evaluating whether the ray intersects the object or not - * This allows {@link THREE.Mesh | meshes} to respond differently to ray casting than {@link THREE.Line | lines} and {@link THREE.Points | pointclouds}. - * **Note** that for meshes, faces must be pointed towards the origin of the {@link Raycaster.ray | ray} in order to be detected; - * intersections of the ray passing through the back of a face will not be detected - * To raycast against both faces of an object, you'll want to set the {@link Mesh.material | material}'s {@link Material.side | side} property to `THREE.DoubleSide`. - * @see {@link intersectObject | .intersectObject()}. - * @param objects The objects to check for intersection with the ray. - * @param recursive If true, it also checks all descendants of the objects. Otherwise it only checks intersection with the objects. Default `true` - * @param optionalTarget Target to set the result. Otherwise a new {@link Array | Array} is instantiated. - * If set, you must clear this array prior to each call (i.e., array.length = 0;). Default `[]` - * @returns An array of intersections is returned. - */ - intersectObjects( - objects: Object3D[], - recursive?: boolean, - optionalTarget?: Array>, - ): Array>; -} diff --git a/src-testing/src/core/RenderTarget.d.ts b/src-testing/src/core/RenderTarget.d.ts deleted file mode 100644 index 2f20cabb5..000000000 --- a/src-testing/src/core/RenderTarget.d.ts +++ /dev/null @@ -1,95 +0,0 @@ -import { - MagnificationTextureFilter, - MinificationTextureFilter, - PixelFormatGPU, - TextureDataType, - Wrapping, -} from "../constants.js"; -import { Vector4 } from "../math/Vector4.js"; -import { DepthTexture } from "../textures/DepthTexture.js"; -import { Texture } from "../textures/Texture.js"; -import { EventDispatcher } from "./EventDispatcher.js"; - -export interface RenderTargetOptions { - wrapS?: Wrapping | undefined; - wrapT?: Wrapping | undefined; - magFilter?: MagnificationTextureFilter | undefined; - minFilter?: MinificationTextureFilter | undefined; - generateMipmaps?: boolean | undefined; // true - format?: number | undefined; // RGBAFormat - type?: TextureDataType | undefined; // UnsignedByteType - anisotropy?: number | undefined; // 1 - colorSpace?: string | undefined; - internalFormat?: PixelFormatGPU | null | undefined; // null - depthBuffer?: boolean | undefined; // true - stencilBuffer?: boolean | undefined; // false - resolveDepthBuffer?: boolean | undefined; // true - resolveStencilBuffer?: boolean | undefined; // true - depthTexture?: DepthTexture | null | undefined; // null - /** - * Defines the count of MSAA samples. Can only be used with WebGL 2. Default is **0**. - * @default 0 - */ - samples?: number | undefined; - count?: number | undefined; -} - -export class RenderTarget extends EventDispatcher<{ dispose: {} }> { - readonly isRenderTarget: true; - - width: number; - height: number; - depth: number; - - scissor: Vector4; - /** - * @default false - */ - scissorTest: boolean; - viewport: Vector4; - textures: TTexture[]; - - /** - * @default true - */ - depthBuffer: boolean; - - /** - * @default false - */ - stencilBuffer: boolean; - - /** - * Defines whether the depth buffer should be resolved when rendering into a multisampled render target. - * @default true - */ - resolveDepthBuffer: boolean; - - /** - * Defines whether the stencil buffer should be resolved when rendering into a multisampled render target. - * This property has no effect when {@link .resolveDepthBuffer} is set to `false`. - * @default true - */ - resolveStencilBuffer: boolean; - - /** - * @default null - */ - depthTexture: DepthTexture | null; - - /** - * Defines the count of MSAA samples. Can only be used with WebGL 2. Default is **0**. - * @default 0 - */ - samples: number; - - constructor(width?: number, height?: number, options?: RenderTargetOptions); - - get texture(): TTexture; - set texture(value: TTexture); - - setSize(width: number, height: number, depth?: number): void; - clone(): this; - copy(source: RenderTarget): this; - dispose(): void; -} diff --git a/src-testing/src/core/Uniform.d.ts b/src-testing/src/core/Uniform.d.ts deleted file mode 100644 index 851ae2bf9..000000000 --- a/src-testing/src/core/Uniform.d.ts +++ /dev/null @@ -1,38 +0,0 @@ -/** - * Uniforms are global GLSL variables. - * They are passed to shader programs. - * @example - * When declaring a uniform of a {@link THREE.ShaderMaterial | ShaderMaterial}, it is declared by value or by object. - * ```typescript - * uniforms: { - * time: { - * value: 1.0 - * }, - * resolution: new Uniform(new Vector2()) - * }; - * ``` - * @see Example: {@link https://threejs.org/examples/#webgl_nodes_materials_instance_uniform | WebGL2 / nodes / materials / instance / uniform} - * @see Example: {@link https://threejs.org/examples/#webgpu_instance_uniform| WebGPU / instance / uniform} - * @see {@link https://threejs.org/docs/index.html#api/en/core/Uniform | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/Uniform.js | Source} - */ -export class Uniform { - /** - * Create a new instance of {@link THREE.Uniform | Uniform} - * @param value An object containing the value to set up the uniform. It's type must be one of the Uniform Types described above. - */ - constructor(value: T); - - /** - * Current value of the uniform. - */ - value: T; - - /** - * Returns a clone of this uniform. - * @remarks - * If the uniform's {@link value} property is an {@link Object | Object} with a `clone()` method, this is used, - * otherwise the value is copied by assignment Array values are **shared** between cloned {@link THREE.UniformUniform | Uniform}s. - */ - clone(): Uniform; -} diff --git a/src-testing/src/core/UniformsGroup.d.ts b/src-testing/src/core/UniformsGroup.d.ts deleted file mode 100644 index 4fb30b2c1..000000000 --- a/src-testing/src/core/UniformsGroup.d.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { Usage } from "../constants.js"; -import { EventDispatcher } from "./EventDispatcher.js"; -import { Uniform } from "./Uniform.js"; - -/** - * @see Example: {@link https://threejs.org/examples/#webgl2_ubo | WebGL2 / UBO} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/UniformsGroup.js | Source} - */ -export class UniformsGroup extends EventDispatcher<{ dispose: {} }> { - constructor(); - - readonly isUniformsGroup: true; - - id: number; - - usage: Usage; - - uniforms: Array; - - add(uniform: Uniform | Uniform[]): this; - - remove(uniform: Uniform | Uniform[]): this; - - setName(name: string): this; - - setUsage(value: Usage): this; - - dispose(): this; - - copy(source: UniformsGroup): this; - - clone(): UniformsGroup; -} diff --git a/src-testing/src/extras/Controls.d.ts b/src-testing/src/extras/Controls.d.ts deleted file mode 100644 index 6202a5c0c..000000000 --- a/src-testing/src/extras/Controls.d.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { EventDispatcher } from "../core/EventDispatcher.js"; -import { Object3D } from "../core/Object3D.js"; - -/** - * Abstract base class for controls. - */ -declare abstract class Controls extends EventDispatcher { - /** - * The 3D object that is managed by the controls. - */ - object: Object3D; - - /** - * The HTML element used for event listeners. If not provided via the constructor, {@link .connect} must be called - * after `domElement` has been set. - */ - domElement: HTMLElement | null; - - /** - * When set to `false`, the controls will not respond to user input. Default is `true`. - */ - enabled: boolean; - - /** - * Creates a new instance of {@link Controls}. - * @param object The object the controls should manage (usually the camera). - * @param domElement The HTML element used for event listeners. (optional) - */ - constructor(object: Object3D, domElement?: HTMLElement | null); - - /** - * Connects the controls to the DOM. This method has so called "side effects" since it adds the module's event - * listeners to the DOM. - */ - connect(): void; - - /** - * Disconnects the controls from the DOM. - */ - disconnect(): void; - - /** - * Call this method if you no longer want use to the controls. It frees all internal resources and removes all event - * listeners. - */ - dispose(): void; - - /** - * Controls should implement this method if they have to update their internal state per simulation step. - */ - update(delta: number): void; -} - -export { Controls }; diff --git a/src-testing/src/extras/DataUtils.d.ts b/src-testing/src/extras/DataUtils.d.ts deleted file mode 100644 index fd678dbf4..000000000 --- a/src-testing/src/extras/DataUtils.d.ts +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Returns a half precision floating point value from the given single precision floating point value. - * @param val A single precision floating point value. - * @see {@link https://threejs.org/docs/index.html#api/en/extras/DataUtils | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/DataUtils.js | Source} - */ -declare function toHalfFloat(val: number): number; - -/** - * Returns a single precision floating point value from the given half precision floating point value. - * @param val A half precision floating point value. - * @see {@link https://threejs.org/docs/index.html#api/en/extras/DataUtils | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/DataUtils.js | Source} - */ -declare function fromHalfFloat(val: number): number; - -declare const DataUtils: { - toHalfFloat: typeof toHalfFloat; - fromHalfFloat: typeof fromHalfFloat; -}; - -export { DataUtils, fromHalfFloat, toHalfFloat }; diff --git a/src-testing/src/extras/Earcut.d.ts b/src-testing/src/extras/Earcut.d.ts deleted file mode 100644 index 623b8ee82..000000000 --- a/src-testing/src/extras/Earcut.d.ts +++ /dev/null @@ -1,15 +0,0 @@ -/** - * An implementation of the {@link Earcut} polygon triangulation algorithm - * @remarks - * The code is a port of {@link https://github.com/mapbox/earcut | mapbox/earcut}. - * @see {@link https://threejs.org/docs/index.html#api/en/extras/Earcut | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/Earcut.js | Source} - */ -export const Earcut: { - /** - * Triangulates the given shape definition by returning an array of triangles - * @remarks - * A triangle is defined by three consecutive integers representing vertex indices. - */ - triangulate(data: number[], holeIndices?: number[], dim?: number): number[]; -}; diff --git a/src-testing/src/extras/ImageUtils.d.ts b/src-testing/src/extras/ImageUtils.d.ts deleted file mode 100644 index 798fc3e90..000000000 --- a/src-testing/src/extras/ImageUtils.d.ts +++ /dev/null @@ -1,32 +0,0 @@ -/** - * A class containing utility functions for images. - * @see {@link https://threejs.org/docs/index.html#api/en/extras/ImageUtils | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/ImageUtils.js | Source} - */ -declare class ImageUtils { - /** - * Returns a data URI containing a representation of the given image. - * @param image The image object. - */ - static getDataURL( - image: HTMLImageElement | HTMLCanvasElement | CanvasImageSource | ImageBitmap | ImageData, - ): string; - - /** - * Converts the given sRGB image data to linear color space. - * @param image - */ - static sRGBToLinear(image: HTMLImageElement | HTMLCanvasElement | ImageBitmap): HTMLCanvasElement; - - /** - * Converts the given sRGB image data to linear color space. - * @param image - */ - static sRGBToLinear(image: ImageData): { - data: ImageData["data"]; - width: ImageData["width"]; - height: ImageData["height"]; - }; -} - -export { ImageUtils }; diff --git a/src-testing/src/extras/PMREMGenerator.d.ts b/src-testing/src/extras/PMREMGenerator.d.ts deleted file mode 100644 index 3eb4a15e1..000000000 --- a/src-testing/src/extras/PMREMGenerator.d.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { WebGLRenderer } from "../renderers/WebGLRenderer.js"; -import { WebGLRenderTarget } from "../renderers/WebGLRenderTarget.js"; -import { Scene } from "../scenes/Scene.js"; -import { CubeTexture } from "../textures/CubeTexture.js"; -import { Texture } from "../textures/Texture.js"; - -/** - * This class generates a Prefiltered, Mipmapped Radiance Environment Map (PMREM) from a cubeMap environment texture. - * @remarks - * This allows different levels of blur to be quickly accessed based on material roughness - * Unlike a traditional mipmap chain, it only goes down to the LOD_MIN level (above), and then creates extra even more filtered 'mips' at the same LOD_MIN resolution, - * associated with higher roughness levels - * In this way we maintain resolution to smoothly interpolate diffuse lighting while limiting sampling computation. - * @remarks - * Note: The minimum {@link THREE.MeshStandardMaterial | MeshStandardMaterial}'s roughness depends on the size of the provided texture - * If your render has small dimensions or the shiny parts have a lot of curvature, you may still be able to get away with a smaller texture size. - * - * | texture size | minimum roughness | - * |--------------|--------------------| - * | 16 | 0.21 | - * | 32 | 0.15 | - * | 64 | 0.11 | - * | 128 | 0.076 | - * | 256 | 0.054 | - * | 512 | 0.038 | - * | 1024 | 0.027 | - * - * @see {@link https://threejs.org/docs/index.html#api/en/extras/PMREMGenerator | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/PMREMGenerator.js | Source} - */ -export class PMREMGenerator { - /** - * This constructor creates a new PMREMGenerator. - * @param renderer - */ - constructor(renderer: WebGLRenderer); - - /** - * Generates a PMREM from a supplied Scene, which can be faster than using an image if networking bandwidth is low - * @remarks - * Optional near and far planes ensure the scene is rendered in its entirety (the cubeCamera is placed at the origin). - * @param scene The given scene. - * @param sigma Specifies a blur radius in radians to be applied to the scene before PMREM generation. Default `0`. - * @param near The near plane value. Default `0.1`. - * @param far The far plane value. Default `100`. - */ - fromScene(scene: Scene, sigma?: number, near?: number, far?: number): WebGLRenderTarget; - - /** - * Generates a PMREM from an equirectangular texture, which can be either LDR or HDR. The ideal input image size is - * 1k (1024 x 512), as this matches best with the 256 x 256 cubemap output. The smallest supported equirectangular - * image size is 64 x 32. - */ - fromEquirectangular(equirectangular: Texture, renderTarget?: WebGLRenderTarget | null): WebGLRenderTarget; - - /** - * Generates a PMREM from an cubemap texture, which can be either LDR or HDR. The ideal input cube size is - * 256 x 256, as this matches best with the 256 x 256 cubemap output. The smallest supported cube size is 16 x 16. - */ - fromCubemap(cubemap: CubeTexture, renderTarget?: WebGLRenderTarget | null): WebGLRenderTarget; - - /** - * Pre-compiles the cubemap shader - * @remarks - * You can get faster start-up by invoking this method during your texture's network fetch for increased concurrency. - */ - compileCubemapShader(): void; - - /** - * Pre-compiles the equirectangular shader - * @remarks - * You can get faster start-up by invoking this method during your texture's network fetch for increased concurrency. - */ - compileEquirectangularShader(): void; - - /** - * Frees the GPU-related resources allocated by this instance - * @remarks - * Call this method whenever this instance is no longer used in your app. - */ - dispose(): void; -} diff --git a/src-testing/src/extras/ShapeUtils.d.ts b/src-testing/src/extras/ShapeUtils.d.ts deleted file mode 100644 index 60fe8aaf9..000000000 --- a/src-testing/src/extras/ShapeUtils.d.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { Vector2Like } from "../math/Vector2.js"; - -/** - * A class containing utility functions for shapes. - * @remarks Note that these are all linear functions so it is necessary to calculate separately for x, y (and z, w if present) components of a vector. - * @see {@link https://threejs.org/docs/index.html#api/en/extras/ShapeUtils | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/ShapeUtils.js | Source} - */ -export class ShapeUtils { - /** - * Calculate area of a ( 2D ) contour polygon. - */ - static area(contour: readonly Vector2Like[]): number; - - /** - * Note that this is a linear function so it is necessary to calculate separately for x, y components of a polygon. - * @remarks Used internally by {@link THREE.Path | Path}, {@link THREE.ExtrudeGeometry | ExtrudeGeometry} and {@link THREE.ShapeGeometry | ShapeGeometry}. - */ - static isClockWise(pts: readonly Vector2Like[]): boolean; - - /** - * Used internally by {@link THREE.ExtrudeGeometry | ExtrudeGeometry} and {@link THREE.ShapeGeometry | ShapeGeometry} to calculate faces in shapes with holes. - */ - static triangulateShape(contour: Vector2Like[], holes: Vector2Like[][]): number[][]; -} diff --git a/src-testing/src/extras/TextureUtils.d.ts b/src-testing/src/extras/TextureUtils.d.ts deleted file mode 100644 index 254458b43..000000000 --- a/src-testing/src/extras/TextureUtils.d.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { CompressedPixelFormat, PixelFormat, TextureDataType } from "../constants.js"; -import { Texture } from "../textures/Texture.js"; - -/** - * Scales the texture as large as possible within its surface without cropping or stretching the texture. The method - * preserves the original aspect ratio of the texture. Akin to CSS `object-fit: contain`. - */ -declare function contain(texture: Texture, aspect: number): Texture; - -/** - * Scales the texture to the smallest possible size to fill the surface, leaving no empty space. The method preserves - * the original aspect ratio of the texture. Akin to CSS `object-fit: cover`. - */ -declare function cover(texture: Texture, aspect: number): Texture; - -/** - * Configures the texture to the default transformation. Akin to CSS `object-fit: fill`. - */ -declare function fill(texture: Texture): Texture; - -/** - * Given the width, height, format, and type of a texture. Determines how many bytes must be used to represent the - * texture. - */ -declare function getByteLength( - width: number, - height: number, - format: PixelFormat | CompressedPixelFormat, - type: TextureDataType, -): number; - -/** - * A class containing utility functions for textures. - */ -declare const TextureUtils: { - contain: typeof contain; - cover: typeof cover; - fill: typeof fill; - getByteLength: typeof getByteLength; -}; - -export { contain, cover, fill, getByteLength, TextureUtils }; diff --git a/src-testing/src/extras/core/Curve.d.ts b/src-testing/src/extras/core/Curve.d.ts deleted file mode 100644 index 9e3610903..000000000 --- a/src-testing/src/extras/core/Curve.d.ts +++ /dev/null @@ -1,162 +0,0 @@ -import { Vector2 } from "../../math/Vector2.js"; -import { Vector3 } from "../../math/Vector3.js"; - -export interface CurveJSON { - metadata: { version: number; type: string; generator: string }; - arcLengthDivisions: number; - type: string; -} - -/** - * An abstract base class for creating a {@link Curve} object that contains methods for interpolation - * @remarks - * For an array of Curves see {@link THREE.CurvePath | CurvePath}. - * @remarks - * This following curves inherit from THREE.Curve: - * - * **2D curves** - * - {@link THREE.ArcCurve} - * - {@link THREE.CubicBezierCurve} - * - {@link THREE.EllipseCurve} - * - {@link THREE.LineCurve} - * - {@link THREE.QuadraticBezierCurve} - * - {@link THREE.SplineCurve} - * - * **3D curves** - * - {@link THREE.CatmullRomCurve3} - * - {@link THREE.CubicBezierCurve3} - * - {@link THREE.LineCurve3} - * - {@link THREE.QuadraticBezierCurve3} - * - * @see {@link https://threejs.org/docs/index.html#api/en/extras/core/Curve | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/core/Curve.js | Source} - */ -export abstract class Curve { - protected constructor(); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `Curve` - */ - readonly type: string | "Curve"; - - /** - * This value determines the amount of divisions when calculating the cumulative segment lengths of a {@link Curve} - * via {@link .getLengths}. - * To ensure precision when using methods like {@link .getSpacedPoints}, it is recommended to increase {@link .arcLengthDivisions} if the {@link Curve} is very large. - * @defaultValue `200` - * @remarks Expects a `Integer` - */ - arcLengthDivisions: number; - - /** - * Returns a vector for a given position on the curve. - * @param t A position on the curve. Must be in the range `[ 0, 1 ]`. Expects a `Float` - * @param optionalTarget If specified, the result will be copied into this Vector, otherwise a new Vector will be created. Default `new T`. - */ - getPoint(t: number, optionalTarget?: TVector): TVector; - - /** - * Returns a vector for a given position on the {@link Curve} according to the arc length. - * @param u A position on the {@link Curve} according to the arc length. Must be in the range `[ 0, 1 ]`. Expects a `Float` - * @param optionalTarget If specified, the result will be copied into this Vector, otherwise a new Vector will be created. Default `new T`. - */ - getPointAt(u: number, optionalTarget?: TVector): TVector; - - /** - * Returns a set of divisions `+1` points using {@link .getPoint | getPoint(t)}. - * @param divisions Number of pieces to divide the {@link Curve} into. Expects a `Integer`. Default `5` - */ - getPoints(divisions?: number): TVector[]; - - /** - * Returns a set of divisions `+1` equi-spaced points using {@link .getPointAt | getPointAt(u)}. - * @param divisions Number of pieces to divide the {@link Curve} into. Expects a `Integer`. Default `5` - */ - getSpacedPoints(divisions?: number): TVector[]; - - /** - * Get total {@link Curve} arc length. - */ - getLength(): number; - - /** - * Get list of cumulative segment lengths. - * @param divisions Expects a `Integer` - */ - getLengths(divisions?: number): number[]; - - /** - * Update the cumulative segment distance cache - * @remarks - * The method must be called every time {@link Curve} parameters are changed - * If an updated {@link Curve} is part of a composed {@link Curve} like {@link THREE.CurvePath | CurvePath}, - * {@link .updateArcLengths}() must be called on the composed curve, too. - */ - updateArcLengths(): void; - - /** - * Given u in the range `[ 0, 1 ]`, - * @remarks - * `u` and `t` can then be used to give you points which are equidistant from the ends of the curve, using {@link .getPoint}. - * @param u Expects a `Float` - * @param distance Expects a `Float` - * @returns `t` also in the range `[ 0, 1 ]`. Expects a `Float`. - */ - getUtoTmapping(u: number, distance: number): number; - - /** - * Returns a unit vector tangent at t - * @remarks - * If the derived {@link Curve} does not implement its tangent derivation, two points a small delta apart will be used to find its gradient which seems to give a reasonable approximation. - * @param t A position on the curve. Must be in the range `[ 0, 1 ]`. Expects a `Float` - * @param optionalTarget If specified, the result will be copied into this Vector, otherwise a new Vector will be created. - */ - getTangent(t: number, optionalTarget?: TVector): TVector; - - /** - * Returns tangent at a point which is equidistant to the ends of the {@link Curve} from the point given in {@link .getTangent}. - * @param u A position on the {@link Curve} according to the arc length. Must be in the range `[ 0, 1 ]`. Expects a `Float` - * @param optionalTarget If specified, the result will be copied into this Vector, otherwise a new Vector will be created. - */ - getTangentAt(u: number, optionalTarget?: TVector): TVector; - - /** - * Generates the Frenet Frames - * @remarks - * Requires a {@link Curve} definition in 3D space - * Used in geometries like {@link THREE.TubeGeometry | TubeGeometry} or {@link THREE.ExtrudeGeometry | ExtrudeGeometry}. - * @param segments Expects a `Integer` - * @param closed - */ - computeFrenetFrames( - segments: number, - closed?: boolean, - ): { - tangents: Vector3[]; - normals: Vector3[]; - binormals: Vector3[]; - }; - - /** - * Creates a clone of this instance. - */ - clone(): this; - /** - * Copies another {@link Curve} object to this instance. - * @param source - */ - copy(source: Curve): this; - - /** - * Returns a JSON object representation of this instance. - */ - toJSON(): CurveJSON; - - /** - * Copies the data from the given JSON object to this instance. - * @param json - */ - fromJSON(json: CurveJSON): this; -} diff --git a/src-testing/src/extras/core/CurvePath.d.ts b/src-testing/src/extras/core/CurvePath.d.ts deleted file mode 100644 index 3a8577fd1..000000000 --- a/src-testing/src/extras/core/CurvePath.d.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { Vector2 } from "../../math/Vector2.js"; -import { Vector3 } from "../../math/Vector3.js"; -import { Curve, CurveJSON } from "./Curve.js"; - -export interface CurvePathJSON extends CurveJSON { - autoClose: boolean; - curves: CurveJSON[]; -} - -/** - * Curved Path - a curve path is simply a array of connected curves, but retains the api of a curve. - * @remarks - * A {@link CurvePath} is simply an array of connected curves, but retains the api of a curve. - * @see {@link https://threejs.org/docs/index.html#api/en/extras/core/CurvePath | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/core/CurvePath.js | Source} - */ -export class CurvePath extends Curve { - /** - * The constructor take no parameters. - */ - constructor(); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `CurvePath` - */ - override readonly type: string | "CurvePath"; - - /** - * The array of {@link Curve | Curves}. - * @defaultValue `[]` - */ - curves: Array>; - - /** - * Whether or not to automatically close the path. - * @defaultValue false - */ - autoClose: boolean; - - /** - * Add a curve to the {@link .curves} array. - * @param curve - */ - add(curve: Curve): void; - /** - * Adds a {@link LineCurve | lineCurve} to close the path. - */ - closePath(): this; - - getPoint(t: number, optionalTarget?: TVector): TVector; - - /** - * Get list of cumulative curve lengths of the curves in the {@link .curves} array. - */ - getCurveLengths(): number[]; - - /** - * Returns an array of points representing a sequence of curves - * @remarks - * The `division` parameter defines the number of pieces each curve is divided into - * However, for optimization and quality purposes, the actual sampling resolution for each curve depends on its type - * For example, for a {@link THREE.LineCurve | LineCurve}, the returned number of points is always just 2. - * @param divisions Number of pieces to divide the curve into. Expects a `Integer`. Default `12` - */ - override getPoints(divisions?: number): TVector[]; - - /** - * Returns a set of divisions `+1` equi-spaced points using {@link .getPointAt | getPointAt(u)}. - * @param divisions Number of pieces to divide the curve into. Expects a `Integer`. Default `40` - */ - override getSpacedPoints(divisions?: number): TVector[]; - - toJSON(): CurvePathJSON; - fromJSON(json: CurvePathJSON): this; -} diff --git a/src-testing/src/extras/core/Interpolations.d.ts b/src-testing/src/extras/core/Interpolations.d.ts deleted file mode 100644 index 9f5ed3784..000000000 --- a/src-testing/src/extras/core/Interpolations.d.ts +++ /dev/null @@ -1,36 +0,0 @@ -/** - * Used internally by {@link THREE.SplineCurve | SplineCurve}. - * @param t Interpolation weight. Expects a `Float` - * @param p0 Expects a `Float` - * @param p1 Expects a `Float` - * @param p2 Expects a `Float` - * @param p3 P0, p1, p2, the points defining the spline curve. Expects a `Float` - * @see {@link https://threejs.org/docs/index.html#api/en/extras/core/Interpolations | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/core/Interpolations.js | Source} - */ -declare function CatmullRom(t: number, p0: number, p1: number, p2: number, p3: number): number; - -/** - * Used internally by {@link THREE.QuadraticBezierCurve3 | QuadraticBezierCurve3} and {@link THREE.QuadraticBezierCurve | QuadraticBezierCurve}. - * @param t Interpolation weight. Expects a `Float` - * @param p0 Expects a `Float` - * @param p1 Expects a `Float` - * @param p2 P0, p1, the starting, control and end points defining the curve. Expects a `Float` - * @see {@link https://threejs.org/docs/index.html#api/en/extras/core/Interpolations | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/core/Interpolations.js | Source} - */ -declare function QuadraticBezier(t: number, p0: number, p1: number, p2: number): number; - -/** - * Used internally by {@link THREE.CubicBezierCurve3 | CubicBezierCurve3} and {@link THREE.CubicBezierCurve | CubicBezierCurve}. - * @param t Interpolation weight. Expects a `Float` - * @param p0 Expects a `Float` - * @param p1 Expects a `Float` - * @param p2 Expects a `Float` - * @param p3 P0, p1, p2, the starting, control(twice) and end points defining the curve. Expects a `Float` - * @see {@link https://threejs.org/docs/index.html#api/en/extras/core/Interpolations | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/core/Interpolations.js | Source} - */ -declare function CubicBezier(t: number, p0: number, p1: number, p2: number, p3: number): number; - -export { CatmullRom, CubicBezier, QuadraticBezier }; diff --git a/src-testing/src/extras/core/Path.d.ts b/src-testing/src/extras/core/Path.d.ts deleted file mode 100644 index 28be15b9c..000000000 --- a/src-testing/src/extras/core/Path.d.ts +++ /dev/null @@ -1,166 +0,0 @@ -import { Vector2, Vector2Tuple } from "../../math/Vector2.js"; -import { CurvePath, CurvePathJSON } from "./CurvePath.js"; - -export interface PathJSON extends CurvePathJSON { - currentPoint: Vector2Tuple; -} - -/** - * A 2D {@link Path} representation. - * @remarks - * The class provides methods for creating paths and contours of 2D shapes similar to the 2D Canvas API. - * @example - * ```typescript - * const {@link Path} = new THREE.Path(); - * path.lineTo(0, 0.8); - * path.quadraticCurveTo(0, 1, 0.2, 1); - * path.lineTo(1, 1); - * const points = path.getPoints(); - * const geometry = new THREE.BufferGeometry().setFromPoints(points); - * const material = new THREE.LineBasicMaterial({ - * color: 0xffffff - * }); - * const line = new THREE.Line(geometry, material); - * scene.add(line); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/extras/core/Path | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/core/Path.js | Source} - */ -export class Path extends CurvePath { - /** - * Creates a {@link Path} from the points - * @remarks - * The first point defines the offset, then successive points are added to the {@link CurvePath.curves | curves} array as {@link LineCurve | LineCurves}. - * If no points are specified, an empty {@link Path} is created and the {@link .currentPoint} is set to the origin. - * @param points Array of {@link Vector2 | Vector2s}. - */ - constructor(points?: Vector2[]); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `Path` - */ - override readonly type: string | "Path"; - - /** - * The current offset of the path. Any new {@link THREE.Curve | Curve} added will start here. - * @defaultValue `new THREE.Vector2()` - */ - currentPoint: Vector2; - - /** - * Adds an absolutely positioned {@link THREE.EllipseCurve | EllipseCurve} to the path. - * @param x Expects a `Float` - * @param y X, The absolute center of the arc. Expects a `Float` - * @param radius The radius of the arc. Expects a `Float` - * @param startAngle The start angle in radians. Expects a `Float` - * @param endAngle The end angle in radians. Expects a `Float` - * @param clockwise Sweep the arc clockwise. Default `false` - */ - absarc(aX: number, aY: number, aRadius: number, aStartAngle: number, aEndAngle: number, aClockwise?: boolean): this; - - /** - * Adds an absolutely positioned {@link THREE.EllipseCurve | EllipseCurve} to the path. - * @param x Expects a `Float` - * @param y X, The absolute center of the ellipse. Expects a `Float` - * @param xRadius The radius of the ellipse in the x axis. Expects a `Float` - * @param yRadius The radius of the ellipse in the y axis. Expects a `Float` - * @param startAngle The start angle in radians. Expects a `Float` - * @param endAngle The end angle in radians. Expects a `Float` - * @param clockwise Sweep the ellipse clockwise. Default `false` - * @param rotation The rotation angle of the ellipse in radians, counterclockwise from the positive X axis. Optional, Expects a `Float`. Default `0` - */ - absellipse( - aX: number, - aY: number, - xRadius: number, - yRadius: number, - aStartAngle: number, - aEndAngle: number, - aClockwise?: boolean, - aRotation?: number, - ): this; - - /** - * Adds an {@link THREE.EllipseCurve | EllipseCurve} to the path, positioned relative to {@link .currentPoint}. - * @param x Expects a `Float` - * @param y X, The center of the arc offset from the last call. Expects a `Float` - * @param radius The radius of the arc. Expects a `Float` - * @param startAngle The start angle in radians. Expects a `Float` - * @param endAngle The end angle in radians. Expects a `Float` - * @param clockwise Sweep the arc clockwise. Default `false` - */ - arc(aX: number, aY: number, aRadius: number, aStartAngle: number, aEndAngle: number, aClockwise?: boolean): this; - - /** - * This creates a bezier curve from {@link .currentPoint} with (cp1X, cp1Y) and (cp2X, cp2Y) as control points and updates {@link .currentPoint} to x and y. - * @param cp1X Expects a `Float` - * @param cp1Y Expects a `Float` - * @param cp2X Expects a `Float` - * @param cp2Y Expects a `Float` - * @param x Expects a `Float` - * @param y Expects a `Float` - */ - bezierCurveTo(aCP1x: number, aCP1y: number, aCP2x: number, aCP2y: number, aX: number, aY: number): this; - - /** - * Adds an {@link THREE.EllipseCurve | EllipseCurve} to the path, positioned relative to {@link .currentPoint}. - * @param x Expects a `Float` - * @param y X, The center of the ellipse offset from the last call. Expects a `Float` - * @param xRadius The radius of the ellipse in the x axis. Expects a `Float` - * @param yRadius The radius of the ellipse in the y axis. Expects a `Float` - * @param startAngle The start angle in radians. Expects a `Float` - * @param endAngle The end angle in radians. Expects a `Float` - * @param clockwise Sweep the ellipse clockwise. Default `false` - * @param rotation The rotation angle of the ellipse in radians, counterclockwise from the positive X axis. Optional, Expects a `Float`. Default `0` - */ - ellipse( - aX: number, - aY: number, - xRadius: number, - yRadius: number, - aStartAngle: number, - aEndAngle: number, - aClockwise?: boolean, - aRotation?: number, - ): this; - - /** - * Connects a {@link THREE.LineCurve | LineCurve} from {@link .currentPoint} to x, y onto the path. - * @param x Expects a `Float` - * @param y Expects a `Float` - */ - lineTo(x: number, y: number): this; - - /** - * Move the {@link .currentPoint} to x, y. - * @param x Expects a `Float` - * @param y Expects a `Float` - */ - moveTo(x: number, y: number): this; - - /** - * Creates a quadratic curve from {@link .currentPoint} with cpX and cpY as control point and updates {@link .currentPoint} to x and y. - * @param cpX Expects a `Float` - * @param cpY Expects a `Float` - * @param x Expects a `Float` - * @param y Expects a `Float` - */ - quadraticCurveTo(aCPx: number, aCPy: number, aX: number, aY: number): this; - - /** - * Points are added to the {@link CurvePath.curves | curves} array as {@link THREE.LineCurve | LineCurves}. - * @param vector2s - */ - setFromPoints(vectors: Vector2[]): this; - - /** - * Connects a new {@link THREE.SplineCurve | SplineCurve} onto the path. - * @param points An array of {@link Vector2 | Vector2's} - */ - splineThru(pts: Vector2[]): this; - - toJSON(): PathJSON; - fromJSON(json: PathJSON): this; -} diff --git a/src-testing/src/extras/core/Shape.d.ts b/src-testing/src/extras/core/Shape.d.ts deleted file mode 100644 index 84e5ff37f..000000000 --- a/src-testing/src/extras/core/Shape.d.ts +++ /dev/null @@ -1,86 +0,0 @@ -import { Vector2 } from "../../math/Vector2.js"; -import { Path, PathJSON } from "./Path.js"; - -export interface ShapeJSON extends PathJSON { - uuid: string; - holes: PathJSON[]; -} - -/** - * Defines an arbitrary 2d {@link Shape} plane using paths with optional holes - * @remarks - * It can be used with {@link THREE.ExtrudeGeometry | ExtrudeGeometry}, {@link THREE.ShapeGeometry | ShapeGeometry}, to get points, or to get triangulated faces. - * @example - * ```typescript - * const heartShape = new THREE.Shape(); - * heartShape.moveTo(25, 25); - * heartShape.bezierCurveTo(25, 25, 20, 0, 0, 0); - * heartShape.bezierCurveTo(-30, 0, -30, 35, -30, 35); - * heartShape.bezierCurveTo(-30, 55, -10, 77, 25, 95); - * heartShape.bezierCurveTo(60, 77, 80, 55, 80, 35); - * heartShape.bezierCurveTo(80, 35, 80, 0, 50, 0); - * heartShape.bezierCurveTo(35, 0, 25, 25, 25, 25); - * const extrudeSettings = { - * depth: 8, - * bevelEnabled: true, - * bevelSegments: 2, - * steps: 2, - * bevelSize: 1, - * bevelThickness: 1 - * }; - * const geometry = new THREE.ExtrudeGeometry(heartShape, extrudeSettings); - * const mesh = new THREE.Mesh(geometry, new THREE.MeshPhongMaterial()); - * ``` - * @see Example: {@link https://threejs.org/examples/#webgl_geometry_shapes | geometry / shapes } - * @see Example: {@link https://threejs.org/examples/#webgl_geometry_extrude_shapes | geometry / extrude / shapes } - * @see Example: {@link https://threejs.org/examples/#webgl_geometry_extrude_shapes2 | geometry / extrude / shapes2 } - * @see {@link https://threejs.org/docs/index.html#api/en/extras/core/Shape | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/core/Shape.js | Source} - */ -export class Shape extends Path { - /** - * Creates a {@link Shape} from the points - * @remarks - * The first point defines the offset, then successive points are added to the {@link CurvePath.curves | curves} array as {@link THREE.LineCurve | LineCurves}. - * If no points are specified, an empty {@link Shape} is created and the {@link .currentPoint} is set to the origin. - * @param points Array of {@link Vector2 | Vector2s}. - */ - constructor(points?: Vector2[]); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `Shape` - */ - override readonly type: string | "Shape"; - - /** - * {@link http://en.wikipedia.org/wiki/Universally_unique_identifier | UUID} of this object instance. - * @remarks This gets automatically assigned and shouldn't be edited. - */ - uuid: string; - - /** - * An array of {@link Path | paths} that define the holes in the shape. - * @defaultValue `[]` - */ - holes: Path[]; - - /** - * Call {@link THREE.Curve.getPoints | getPoints} on the {@link Shape} and the {@link holes} array - * @param divisions The fineness of the result. Expects a `Integer` - */ - extractPoints(divisions: number): { - shape: Vector2[]; - holes: Vector2[][]; - }; - - /** - * Get an array of {@link Vector2 | Vector2's} that represent the holes in the shape. - * @param divisions The fineness of the result. Expects a `Integer` - */ - getPointsHoles(divisions: number): Vector2[][]; - - toJSON(): ShapeJSON; - fromJSON(json: ShapeJSON): this; -} diff --git a/src-testing/src/extras/core/ShapePath.d.ts b/src-testing/src/extras/core/ShapePath.d.ts deleted file mode 100644 index 0fcd88312..000000000 --- a/src-testing/src/extras/core/ShapePath.d.ts +++ /dev/null @@ -1,98 +0,0 @@ -import { Color } from "../../math/Color.js"; -import { Vector2 } from "../../math/Vector2.js"; -import { Path } from "./Path.js"; -import { Shape } from "./Shape.js"; - -/** - * This class is used to convert a series of shapes to an array of {@link THREE.Path | Path's}, - * for example an SVG shape to a path. - * @see {@link https://threejs.org/docs/index.html#api/en/extras/core/ShapePath | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/core/ShapePath.js | Source} - */ -export class ShapePath { - /** - * Creates a new {@link ShapePath} - * @remarks - * Unlike a {@link THREE.Path | Path}, no points are passed in as the {@link ShapePath} is designed to be generated after creation. - */ - constructor(); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `ShapePath` - */ - readonly type: "ShapePath"; - - /** - * Array of {@link THREE.Path | Path's}s. - * @defaultValue `[]` - */ - subPaths: Path[]; - - /** - * The current {@link THREE.Path | Path} that is being generated. - * @defaultValue `null` - */ - readonly currentPath: Path | null; - - /** - * {@link THREE.Color | Color} of the shape, by default set to white _(0xffffff)_. - * @defaultValue `new THREE.Color()` - */ - color: Color; - - /** - * Starts a new {@link THREE.Path | Path} and calls {@link THREE.Path.moveTo | Path.moveTo}( x, y ) on that {@link THREE.Path | Path} - * @remarks - * Also points {@link ShapePath.currentPath | currentPath} to that {@link THREE.Path | Path}. - * @param x Expects a `Float` - * @param y Expects a `Float` - */ - moveTo(x: number, y: number): this; - - /** - * This creates a line from the {@link ShapePath.currentPath | currentPath}'s offset to X and Y and updates the offset to X and Y. - * @param x Expects a `Float` - * @param y Expects a `Float` - */ - lineTo(x: number, y: number): this; - - /** - * This creates a quadratic curve from the {@link ShapePath.currentPath | currentPath}'s - * offset to _x_ and _y_ with _cpX_ and _cpY_ as control point and updates the {@link ShapePath.currentPath | currentPath}'s offset to _x_ and _y_. - * @param cpX Expects a `Float` - * @param cpY Expects a `Float` - * @param x Expects a `Float` - * @param y Expects a `Float` - */ - quadraticCurveTo(aCPx: number, aCPy: number, aX: number, aY: number): this; - - /** - * This creates a bezier curve from the {@link ShapePath.currentPath | currentPath}'s - * offset to _x_ and _y_ with _cp1X_, _cp1Y_ and _cp2X_, _cp2Y_ as control points and - * updates the {@link ShapePath.currentPath | currentPath}'s offset to _x_ and _y_. - * @param cp1X Expects a `Float` - * @param cp1Y Expects a `Float` - * @param cp2X Expects a `Float` - * @param cp2Y Expects a `Float` - * @param x Expects a `Float` - * @param y Expects a `Float` - */ - bezierCurveTo(aCP1x: number, aCP1y: number, aCP2x: number, aCP2y: number, aX: number, aY: number): this; - - /** - * Connects a new {@link THREE.SplineCurve | SplineCurve} onto the {@link ShapePath.currentPath | currentPath}. - * @param points An array of {@link THREE.Vector2 | Vector2}s - */ - splineThru(pts: Vector2[]): this; - - /** - * Converts the {@link ShapePath.subPaths | subPaths} array into an array of Shapes - * @remarks - * By default solid shapes are defined clockwise (CW) and holes are defined counterclockwise (CCW) - * If isCCW is set to true, then those are flipped. - * @param isCCW Changes how solids and holes are generated - */ - toShapes(isCCW: boolean): Shape[]; -} diff --git a/src-testing/src/extras/curves/ArcCurve.d.ts b/src-testing/src/extras/curves/ArcCurve.d.ts deleted file mode 100644 index 0932f7ffb..000000000 --- a/src-testing/src/extras/curves/ArcCurve.d.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { EllipseCurve } from "./EllipseCurve.js"; - -/** - * Alias for {@link THREE.EllipseCurve | EllipseCurve}. - * @see {@link https://threejs.org/docs/index.html#api/en/extras/curves/ArcCurve | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/curves/ArcCurve.js | Source} - */ -export class ArcCurve extends EllipseCurve { - /** - * This constructor creates a new {@link ArcCurve}. - * @param aX The X center of the ellipse. Expects a `Float`. Default is `0`. - * @param aY The Y center of the ellipse. Expects a `Float`. Default is `0`. - * @param xRadius The radius of the ellipse in the x direction. Expects a `Float`. Default is `1`. - * @param yRadius The radius of the ellipse in the y direction. Expects a `Float`. Default is `1`. - * @param aStartAngle The start angle of the curve in radians starting from the positive X axis. Default is `0`. - * @param aEndAngle The end angle of the curve in radians starting from the positive X axis. Default is `2 x Math.PI`. - * @param aClockwise Whether the ellipse is drawn clockwise. Default is `false`. - */ - constructor( - aX?: number, - aY?: number, - aRadius?: number, - aStartAngle?: number, - aEndAngle?: number, - aClockwise?: boolean, - ); - - /** - * Read-only flag to check if a given object is of type {@link ArcCurve}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isArcCurve = true; - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `ArcCurve` - */ - override readonly type: string | "ArcCurve"; -} diff --git a/src-testing/src/extras/curves/CatmullRomCurve3.d.ts b/src-testing/src/extras/curves/CatmullRomCurve3.d.ts deleted file mode 100644 index 55088e412..000000000 --- a/src-testing/src/extras/curves/CatmullRomCurve3.d.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { Vector3 } from "../../math/Vector3.js"; -import { Curve } from "../core/Curve.js"; - -export type CurveType = "centripetal" | "chordal" | "catmullrom"; - -/** - * Create a smooth **3D** spline curve from a series of points using the {@link https://en.wikipedia.org/wiki/Centripetal_Catmull-Rom_spline | Catmull-Rom} algorithm. - * @example - * ```typescript - * //Create a closed wavey loop - * const curve = new THREE.CatmullRomCurve3([ - * new THREE.Vector3(-10, 0, 10), - * new THREE.Vector3(-5, 5, 5), - * new THREE.Vector3(0, 0, 0), - * new THREE.Vector3(5, -5, 5), - * new THREE.Vector3(10, 0, 10)]); - * const points = curve.getPoints(50); - * const geometry = new THREE.BufferGeometry().setFromPoints(points); - * const material = new THREE.LineBasicMaterial({ - * color: 0xff0000 - * }); - * // Create the final object to add to the scene - * const curveObject = new THREE.Line(geometry, material); - * ``` - * @see Example: {@link https://threejs.org/examples/#webgl_geometry_extrude_splines | WebGL / geometry / extrude / splines} - * @see {@link https://threejs.org/docs/index.html#api/en/extras/curves/CatmullRomCurve3 | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/curves/CatmullRomCurve3.js | Source} - */ -export class CatmullRomCurve3 extends Curve { - /** - * This constructor creates a new {@link CatmullRomCurve3}. - * @param points An array of {@link THREE.Vector3 | Vector3} points - * @param closed Whether the curve is closed. Default `false` - * @param curveType Type of the curve. Default `centripetal` - * @param tension Tension of the curve. Expects a `Float`. Default `0.5` - */ - constructor(points?: Vector3[], closed?: boolean, curveType?: CurveType, tension?: number); - - /** - * Read-only flag to check if a given object is of type {@link CatmullRomCurve3}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isCatmullRomCurve3 = true; - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `CatmullRomCurve3` - */ - override readonly type: string | "CatmullRomCurve3"; - - /** - * The curve will loop back onto itself when this is true. - * @defaultValue `false` - */ - closed: boolean; - - /** - * The array of {@link THREE.Vector3 | Vector3} points that define the curve. - * @remarks It needs at least two entries. - * @defaultValue `[]` - */ - points: Vector3[]; - - /** - * Possible values are `centripetal`, `chordal` and `catmullrom`. - * @defaultValue `centripetal` - */ - curveType: CurveType; - - /** - * When {@link .curveType} is `catmullrom`, defines catmullrom's tension. - * @remarks Expects a `Float` - */ - tension: number; -} diff --git a/src-testing/src/extras/curves/CubicBezierCurve.d.ts b/src-testing/src/extras/curves/CubicBezierCurve.d.ts deleted file mode 100644 index ae4518312..000000000 --- a/src-testing/src/extras/curves/CubicBezierCurve.d.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { Vector2 } from "../../math/Vector2.js"; -import { Curve } from "../core/Curve.js"; - -/** - * Create a smooth **2D** {@link http://en.wikipedia.org/wiki/B%C3%A9zier_curve#mediaviewer/File:Bezier_curve.svg | cubic bezier curve}, - * defined by a start point, endpoint and two control points. - * @example - * ```typescript - * const curve = new THREE.CubicBezierCurve( - * new THREE.Vector2(-10, 0), - * new THREE.Vector2(-5, 15), - * new THREE.Vector2(20, 15), - * new THREE.Vector2(10, 0)); - * const points = curve.getPoints(50); - * const geometry = new THREE.BufferGeometry().setFromPoints(points); - * const material = new THREE.LineBasicMaterial({ - * color: 0xff0000 - * }); - * // Create the final object to add to the scene - * const curveObject = new THREE.Line(geometry, material); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/extras/curves/CubicBezierCurve | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/curves/CubicBezierCurve.js | Source} - */ -export class CubicBezierCurve extends Curve { - /** - * This constructor creates a new {@link CubicBezierCurve}. - * @param v0 The starting point. Default is `new THREE.Vector2()`. - * @param v1 The first control point. Default is `new THREE.Vector2()`. - * @param v2 The second control point. Default is `new THREE.Vector2()`. - * @param v3 The ending point. Default is `new THREE.Vector2()`. - */ - constructor(v0?: Vector2, v1?: Vector2, v2?: Vector2, v3?: Vector2); - - /** - * Read-only flag to check if a given object is of type {@link CubicBezierCurve}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isCubicBezierCurve = true; - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `CubicBezierCurve` - */ - override readonly type: string | "CubicBezierCurve"; - - /** - * The starting point. - * @defaultValue `new THREE.Vector2()` - */ - v0: Vector2; - - /** - * The first control point. - * @defaultValue `new THREE.Vector2()` - */ - v1: Vector2; - - /** - * The second control point. - * @defaultValue `new THREE.Vector2()` - */ - v2: Vector2; - - /** - * The ending point. - * @defaultValue `new THREE.Vector2()` - */ - v3: Vector2; -} diff --git a/src-testing/src/extras/curves/CubicBezierCurve3.d.ts b/src-testing/src/extras/curves/CubicBezierCurve3.d.ts deleted file mode 100644 index ad8edb356..000000000 --- a/src-testing/src/extras/curves/CubicBezierCurve3.d.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { Vector3 } from "../../math/Vector3.js"; -import { Curve } from "../core/Curve.js"; - -/** - * Create a smooth **3D** {@link http://en.wikipedia.org/wiki/B%C3%A9zier_curve#mediaviewer/File:Bezier_curve.svg | cubic bezier curve}, - * defined by a start point, endpoint and two control points. - * @example - * ```typescript - * const curve = new THREE.CubicBezierCurve( - * new THREE.Vector2(-10, 0), - * new THREE.Vector2(-5, 15), - * new THREE.Vector2(20, 15), - * new THREE.Vector2(10, 0)); - * const points = curve.getPoints(50); - * const geometry = new THREE.BufferGeometry().setFromPoints(points); - * const material = new THREE.LineBasicMaterial({ - * color: 0xff0000 - * }); - * // Create the final object to add to the scene - * const curveObject = new THREE.Line(geometry, material); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/extras/curves/CubicBezierCurve | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/curves/CubicBezierCurve.js | Source} - */ -export class CubicBezierCurve3 extends Curve { - /** - * This constructor creates a new {@link CubicBezierCurve3}. - * @param v0 The starting point. Default is `new THREE.Vector3()`. - * @param v1 The first control point. Default is `new THREE.Vector3()`. - * @param v2 The second control point. Default is `new THREE.Vector3()`. - * @param v3 The ending point. Default is `new THREE.Vector3()`. - */ - constructor(v0?: Vector3, v1?: Vector3, v2?: Vector3, v3?: Vector3); - - /** - * Read-only flag to check if a given object is of type {@link CubicBezierCurve3}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isCubicBezierCurve3 = true; - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `CubicBezierCurve3` - */ - override readonly type: string | "CubicBezierCurve3"; - - /** - * The starting point. - * @defaultValue `new THREE.Vector3()`. - */ - v0: Vector3; - - /** - * The first control point. - * @defaultValue `new THREE.Vector3()`. - */ - v1: Vector3; - - /** - * The second control point. - * @defaultValue `new THREE.Vector3()`. - */ - v2: Vector3; - - /** - * The ending point. - * @defaultValue `new THREE.Vector3()`. - */ - v3: Vector3; -} diff --git a/src-testing/src/extras/curves/Curves.d.ts b/src-testing/src/extras/curves/Curves.d.ts deleted file mode 100644 index 996021d72..000000000 --- a/src-testing/src/extras/curves/Curves.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -export * from "./ArcCurve.js"; -export * from "./CatmullRomCurve3.js"; -export * from "./CubicBezierCurve.js"; -export * from "./CubicBezierCurve3.js"; -export * from "./EllipseCurve.js"; -export * from "./LineCurve.js"; -export * from "./LineCurve3.js"; -export * from "./QuadraticBezierCurve.js"; -export * from "./QuadraticBezierCurve3.js"; -export * from "./SplineCurve.js"; diff --git a/src-testing/src/extras/curves/EllipseCurve.d.ts b/src-testing/src/extras/curves/EllipseCurve.d.ts deleted file mode 100644 index 4d15ca8c2..000000000 --- a/src-testing/src/extras/curves/EllipseCurve.d.ts +++ /dev/null @@ -1,115 +0,0 @@ -import { Vector2 } from "../../math/Vector2.js"; -import { Curve } from "../core/Curve.js"; - -/** - * Creates a 2d curve in the shape of an ellipse - * @remarks - * Setting the {@link xRadius} equal to the {@link yRadius} will result in a circle. - * @example - * ```typescript - * const curve = new THREE.EllipseCurve( - * 0, 0, // ax, aY - * 10, 10, // xRadius, yRadius - * 0, 2 * Math.PI, // aStartAngle, aEndAngle - * false, // aClockwise - * 0 // aRotation - * ); - * const points = curve.getPoints(50); - * const geometry = new THREE.BufferGeometry().setFromPoints(points); - * const material = new THREE.LineBasicMaterial({ color: 0xff0000 }); - * // Create the final object to add to the scene - * const ellipse = new THREE.Line(geometry, material); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/extras/curves/EllipseCurve | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/curves/EllipseCurve.js | Source} - */ -export class EllipseCurve extends Curve { - /** - * This constructor creates a new {@link EllipseCurve}. - * @param aX The X center of the ellipse. Expects a `Float`. Default is `0`. - * @param aY The Y center of the ellipse. Expects a `Float`. Default is `0`. - * @param xRadius The radius of the ellipse in the x direction. Expects a `Float`. Default is `1`. - * @param yRadius The radius of the ellipse in the y direction. Expects a `Float`. Default is `1`. - * @param aStartAngle The start angle of the curve in radians starting from the positive X axis. Default is `0`. - * @param aEndAngle The end angle of the curve in radians starting from the positive X axis. Default is `2 x Math.PI`. - * @param aClockwise Whether the ellipse is drawn clockwise. Default is `false`. - * @param aRotation The rotation angle of the ellipse in radians, counterclockwise from the positive X axis. Default is `0`. - */ - constructor( - aX?: number, - aY?: number, - xRadius?: number, - yRadius?: number, - aStartAngle?: number, - aEndAngle?: number, - aClockwise?: boolean, - aRotation?: number, - ); - - /** - * Read-only flag to check if a given object is of type {@link EllipseCurve}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isEllipseCurve = true; - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `EllipseCurve` - */ - override readonly type: string | "EllipseCurve"; - - /** - * The X center of the ellipse. - * @remarks Expects a `Float` - * @defaultValue `0` - */ - aX: number; - - /** - * The Y center of the ellipse. - * @remarks Expects a `Float` - * @defaultValue `0` - */ - aY: number; - - /** - * The radius of the ellipse in the x direction. - * @defaultValue `1` - */ - xRadius: number; - - /** - * The radius of the ellipse in the y direction. - * @defaultValue `1` - */ - yRadius: number; - - /** - * The start angle of the curve in radians starting from the middle right side. - * @remarks Expects a `Float` - * @defaultValue `0` - */ - aStartAngle: number; - - /** - * The end angle of the curve in radians starting from the middle right side. - * @remarks Expects a `Float` - * @defaultValue `2 * Math.PI` - */ - aEndAngle: number; - - /** - * Whether the ellipse is drawn clockwise. - * @defaultValue `false`` - */ - aClockwise: boolean; - - /** - * The rotation angle of the ellipse in radians, counterclockwise from the positive X axis (optional). - * @remarks Expects a `Float` - * @defaultValue `0` - */ - aRotation: number; -} diff --git a/src-testing/src/extras/curves/LineCurve.d.ts b/src-testing/src/extras/curves/LineCurve.d.ts deleted file mode 100644 index 3bcb000d3..000000000 --- a/src-testing/src/extras/curves/LineCurve.d.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { Vector2 } from "../../math/Vector2.js"; -import { Curve } from "../core/Curve.js"; - -/** - * A curve representing a **2D** line segment. - * @see {@link https://threejs.org/docs/index.html#api/en/extras/curves/LineCurve | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/curves/LineCurve.js | Source} - */ -export class LineCurve extends Curve { - /** - * This constructor creates a new {@link LineCurve}. - * @param v1 The start point. Default is `new THREE.Vector2()`. - * @param v2 The end point. Default is `new THREE.Vector2()`. - */ - constructor(v1?: Vector2, v2?: Vector2); - - /** - * Read-only flag to check if a given object is of type {@link LineCurve}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isLineCurve = true; - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `LineCurve` - */ - override readonly type: string | "LineCurve"; - - /** - * The start point. - * @defaultValue `new THREE.Vector2()` - */ - v1: Vector2; - - /** - * The end point - * @defaultValue `new THREE.Vector2()` - */ - v2: Vector2; -} diff --git a/src-testing/src/extras/curves/LineCurve3.d.ts b/src-testing/src/extras/curves/LineCurve3.d.ts deleted file mode 100644 index c7ae7c301..000000000 --- a/src-testing/src/extras/curves/LineCurve3.d.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { Vector3 } from "../../math/Vector3.js"; -import { Curve } from "../core/Curve.js"; - -/** - * A curve representing a **3D** line segment. - * @see {@link https://threejs.org/docs/index.html#api/en/extras/curves/LineCurve3 | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/curves/LineCurve3.js | Source} - */ -export class LineCurve3 extends Curve { - /** - * This constructor creates a new {@link LineCurve3}. - * @param v1 The start point. Default is `new THREE.Vector3()`. - * @param v2 The end point. Default is `new THREE.Vector3()`. - */ - constructor(v1?: Vector3, v2?: Vector3); - - /** - * Read-only flag to check if a given object is of type {@link LineCurve3}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isLineCurve3 = true; - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `LineCurve3` - */ - override readonly type: string | "LineCurve3"; - - /** - * The start point. - * @defaultValue `new THREE.Vector3()`. - */ - v1: Vector3; - - /** - * The end point. - * @defaultValue `new THREE.Vector3()`. - */ - v2: Vector3; -} diff --git a/src-testing/src/extras/curves/QuadraticBezierCurve.d.ts b/src-testing/src/extras/curves/QuadraticBezierCurve.d.ts deleted file mode 100644 index 8ae4c3213..000000000 --- a/src-testing/src/extras/curves/QuadraticBezierCurve.d.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { Vector2 } from "../../math/Vector2.js"; -import { Curve } from "../core/Curve.js"; - -/** - * Create a smooth **2D** {@link http://en.wikipedia.org/wiki/B%C3%A9zier_curve#mediaviewer/File:B%C3%A9zier_2_big.gif | quadratic bezier curve}, - * defined by a start point, end point and a single control point. - * @example - * ```typescript - * const curve = new THREE.QuadraticBezierCurve( - * new THREE.Vector2(-10, 0), - * new THREE.Vector2(20, 15), - * new THREE.Vector2(10, 0)); - * const points = curve.getPoints(50); - * const geometry = new THREE.BufferGeometry().setFromPoints(points); - * const material = new THREE.LineBasicMaterial({ - * color: 0xff0000 - * }); - * // Create the final object to add to the scene - * const curveObject = new THREE.Line(geometry, material); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/extras/curves/QuadraticBezierCurve | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/curves/QuadraticBezierCurve.js | Source} - */ -export class QuadraticBezierCurve extends Curve { - /** - * This constructor creates a new {@link QuadraticBezierCurve}. - * @param v0 The start point. Default is `new THREE.Vector2()`. - * @param v1 The control point. Default is `new THREE.Vector2()`. - * @param v2 The end point. Default is `new THREE.Vector2()`. - */ - constructor(v0?: Vector2, v1?: Vector2, v2?: Vector2); - - /** - * Read-only flag to check if a given object is of type {@link LineCurve3}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isQuadraticBezierCurve = true; - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `QuadraticBezierCurve` - */ - override readonly type: string | "QuadraticBezierCurve"; - - /** - * The start point. - * @defaultValue `new THREE.Vector2()` - */ - v0: Vector2; - - /** - * The control point. - * @defaultValue `new THREE.Vector2()` - */ - v1: Vector2; - - /** - * The end point. - * @defaultValue `new THREE.Vector2()` - */ - v2: Vector2; -} diff --git a/src-testing/src/extras/curves/QuadraticBezierCurve3.d.ts b/src-testing/src/extras/curves/QuadraticBezierCurve3.d.ts deleted file mode 100644 index 3964af820..000000000 --- a/src-testing/src/extras/curves/QuadraticBezierCurve3.d.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { Vector3 } from "../../math/Vector3.js"; -import { Curve } from "../core/Curve.js"; - -/** - * Create a smooth **3D** {@link http://en.wikipedia.org/wiki/B%C3%A9zier_curve#mediaviewer/File:B%C3%A9zier_2_big.gif | quadratic bezier curve}, - * defined by a start point, end point and a single control point. - * @example - * ```typescript - * const curve = new THREE.QuadraticBezierCurve3( - * new THREE.Vector3(-10, 0, 0), - * new THREE.Vector3(20, 15, 0), - * new THREE.Vector3(10, 0, 0)); - * const points = curve.getPoints(50); - * const geometry = new THREE.BufferGeometry().setFromPoints(points); - * const material = new THREE.LineBasicMaterial({ - * color: 0xff0000 - * }); - * // Create the final object to add to the scene - * const curveObject = new THREE.Line(geometry, material); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/extras/curves/QuadraticBezierCurve3 | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/curves/QuadraticBezierCurve3.js | Source} - */ -export class QuadraticBezierCurve3 extends Curve { - /** - * This constructor creates a new {@link QuadraticBezierCurve}. - * @param v0 The start point. Default is `new THREE.Vector3()`. - * @param v1 The control point. Default is `new THREE.Vector3()`. - * @param v2 The end point. Default is `new THREE.Vector3()`. - */ - constructor(v0?: Vector3, v1?: Vector3, v2?: Vector3); - - /** - * Read-only flag to check if a given object is of type {@link QuadraticBezierCurve3}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isQuadraticBezierCurve3 = true; - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `QuadraticBezierCurve3` - */ - override readonly type: string | "QuadraticBezierCurve3"; - - /** - * The start point. - * @defaultValue `new THREE.Vector3()` - */ - v0: Vector3; - - /** - * The control point. - * @defaultValue `new THREE.Vector3()` - */ - v1: Vector3; - - /** - * The end point. - * @defaultValue `new THREE.Vector3()` - */ - v2: Vector3; -} diff --git a/src-testing/src/extras/curves/SplineCurve.d.ts b/src-testing/src/extras/curves/SplineCurve.d.ts deleted file mode 100644 index c3c56210a..000000000 --- a/src-testing/src/extras/curves/SplineCurve.d.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { Vector2 } from "../../math/Vector2.js"; -import { Curve } from "../core/Curve.js"; - -/** - * Create a smooth **2D** spline curve from a series of points. - * @example - * ```typescript - * // Create a sine-like wave - * const curve = new THREE.SplineCurve([ - * new THREE.Vector2(-10, 0), - * new THREE.Vector2(-5, 5), - * new THREE.Vector2(0, 0), - * new THREE.Vector2(5, -5), - * new THREE.Vector2(10, 0)]); - * const points = curve.getPoints(50); - * const geometry = new THREE.BufferGeometry().setFromPoints(points); - * const material = new THREE.LineBasicMaterial({ - * color: 0xff0000 - * }); - * // Create the final object to add to the scene - * const splineObject = new THREE.Line(geometry, material); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/extras/curves/SplineCurve | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/curves/SplineCurve.js | Source} - */ -export class SplineCurve extends Curve { - /** - * This constructor creates a new {@link SplineCurve}. - * @param points An array of {@link THREE.Vector2 | Vector2} points that define the curve. Default `[]` - */ - constructor(points?: Vector2[]); - - /** - * Read-only flag to check if a given object is of type {@link SplineCurve}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isSplineCurve = true; - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `SplineCurve` - */ - override readonly type: string | "SplineCurve"; - - /** - * The array of {@link THREE.Vector2 | Vector2} points that define the curve. - * @defaultValue `[]` - */ - points: Vector2[]; -} diff --git a/src-testing/src/geometries/BoxGeometry.d.ts b/src-testing/src/geometries/BoxGeometry.d.ts deleted file mode 100644 index 7a756ae56..000000000 --- a/src-testing/src/geometries/BoxGeometry.d.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { BufferGeometry } from "../core/BufferGeometry.js"; - -/** - * {@link BoxGeometry} is a geometry class for a rectangular cuboid with a given 'width', 'height', and 'depth' - * @remarks On creation, the cuboid is centred on the origin, with each edge parallel to one of the axes. - * @example - * ```typescript - * const geometry = new THREE.BoxGeometry(1, 1, 1); - * const material = new THREE.MeshBasicMaterial({ - * color: 0x00ff00 - * }); - * const cube = new THREE.Mesh(geometry, material); - * scene.add(cube); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/geometries/BoxGeometry | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/BoxGeometry.js | Source} - */ -export class BoxGeometry extends BufferGeometry { - /** - * Create a new instance of {@link BoxGeometry} - * @param width Width; that is, the length of the edges parallel to the X axis. Optional; Expects a `Float`. Default `1` - * @param height Height; that is, the length of the edges parallel to the Y axis. Optional; Expects a `Float`. Default `1` - * @param depth Depth; that is, the length of the edges parallel to the Z axis. Optional; Expects a `Float`. Default `1` - * @param widthSegments Number of segmented rectangular faces along the width of the sides. Optional; Expects a `Integer`. Default `1` - * @param heightSegments Number of segmented rectangular faces along the height of the sides. Optional; Expects a `Integer`. Default `1` - * @param depthSegments Number of segmented rectangular faces along the depth of the sides. Optional; Expects a `Integer`. Default `1` - */ - constructor( - width?: number, - height?: number, - depth?: number, - widthSegments?: number, - heightSegments?: number, - depthSegments?: number, - ); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `BoxGeometry` - */ - override readonly type: string | "BoxGeometry"; - - /** - * An object with a property for each of the constructor parameters. - * @remarks Any modification after instantiation does not change the geometry. - */ - readonly parameters: { - readonly width: number; - readonly height: number; - readonly depth: number; - readonly widthSegments: number; - readonly heightSegments: number; - readonly depthSegments: number; - }; - - /** @internal */ - static fromJSON(data: {}): BoxGeometry; -} diff --git a/src-testing/src/geometries/CapsuleGeometry.d.ts b/src-testing/src/geometries/CapsuleGeometry.d.ts deleted file mode 100644 index b20616035..000000000 --- a/src-testing/src/geometries/CapsuleGeometry.d.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { BufferGeometry } from "../core/BufferGeometry.js"; - -/** - * {@link CapsuleGeometry} is a geometry class for a capsule with given radii and height - * @remarks It is constructed using a lathe. - * @example - * ```typescript - * const geometry = new THREE.CapsuleGeometry(1, 1, 4, 8); - * const material = new THREE.MeshBasicMaterial({ - * color: 0x00ff00 - * }); - * const capsule = new THREE.Mesh(geometry, material); - * scene.add(capsule); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/geometries/CapsuleGeometry | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/CapsuleGeometry.js | Source} - */ -export class CapsuleGeometry extends BufferGeometry { - /** - * Create a new instance of {@link CapsuleGeometry} - * @param radius Radius of the capsule. Expects a `Float`. Default `1` - * @param length Length of the middle section. Expects a `Float`. Default `1` - * @param capSegments Number of curve segments used to build the caps. Expects a `Integer`. Default `4` - * @param radialSegments Number of segmented faces around the circumference of the capsule. Expects a `Integer`. Default `8` - */ - constructor(radius?: number, length?: number, capSegments?: number, radialSegments?: number); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `CapsuleGeometry` - */ - override readonly type: string | "CapsuleGeometry"; - - /** - * An object with a property for each of the constructor parameters. - * @remarks Any modification after instantiation does not change the geometry. - */ - readonly parameters: { - readonly radius: number; - readonly length: number; - readonly capSegments: number; - readonly radialSegments: number; - }; - - /** @internal */ - static fromJSON(data: {}): CapsuleGeometry; -} diff --git a/src-testing/src/geometries/CircleGeometry.d.ts b/src-testing/src/geometries/CircleGeometry.d.ts deleted file mode 100644 index b512e4866..000000000 --- a/src-testing/src/geometries/CircleGeometry.d.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { BufferGeometry } from "../core/BufferGeometry.js"; - -/** - * {@link CircleGeometry} is a simple shape of Euclidean geometry - * @remarks - * It is constructed from a number of triangular segments that are oriented around a central point and extend as far out as a given radius - * It is built counter-clockwise from a start angle and a given central angle - * It can also be used to create regular polygons, where the number of segments determines the number of sides. - * @example - * ```typescript - * const geometry = new THREE.CircleGeometry(5, 32); - * const material = new THREE.MeshBasicMaterial({ - * color: 0xffff00 - * }); - * const circle = new THREE.Mesh(geometry, material); - * scene.add(circle); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/geometries/CircleGeometry | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/CircleGeometry.js | Source} - */ -export class CircleGeometry extends BufferGeometry { - /** - * Create a new instance of {@link CircleGeometry} - * @param radius Radius of the circle. Expects a `Float`. Default `1` - * @param segments Number of segments (triangles). Expects a `Integer`. Minimum `3`. Default `32` - * @param thetaStart Start angle for first segment. Expects a `Float`. Default `0`, _(three o'clock position)_. - * @param thetaLength The central angle, often called theta, of the circular sector. Expects a `Float`. Default `Math.PI * 2`, _which makes for a complete circle_. - */ - constructor(radius?: number, segments?: number, thetaStart?: number, thetaLength?: number); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `CircleGeometry` - */ - override readonly type: string | "CircleGeometry"; - - /** - * An object with a property for each of the constructor parameters. - * @remarks Any modification after instantiation does not change the geometry. - */ - readonly parameters: { - readonly radius: number; - readonly segments: number; - readonly thetaStart: number; - readonly thetaLength: number; - }; - - /** @internal */ - static fromJSON(data: {}): CircleGeometry; -} diff --git a/src-testing/src/geometries/ConeGeometry.d.ts b/src-testing/src/geometries/ConeGeometry.d.ts deleted file mode 100644 index 683376429..000000000 --- a/src-testing/src/geometries/ConeGeometry.d.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { CylinderGeometry } from "./CylinderGeometry.js"; - -/** - * A class for generating cone geometries. - * @example - * ```typescript - * const geometry = new THREE.ConeGeometry(5, 20, 32); - * const material = new THREE.MeshBasicMaterial({ - * color: 0xffff00 - * }); - * const cone = new THREE.Mesh(geometry, material); - * scene.add(cone); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/geometries/ConeGeometry | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/ConeGeometry.js | Source} - */ -export class ConeGeometry extends CylinderGeometry { - /** - * Create a new instance of {@link ConeGeometry} - * @param radius Radius of the cone base. Expects a `Float`. Default `1` - * @param height Height of the cone. Expects a `Float`. Default `1` - * @param radialSegments Number of segmented faces around the circumference of the cone. Expects a `Integer`. Default `32` - * @param heightSegments Number of rows of faces along the height of the cone. Expects a `Integer`. Default `1` - * @param openEnded A Boolean indicating whether the base of the cone is open or capped. Default `false`, _meaning capped_. - * @param thetaStart Start angle for first segment. Expects a `Float`. Default `0`, _(three o'clock position)_. - * @param thetaLength The central angle, often called theta, of the circular sector. Expects a `Float`. Default `Math.PI * 2`, _which makes for a complete cone_. - */ - constructor( - radius?: number, - height?: number, - radialSegments?: number, - heightSegments?: number, - openEnded?: boolean, - thetaStart?: number, - thetaLength?: number, - ); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `ConeGeometry` - */ - override readonly type: string | "ConeGeometry"; - - /** - * An object with a property for each of the constructor parameters. - * @remarks {@link radiusTop} and {@link radiusBottom} are from base {@link THREE.CylinderGeometry} class. - * @remarks Any modification after instantiation does not change the geometry. - */ - override readonly parameters: { - readonly radius: number; - readonly radiusTop: number; - readonly radiusBottom: number; - readonly height: number; - readonly radialSegments: number; - readonly heightSegments: number; - readonly openEnded: boolean; - readonly thetaStart: number; - readonly thetaLength: number; - }; - - /** @internal */ - static fromJSON(data: {}): ConeGeometry; -} diff --git a/src-testing/src/geometries/CylinderGeometry.d.ts b/src-testing/src/geometries/CylinderGeometry.d.ts deleted file mode 100644 index 90f1b06f3..000000000 --- a/src-testing/src/geometries/CylinderGeometry.d.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { BufferGeometry } from "../core/BufferGeometry.js"; - -/** - * A class for generating cylinder geometries. - * @example - * ```typescript - * const geometry = new THREE.CylinderGeometry(5, 5, 20, 32); - * const material = new THREE.MeshBasicMaterial({ - * color: 0xffff00 - * }); - * const cylinder = new THREE.Mesh(geometry, material); - * scene.add(cylinder); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/geometries/CylinderGeometry | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/CylinderGeometry.js | Source} - */ -export class CylinderGeometry extends BufferGeometry { - /** - * Create a new instance of {@link CylinderGeometry} - * @param radiusTop Radius of the cylinder at the top. Default `1` - * @param radiusBottom Radius of the cylinder at the bottom. Default `1` - * @param height Height of the cylinder. Default `1` - * @param radialSegments Number of segmented faces around the circumference of the cylinder. Default `32` - * @param heightSegments Number of rows of faces along the height of the cylinder. Expects a `Integer`. Default `1` - * @param openEnded A Boolean indicating whether the ends of the cylinder are open or capped. Default `false`, _meaning capped_. - * @param thetaStart Start angle for first segment. Default `0`, _(three o'clock position)_. - * @param thetaLength The central angle, often called theta, of the circular sector. Default `Math.PI * 2`, _which makes for a complete cylinder. - */ - constructor( - radiusTop?: number, - radiusBottom?: number, - height?: number, - radialSegments?: number, - heightSegments?: number, - openEnded?: boolean, - thetaStart?: number, - thetaLength?: number, - ); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `CylinderGeometry` - */ - override readonly type: string | "CylinderGeometry"; - - /** - * An object with a property for each of the constructor parameters. - * @remarks Any modification after instantiation does not change the geometry. - */ - readonly parameters: { - readonly radiusTop: number; - readonly radiusBottom: number; - readonly height: number; - readonly radialSegments: number; - readonly heightSegments: number; - readonly openEnded: boolean; - readonly thetaStart: number; - readonly thetaLength: number; - }; - - /** @internal */ - static fromJSON(data: any): CylinderGeometry; -} diff --git a/src-testing/src/geometries/DodecahedronGeometry.d.ts b/src-testing/src/geometries/DodecahedronGeometry.d.ts deleted file mode 100644 index e79e5a895..000000000 --- a/src-testing/src/geometries/DodecahedronGeometry.d.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { PolyhedronGeometry } from "./PolyhedronGeometry.js"; - -/** - * A class for generating a dodecahedron geometries. - * @see {@link https://threejs.org/docs/index.html#api/en/geometries/DodecahedronGeometry | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/DodecahedronGeometry.js | Source} - */ -export class DodecahedronGeometry extends PolyhedronGeometry { - /** - * Create a new instance of {@link DodecahedronGeometry} - * @param radius Radius of the dodecahedron. Expects a `Float`. Default `1` - * @param detail Setting this to a value greater than 0 adds vertices making it no longer a dodecahedron. Expects a `Integer`. Default `0` - */ - constructor(radius?: number, detail?: number); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `DodecahedronGeometry` - */ - override readonly type: string | "DodecahedronGeometry"; - - /** @internal */ - static fromJSON(data: {}): DodecahedronGeometry; -} diff --git a/src-testing/src/geometries/EdgesGeometry.d.ts b/src-testing/src/geometries/EdgesGeometry.d.ts deleted file mode 100644 index b901b10d7..000000000 --- a/src-testing/src/geometries/EdgesGeometry.d.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { BufferGeometry } from "../core/BufferGeometry.js"; - -/** - * This can be used as a helper object to view the edges of a {@link THREE.BufferGeometry | geometry}. - * @example - * ```typescript - * const geometry = new THREE.BoxGeometry(100, 100, 100); - * const edges = new THREE.EdgesGeometry(geometry); - * const line = new THREE.LineSegments(edges, new THREE.LineBasicMaterial({ - * color: 0xffffff - * })); - * scene.add(line); - * ``` - * @see Example: {@link https://threejs.org/examples/#webgl_helpers | helpers} - * @see {@link https://threejs.org/docs/index.html#api/en/geometries/EdgesGeometry | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/EdgesGeometry.js | Source} - */ -export class EdgesGeometry extends BufferGeometry { - /** - * Create a new instance of {@link EdgesGeometry} - * @param geometry Any geometry object. Default `null`. - * @param thresholdAngle An edge is only rendered if the angle (in degrees) between the face normals of the adjoining faces exceeds this value. Expects a `Integer`. Default `1` _degree_. - */ - constructor(geometry?: TBufferGeometry | null, thresholdAngle?: number); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `EdgesGeometry` - */ - override readonly type: string | "EdgesGeometry"; - - /** - * An object with a property for each of the constructor parameters. - * @remarks Any modification after instantiation does not change the geometry. - */ - readonly parameters: { - readonly geometry: TBufferGeometry | null; - readonly thresholdAngle: number; - }; -} diff --git a/src-testing/src/geometries/ExtrudeGeometry.d.ts b/src-testing/src/geometries/ExtrudeGeometry.d.ts deleted file mode 100644 index d872b7c21..000000000 --- a/src-testing/src/geometries/ExtrudeGeometry.d.ts +++ /dev/null @@ -1,152 +0,0 @@ -import { BufferGeometry } from "../core/BufferGeometry.js"; -import { Curve } from "../extras/core/Curve.js"; -import { Shape } from "../extras/core/Shape.js"; -import { Vector2 } from "../math/Vector2.js"; -import { Vector3 } from "../math/Vector3.js"; - -export interface ExtrudeGeometryOptions { - /** - * Number of points on the curves. - * Expects a `Integer`. - * @defaultValue `12` - */ - curveSegments?: number | undefined; - - /** - * Number of points used for subdividing segments along the depth of the extruded spline. - * @defaultValue `1` - */ - steps?: number | undefined; - - /** - * Depth to extrude the shape. - * @defaultValue `1` - */ - depth?: number | undefined; - - /** - * Turn on bevel. Applying beveling to the shape. - * @defaultValue `true` - */ - bevelEnabled?: boolean | undefined; - - /** - * How deep into the original shape the bevel goes. - * Expects a `Float`. - * @defaultValue `0.2` - */ - bevelThickness?: number | undefined; - - /** - * Distance from the shape outline that the bevel extends - * Expects a `Float`. - * @defaultValue `bevelThickness - 0.1` - */ - bevelSize?: number | undefined; - - /** - * Distance from the shape outline that the bevel starts. - * Expects a `Float`. - * @defaultValue `0` - */ - bevelOffset?: number | undefined; - - /** - * Number of bevel layers/segments. - * Expects a `Integer`. - * @defaultValue `3` - */ - bevelSegments?: number | undefined; - - /** - * A 3D spline path along which the shape should be extruded. - * @remarks Bevels not supported for path extrusion. - */ - extrudePath?: Curve | undefined; - - /** - * A object that provides UV generator functions. - */ - UVGenerator?: UVGenerator | undefined; -} - -export interface UVGenerator { - generateTopUV( - geometry: ExtrudeGeometry, - vertices: number[], - indexA: number, - indexB: number, - indexC: number, - ): Vector2[]; - generateSideWallUV( - geometry: ExtrudeGeometry, - vertices: number[], - indexA: number, - indexB: number, - indexC: number, - indexD: number, - ): Vector2[]; -} - -/** - * Creates extruded geometry from a path shape. - * @remarks This object extrudes a 2D shape to a 3D geometry. - * @remarks When creating a Mesh with this geometry, if you'd like to have a separate material used for its face and its extruded sides, you can use an array of materials - * @remarks The first material will be applied to the face; the second material will be applied to the sides. - * @example - * ```typescript - * const length = 12, width = 8; - * const shape = new THREE.Shape(); - * shape.moveTo(0, 0); - * shape.lineTo(0, width); - * shape.lineTo(length, width); - * shape.lineTo(length, 0); - * shape.lineTo(0, 0); - * const extrudeSettings = { - * steps: 2, - * depth: 16, - * bevelEnabled: true, - * bevelThickness: 1, - * bevelSize: 1, - * bevelOffset: 0, - * bevelSegments: 1 - * }; - * const geometry = new THREE.ExtrudeGeometry(shape, extrudeSettings); - * const material = new THREE.MeshBasicMaterial({ - * color: 0x00ff00 - * }); - * const mesh = new THREE.Mesh(geometry, material); - * scene.add(mesh); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/geometries/ExtrudeGeometry | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/ExtrudeGeometry.js | Source} - */ -export class ExtrudeGeometry extends BufferGeometry { - /** - * Create a new instance of {@link ExtrudeGeometry} - * @param shapes Shape or an array of shapes. Default `new Shape([new Vector2(0.5, 0.5), new Vector2(-0.5, 0.5), new Vector2(-0.5, -0.5), new Vector2(0.5, -0.5)])`. - * @param options Object that can contain the following parameters. @see {@link ExtrudeGeometryOptions} for defaults. - */ - constructor(shapes?: Shape | Shape[], options?: ExtrudeGeometryOptions); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `ExtrudeGeometry` - */ - override readonly type: string | "ExtrudeGeometry"; - - /** - * An object with a property for each of the constructor parameters. - * @remarks Any modification after instantiation does not change the geometry. - */ - readonly parameters: { - readonly shapes: Shape | Shape[]; - readonly options: ExtrudeGeometryOptions; - }; - - addShape(shape: Shape): void; - - /** @internal */ - static fromJSON(data: {}, shapes: unknown): ExtrudeGeometry; -} diff --git a/src-testing/src/geometries/Geometries.d.ts b/src-testing/src/geometries/Geometries.d.ts deleted file mode 100644 index b1be46c46..000000000 --- a/src-testing/src/geometries/Geometries.d.ts +++ /dev/null @@ -1,21 +0,0 @@ -export * from "./BoxGeometry.js"; -export * from "./CapsuleGeometry.js"; -export * from "./CircleGeometry.js"; -export * from "./ConeGeometry.js"; -export * from "./CylinderGeometry.js"; -export * from "./DodecahedronGeometry.js"; -export * from "./EdgesGeometry.js"; -export * from "./ExtrudeGeometry.js"; -export * from "./IcosahedronGeometry.js"; -export * from "./LatheGeometry.js"; -export * from "./OctahedronGeometry.js"; -export * from "./PlaneGeometry.js"; -export * from "./PolyhedronGeometry.js"; -export * from "./RingGeometry.js"; -export * from "./ShapeGeometry.js"; -export * from "./SphereGeometry.js"; -export * from "./TetrahedronGeometry.js"; -export * from "./TorusGeometry.js"; -export * from "./TorusKnotGeometry.js"; -export * from "./TubeGeometry.js"; -export * from "./WireframeGeometry.js"; diff --git a/src-testing/src/geometries/IcosahedronGeometry.d.ts b/src-testing/src/geometries/IcosahedronGeometry.d.ts deleted file mode 100644 index 4c05b54de..000000000 --- a/src-testing/src/geometries/IcosahedronGeometry.d.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { PolyhedronGeometry } from "./PolyhedronGeometry.js"; - -/** - * A class for generating an icosahedron geometry. - * @see {@link https://threejs.org/docs/index.html#api/en/geometries/IcosahedronGeometry | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/IcosahedronGeometry.js | Source} - */ -export class IcosahedronGeometry extends PolyhedronGeometry { - /** - * Create a new instance of {@link IcosahedronGeometry} - * @param radius Expects a `Float`. Default `1` - * @param detail Setting this to a value greater than 0 adds more vertices making it no longer an icosahedron. - * When detail is greater than 1, it's effectively a sphere. Expects a `Integer`. Default `0` - */ - constructor(radius?: number, detail?: number); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `IcosahedronGeometry` - */ - override readonly type: string | "IcosahedronGeometry"; - - /** @internal */ - static fromJSON(data: {}): IcosahedronGeometry; -} diff --git a/src-testing/src/geometries/LatheGeometry.d.ts b/src-testing/src/geometries/LatheGeometry.d.ts deleted file mode 100644 index f4194e514..000000000 --- a/src-testing/src/geometries/LatheGeometry.d.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { BufferGeometry } from "../core/BufferGeometry.js"; -import { Vector2 } from "../math/Vector2.js"; - -/** - * Creates meshes with axial symmetry like vases - * @remarks - * The lathe rotates around the Y axis. - * @example - * ```typescript - * const points = []; - * for (let i = 0; i & lt; 10; i++) { - * points.push(new THREE.Vector2(Math.sin(i * 0.2) * 10 + 5, (i - 5) * 2)); - * } - * const geometry = new THREE.LatheGeometry(points); - * const material = new THREE.MeshBasicMaterial({ - * color: 0xffff00 - * }); - * const lathe = new THREE.Mesh(geometry, material); - * scene.add(lathe); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/geometries/LatheGeometry | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/LatheGeometry.js | Source} - */ -export class LatheGeometry extends BufferGeometry { - /** - * This creates a {@link LatheGeometry} based on the parameters. - * @param points Array of Vector2s. The x-coordinate of each point must be greater than zero. - * Default `[new Vector2(0, -0.5), new Vector2(0.5, 0), new Vector2(0, 0.5)]` _which creates a simple diamond shape_. - * @param segments The number of circumference segments to generate. Expects a `Integer`. Default `12`. - * @param phiStart The starting angle in radians. Expects a `Float`. Default `0`. - * @param phiLength The radian (0 to 2*PI) range of the lathed section 2*PI is a closed lathe, less than 2PI is a portion. Expects a `Float`. Default `Math.PI * 2`. - */ - constructor(points?: Vector2[], segments?: number, phiStart?: number, phiLength?: number); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `LatheGeometry` - */ - override readonly type: string | "LatheGeometry"; - - /** - * An object with a property for each of the constructor parameters. - * @remarks Any modification after instantiation does not change the geometry. - */ - readonly parameters: { - readonly points: Vector2[]; - readonly segments: number; - readonly phiStart: number; - readonly phiLength: number; - }; - - /** @internal */ - static fromJSON(data: {}): LatheGeometry; -} diff --git a/src-testing/src/geometries/OctahedronGeometry.d.ts b/src-testing/src/geometries/OctahedronGeometry.d.ts deleted file mode 100644 index 09ba0b1e7..000000000 --- a/src-testing/src/geometries/OctahedronGeometry.d.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { PolyhedronGeometry } from "./PolyhedronGeometry.js"; - -/** - * A class for generating an octahedron geometry. - * @see {@link https://threejs.org/docs/index.html#api/en/geometries/OctahedronGeometry | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/OctahedronGeometry.js | Source} - */ -export class OctahedronGeometry extends PolyhedronGeometry { - /** - * Create a new instance of {@link OctahedronGeometry} - * @param radius Radius of the octahedron. Expects a `Float`. Default `1` - * @param detail Setting this to a value greater than zero add vertices making it no longer an octahedron. Expects a `Integer`. Default `0` - */ - constructor(radius?: number, detail?: number); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `OctahedronGeometry` - */ - override readonly type: string | "OctahedronGeometry"; - - /** @internal */ - static fromJSON(data: {}): OctahedronGeometry; -} diff --git a/src-testing/src/geometries/PlaneGeometry.d.ts b/src-testing/src/geometries/PlaneGeometry.d.ts deleted file mode 100644 index fda5f4908..000000000 --- a/src-testing/src/geometries/PlaneGeometry.d.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { BufferGeometry } from "../core/BufferGeometry.js"; - -/** - * A class for generating plane geometries. - * @example - * ```typescript - * const geometry = new THREE.PlaneGeometry(1, 1); - * const material = new THREE.MeshBasicMaterial({ - * color: 0xffff00, - * side: THREE.DoubleSide - * }); - * const plane = new THREE.Mesh(geometry, material); - * scene.add(plane); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/geometries/PlaneGeometry | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/PlaneGeometry.js | Source} - */ -export class PlaneGeometry extends BufferGeometry { - /** - * Create a new instance of {@link PlaneGeometry} - * @param width Width along the X axis. Expects a `Float`. Default `1` - * @param height Height along the Y axis. Expects a `Float`. Default `1` - * @param widthSegments Number of segmented faces along the width of the sides. Expects a `Integer`. Default `1` - * @param heightSegments Number of segmented faces along the height of the sides. Expects a `Integer`. Default `1` - */ - constructor(width?: number, height?: number, widthSegments?: number, heightSegments?: number); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `PlaneGeometry` - */ - override readonly type: string | "PlaneGeometry"; - - /** - * An object with a property for each of the constructor parameters. - * @remarks Any modification after instantiation does not change the geometry. - */ - readonly parameters: { - readonly width: number; - readonly height: number; - readonly widthSegments: number; - readonly heightSegments: number; - }; - - /** @internal */ - static fromJSON(data: {}): PlaneGeometry; -} diff --git a/src-testing/src/geometries/PolyhedronGeometry.d.ts b/src-testing/src/geometries/PolyhedronGeometry.d.ts deleted file mode 100644 index f4c07772b..000000000 --- a/src-testing/src/geometries/PolyhedronGeometry.d.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { BufferGeometry } from "../core/BufferGeometry.js"; - -/** - * A polyhedron is a solid in three dimensions with flat faces - * @remarks - * This class will take an array of vertices, project them onto a sphere, and then divide them up to the desired level of detail - * This class is used by {@link THREE.DodecahedronGeometry | DodecahedronGeometry}, {@link THREE.IcosahedronGeometry | IcosahedronGeometry}, - * {@link THREE.OctahedronGeometry | OctahedronGeometry}, and {@link THREE.TetrahedronGeometry | TetrahedronGeometry} to generate their respective geometries. - * @example - * ```typescript - * const verticesOfCube = [-1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, ]; - * const indicesOfFaces = [ - * 2, 1, 0, 0, 3, 2, - * 0, 4, 7, 7, 3, 0, - * 0, 1, 5, 5, 4, 0, - * 1, 2, 6, 6, 5, 1, - * 2, 3, 7, 7, 6, 2, - * 4, 5, 6, 6, 7, 4]; - * const geometry = new THREE.PolyhedronGeometry(verticesOfCube, indicesOfFaces, 6, 2); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/geometries/PolyhedronGeometry | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/PolyhedronGeometry.js | Source} - */ -export class PolyhedronGeometry extends BufferGeometry { - /** - * Create a new instance of {@link PolyhedronGeometry} - * @param vertices Array of points of the form [1,1,1, -1,-1,-1, ... ]. Default `[]`. - * @param indices Array of indices that make up the faces of the form [0,1,2, 2,3,0, ... ]. Default `[]`. - * @param radius [page:The radius of the final shape Expects a `Float`. Default `1` - * @param detail [page:How many levels to subdivide the geometry. The more detail, the smoother the shape. Expects a `Integer`. Default `0` - */ - constructor(vertices?: number[], indices?: number[], radius?: number, detail?: number); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `PolyhedronGeometry` - */ - override readonly type: string | "PolyhedronGeometry"; - - /** - * An object with a property for each of the constructor parameters. - * @remarks Any modification after instantiation does not change the geometry. - */ - readonly parameters: { - readonly vertices: number[]; - readonly indices: number[]; - readonly radius: number; - readonly detail: number; - }; - - /** @internal */ - static fromJSON(data: {}): PolyhedronGeometry; -} diff --git a/src-testing/src/geometries/RingGeometry.d.ts b/src-testing/src/geometries/RingGeometry.d.ts deleted file mode 100644 index 2cbc63ef4..000000000 --- a/src-testing/src/geometries/RingGeometry.d.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { BufferGeometry } from "../core/BufferGeometry.js"; - -/** - * A class for generating a two-dimensional ring geometry. - * @example - * ```typescript - * const geometry = new THREE.RingGeometry(1, 5, 32); - * const material = new THREE.MeshBasicMaterial({ - * color: 0xffff00, - * side: THREE.DoubleSide - * }); - * const mesh = new THREE.Mesh(geometry, material); - * scene.add(mesh); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/geometries/RingGeometry | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/RingGeometry.js | Source} - */ -export class RingGeometry extends BufferGeometry { - /** - * Create a new instance of {@link RingGeometry} - * @param innerRadius Expects a `Float`. Default `0.5`. - * @param outerRadius Expects a `Float`. Default `1`. - * @param thetaSegments Number of segments. A higher number means the ring will be more round. Minimum is 3. Expects a `Integer`. Default `32`. - * @param phiSegments Number of segments per ring segment. Minimum is `1`. Expects a `Integer`. Default `1`. - * @param thetaStart Starting angle. Expects a `Float`. Default `0`. - * @param thetaLength Central angle. Expects a `Float`. Default `Math.PI * 2`. - */ - constructor( - innerRadius?: number, - outerRadius?: number, - thetaSegments?: number, - phiSegments?: number, - thetaStart?: number, - thetaLength?: number, - ); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `RingGeometry` - */ - override readonly type: string | "RingGeometry"; - - /** - * An object with a property for each of the constructor parameters. - * @remarks Any modification after instantiation does not change the geometry. - */ - readonly parameters: { - readonly innerRadius: number; - readonly outerRadius: number; - readonly thetaSegments: number; - readonly phiSegments: number; - readonly thetaStart: number; - readonly thetaLength: number; - }; - - /** @internal */ - static fromJSON(data: {}): RingGeometry; -} diff --git a/src-testing/src/geometries/ShapeGeometry.d.ts b/src-testing/src/geometries/ShapeGeometry.d.ts deleted file mode 100644 index a3089a645..000000000 --- a/src-testing/src/geometries/ShapeGeometry.d.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { BufferGeometry } from "../core/BufferGeometry.js"; -import { Shape } from "../extras/core/Shape.js"; - -/** - * Creates an one-sided polygonal geometry from one or more path shapes. - * @example - * ```typescript - * const x = 0, y = 0; - * const heartShape = new THREE.Shape(); - * heartShape.moveTo(x + 5, y + 5); - * heartShape.bezierCurveTo(x + 5, y + 5, x + 4, y, x, y); - * heartShape.bezierCurveTo(x - 6, y, x - 6, y + 7, x - 6, y + 7); - * heartShape.bezierCurveTo(x - 6, y + 11, x - 3, y + 15.4, x + 5, y + 19); - * heartShape.bezierCurveTo(x + 12, y + 15.4, x + 16, y + 11, x + 16, y + 7); - * heartShape.bezierCurveTo(x + 16, y + 7, x + 16, y, x + 10, y); - * heartShape.bezierCurveTo(x + 7, y, x + 5, y + 5, x + 5, y + 5); - * const geometry = new THREE.ShapeGeometry(heartShape); - * const material = new THREE.MeshBasicMaterial({ - * color: 0x00ff00 - * }); - * const mesh = new THREE.Mesh(geometry, material); - * scene.add(mesh); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/geometries/ShapeGeometry | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/ShapeGeometry.js | Source} - */ -export class ShapeGeometry extends BufferGeometry { - /** - * Create a new instance of {@link ShapeGeometry} - * @param shapes Array of shapes or a single {@link THREE.Shape | Shape}. Default `new Shape([new Vector2(0, 0.5), new Vector2(-0.5, -0.5), new Vector2(0.5, -0.5)])`, _a single triangle shape_. - * @param curveSegments Number of segments per shape. Expects a `Integer`. Default `12` - */ - constructor(shapes?: Shape | Shape[], curveSegments?: number); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `ShapeGeometry` - */ - override readonly type: string | "ShapeGeometry"; - - /** - * An object with a property for each of the constructor parameters. - * @remarks Any modification after instantiation does not change the geometry. - */ - readonly parameters: { - readonly shapes: Shape | Shape[]; - readonly curveSegments: number; - }; - - /** @internal */ - static fromJSON(data: {}): ShapeGeometry; -} diff --git a/src-testing/src/geometries/SphereGeometry.d.ts b/src-testing/src/geometries/SphereGeometry.d.ts deleted file mode 100644 index b597bb26c..000000000 --- a/src-testing/src/geometries/SphereGeometry.d.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { BufferGeometry } from "../core/BufferGeometry.js"; - -/** - * A class for generating sphere geometries. - * @example - * ```typescript - * const geometry = new THREE.SphereGeometry(15, 32, 16); - * const material = new THREE.MeshBasicMaterial({ - * color: 0xffff00 - * }); - * const sphere = new THREE.Mesh(geometry, material); - * scene.add(sphere); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/geometries/SphereGeometry | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/SphereGeometry.js | Source} - */ -export class SphereGeometry extends BufferGeometry { - /** - * Create a new instance of {@link SphereGeometry} - * @remarks - * The geometry is created by sweeping and calculating vertexes - * around the **Y** axis (horizontal sweep) and the **Z** axis (vertical sweep) - * Thus, incomplete spheres (akin to `'sphere slices'`) can be created - * through the use of different values of {@link phiStart}, {@link phiLength}, {@link thetaStart} and {@link thetaLength}, - * in order to define the points in which we start (or end) calculating those vertices. - * @param radius Sphere radius. Expects a `Float`. Default `1` - * @param widthSegments Number of horizontal segments. Minimum value is 3, and the Expects a `Integer`. Default `32` - * @param heightSegments Number of vertical segments. Minimum value is 2, and the Expects a `Integer`. Default `16` - * @param phiStart Specify horizontal starting angle. Expects a `Float`. Default `0` - * @param phiLength Specify horizontal sweep angle size. Expects a `Float`. Default `Math.PI * 2` - * @param thetaStart Specify vertical starting angle. Expects a `Float`. Default `0` - * @param thetaLength Specify vertical sweep angle size. Expects a `Float`. Default `Math.PI` - */ - constructor( - radius?: number, - widthSegments?: number, - heightSegments?: number, - phiStart?: number, - phiLength?: number, - thetaStart?: number, - thetaLength?: number, - ); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `SphereGeometry` - */ - override readonly type: string | "SphereGeometry"; - - /** - * An object with a property for each of the constructor parameters. - * @remarks Any modification after instantiation does not change the geometry. - */ - readonly parameters: { - readonly radius: number; - readonly widthSegments: number; - readonly heightSegments: number; - readonly phiStart: number; - readonly phiLength: number; - readonly thetaStart: number; - readonly thetaLength: number; - }; - - /** @internal */ - static fromJSON(data: {}): SphereGeometry; -} diff --git a/src-testing/src/geometries/TetrahedronGeometry.d.ts b/src-testing/src/geometries/TetrahedronGeometry.d.ts deleted file mode 100644 index 2dd0fe5b6..000000000 --- a/src-testing/src/geometries/TetrahedronGeometry.d.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { PolyhedronGeometry } from "./PolyhedronGeometry.js"; - -/** - * A class for generating a tetrahedron geometries. - * @see {@link https://threejs.org/docs/index.html#api/en/geometries/TetrahedronGeometry | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/TetrahedronGeometry.js | Source} - */ -export class TetrahedronGeometry extends PolyhedronGeometry { - /** - * Create a new instance of {@link TetrahedronGeometry} - * @param radius Radius of the tetrahedron. Expects a `Float`. Default `1` - * @param detail Setting this to a value greater than 0 adds vertices making it no longer a tetrahedron. Expects a `Integer`. Default `0` - */ - constructor(radius?: number, detail?: number); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `TetrahedronGeometry` - */ - override readonly type: string | "TetrahedronGeometry"; - - /** @internal */ - static fromJSON(data: {}): TetrahedronGeometry; -} diff --git a/src-testing/src/geometries/TorusGeometry.d.ts b/src-testing/src/geometries/TorusGeometry.d.ts deleted file mode 100644 index 47a70ceea..000000000 --- a/src-testing/src/geometries/TorusGeometry.d.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { BufferGeometry } from "../core/BufferGeometry.js"; - -/** - * A class for generating torus geometries. - * @example - * ```typescript - * const geometry = new THREE.TorusGeometry(10, 3, 16, 100); - * const material = new THREE.MeshBasicMaterial({ - * color: 0xffff00 - * }); - * const torus = new THREE.Mesh(geometry, material); - * scene.add(torus); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/geometries/TorusGeometry | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/TorusGeometry.js | Source} - */ -export class TorusGeometry extends BufferGeometry { - /** - * Create a new instance of {@link TorusGeometry} - * @param radius Radius of the torus, from the center of the torus to the center of the tube. Expects a `Float`. Default `1`. - * @param tube Radius of the tube. Expects a `Float`. Default `0.4`. - * @param radialSegments Expects a `Integer`.Default is `12`. - * @param tubularSegments Expects a `Integer`. Default `48`. - * @param arc Central angle. Expects a `Float`. Default `Math.PI * 2` - */ - constructor(radius?: number, tube?: number, radialSegments?: number, tubularSegments?: number, arc?: number); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `TorusGeometry` - */ - override readonly type: string | "TorusGeometry"; - - /** - * An object with a property for each of the constructor parameters. - * @remarks Any modification after instantiation does not change the geometry. - */ - readonly parameters: { - readonly radius: number; - readonly tube: number; - readonly radialSegments: number; - readonly tubularSegments: number; - readonly arc: number; - }; - - /** @internal */ - static fromJSON(data: any): TorusGeometry; -} diff --git a/src-testing/src/geometries/TorusKnotGeometry.d.ts b/src-testing/src/geometries/TorusKnotGeometry.d.ts deleted file mode 100644 index 103b6916e..000000000 --- a/src-testing/src/geometries/TorusKnotGeometry.d.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { BufferGeometry } from "../core/BufferGeometry.js"; - -/** - * Creates a torus knot, the particular shape of which is defined by a pair of coprime integers, p and q - * If p and q are not coprime, the result will be a torus link. - * @example - * ```typescript - * const geometry = new THREE.TorusKnotGeometry(10, 3, 100, 16); - * const material = new THREE.MeshBasicMaterial({ - * color: 0xffff00 - * }); - * const torusKnot = new THREE.Mesh(geometry, material); - * scene.add(torusKnot); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/geometries/TorusKnotGeometry | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/TorusKnotGeometry.js | Source} - */ -export class TorusKnotGeometry extends BufferGeometry { - /** - * Create a new instance of {@link TorusKnotGeometry} - * @param radius Radius of the torus.. Default `1`. - * @param tube Expects a `Float`. Default `0.4`. - * @param tubularSegments Expects a `Integer`. Default `64`. - * @param radialSegments Expects a `Integer`. Default `8`. - * @param p This value determines, how many times the geometry winds around its axis of rotational symmetry. Expects a `Integer`. Default `2`. - * @param q This value determines, how many times the geometry winds around a circle in the interior of the torus. Expects a `Integer`. Default `3`. - */ - constructor( - radius?: number, - tube?: number, - tubularSegments?: number, - radialSegments?: number, - p?: number, - q?: number, - ); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `TorusKnotGeometry` - */ - override readonly type: string | "TorusKnotGeometry"; - - /** - * An object with a property for each of the constructor parameters. - * @remarks Any modification after instantiation does not change the geometry. - */ - readonly parameters: { - readonly radius: number; - readonly tube: number; - readonly tubularSegments: number; - readonly radialSegments: number; - readonly p: number; - readonly q: number; - }; - - /** @internal */ - static fromJSON(data: {}): TorusKnotGeometry; -} diff --git a/src-testing/src/geometries/TubeGeometry.d.ts b/src-testing/src/geometries/TubeGeometry.d.ts deleted file mode 100644 index 37e7129ad..000000000 --- a/src-testing/src/geometries/TubeGeometry.d.ts +++ /dev/null @@ -1,86 +0,0 @@ -import { BufferGeometry } from "../core/BufferGeometry.js"; -import { Curve } from "../extras/core/Curve.js"; -import { Vector3 } from "../math/Vector3.js"; - -/** - * Creates a tube that extrudes along a 3d curve. - * @example - * ```typescript - * class CustomSinCurve extends THREE.Curve { - * constructor(scale = 1) { - * super(); - * this.scale = scale; - * } - * getPoint(t, optionalTarget = new THREE.Vector3()) { - * const tx = t * 3 - 1.5; - * const ty = Math.sin(2 * Math.PI * t); - * const tz = 0; - * return optionalTarget.set(tx, ty, tz).multiplyScalar(this.scale); - * } - * } - * const path = new CustomSinCurve(10); - * const geometry = new THREE.TubeGeometry(path, 20, 2, 8, false); - * const material = new THREE.MeshBasicMaterial({ - * color: 0x00ff00 - * }); - * const mesh = new THREE.Mesh(geometry, material); - * scene.add(mesh); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/geometries/TubeGeometry | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/TubeGeometry.js | Source} - */ -export class TubeGeometry extends BufferGeometry { - /** - * Create a new instance of {@link TubeGeometry} - * @param path A 3D path that inherits from the {@link THREE.Curve | Curve} base class. - * Default {@link THREE.QuadraticBezierCurve3 | new THREE.QuadraticBezierCurve3(new Vector3(-1, -1, 0 ), new Vector3(-1, 1, 0), new Vector3(1, 1, 0))}. - * @param tubularSegments The number of segments that make up the tube. Expects a `Integer`. Default `64`. - * @param radius The radius of the tube. Expects a `Float`. Default `1`. - * @param radialSegments The number of segments that make up the cross-section. Expects a `Integer`. Default `8`. - * @param closed Is the tube open or closed. Default `false`. - */ - constructor( - path?: Curve, - tubularSegments?: number, - radius?: number, - radialSegments?: number, - closed?: boolean, - ); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `TubeGeometry` - */ - override readonly type: string | "TubeGeometry"; - - /** - * An object with a property for each of the constructor parameters. - * @remarks Any modification after instantiation does not change the geometry. - */ - readonly parameters: { - readonly path: Curve; - readonly tubularSegments: number; - readonly radius: number; - readonly radialSegments: number; - readonly closed: boolean; - }; - - /** - * An array of {@link THREE.Vector3 | Vector3} tangents - */ - tangents: Vector3[]; - - /** - * An array of {@link THREE.Vector3 | Vector3} normals - */ - normals: Vector3[]; - - /** - * An array of {@link THREE.Vector3 | Vector3} binormals - */ - binormals: Vector3[]; - - /** @internal */ - static fromJSON(data: {}): TubeGeometry; -} diff --git a/src-testing/src/geometries/WireframeGeometry.d.ts b/src-testing/src/geometries/WireframeGeometry.d.ts deleted file mode 100644 index 6263316a6..000000000 --- a/src-testing/src/geometries/WireframeGeometry.d.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { BufferGeometry } from "../core/BufferGeometry.js"; - -/** - * This can be used as a helper object to view a {@link BufferGeometry | geometry} as a wireframe. - * @example - * ```typescript - * const geometry = new THREE.SphereGeometry(100, 100, 100); - * const wireframe = new THREE.WireframeGeometry(geometry); - * const line = new THREE.LineSegments(wireframe); - * line.material.depthTest = false; - * line.material.opacity = 0.25; - * line.material.transparent = true; - * scene.add(line); - * ``` - * @see Example: {@link https://threejs.org/examples/#webgl_helpers | helpers} - * @see {@link https://threejs.org/docs/index.html#api/en/geometries/WireframeGeometry | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/WireframeGeometry.js | Source} - */ -export class WireframeGeometry extends BufferGeometry { - /** - * Create a new instance of {@link WireframeGeometry} - * @param geometry Any geometry object. Default `null`. - */ - constructor(geometry?: TBufferGeometry); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `WireframeGeometry` - */ - override readonly type: string | "WireframeGeometry"; - - /** - * An object with a property for each of the constructor parameters. - * @remarks Any modification after instantiation does not change the geometry. - */ - readonly parameters: { - readonly geometry: TBufferGeometry; - }; -} diff --git a/src-testing/src/helpers/ArrowHelper.d.ts b/src-testing/src/helpers/ArrowHelper.d.ts deleted file mode 100644 index 94896123c..000000000 --- a/src-testing/src/helpers/ArrowHelper.d.ts +++ /dev/null @@ -1,93 +0,0 @@ -import { Object3D } from "../core/Object3D.js"; -import { ColorRepresentation } from "../math/Color.js"; -import { Vector3 } from "../math/Vector3.js"; -import { Line } from "../objects/Line.js"; -import { Mesh } from "../objects/Mesh.js"; - -/** - * An 3D arrow object for visualizing directions. - * @example - * ```typescript - * const dir = new THREE.Vector3(1, 2, 0); - * //normalize the direction vector (convert to vector of length 1) - * dir.normalize(); - * const origin = new THREE.Vector3(0, 0, 0); - * const length = 1; - * const hex = 0xffff00; - * const {@link ArrowHelper} = new THREE.ArrowHelper(dir, origin, length, hex); - * scene.add(arrowHelper); - * ``` - * @see Example: {@link https://threejs.org/examples/#webgl_shadowmesh | WebGL / shadowmesh} - * @see {@link https://threejs.org/docs/index.html#api/en/helpers/ArrowHelper | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/helpers/ArrowHelper.js | Source} - */ -export class ArrowHelper extends Object3D { - /** - * Create a new instance of {@link ArrowHelper} - * @param dir Direction from origin. Must be a unit vector. Default `new THREE.Vector3(0, 0, 1)` - * @param origin Point at which the arrow starts. Default `new THREE.Vector3(0, 0, 0)` - * @param length Length of the arrow. Default `1` - * @param hex Hexadecimal value to define color. Default `0xffff00` - * @param headLength The length of the head of the arrow. Default `0.2 * length` - * @param headWidth The width of the head of the arrow. Default `0.2 * headLength` - */ - constructor( - dir?: Vector3, - origin?: Vector3, - length?: number, - color?: ColorRepresentation, - headLength?: number, - headWidth?: number, - ); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @override - * @defaultValue `ArrowHelper` - */ - override readonly type: string | "ArrowHelper"; - - /** - * Contains the line part of the arrowHelper. - */ - line: Line; - - /** - * Contains the cone part of the arrowHelper. - */ - cone: Mesh; - - /** - * Sets the color of the arrowHelper. - * @param color The desired color. - */ - setColor(color: ColorRepresentation): void; - - /** - * @param dir The desired direction. Must be a unit vector. - */ - setDirection(dir: Vector3): void; - - /** - * Sets the length of the arrowhelper. - * @param length The desired length. - * @param headLength The length of the head of the arrow. Default `0.2 * length` - * @param headWidth The width of the head of the arrow. Default `0.2 * headLength` - */ - setLength(length: number, headLength?: number, headWidth?: number): void; - - /** - * Copy the given object into this object - * @remarks Note: event listeners and user-defined callbacks ({@link onAfterRender | .onAfterRender} and {@link onBeforeRender | .onBeforeRender}) are not copied. - * @param source - */ - override copy(source: this): this; - - /** - * Frees the GPU-related resources allocated by this instance - * @remarks - * Call this method whenever this instance is no longer used in your app. - */ - dispose(): void; -} diff --git a/src-testing/src/helpers/AxesHelper.d.ts b/src-testing/src/helpers/AxesHelper.d.ts deleted file mode 100644 index c0633c102..000000000 --- a/src-testing/src/helpers/AxesHelper.d.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { ColorRepresentation } from "../math/Color.js"; -import { LineSegments } from "../objects/LineSegments.js"; - -/** - * An axis object to visualize the 3 axes in a simple way. - * @remarks - * The X axis is red - * The Y axis is green - * The Z axis is blue. - * @example - * ```typescript - * const {@link AxesHelper} = new THREE.AxesHelper(5); - * scene.add(axesHelper); - * ``` - * @see Example: {@link https://threejs.org/examples/#webgl_buffergeometry_compression | WebGL / buffergeometry / compression} - * @see Example: {@link https://threejs.org/examples/#webgl_geometry_convex | WebGL / geometry / convex} - * @see Example: {@link https://threejs.org/examples/#webgl_loader_nrrd | WebGL / loader / nrrd} - * @see {@link https://threejs.org/docs/index.html#api/en/helpers/AxesHelper | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/helpers/AxesHelper.js | Source} - */ -export class AxesHelper extends LineSegments { - /** - * Create a new instance of {@link AxesHelper} - * @param size Size of the lines representing the axes. Default `1` - */ - constructor(size?: number); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @override - * @defaultValue `AxesHelper` - */ - override readonly type: string | "AxesHelper"; - - /** - * Sets the axes colors to {@link Color | xAxisColor}, {@link Color | yAxisColor}, {@link Color | zAxisColor}. - * @param xAxisColor - * @param yAxisColor - * @param zAxisColor - */ - setColors(xAxisColor: ColorRepresentation, yAxisColor: ColorRepresentation, zAxisColor: ColorRepresentation): this; - - /** - * Frees the GPU-related resources allocated by this instance - * @remarks - * Call this method whenever this instance is no longer used in your app. - */ - dispose(): void; -} diff --git a/src-testing/src/helpers/Box3Helper.d.ts b/src-testing/src/helpers/Box3Helper.d.ts deleted file mode 100644 index 78e1c6f82..000000000 --- a/src-testing/src/helpers/Box3Helper.d.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { Box3 } from "../math/Box3.js"; -import { ColorRepresentation } from "../math/Color.js"; -import { LineSegments } from "../objects/LineSegments.js"; - -/** - * Helper object to visualize a {@link THREE.Box3 | Box3}. - * @example - * ```typescript - * const box = new THREE.Box3(); - * box.setFromCenterAndSize(new THREE.Vector3(1, 1, 1), new THREE.Vector3(2, 1, 3)); - * const helper = new THREE.Box3Helper(box, 0xffff00); - * scene.add(helper); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/helpers/Box3Helper | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/helpers/Box3Helper.js | Source} - */ -export class Box3Helper extends LineSegments { - /** - * Creates a new wireframe box that represents the passed Box3. - * @param box The Box3 to show. - * @param color The box's color. Default `0xffff00` - */ - constructor(box: Box3, color?: ColorRepresentation); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @override - * @defaultValue `Box3Helper` - */ - override readonly type: string | "Box3Helper"; - - /** - * The Box3 being visualized. - */ - box: Box3; - - /** - * Frees the GPU-related resources allocated by this instance - * @remarks - * Call this method whenever this instance is no longer used in your app. - */ - dispose(): void; -} diff --git a/src-testing/src/helpers/BoxHelper.d.ts b/src-testing/src/helpers/BoxHelper.d.ts deleted file mode 100644 index d049a5b72..000000000 --- a/src-testing/src/helpers/BoxHelper.d.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { BufferGeometry } from "../core/BufferGeometry.js"; -import { Object3D } from "../core/Object3D.js"; -import { LineBasicMaterial } from "../materials/LineBasicMaterial.js"; -import { ColorRepresentation } from "../math/Color.js"; -import { LineSegments } from "../objects/LineSegments.js"; - -/** - * Helper object to graphically show the world-axis-aligned bounding box around an object - * @remarks - * The actual bounding box is handled with {@link THREE.Box3 | Box3}, this is just a visual helper for debugging - * It can be automatically resized with the {@link THREE.BoxHelper.update | BoxHelper.update} method when the object it's created from is transformed - * Note that the object must have a {@link THREE.BufferGeometry | BufferGeometry} for this to work, so it won't work with {@link Sprite | Sprites}. - * @example - * ```typescript - * const sphere = new THREE.SphereGeometry(); - * const object = new THREE.Mesh(sphere, new THREE.MeshBasicMaterial(0xff0000)); - * const box = new THREE.BoxHelper(object, 0xffff00); - * scene.add(box); - * ``` - * @see Example: {@link https://threejs.org/examples/#webgl_helpers | WebGL / helpers} - * @see Example: {@link https://threejs.org/examples/#webgl_loader_nrrd | WebGL / loader / nrrd} - * @see Example: {@link https://threejs.org/examples/#webgl_buffergeometry_drawrange | WebGL / buffergeometry / drawrange} - * @see {@link https://threejs.org/docs/index.html#api/en/helpers/BoxHelper | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/helpers/BoxHelper.js | Source} - */ -export class BoxHelper extends LineSegments { - /** - * Creates a new wireframe box that bounds the passed object - * @remarks - * Internally this uses {@link THREE.Box3.setFromObject | Box3.setFromObject} to calculate the dimensions - * Note that this includes any children. - * @param object The object3D to show the world-axis-aligned bounding box. - * @param color Hexadecimal value that defines the box's color. Default `0xffff00` - */ - constructor(object: Object3D, color?: ColorRepresentation); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @override - * @defaultValue `BoxHelper` - */ - override readonly type: string | "BoxHelper"; - - /** - * Updates the helper's geometry to match the dimensions of the object, including any children - * @remarks - * See {@link THREE.Box3.setFromObject | Box3.setFromObject}. - */ - update(object?: Object3D): void; - - /** - * Updates the wireframe box for the passed object. - * @param object {@link THREE.Object3D | Object3D} to create the helper of. - */ - setFromObject(object: Object3D): this; - - /** - * Frees the GPU-related resources allocated by this instance - * @remarks - * Call this method whenever this instance is no longer used in your app. - */ - dispose(): void; -} diff --git a/src-testing/src/helpers/CameraHelper.d.ts b/src-testing/src/helpers/CameraHelper.d.ts deleted file mode 100644 index 469dcaa0d..000000000 --- a/src-testing/src/helpers/CameraHelper.d.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { Camera } from "../cameras/Camera.js"; -import { Color } from "../math/Color.js"; -import { Matrix4 } from "../math/Matrix4.js"; -import { LineSegments } from "../objects/LineSegments.js"; - -/** - * This helps with visualizing what a camera contains in its frustum - * @remarks - * It visualizes the frustum of a camera using a {@link THREE.LineSegments | LineSegments}. - * @remarks {@link CameraHelper} must be a child of the scene. - * @example - * ```typescript - * const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); - * const helper = new THREE.CameraHelper(camera); - * scene.add(helper); - * ``` - * @see Example: {@link https://threejs.org/examples/#webgl_camera | WebGL / camera} - * @see Example: {@link https://threejs.org/examples/#webgl_geometry_extrude_splines | WebGL / extrude / splines} - * @see {@link https://threejs.org/docs/index.html#api/en/helpers/CameraHelper | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/helpers/CameraHelper.js | Source} - */ -export class CameraHelper extends LineSegments { - /** - * This create a new {@link CameraHelper} for the specified camera. - * @param camera The camera to visualize. - */ - constructor(camera: Camera); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @override - * @defaultValue `CameraHelper` - */ - override readonly type: string | "CameraHelper"; - - /** - * The camera being visualized. - */ - camera: Camera; - - /** - * This contains the points used to visualize the camera. - */ - pointMap: { [id: string]: number[] }; - - /** - * Reference to the {@link THREE.Camera.matrixWorld | camera.matrixWorld}. - */ - matrix: Matrix4; - - /** - * Is set to `false`, as the helper is using the {@link THREE.Camera.matrixWorld | camera.matrixWorld}. - * @see {@link THREE.Object3D.matrixAutoUpdate | Object3D.matrixAutoUpdate}. - * @defaultValue `false`. - */ - override matrixAutoUpdate: boolean; - - /** - * Defines the colors of the helper. - * @param frustum - * @param cone - * @param up - * @param target - * @param cross - */ - setColors(frustum: Color, cone: Color, up: Color, target: Color, cross: Color): this; - - /** - * Updates the helper based on the projectionMatrix of the camera. - */ - update(): void; - - /** - * Frees the GPU-related resources allocated by this instance - * @remarks - * Call this method whenever this instance is no longer used in your app. - */ - dispose(): void; -} diff --git a/src-testing/src/helpers/DirectionalLightHelper.d.ts b/src-testing/src/helpers/DirectionalLightHelper.d.ts deleted file mode 100644 index 729eccedd..000000000 --- a/src-testing/src/helpers/DirectionalLightHelper.d.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { Object3D } from "../core/Object3D.js"; -import { DirectionalLight } from "../lights/DirectionalLight.js"; -import { ColorRepresentation } from "../math/Color.js"; -import { Matrix4 } from "../math/Matrix4.js"; -import { Line } from "../objects/Line.js"; - -/** - * Helper object to assist with visualizing a {@link THREE.DirectionalLight | DirectionalLight}'s effect on the scene - * @remarks - * This consists of plane and a line representing the light's position and direction. - * @example - * ```typescript - * const light = new THREE.DirectionalLight(0xFFFFFF); - * scene.add(light); - * - * const helper = new THREE.DirectionalLightHelper(light, 5); - * scene.add(helper); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/helpers/DirectionalLightHelper | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/helpers/DirectionalLightHelper.js | Source} - */ -export class DirectionalLightHelper extends Object3D { - /** - * Create a new instance of {@link DirectionalLightHelper} - * @param light The light to be visualized. - * @param size Dimensions of the plane. Default `1` - * @param color If this is not the set the helper will take the color of the light. Default `light.color` - */ - constructor(light: DirectionalLight, size?: number, color?: ColorRepresentation); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @override - * @defaultValue `DirectionalLightHelper` - */ - override readonly type: string | "DirectionalLightHelper"; - - /** - * Contains the line mesh showing the location of the directional light. - */ - lightPlane: Line; - - /** - * Reference to the {@link THREE.DirectionalLight | directionalLight} being visualized. - */ - light: DirectionalLight; - - /** - * Reference to the {@link THREE.DirectionalLight.matrixWorld | light.matrixWorld}. - */ - matrix: Matrix4; - - /** - * Is set to `false`, as the helper is using the {@link THREE.DirectionalLight.matrixWorld | light.matrixWorld}. - * @see {@link THREE.Object3D.matrixAutoUpdate | Object3D.matrixAutoUpdate}. - * @defaultValue `false`. - */ - override matrixAutoUpdate: boolean; - - /** - * The color parameter passed in the constructor. - * @remarks If this is changed, the helper's color will update the next time {@link update} is called. - * @defaultValue `undefined` - */ - color: ColorRepresentation | undefined; - - targetLine: Line; // TODO: Double check if this need to be exposed or not. - - /** - * Updates the helper to match the position and direction of the {@link light | DirectionalLight} being visualized. - */ - update(): void; - - /** - * Frees the GPU-related resources allocated by this instance - * @remarks - * Call this method whenever this instance is no longer used in your app. - */ - dispose(): void; -} diff --git a/src-testing/src/helpers/GridHelper.d.ts b/src-testing/src/helpers/GridHelper.d.ts deleted file mode 100644 index 0b786b992..000000000 --- a/src-testing/src/helpers/GridHelper.d.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { BufferGeometry } from "../core/BufferGeometry.js"; -import { LineBasicMaterial } from "../materials/LineBasicMaterial.js"; -import { ColorRepresentation } from "../math/Color.js"; -import { LineSegments } from "../objects/LineSegments.js"; - -/** - * The {@link GridHelper} is an object to define grids - * @remarks - * Grids are two-dimensional arrays of lines. - * @example - * ```typescript - * const size = 10; - * const divisions = 10; - * const {@link GridHelper} = new THREE.GridHelper(size, divisions); - * scene.add(gridHelper); - * ``` - * @see Example: {@link https://threejs.org/examples/#webgl_helpers | WebGL / helpers} - * @see {@link https://threejs.org/docs/index.html#api/en/helpers/GridHelper | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/helpers/GridHelper.js | Source} - */ -export class GridHelper extends LineSegments { - /** - * Creates a new {@link GridHelper} of size 'size' and divided into 'divisions' segments per side - * @remarks - * Colors are optional. - * @param size The size of the grid. Default `10` - * @param divisions The number of divisions across the grid. Default `10` - * @param colorCenterLine The color of the centerline. This can be a {@link THREE.Color | Color}, a hexadecimal value and an CSS-Color name. Default `0x444444` - * @param colorGrid The color of the lines of the grid. This can be a {@link THREE.Color | Color}, a hexadecimal value and an CSS-Color name. Default `0x888888` - */ - constructor(size?: number, divisions?: number, color1?: ColorRepresentation, color2?: ColorRepresentation); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @override - * @defaultValue `GridHelper` - */ - override readonly type: string | "GridHelper"; - - /** - * Frees the GPU-related resources allocated by this instance - * @remarks - * Call this method whenever this instance is no longer used in your app. - */ - dispose(): void; -} diff --git a/src-testing/src/helpers/HemisphereLightHelper.d.ts b/src-testing/src/helpers/HemisphereLightHelper.d.ts deleted file mode 100644 index 80366b63b..000000000 --- a/src-testing/src/helpers/HemisphereLightHelper.d.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { Object3D } from "../core/Object3D.js"; -import { HemisphereLight } from "../lights/HemisphereLight.js"; -import { MeshBasicMaterial } from "../materials/MeshBasicMaterial.js"; -import { ColorRepresentation } from "../math/Color.js"; -import { Matrix4 } from "../math/Matrix4.js"; - -/** - * Creates a visual aid consisting of a spherical {@link THREE.Mesh | Mesh} for a {@link THREE.HemisphereLight | HemisphereLight}. - * @example - * ```typescript - * const light = new THREE.HemisphereLight(0xffffbb, 0x080820, 1); - * const helper = new THREE.HemisphereLightHelper(light, 5); - * scene.add(helper); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/helpers/HemisphereLightHelper | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/helpers/HemisphereLightHelper.js | Source} - */ -export class HemisphereLightHelper extends Object3D { - /** - * Create a new instance of {@link HemisphereLightHelper} - * @param light The light being visualized. - * @param size Thr sphere size - * @param color If this is not the set the helper will take the color of the light. - */ - constructor(light: HemisphereLight, size: number, color?: ColorRepresentation); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @override - * @defaultValue `HemisphereLightHelper` - */ - override readonly type: string | "HemisphereLightHelper"; - - /** - * Reference to the HemisphereLight being visualized. - */ - light: HemisphereLight; - - /** - * Reference to the {@link THREE.HemisphereLight.matrixWorld | light.matrixWorld}. - */ - matrix: Matrix4; - - /** - * Is set to `false`, as the helper is using the {@link THREE.HemisphereLight.matrixWorld | light.matrixWorld}. - * @see {@link THREE.Object3D.matrixAutoUpdate | Object3D.matrixAutoUpdate}. - * @defaultValue `false`. - */ - override matrixAutoUpdate: boolean; - - material: MeshBasicMaterial; // TODO: Double check if this need to be exposed or not. - - /** - * The color parameter passed in the constructor. - * @remarks If this is changed, the helper's color will update the next time {@link update} is called. - * @defaultValue `undefined` - */ - color: ColorRepresentation | undefined; - - /** - * Updates the helper to match the position and direction of the {@link .light | HemisphereLight}. - */ - update(): void; - - /** - * Frees the GPU-related resources allocated by this instance - * @remarks - * Call this method whenever this instance is no longer used in your app. - */ - dispose(): void; -} diff --git a/src-testing/src/helpers/PlaneHelper.d.ts b/src-testing/src/helpers/PlaneHelper.d.ts deleted file mode 100644 index 43c9821cb..000000000 --- a/src-testing/src/helpers/PlaneHelper.d.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { Plane } from "../math/Plane.js"; -import { LineSegments } from "../objects/LineSegments.js"; - -/** - * Helper object to visualize a {@link THREE.Plane | Plane}. - * @example - * ```typescript - * const plane = new THREE.Plane(new THREE.Vector3(1, 1, 0.2), 3); - * const helper = new THREE.PlaneHelper(plane, 1, 0xffff00); - * scene.add(helper); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/helpers/PlaneHelper | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/helpers/PlaneHelper.js | Source} - */ -export class PlaneHelper extends LineSegments { - /** - * Creates a new wireframe representation of the passed plane. - * @param plane The plane to visualize. - * @param size Side length of plane helper. Expects a `Float`. Default `1` - * @param hex Color. Default `0xffff00` - */ - constructor(plane: Plane, size?: number, hex?: number); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @override - * @defaultValue `PlaneHelper` - */ - override readonly type: string | "PlaneHelper"; - - /** - * The {@link Plane | plane} being visualized. - */ - plane: Plane; - - /** - * The side lengths of plane helper. - * @remarks Expects a `Float` - * @defaultValue `1` - */ - size: number; - - /** - * Frees the GPU-related resources allocated by this instance - * @remarks - * Call this method whenever this instance is no longer used in your app. - */ - dispose(): void; -} diff --git a/src-testing/src/helpers/PointLightHelper.d.ts b/src-testing/src/helpers/PointLightHelper.d.ts deleted file mode 100644 index 7d61da5e3..000000000 --- a/src-testing/src/helpers/PointLightHelper.d.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { Object3D } from "../core/Object3D.js"; -import { PointLight } from "../lights/PointLight.js"; -import { ColorRepresentation } from "../math/Color.js"; -import { Matrix4 } from "../math/Matrix4.js"; - -/** - * This displays a helper object consisting of a spherical {@link THREE.Mesh | Mesh} for visualizing a {@link THREE.PointLight | PointLight}. - * @example - * ```typescript - * const pointLight = new THREE.PointLight(0xff0000, 1, 100); - * pointLight.position.set(10, 10, 10); - * scene.add(pointLight); - * const sphereSize = 1; - * const {@link PointLightHelper} = new THREE.PointLightHelper(pointLight, sphereSize); - * scene.add(pointLightHelper); - * ``` - * @see Example: {@link https://threejs.org/examples/#webgl_helpers | WebGL / helpers} - * @see {@link https://threejs.org/docs/index.html#api/en/helpers/PointLightHelper | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/helpers/PointLightHelper.js | Source} - */ -export class PointLightHelper extends Object3D { - /** - * Create a new instance of {@link PointLightHelper} - * @param light The light to be visualized. - * @param sphereSize The size of the sphere helper. Expects a `Float`. Default `1` - * @param color If this is not the set the helper will take the color of the light. - */ - constructor(light: PointLight, sphereSize?: number, color?: ColorRepresentation); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @override - * @defaultValue `PointLightHelper` - */ - override readonly type: string | "PointLightHelper"; - - /** - * The {@link THREE.PointLight | PointLight} that is being visualized. - */ - light: PointLight; - - /** - * Reference to the {@link THREE.PointLight.matrixWorld | light.matrixWorld}. - */ - matrix: Matrix4; - - /** - * The color parameter passed in the constructor. - * @remarks If this is changed, the helper's color will update the next time {@link update} is called. - * @defaultValue `undefined` - */ - color: ColorRepresentation | undefined; - - /** - * Is set to `false`, as the helper is using the {@link THREE.PointLight.matrixWorld | light.matrixWorld}. - * @see {@link THREE.Object3D.matrixAutoUpdate | Object3D.matrixAutoUpdate}. - * @defaultValue `false`. - */ - override matrixAutoUpdate: boolean; - - /** - * Updates the helper to match the position of the {@link THREE..light | .light}. - */ - update(): void; - - /** - * Frees the GPU-related resources allocated by this instance - * @remarks - * Call this method whenever this instance is no longer used in your app. - */ - dispose(): void; -} diff --git a/src-testing/src/helpers/PolarGridHelper.d.ts b/src-testing/src/helpers/PolarGridHelper.d.ts deleted file mode 100644 index 994d71c94..000000000 --- a/src-testing/src/helpers/PolarGridHelper.d.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { ColorRepresentation } from "../math/Color.js"; -import { LineSegments } from "../objects/LineSegments.js"; - -/** - * The {@link PolarGridHelper} is an object to define polar grids - * @remarks - * Grids are two-dimensional arrays of lines. - * @example - * ```typescript - * const radius = 10; - * const sectors = 16; - * const rings = 8; - * const divisions = 64; - * const helper = new THREE.PolarGridHelper(radius, sectors, rings, divisions); - * scene.add(helper); - * ``` - * @see Example: {@link https://threejs.org/examples/#webgl_helpers | WebGL / helpers} - * @see {@link https://threejs.org/docs/index.html#api/en/helpers/PolarGridHelper | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/helpers/PolarGridHelper.js | Source} - */ -export class PolarGridHelper extends LineSegments { - /** - * Creates a new {@link PolarGridHelper} of radius 'radius' with 'sectors' number of sectors and 'rings' number of rings, where each circle is smoothed into 'divisions' number of line segments. - * @remarks Colors are optional. - * @param radius The radius of the polar grid. This can be any positive number. Default `10`. - * @param sectors The number of sectors the grid will be divided into. This can be any positive integer. Default `16`. - * @param rings The number of rings. This can be any positive integer. Default `8`. - * @param divisions The number of line segments used for each circle. This can be any positive integer that is 3 or greater. Default `64`. - * @param color1 The first color used for grid elements. This can be a {@link THREE.Color | Color}, a hexadecimal value and an CSS-Color name. Default `0x444444`. - * @param color2 The second color used for grid elements. This can be a {@link THREE.Color | Color}, a hexadecimal value and an CSS-Color name. Default `0x888888`. - */ - constructor( - radius?: number, - radials?: number, - circles?: number, - divisions?: number, - color1?: ColorRepresentation, - color2?: ColorRepresentation, - ); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @override - * @defaultValue `PolarGridHelper` - */ - override readonly type: string | "PolarGridHelper"; - - /** - * Frees the GPU-related resources allocated by this instance - * @remarks - * Call this method whenever this instance is no longer used in your app. - */ - dispose(): void; -} diff --git a/src-testing/src/helpers/SkeletonHelper.d.ts b/src-testing/src/helpers/SkeletonHelper.d.ts deleted file mode 100644 index 772ebf30e..000000000 --- a/src-testing/src/helpers/SkeletonHelper.d.ts +++ /dev/null @@ -1,78 +0,0 @@ -import { Object3D } from "../core/Object3D.js"; -import { Matrix4 } from "../math/Matrix4.js"; -import { Bone } from "../objects/Bone.js"; -import { LineSegments } from "../objects/LineSegments.js"; -import { SkinnedMesh } from "../objects/SkinnedMesh.js"; - -/** - * A helper object to assist with visualizing a {@link Skeleton | Skeleton} - * @remarks - * The helper is rendered using a {@link LineBasicMaterial | LineBasicMaterial}. - * @example - * ```typescript - * const helper = new THREE.SkeletonHelper(skinnedMesh); - * scene.add(helper); - * ``` - * @see Example: {@link https://threejs.org/examples/#webgl_animation_skinning_blending | WebGL / animation / skinning / blending} - * @see Example: {@link https://threejs.org/examples/#webgl_animation_skinning_morph | WebGL / animation / skinning / morph} - * @see Example: {@link https://threejs.org/examples/#webgl_loader_bvh | WebGL / loader / bvh } - * @see {@link https://threejs.org/docs/index.html#api/en/helpers/SkeletonHelper | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/helpers/SkeletonHelper.js | Source} - */ -export class SkeletonHelper extends LineSegments { - /** - * Create a new instance of {@link SkeletonHelper} - * @param object Usually an instance of {@link THREE.SkinnedMesh | SkinnedMesh}. - * However, any instance of {@link THREE.Object3D | Object3D} can be used if it represents a hierarchy of {@link Bone | Bone}s (via {@link THREE.Object3D.children | Object3D.children}). - */ - constructor(object: SkinnedMesh | Object3D); - - /** - * Read-only flag to check if a given object is of type {@link SkeletonHelper}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isSkeletonHelper = true; - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @override - * @defaultValue `SkeletonHelper` - */ - override readonly type: string | "SkeletonHelper"; - - /** - * The list of bones that the helper renders as {@link Line | Lines}. - */ - bones: Bone[]; - - /** - * The object passed in the constructor. - */ - root: SkinnedMesh | Object3D; - - /** - * Reference to the {@link THREE.Object3D.matrixWorld | root.matrixWorld}. - */ - matrix: Matrix4; - - /** - * Is set to `false`, as the helper is using the {@link THREE.Object3D.matrixWorld | root.matrixWorld}. - * @see {@link THREE.Object3D.matrixAutoUpdate | Object3D.matrixAutoUpdate}. - * @defaultValue `false`. - */ - override matrixAutoUpdate: boolean; - - /** - * Updates the helper. - */ - update(): void; - - /** - * Frees the GPU-related resources allocated by this instance - * @remarks - * Call this method whenever this instance is no longer used in your app. - */ - dispose(): void; -} diff --git a/src-testing/src/helpers/SpotLightHelper.d.ts b/src-testing/src/helpers/SpotLightHelper.d.ts deleted file mode 100644 index f620ed990..000000000 --- a/src-testing/src/helpers/SpotLightHelper.d.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { Object3D } from "../core/Object3D.js"; -import { Light } from "../lights/Light.js"; -import { ColorRepresentation } from "../math/Color.js"; -import { Matrix4 } from "../math/Matrix4.js"; -import { LineSegments } from "../objects/LineSegments.js"; - -/** - * This displays a cone shaped helper object for a {@link THREE.SpotLight | SpotLight}. - * @example - * ```typescript - * const spotLight = new THREE.SpotLight(0xffffff); - * spotLight.position.set(10, 10, 10); - * scene.add(spotLight); - * const {@link SpotLightHelper} = new THREE.SpotLightHelper(spotLight); - * scene.add(spotLightHelper); - * ``` - * @see Example: {@link https://threejs.org/examples/#webgl_lights_spotlights | WebGL/ lights / spotlights } - * @see {@link https://threejs.org/docs/index.html#api/en/helpers/SpotLightHelper | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/helpers/SpotLightHelper.js | Source} - */ -export class SpotLightHelper extends Object3D { - /** - * Create a new instance of {@link SpotLightHelper} - * @param light The {@link THREE.SpotLight | SpotLight} to be visualized. - * @param color If this is not the set the helper will take the color of the light. Default `light.color` - */ - constructor(light: Light, color?: ColorRepresentation); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @override - * @defaultValue `SpotLightHelper` - */ - override readonly type: string | "SpotLightHelper"; - - /** - * {@link THREE.LineSegments | LineSegments} used to visualize the light. - */ - cone: LineSegments; - - /** - * Reference to the {@link THREE.SpotLight | SpotLight} being visualized. - */ - light: Light; - - /** - * Reference to the spotLight's {@link Object3D.matrixWorld | matrixWorld}. - */ - matrix: Matrix4; - - /** - * The color parameter passed in the constructor. - * If this is changed, the helper's color will update the next time {@link SpotLightHelper.update | update} is called. - * @defaultValue `undefined` - */ - color: ColorRepresentation | undefined; - - /** - * Is set to `false`, as the helper is using the {@link THREE.Light.matrixWorld | light.matrixWorld}. - * @see {@link THREE.Object3D.matrixAutoUpdate | Object3D.matrixAutoUpdate}. - * @defaultValue `false`. - */ - override matrixAutoUpdate: boolean; - - /** - * Updates the light helper. - */ - update(): void; - - /** - * Frees the GPU-related resources allocated by this instance - * @remarks - * Call this method whenever this instance is no longer used in your app. - */ - dispose(): void; -} diff --git a/src-testing/src/lights/AmbientLight.d.ts b/src-testing/src/lights/AmbientLight.d.ts deleted file mode 100644 index 7000a37e7..000000000 --- a/src-testing/src/lights/AmbientLight.d.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { ColorRepresentation } from "../math/Color.js"; -import { Light } from "./Light.js"; - -/** - * This light globally illuminates all objects in the scene equally. - * @remarks This light cannot be used to cast shadows as it does not have a direction. - * @example - * ```typescript - * const light = new THREE.AmbientLight(0x404040); // soft white light - * scene.add(light); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/lights/AmbientLight | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/lights/AmbientLight.js | Source} - */ -export class AmbientLight extends Light { - /** - * Creates a new {@link AmbientLight}. - * @param color Numeric value of the RGB component of the color. Default `0xffffff` - * @param intensity Numeric value of the light's strength/intensity. Expects a `Float`. Default `1` - */ - constructor(color?: ColorRepresentation, intensity?: number); - - /** - * Read-only flag to check if a given object is of type {@link AmbientLight}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isAmbientLight: true; - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `AmbientLight` - */ - override readonly type: string | "AmbientLight"; -} diff --git a/src-testing/src/lights/DirectionalLight.d.ts b/src-testing/src/lights/DirectionalLight.d.ts deleted file mode 100644 index 3d43b7d89..000000000 --- a/src-testing/src/lights/DirectionalLight.d.ts +++ /dev/null @@ -1,103 +0,0 @@ -import { Object3D } from "../core/Object3D.js"; -import { ColorRepresentation } from "../math/Color.js"; -import { Vector3 } from "../math/Vector3.js"; -import { DirectionalLightShadow } from "./DirectionalLightShadow.js"; -import { Light } from "./Light.js"; - -/** - * A light that gets emitted in a specific direction - * @remarks - * This light will behave as though it is infinitely far away and the rays produced from it are all parallel - * The common use case for this is to simulate daylight; the sun is far enough away that its position can be considered to be infinite, and all light rays coming from it are parallel. - * A common point of confusion for directional lights is that setting the rotation has no effect - * @remarks - * This is because three.js's {@link DirectionalLight} is the equivalent to what is often called a 'Target Direct Light' in other applications. - * This means that its direction is calculated as pointing from the light's {@link THREE.Object3D.position | position} to the {@link THREE.DirectionalLight.target | target}'s - * position (as opposed to a 'Free Direct Light' that just has a rotation component). - * See the {@link THREE.DirectionalLight.target | target} property below for details on updating the target. - * @example - * ```typescript - * // White directional light at half intensity shining from the top. - * const {@link DirectionalLight} = new THREE.DirectionalLight(0xffffff, 0.5); - * scene.add(directionalLight); - * ``` - * @see Example: {@link https://threejs.org/examples/#misc_controls_fly | controls / fly } - * @see Example: {@link https://threejs.org/examples/#webgl_effects_parallaxbarrier | effects / parallaxbarrier } - * @see Example: {@link https://threejs.org/examples/#webgl_effects_stereo | effects / stereo } - * @see Example: {@link https://threejs.org/examples/#webgl_geometry_extrude_splines | geometry / extrude / splines } - * @see Example: {@link https://threejs.org/examples/#webgl_materials_bumpmap | materials / bumpmap } - * @see {@link https://threejs.org/docs/index.html#api/en/lights/DirectionalLight | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/lights/DirectionalLight.js | Source} - */ -export class DirectionalLight extends Light { - /** - * Creates a new {@link DirectionalLight}. - * @param color Hexadecimal color of the light. Default `0xffffff` _(white)_. - * @param intensity Numeric value of the light's strength/intensity. Expects a `Float`. Default `1` - */ - constructor(color?: ColorRepresentation, intensity?: number); - - /** - * Read-only flag to check if a given object is of type {@link DirectionalLight}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isDirectionalLight: true; - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `DirectionalLight` - */ - override readonly type: string | "DirectionalLight"; - - /** - * Whether the object gets rendered into shadow map. - * @remarks - * If set to `true` light will cast dynamic shadows. - * **Warning**: This is expensive and requires tweaking to get shadows looking right. - * @see {@link THREE.DirectionalLightShadow | DirectionalLightShadow} for details. - * @defaultValue `false` - */ - override castShadow: boolean; - - /** - * This is set equal to {@link THREE.Object3D.DEFAULT_UP}, so that the light shines from the top down. - * @defaultValue {@link Object3D.DEFAULT_UP} _(0, 1, 0)_ - */ - override readonly position: Vector3; - - /** - * A {@link THREE.DirectionalLightShadow | DirectionalLightShadow} used to calculate shadows for this light. - * @defaultValue `new THREE.DirectionalLightShadow()` - */ - shadow: DirectionalLightShadow; - - /** - * The {@link DirectionalLight} points from its {@link DirectionalLight.position | position} to target.position. - * @remarks **Note**: For the target's position to be changed to anything other than the default, - * it must be added to the {@link THREE.Scene | scene} using - * ```typescript - * Scene.add( light.target ); - * ``` - * This is so that the target's {@link THREE.Object3D.matrixWorld | matrixWorld} gets automatically updated each frame. - * - * It is also possible to set the target to be another object in the scene (anything with a {@link THREE.Object3D.position | position} property), - * like so: - * ```typescript - * const targetObject = new THREE.Object3D(); - * scene.add(targetObject); - * light.target = targetObject; - * ``` - * The {@link DirectionalLight} will now track the target object. - * @defaultValue `new THREE.Object3D()` at _(0, 0, 0)_ - */ - target: Object3D; - - /** - * Frees the GPU-related resources allocated by this instance - * @remarks - * Call this method whenever this instance is no longer used in your app. - */ - dispose(): void; -} diff --git a/src-testing/src/lights/DirectionalLightShadow.d.ts b/src-testing/src/lights/DirectionalLightShadow.d.ts deleted file mode 100644 index 805e4fa0b..000000000 --- a/src-testing/src/lights/DirectionalLightShadow.d.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { OrthographicCamera } from "../cameras/OrthographicCamera.js"; -import { LightShadow } from "./LightShadow.js"; - -/** - * This is used internally by {@link DirectionalLight | DirectionalLights} for calculating shadows. - * Unlike the other shadow classes, this uses an {@link THREE.OrthographicCamera | OrthographicCamera} to calculate the shadows, - * rather than a {@link THREE.PerspectiveCamera | PerspectiveCamera} - * @remarks - * This is because light rays from a {@link THREE.DirectionalLight | DirectionalLight} are parallel. - * @example - * ```typescript - * //Create a WebGLRenderer and turn on shadows in the renderer - * const renderer = new THREE.WebGLRenderer(); - * renderer.shadowMap.enabled = true; - * renderer.shadowMap.type = THREE.PCFSoftShadowMap; // default THREE.PCFShadowMap - * //Create a DirectionalLight and turn on shadows for the light - * const light = new THREE.DirectionalLight(0xffffff, 1); - * light.position.set(0, 1, 0); //default; light shining from top - * light.castShadow = true; // default false - * scene.add(light); - * //Set up shadow properties for the light - * light.shadow.mapSize.width = 512; // default - * light.shadow.mapSize.height = 512; // default - * light.shadow.camera.near = 0.5; // default - * light.shadow.camera.far = 500; // default - * //Create a sphere that cast shadows (but does not receive them) - * const sphereGeometry = new THREE.SphereGeometry(5, 32, 32); - * const sphereMaterial = new THREE.MeshStandardMaterial({ - * color: 0xff0000 - * }); - * const sphere = new THREE.Mesh(sphereGeometry, sphereMaterial); - * sphere.castShadow = true; //default is false - * sphere.receiveShadow = false; //default - * scene.add(sphere); - * //Create a plane that receives shadows (but does not cast them) - * const planeGeometry = new THREE.PlaneGeometry(20, 20, 32, 32); - * const planeMaterial = new THREE.MeshStandardMaterial({ - * color: 0x00ff00 - * }) - * const plane = new THREE.Mesh(planeGeometry, planeMaterial); - * plane.receiveShadow = true; - * scene.add(plane); - * //Create a helper for the shadow camera (optional) - * const helper = new THREE.CameraHelper(light.shadow.camera); - * scene.add(helper); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/lights/shadows/DirectionalLightShadow | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/lights/DirectionalLightShadow.js | Source} - */ -export class DirectionalLightShadow extends LightShadow { - /** - * Create a new instance of {@link DirectionalLightShadow} - */ - constructor(); - - /** - * Read-only flag to check if a given object is of type {@link DirectionalLightShadow}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isDirectionalLightShadow: true; - - /** - * The light's view of the world. - * @remarks This is used to generate a depth map of the scene; objects behind other objects from the light's perspective will be in shadow. - * @defaultValue is an {@link THREE.OrthographicCamera | OrthographicCamera} with - * {@link OrthographicCamera.left | left} and {@link OrthographicCamera.bottom | bottom} set to -5, - * {@link OrthographicCamera.right | right} and {@link OrthographicCamera.top | top} set to 5, - * the {@link OrthographicCamera.near | near} clipping plane at 0.5 and - * the {@link OrthographicCamera.far | far} clipping plane at 500. - */ - camera: OrthographicCamera; -} diff --git a/src-testing/src/lights/HemisphereLight.d.ts b/src-testing/src/lights/HemisphereLight.d.ts deleted file mode 100644 index 1a796dfc8..000000000 --- a/src-testing/src/lights/HemisphereLight.d.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { Color, ColorRepresentation } from "../math/Color.js"; -import { Vector3 } from "../math/Vector3.js"; -import { Light } from "./Light.js"; - -/** - * A light source positioned directly above the scene, with color fading from the sky color to the ground color. - * @remarks This light cannot be used to cast shadows. - * @example - * ```typescript - * const light = new THREE.HemisphereLight(0xffffbb, 0x080820, 1); - * scene.add(light); - * ``` - * @see Example: {@link https://threejs.org/examples/#webgl_animation_skinning_blending | animation / skinning / blending } - * @see Example: {@link https://threejs.org/examples/#webgl_lights_hemisphere | lights / hemisphere } - * @see Example: {@link https://threejs.org/examples/#misc_controls_pointerlock | controls / pointerlock } - * @see Example: {@link https://threejs.org/examples/#webgl_loader_collada_kinematics | loader / collada / kinematics } - * @see Example: {@link https://threejs.org/examples/#webgl_loader_stl | loader / stl } - * @see {@link https://threejs.org/docs/index.html#api/en/lights/HemisphereLight | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/lights/HemisphereLight.js | Source} - */ -export class HemisphereLight extends Light { - /** - * Creates a new {@link HemisphereLight}. - * @param skyColor Hexadecimal color of the sky. Expects a `Integer`. Default `0xffffff` _(white)_. - * @param groundColor Hexadecimal color of the ground. Expects a `Integer`. Default `0xffffff` _(white)_. - * @param intensity Numeric value of the light's strength/intensity. Expects a `Float`. Default `1`. - */ - constructor(skyColor?: ColorRepresentation, groundColor?: ColorRepresentation, intensity?: number); - - /** - * Read-only flag to check if a given object is of type {@link HemisphereLight}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isHemisphereLight: true; - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `HemisphereLight` - */ - override readonly type: string | "HemisphereLight"; - - /** - * This is set equal to {@link THREE.Object3D.DEFAULT_UP}, so that the light shines from the top down. - * @defaultValue {@link Object3D.DEFAULT_UP} _(0, 1, 0)_ - */ - override readonly position: Vector3; - - /** - * The light's sky color, as passed in the constructor. - * @defaultValue `new THREE.Color()` set to white _(0xffffff)_. - */ - override color: Color; - - /** - * The light's ground color, as passed in the constructor. - * @defaultValue `new THREE.Color()` set to white _(0xffffff)_. - */ - groundColor: Color; -} diff --git a/src-testing/src/lights/Light.d.ts b/src-testing/src/lights/Light.d.ts deleted file mode 100644 index 3ae757e3b..000000000 --- a/src-testing/src/lights/Light.d.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { JSONMeta, Object3D, Object3DJSON } from "../core/Object3D.js"; -import { Color, ColorRepresentation } from "../math/Color.js"; -import { LightShadow, LightShadowJSON } from "./LightShadow.js"; - -export interface LightJSON extends Object3DJSON { - color: number; - intensity: number; - - groundColor?: number; - - distance?: number; - angle?: number; - decay?: number; - penumbra?: number; - - shadow?: LightShadowJSON; - target?: string; -} - -/** - * Abstract base class for lights. - * @remarks All other light types inherit the properties and methods described here. - */ -export abstract class Light extends Object3D { - /** - * Creates a new {@link Light} - * @remarks - * **Note** that this is not intended to be called directly (use one of derived classes instead). - * @param color Hexadecimal color of the light. Default `0xffffff` _(white)_. - * @param intensity Numeric value of the light's strength/intensity. Expects a `Float`. Default `1`. - */ - constructor(color?: ColorRepresentation, intensity?: number); - - /** - * Read-only flag to check if a given object is of type {@link HemisphereLight}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isLight: true; - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `Light` - */ - override readonly type: string | "Light"; - - /** - * Color of the light. \ - * @defaultValue `new THREE.Color(0xffffff)` _(white)_. - */ - color: Color; - - /** - * The light's intensity, or strength. - * The units of intensity depend on the type of light. - * @defaultValue `1` - */ - intensity: number; - - /** - * A {@link THREE.LightShadow | LightShadow} used to calculate shadows for this light. - * @remarks Available only on Light's that support shadows. - */ - shadow: TShadowSupport; - - /** - * Copies value of all the properties from the {@link Light | source} to this instance. - * @param source - * @param recursive - */ - copy(source: this, recursive?: boolean): this; - - /** - * Frees the GPU-related resources allocated by this instance - * @remarks - * Call this method whenever this instance is no longer used in your app. - */ - dispose(): void; - - toJSON(meta?: JSONMeta): LightJSON; -} diff --git a/src-testing/src/lights/LightProbe.d.ts b/src-testing/src/lights/LightProbe.d.ts deleted file mode 100644 index a63ffdc57..000000000 --- a/src-testing/src/lights/LightProbe.d.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { SphericalHarmonics3 } from "../math/SphericalHarmonics3.js"; -import { Light } from "./Light.js"; - -/** - * Light probes are an alternative way of adding light to a 3D scene. - * @remarks - * Unlike classical light sources (e.g - * directional, point or spot lights), light probes do not emit light - * Instead they store information about light passing through 3D space - * During rendering, the light that hits a 3D object is approximated by using the data from the light probe. - * Light probes are usually created from (radiance) environment maps - * The class {@link THREE.LightProbeGenerator | LightProbeGenerator} can be used to create light probes from - * instances of {@link THREE.CubeTexture | CubeTexture} or {@link THREE.WebGLCubeRenderTarget | WebGLCubeRenderTarget} - * However, light estimation data could also be provided in other forms e.g - * by WebXR - * This enables the rendering of augmented reality content that reacts to real world lighting. - * The current probe implementation in three.js supports so-called diffuse light probes - * This type of light probe is functionally equivalent to an irradiance environment map. - * @see Example: {@link https://threejs.org/examples/#webgl_lightprobe | WebGL / light probe } - * @see Example: {@link https://threejs.org/examples/#webgl_lightprobe_cubecamera | WebGL / light probe / cube camera } - * @see {@link https://threejs.org/docs/index.html#api/en/lights/LightProbe | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/lights/LightProbe.js | Source} - */ -export class LightProbe extends Light { - /** - * Creates a new LightProbe. - * @param sh An instance of {@link THREE.SphericalHarmonics3 | SphericalHarmonics3}. Default `new THREE.SphericalHarmonics3()``. - * @param intensity Numeric value of the light probe's intensity. Expects a `Float`. Default `1`. - */ - constructor(sh?: SphericalHarmonics3, intensity?: number); - - /** - * Read-only flag to check if a given object is of type {@link DirectionalLight}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isLightProbe: true; - - /** - * A light probe uses spherical harmonics to encode lighting information. - * @defaultValue `new THREE.SphericalHarmonics3()` - */ - sh: SphericalHarmonics3; - - /** @internal */ - fromJSON(json: {}): LightProbe; -} diff --git a/src-testing/src/lights/LightShadow.d.ts b/src-testing/src/lights/LightShadow.d.ts deleted file mode 100644 index 53c163c3e..000000000 --- a/src-testing/src/lights/LightShadow.d.ts +++ /dev/null @@ -1,169 +0,0 @@ -import { Camera } from "../cameras/Camera.js"; -import { Object3DJSONObject } from "../core/Object3D.js"; -import { Frustum } from "../math/Frustum.js"; -import { Matrix4 } from "../math/Matrix4.js"; -import { Vector2, Vector2Tuple } from "../math/Vector2.js"; -import { Vector4 } from "../math/Vector4.js"; -import { WebGLRenderTarget } from "../renderers/WebGLRenderTarget.js"; -import { Light } from "./Light.js"; - -export interface LightShadowJSON { - intensity?: number; - bias?: number; - normalBias?: number; - radius?: number; - mapSize?: Vector2Tuple; - - camera: Omit; -} - -/** - * Serves as a base class for the other shadow classes. - * @see {@link https://threejs.org/docs/index.html#api/en/lights/shadows/LightShadow | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/lights/LightShadow.js | Source} - */ -export class LightShadow { - /** - * Create a new instance of {@link LightShadow} - * @param camera The light's view of the world. - */ - constructor(camera: TCamera); - - /** - * The light's view of the world. - * @remark This is used to generate a depth map of the scene; objects behind other objects from the light's perspective will be in shadow. - */ - camera: TCamera; - - /** - * The intensity of the shadow. The default is `1`. Valid values are in the range `[0, 1]`. - */ - intensity: number; - - /** - * Shadow map bias, how much to add or subtract from the normalized depth when deciding whether a surface is in shadow. - * @remark The Very tiny adjustments here (in the order of 0.0001) may help reduce artifacts in shadows. - * @remarks Expects a `Float` - * @defaultValue `0` - */ - bias: number; - - /** - * Defines how much the position used to query the shadow map is offset along the object normal. - * @remark The Increasing this value can be used to reduce shadow acne especially in large scenes where light shines onto geometry at a shallow angle. - * @remark The cost is that shadows may appear distorted. - * @remarks Expects a `Float` - * @defaultValue `0` - */ - normalBias: number; - - /** - * Setting this to values greater than 1 will blur the edges of the shadow.toi - * @remark High values will cause unwanted banding effects in the shadows - a greater {@link LightShadow.mapSize | mapSize - * will allow for a higher value to be used here before these effects become visible. - * @remark If {@link THREE.WebGLRenderer.shadowMap.type | WebGLRenderer.shadowMap.type} is set to {@link Renderer | PCFSoftShadowMap}, - * radius has no effect and it is recommended to increase softness by decreasing {@link LightShadow.mapSize | mapSize} instead. - * @remark Note that this has no effect if the {@link THREE.WebGLRenderer.shadowMap | WebGLRenderer.shadowMap}.{@link THREE.WebGLShadowMap.type | type} - * is set to {@link THREE.BasicShadowMap | BasicShadowMap}. - * @remarks Expects a `Float` - * @defaultValue `1` - */ - radius: number; - - /** - * The amount of samples to use when blurring a VSM shadow map. - * @remarks Expects a `Integer` - * @defaultValue `8` - */ - blurSamples: number; - - /** - * A {@link THREE.Vector2 | Vector2} defining the width and height of the shadow map. - * @remarks Higher values give better quality shadows at the cost of computation time. - * @remarks Values must be powers of 2, up to the {@link THREE.WebGLRenderer.capabilities | WebGLRenderer.capabilities}.maxTextureSize for a given device, - * although the width and height don't have to be the same (so, for example, (512, 1024) is valid). - * @defaultValue `new THREE.Vector2(512, 512)` - */ - mapSize: Vector2; - - /** - * The depth map generated using the internal camera; a location beyond a pixel's depth is in shadow. Computed internally during rendering. - * @defaultValue null - */ - map: WebGLRenderTarget | null; - - /** - * The distribution map generated using the internal camera; an occlusion is calculated based on the distribution of depths. Computed internally during rendering. - * @defaultValue null - */ - mapPass: WebGLRenderTarget | null; - - /** - * Model to shadow camera space, to compute location and depth in shadow map. - * Stored in a {@link Matrix4 | Matrix4}. - * @remarks This is computed internally during rendering. - * @defaultValue new THREE.Matrix4() - */ - matrix: Matrix4; - - /** - * Enables automatic updates of the light's shadow. If you do not require dynamic lighting / shadows, you may set this to `false`. - * @defaultValue `true` - */ - autoUpdate: boolean; - - /** - * When set to `true`, shadow maps will be updated in the next `render` call. - * If you have set {@link autoUpdate} to `false`, you will need to set this property to `true` and then make a render call to update the light's shadow. - * @defaultValue `false` - */ - needsUpdate: boolean; - - /** - * Used internally by the renderer to get the number of viewports that need to be rendered for this shadow. - */ - getViewportCount(): number; - - /** - * Copies value of all the properties from the {@link {@link LightShadow} | source} to this Light. - * @param source - */ - copy(source: LightShadow): this; - - /** - * Creates a new {@link LightShadow} with the same properties as this one. - */ - clone(recursive?: boolean): this; - - /** - * Serialize this LightShadow. - */ - toJSON(): LightShadowJSON; - - /** - * Gets the shadow cameras frustum - * @remarks - * Used internally by the renderer to cull objects. - */ - getFrustum(): Frustum; - - /** - * Update the matrices for the camera and shadow, used internally by the renderer. - * @param light The light for which the shadow is being rendered. - */ - updateMatrices(light: Light): void; - - getViewport(viewportIndex: number): Vector4; - - /** - * Used internally by the renderer to extend the shadow map to contain all viewports - */ - getFrameExtents(): Vector2; - - /** - * Frees the GPU-related resources allocated by this instance - * @remarks - * Call this method whenever this instance is no longer used in your app. - */ - dispose(): void; -} diff --git a/src-testing/src/lights/PointLight.d.ts b/src-testing/src/lights/PointLight.d.ts deleted file mode 100644 index c13044e12..000000000 --- a/src-testing/src/lights/PointLight.d.ts +++ /dev/null @@ -1,102 +0,0 @@ -import { ColorRepresentation } from "../math/Color.js"; -import { Light } from "./Light.js"; -import { PointLightShadow } from "./PointLightShadow.js"; - -/** - * A light that gets emitted from a single point in all directions - * @remarks - * A common use case for this is to replicate the light emitted from a bare lightbulb. - * @example - * ```typescript - * const light = new THREE.PointLight(0xff0000, 1, 100); - * light.position.set(50, 50, 50); - * scene.add(light); - * ``` - * @see Example: {@link https://threejs.org/examples/#webgl_lights_pointlights | lights / pointlights } - * @see Example: {@link https://threejs.org/examples/#webgl_effects_anaglyph | effects / anaglyph } - * @see Example: {@link https://threejs.org/examples/#webgl_geometry_text | geometry / text } - * @see Example: {@link https://threejs.org/examples/#webgl_lensflares | lensflares } - * @see {@link https://threejs.org/docs/index.html#api/en/lights/PointLight | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/lights/PointLight.js | Source} - */ -export class PointLight extends Light { - /** - * Creates a new PointLight. - * @param color Hexadecimal color of the light. Default is 0xffffff (white). Expects a `Integer` - * @param intensity Numeric value of the light's strength/intensity. Expects a `Float`. Default `1` - * @param distance Maximum range of the light. Default is 0 (no limit). - * @param decay The amount the light dims along the distance of the light. Expects a `Float`. Default `2` - */ - constructor(color?: ColorRepresentation, intensity?: number, distance?: number, decay?: number); - - /** - * Read-only flag to check if a given object is of type {@link PointLight}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isPointLight: true; - - /** - * @default 'PointLight' - */ - type: string; - - /** - * The light's intensity. - * - * When **{@link WebGLRenderer.useLegacyLights | legacy lighting mode} is disabled** — intensity is the luminous intensity of the light measured in candela (cd). - * @remarks Changing the intensity will also change the light's power. - * @remarks Expects a `Float` - * @defaultValue `1` - */ - intensity: number; - - /** - * When **Default mode** — When distance is zero, light does not attenuate. When distance is non-zero, - * light will attenuate linearly from maximum intensity at the light's position down to zero at this distance from the light. - * - * When **{@link WebGLRenderer.useLegacyLights | legacy lighting mode} is disabled** — When distance is zero, - * light will attenuate according to inverse-square law to infinite distance. - * When distance is non-zero, light will attenuate according to inverse-square law until near the distance cutoff, - * where it will then attenuate quickly and smoothly to 0. Inherently, cutoffs are not physically correct. - * - * @defaultValue `0.0` - * @remarks Expects a `Float` - */ - distance: number; - - /** - * If set to `true` light will cast dynamic shadows. - * **Warning**: This is expensive and requires tweaking to get shadows looking right. - * @see {@link THREE.PointLightShadow | PointLightShadow} for details. - * @defaultValue `false` - */ - castShadow: boolean; - - /** - * The amount the light dims along the distance of the light. - * In context of physically-correct rendering the default value should not be changed. - * @remarks Expects a `Float` - * @defaultValue `2` - */ - decay: number; - - /** - * A {@link THREE.PointLightShadow | PointLightShadow} used to calculate shadows for this light. - * The lightShadow's {@link LightShadow.camera | camera} is set to - * a {@link THREE.PerspectiveCamera | PerspectiveCamera} with {@link PerspectiveCamera.fov | fov} of 90, - * {@link PerspectiveCamera.aspect | aspect} of 1, - * {@link PerspectiveCamera.near | near} clipping plane at 0.5 - * and {@link PerspectiveCamera.far | far} clipping plane at 500. - * @defaultValue new THREE.PointLightShadow() - */ - shadow: PointLightShadow; - - /** - * The light's power. - * When **{@link WebGLRenderer.useLegacyLights | legacy lighting mode} is disabled** — power is the luminous power of the light measured in lumens (lm). - * @remarks Changing the power will also change the light's intensity. - * @remarks Expects a `Float` - */ - power: number; -} diff --git a/src-testing/src/lights/PointLightShadow.d.ts b/src-testing/src/lights/PointLightShadow.d.ts deleted file mode 100644 index 1d0e7e4af..000000000 --- a/src-testing/src/lights/PointLightShadow.d.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { PerspectiveCamera } from "../cameras/PerspectiveCamera.js"; -import { Light } from "./Light.js"; -import { LightShadow } from "./LightShadow.js"; - -/** - * Shadow for {@link THREE.PointLight | PointLight} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/lights/PointLightShadow.js | Source} - */ -export class PointLightShadow extends LightShadow { - /** - * Read-only flag to check if a given object is of type {@link PointLightShadow}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isPointLightShadow = true; - - /** - * Update the matrices for the camera and shadow, used internally by the renderer. - * @param light The light for which the shadow is being rendered. - */ - override updateMatrices(light: Light, viewportIndex?: number): void; -} diff --git a/src-testing/src/lights/RectAreaLight.d.ts b/src-testing/src/lights/RectAreaLight.d.ts deleted file mode 100644 index 2861e9794..000000000 --- a/src-testing/src/lights/RectAreaLight.d.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { ColorRepresentation } from "../math/Color.js"; -import { Light } from "./Light.js"; - -/** - * {@link RectAreaLight} emits light uniformly across the face a rectangular plane - * @remarks - * This light type can be used to simulate light sources such as bright windows or strip lighting. - * Important Notes: - * - There is no shadow support. - * - Only {@link MeshStandardMaterial | MeshStandardMaterial} and {@link MeshPhysicalMaterial | MeshPhysicalMaterial} are supported. - * - You have to include {@link https://threejs.org/examples/jsm/lights/RectAreaLightUniformsLib.js | RectAreaLightUniformsLib} into your scene and call `init()`. - * @example - * ```typescript - * const width = 10; - * const height = 10; - * const intensity = 1; - * const rectLight = new THREE.RectAreaLight(0xffffff, intensity, width, height); - * rectLight.position.set(5, 5, 0); - * rectLight.lookAt(0, 0, 0); - * scene.add(rectLight) - * const rectLightHelper = new RectAreaLightHelper(rectLight); - * rectLight.add(rectLightHelper); - * ``` - * @see Example: {@link https://threejs.org/examples/#webgl_lights_rectarealight | WebGL / {@link RectAreaLight} } - * @see {@link https://threejs.org/docs/index.html#api/en/lights/RectAreaLight | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/lights/RectAreaLight.js | Source} - */ -export class RectAreaLight extends Light { - /** - * Creates a new {@link RectAreaLight}. - * @param color Hexadecimal color of the light. Default `0xffffff` _(white)_. - * @param intensity The light's intensity, or brightness. Expects a `Float`. Default `1` - * @param width Width of the light. Expects a `Float`. Default `10` - * @param height Height of the light. Expects a `Float`. Default `10` - */ - constructor(color?: ColorRepresentation, intensity?: number, width?: number, height?: number); - - /** - * Read-only flag to check if a given object is of type {@link RectAreaLight}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isRectAreaLight: true; - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `RectAreaLight` - */ - override readonly type: string | "RectAreaLight"; - - /** - * The width of the light. - * @remarks Expects a `Float` - * @defaultValue `10` - */ - width: number; - - /** - * The height of the light. - * @remarks Expects a `Float` - * @defaultValue `10` - */ - height: number; - - /** - * The light's intensity. - * @remarks Changing the intensity will also change the light's power. - * When **{@link WebGLRenderer.useLegacyLights | legacy lighting mode} is disabled** — intensity is the luminance (brightness) of the light measured in nits (cd/m^2). - * @remarks Expects a `Float` - * @defaultValue `1` - */ - intensity: number; - - /** - * The light's power. - * @remarks Changing the power will also change the light's intensity. - * When **{@link WebGLRenderer.useLegacyLights | legacy lighting mode} is disabled** — power is the luminous power of the light measured in lumens (lm). - * @remarks Expects a `Float` - */ - power: number; -} diff --git a/src-testing/src/lights/SpotLight.d.ts b/src-testing/src/lights/SpotLight.d.ts deleted file mode 100644 index 7f42488a8..000000000 --- a/src-testing/src/lights/SpotLight.d.ts +++ /dev/null @@ -1,164 +0,0 @@ -import { Object3D } from "../core/Object3D.js"; -import { ColorRepresentation } from "../math/Color.js"; -import { Vector3 } from "../math/Vector3.js"; -import { Texture } from "../textures/Texture.js"; -import { Light } from "./Light.js"; -import { SpotLightShadow } from "./SpotLightShadow.js"; - -/** - * This light gets emitted from a single point in one direction, along a cone that increases in size the further from the light it gets. - * @example - * ```typescript - * // white {@link SpotLight} shining from the side, modulated by a texture, casting a shadow - * const {@link SpotLight} = new THREE.SpotLight(0xffffff); - * spotLight.position.set(100, 1000, 100); - * spotLight.map = new THREE.TextureLoader().load(url); - * spotLight.castShadow = true; - * spotLight.shadow.mapSize.width = 1024; - * spotLight.shadow.mapSize.height = 1024; - * spotLight.shadow.camera.near = 500; - * spotLight.shadow.camera.far = 4000; - * spotLight.shadow.camera.fov = 30; - * scene.add(spotLight); - * ``` - * @see Example: {@link https://threejs.org/examples/#webgl_lights_spotlight | lights / {@link SpotLight} } - * @see Example: {@link https://threejs.org/examples/#webgl_lights_spotlights | lights / spotlights } - * @see {@link https://threejs.org/docs/index.html#api/en/lights/SpotLight | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/lights/SpotLight.js | Source} - */ -export class SpotLight extends Light { - /** - * Creates a new SpotLight. - * @param color Hexadecimal color of the light. Default `0xffffff` _(white)_. - * @param intensity Numeric value of the light's strength/intensity. Expects a `Float`. Default `1`. - * @param distance Maximum range of the light. Default is 0 (no limit). Expects a `Float`. - * @param angle Maximum angle of light dispersion from its direction whose upper bound is Math.PI/2. - * @param penumbra Percent of the {@link SpotLight} cone that is attenuated due to penumbra. Takes values between zero and 1. Expects a `Float`. Default `0`. - * @param decay The amount the light dims along the distance of the light. Expects a `Float`. Default `2`. - */ - constructor( - color?: ColorRepresentation, - intensity?: number, - distance?: number, - angle?: number, - penumbra?: number, - decay?: number, - ); - - /** - * Read-only flag to check if a given object is of type {@link SpotLight}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isSpotLight: true; - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `SpotLight` - */ - override readonly type: string | "SpotLight"; - - /** - * This is set equal to {@link THREE.Object3D.DEFAULT_UP | Object3D.DEFAULT_UP} (0, 1, 0), so that the light shines from the top down. - * @defaultValue `{@link Object3D.DEFAULT_UP}` - */ - readonly position: Vector3; - - /** - * The {@link SpotLight} points from its {@link SpotLight.position | position} to target.position. - * @remarks - * **Note**: For the target's position to be changed to anything other than the default, - * it must be added to the {@link Scene | scene} using - * - * ```typescript - * scene.add( light.target ); - * ``` - * - * This is so that the target's {@link Object3D.matrixWorld | matrixWorld} gets automatically updated each frame. - * It is also possible to set the target to be another object in the scene (anything with a {@link THREE.Object3D.position | position} property), like so: - * ```typescript - * const targetObject = new THREE.Object3D(); - * scene.add(targetObject); - * light.target = targetObject; - * ``` - * The {@link SpotLight} will now track the target object. - * @defaultValue `new THREE.Object3D()` _The default position of the target is *(0, 0, 0)*._ - */ - target: Object3D; - - /** - * If set to `true` light will cast dynamic shadows. - * @remarks **Warning**: This is expensive and requires tweaking to get shadows looking right. the {@link THREE.SpotLightShadow | SpotLightShadow} for details. - * @defaultValue `false` - */ - override castShadow: boolean; - - /** - * The light's intensity. - * @remarks Changing the intensity will also change the light's power. - * When **{@link WebGLRenderer.useLegacyLights | legacy lighting mode} is disabled** — intensity is the luminous intensity of the light measured in candela (cd). - * @remarks Expects a `Float` - * @defaultValue `1` - */ - intensity: number; - - /** - * When **Default mode** — When distance is zero, light does not attenuate. When distance is non-zero, - * light will attenuate linearly from maximum intensity at the light's position down to zero at this distance from the light. - * - * When **{@link WebGLRenderer.useLegacyLights | legacy lighting mode} is disabled** — When distance is zero, - * light will attenuate according to inverse-square law to infinite distance. - * When distance is non-zero, light will attenuate according to inverse-square law until near the distance cutoff, - * where it will then attenuate quickly and smoothly to `0`. Inherently, cutoffs are not physically correct. - * @remarks Expects a `Float` - * @defaultValue `0.0` - */ - distance: number; - - /** - * Maximum extent of the spotlight, in radians, from its direction. - * @remarks Should be no more than `Math.PI/2`. - * @remarks Expects a `Float` - * @defaultValue `Math.PI / 3` - */ - angle: number; - - /** - * The amount the light dims along the distance of the light. - * In context of physically-correct rendering the default value should not be changed. - * @remarks Expects a `Float` - * @defaultValue `2` - */ - decay: number; - - /** - * A {@link THREE.SpotLightShadow | SpotLightShadow} used to calculate shadows for this light. - * @defaultValue `new THREE.SpotLightShadow()` - */ - shadow: SpotLightShadow; - - /** - * The light's power. - * @remarks Changing the power will also change the light's intensity. - * When **{@link WebGLRenderer.useLegacyLights | legacy lighting mode} is disabled** — power is the luminous power of the light measured in lumens (lm). - * @remarks Expects a `Float` - */ - power: number; - - /** - * Percent of the {@link SpotLight} cone that is attenuated due to penumbra. - * @remarks Takes values between zero and 1. - * @remarks Expects a `Float` - * @defaultValue `0.0` - */ - penumbra: number; - - /** - * A {@link THREE.Texture | Texture} used to modulate the color of the light. - * The spot light color is mixed with the _RGB_ value of this texture, with a ratio corresponding to its alpha value. - * The cookie-like masking effect is reproduced using pixel values (0, 0, 0, 1-cookie_value). - * @remarks **Warning**: {@link SpotLight.map} is disabled if {@link SpotLight.castShadow} is `false`. - */ - map: Texture | null; -} diff --git a/src-testing/src/lights/SpotLightShadow.d.ts b/src-testing/src/lights/SpotLightShadow.d.ts deleted file mode 100644 index 77f075c44..000000000 --- a/src-testing/src/lights/SpotLightShadow.d.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { PerspectiveCamera } from "../cameras/PerspectiveCamera.js"; -import { LightShadow } from "./LightShadow.js"; - -/** - * This is used internally by {@link SpotLight | SpotLights} for calculating shadows. - * @example - * ```typescript - * //Create a WebGLRenderer and turn on shadows in the renderer - * const renderer = new THREE.WebGLRenderer(); - * renderer.shadowMap.enabled = true; - * renderer.shadowMap.type = THREE.PCFSoftShadowMap; // default THREE.PCFShadowMap - * //Create a SpotLight and turn on shadows for the light - * const light = new THREE.SpotLight(0xffffff); - * light.castShadow = true; // default false - * scene.add(light); - * //Set up shadow properties for the light - * light.shadow.mapSize.width = 512; // default - * light.shadow.mapSize.height = 512; // default - * light.shadow.camera.near = 0.5; // default - * light.shadow.camera.far = 500; // default - * light.shadow.focus = 1; // default - * //Create a sphere that cast shadows (but does not receive them) - * const sphereGeometry = new THREE.SphereGeometry(5, 32, 32); - * const sphereMaterial = new THREE.MeshStandardMaterial({ - * color: 0xff0000 - * }); - * const sphere = new THREE.Mesh(sphereGeometry, sphereMaterial); - * sphere.castShadow = true; //default is false - * sphere.receiveShadow = false; //default - * scene.add(sphere); - * //Create a plane that receives shadows (but does not cast them) - * const planeGeometry = new THREE.PlaneGeometry(20, 20, 32, 32); - * const planeMaterial = new THREE.MeshStandardMaterial({ - * color: 0x00ff00 - * }) - * const plane = new THREE.Mesh(planeGeometry, planeMaterial); - * plane.receiveShadow = true; - * scene.add(plane); - * //Create a helper for the shadow camera (optional) - * const helper = new THREE.CameraHelper(light.shadow.camera); - * scene.add(helper); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/lights/shadows/SpotLightShadow | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/lights/SpotLightShadow.js | Source} - */ -export class SpotLightShadow extends LightShadow { - /** - * Read-only flag to check if a given object is of type {@link SpotLightShadow}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isSpotLightShadow: true; - - /** - * The light's view of the world. - * @remarks This is used to generate a depth map of the scene; objects behind other objects from the light's perspective will be in shadow. - * @remarks - * The {@link THREE.PerspectiveCamera.fov | fov} will track the {@link THREE.SpotLight.angle | angle} property - * of the owning {@link SpotLight | SpotLight} via the {@link SpotLightShadow.update | update} method. - * Similarly, the {@link THREE.PerspectiveCamera.aspect | aspect} property will track the aspect of the {@link LightShadow.mapSize | mapSize}. - * If the {@link SpotLight.distance | distance} property of the light is set, the {@link THREE.PerspectiveCamera.far | far} clipping plane will track that, otherwise it defaults to `500`. - * @defaultValue is a {@link THREE.PerspectiveCamera | PerspectiveCamera} with {@link THREE.PerspectiveCamera.near | near} clipping plane at `0.5`. - */ - camera: PerspectiveCamera; - - /** - * Used to focus the shadow camera. - * @remarks The camera's field of view is set as a percentage of the spotlight's field-of-view. Range is `[0, 1]`. 0`. - * @defaultValue `1` - */ - focus: number; -} diff --git a/src-testing/src/lights/webgpu/IESSpotLight.d.ts b/src-testing/src/lights/webgpu/IESSpotLight.d.ts deleted file mode 100644 index bf1b66006..000000000 --- a/src-testing/src/lights/webgpu/IESSpotLight.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { Texture } from "../../textures/Texture.js"; -import { SpotLight } from "../SpotLight.js"; - -export default class IESSpotLight extends SpotLight { - iesMap: Texture | null; -} diff --git a/src-testing/src/loaders/AnimationLoader.d.ts b/src-testing/src/loaders/AnimationLoader.d.ts deleted file mode 100644 index 567f30f30..000000000 --- a/src-testing/src/loaders/AnimationLoader.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { AnimationClip } from "../animation/AnimationClip.js"; -import { Loader } from "./Loader.js"; -import { LoadingManager } from "./LoadingManager.js"; - -export class AnimationLoader extends Loader { - constructor(manager?: LoadingManager); - - parse(json: readonly unknown[]): AnimationClip[]; -} diff --git a/src-testing/src/loaders/AudioLoader.d.ts b/src-testing/src/loaders/AudioLoader.d.ts deleted file mode 100644 index 0204bef47..000000000 --- a/src-testing/src/loaders/AudioLoader.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { Loader } from "./Loader.js"; -import { LoadingManager } from "./LoadingManager.js"; - -export class AudioLoader extends Loader { - constructor(manager?: LoadingManager); -} diff --git a/src-testing/src/loaders/BufferGeometryLoader.d.ts b/src-testing/src/loaders/BufferGeometryLoader.d.ts deleted file mode 100644 index 0aa994011..000000000 --- a/src-testing/src/loaders/BufferGeometryLoader.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { BufferGeometry } from "../core/BufferGeometry.js"; -import { InstancedBufferGeometry } from "../core/InstancedBufferGeometry.js"; -import { Loader } from "./Loader.js"; -import { LoadingManager } from "./LoadingManager.js"; - -export class BufferGeometryLoader extends Loader { - constructor(manager?: LoadingManager); - - parse(json: unknown): InstancedBufferGeometry | BufferGeometry; -} diff --git a/src-testing/src/loaders/Cache.d.ts b/src-testing/src/loaders/Cache.d.ts deleted file mode 100644 index 0742af8f5..000000000 --- a/src-testing/src/loaders/Cache.d.ts +++ /dev/null @@ -1,21 +0,0 @@ -declare const Cache: { - /** - * @default false - */ - enabled: boolean; - - /** - * @default {} - */ - files: any; - - add(key: string, file: any): void; - - get(key: string): any; - - remove(key: string): void; - - clear(): void; -}; - -export { Cache }; diff --git a/src-testing/src/loaders/CompressedTextureLoader.d.ts b/src-testing/src/loaders/CompressedTextureLoader.d.ts deleted file mode 100644 index eeca01ded..000000000 --- a/src-testing/src/loaders/CompressedTextureLoader.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { CompressedTexture } from "../textures/CompressedTexture.js"; -import { Loader } from "./Loader.js"; -import { LoadingManager } from "./LoadingManager.js"; - -export class CompressedTextureLoader extends Loader { - constructor(manager?: LoadingManager); - - load( - url: string, - onLoad?: (data: CompressedTexture) => void, - onProgress?: (event: ProgressEvent) => void, - onError?: (err: unknown) => void, - ): CompressedTexture; -} diff --git a/src-testing/src/loaders/CubeTextureLoader.d.ts b/src-testing/src/loaders/CubeTextureLoader.d.ts deleted file mode 100644 index f6cd285c4..000000000 --- a/src-testing/src/loaders/CubeTextureLoader.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { CubeTexture } from "../textures/CubeTexture.js"; -import { Loader } from "./Loader.js"; -import { LoadingManager } from "./LoadingManager.js"; - -export class CubeTextureLoader extends Loader { - constructor(manager?: LoadingManager); - - load( - url: readonly string[], - onLoad?: (data: CubeTexture) => void, - onProgress?: (event: ProgressEvent) => void, - onError?: (err: unknown) => void, - ): CubeTexture; -} diff --git a/src-testing/src/loaders/DataTextureLoader.d.ts b/src-testing/src/loaders/DataTextureLoader.d.ts deleted file mode 100644 index 0cc8d7475..000000000 --- a/src-testing/src/loaders/DataTextureLoader.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { DataTexture } from "../textures/DataTexture.js"; -import { Loader } from "./Loader.js"; -import { LoadingManager } from "./LoadingManager.js"; - -export class DataTextureLoader extends Loader { - constructor(manager?: LoadingManager); - - load( - url: string, - onLoad?: (data: DataTexture, texData: object) => void, - onProgress?: (event: ProgressEvent) => void, - onError?: (err: unknown) => void, - ): DataTexture; -} diff --git a/src-testing/src/loaders/FileLoader.d.ts b/src-testing/src/loaders/FileLoader.d.ts deleted file mode 100644 index 25ceba9cd..000000000 --- a/src-testing/src/loaders/FileLoader.d.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Loader } from "./Loader.js"; -import { LoadingManager } from "./LoadingManager.js"; - -export class FileLoader extends Loader { - constructor(manager?: LoadingManager); - - load( - url: string, - onLoad?: (data: string | ArrayBuffer) => void, - onProgress?: (event: ProgressEvent) => void, - onError?: (err: unknown) => void, - ): void; - - mimeType: string | undefined; - responseType: string | undefined; - - setMimeType(mimeType: string): FileLoader; - setResponseType(responseType: string): FileLoader; -} diff --git a/src-testing/src/loaders/ImageBitmapLoader.d.ts b/src-testing/src/loaders/ImageBitmapLoader.d.ts deleted file mode 100644 index f182d326a..000000000 --- a/src-testing/src/loaders/ImageBitmapLoader.d.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Loader } from "./Loader.js"; -import { LoadingManager } from "./LoadingManager.js"; - -export class ImageBitmapLoader extends Loader { - constructor(manager?: LoadingManager); - - load( - url: string, - onLoad?: (data: ImageBitmap) => void, - onProgress?: (event: ProgressEvent) => void, - onError?: (err: unknown) => void, - ): void; - - /** - * @default { premultiplyAlpha: 'none' } - */ - options: undefined | object; - - readonly isImageBitmapLoader: true; - - setOptions(options: object): ImageBitmapLoader; -} diff --git a/src-testing/src/loaders/ImageLoader.d.ts b/src-testing/src/loaders/ImageLoader.d.ts deleted file mode 100644 index 2189198e4..000000000 --- a/src-testing/src/loaders/ImageLoader.d.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { Loader } from "./Loader.js"; -import { LoadingManager } from "./LoadingManager.js"; - -/** - * A loader for loading an image. - * Unlike other loaders, this one emits events instead of using predefined callbacks. So if you're interested in getting notified when things happen, you need to add listeners to the object. - */ -export class ImageLoader extends Loader { - constructor(manager?: LoadingManager); - - load( - url: string, - onLoad?: (data: HTMLImageElement) => void, - onProgress?: (event: ProgressEvent) => void, - onError?: (err: unknown) => void, - ): HTMLImageElement; -} diff --git a/src-testing/src/loaders/Loader.d.ts b/src-testing/src/loaders/Loader.d.ts deleted file mode 100644 index 0f65e66f3..000000000 --- a/src-testing/src/loaders/Loader.d.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { LoadingManager } from "./LoadingManager.js"; - -/** - * Base class for implementing loaders. - */ -export class Loader { - constructor(manager?: LoadingManager); - - /** - * @default 'anonymous' - */ - crossOrigin: string; - - /** - * @default false - */ - withCredentials: boolean; - - /** - * @default '' - */ - path: string; - - /** - * @default '' - */ - resourcePath: string; - manager: LoadingManager; - - /** - * @default {} - */ - requestHeader: { [header: string]: string }; - - load( - url: TUrl, - onLoad: (data: TData) => void, - onProgress?: (event: ProgressEvent) => void, - onError?: (err: unknown) => void, - ): void; - loadAsync(url: TUrl, onProgress?: (event: ProgressEvent) => void): Promise; - - setCrossOrigin(crossOrigin: string): this; - setWithCredentials(value: boolean): this; - setPath(path: string): this; - setResourcePath(resourcePath: string): this; - setRequestHeader(requestHeader: { [header: string]: string }): this; - - static DEFAULT_MATERIAL_NAME: string; -} diff --git a/src-testing/src/loaders/LoaderUtils.d.ts b/src-testing/src/loaders/LoaderUtils.d.ts deleted file mode 100644 index 2f00baeff..000000000 --- a/src-testing/src/loaders/LoaderUtils.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -export class LoaderUtils { - /** - * @deprecated decodeText() has been deprecated with r165 and will be removed with r175. Use TextDecoder instead. - */ - static decodeText(array: BufferSource): string; - - static extractUrlBase(url: string): string; - - static resolveURL(url: string, path: string): string; -} diff --git a/src-testing/src/loaders/LoadingManager.d.ts b/src-testing/src/loaders/LoadingManager.d.ts deleted file mode 100644 index ab5b546cd..000000000 --- a/src-testing/src/loaders/LoadingManager.d.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { Loader } from "./Loader.js"; - -export const DefaultLoadingManager: LoadingManager; - -/** - * Handles and keeps track of loaded and pending data. - */ -export class LoadingManager { - constructor( - onLoad?: () => void, - onProgress?: (url: string, loaded: number, total: number) => void, - onError?: (url: string) => void, - ); - - /** - * Will be called when loading of an item starts. - * @param url The url of the item that started loading. - * @param loaded The number of items already loaded so far. - * @param total The total amount of items to be loaded. - */ - onStart?: ((url: string, loaded: number, total: number) => void) | undefined; - - /** - * Will be called when all items finish loading. - * The default is a function with empty body. - */ - onLoad: () => void; - - /** - * Will be called for each loaded item. - * The default is a function with empty body. - * @param url The url of the item just loaded. - * @param loaded The number of items already loaded so far. - * @param total The total amount of items to be loaded. - */ - onProgress: (url: string, loaded: number, total: number) => void; - - /** - * Will be called when item loading fails. - * The default is a function with empty body. - * @param url The url of the item that errored. - */ - onError: (url: string) => void; - - /** - * If provided, the callback will be passed each resource URL before a request is sent. - * The callback may return the original URL, or a new URL to override loading behavior. - * This behavior can be used to load assets from .ZIP files, drag-and-drop APIs, and Data URIs. - * @param callback URL modifier callback. Called with url argument, and must return resolvedURL. - */ - setURLModifier(callback?: (url: string) => string): this; - - /** - * Given a URL, uses the URL modifier callback (if any) and returns a resolved URL. - * If no URL modifier is set, returns the original URL. - * @param url the url to load - */ - resolveURL(url: string): string; - - itemStart(url: string): void; - itemEnd(url: string): void; - itemError(url: string): void; - - // handlers - - addHandler(regex: RegExp, loader: Loader): this; - removeHandler(regex: RegExp): this; - getHandler(file: string): Loader | null; -} diff --git a/src-testing/src/loaders/MaterialLoader.d.ts b/src-testing/src/loaders/MaterialLoader.d.ts deleted file mode 100644 index 742c22a04..000000000 --- a/src-testing/src/loaders/MaterialLoader.d.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { Material } from "../materials/Material.js"; -import { Texture } from "../textures/Texture.js"; -import { Loader } from "./Loader.js"; -import { LoadingManager } from "./LoadingManager.js"; - -export class MaterialLoader extends Loader { - /** - * @default {} - */ - textures: { [key: string]: Texture }; - - constructor(manager?: LoadingManager); - - parse(json: unknown): Material; - - setTextures(textures: { [key: string]: Texture }): this; - - createMaterialFromType(type: string): Material; - - static createMaterialFromType(type: string): Material; -} diff --git a/src-testing/src/loaders/ObjectLoader.d.ts b/src-testing/src/loaders/ObjectLoader.d.ts deleted file mode 100644 index 306c75700..000000000 --- a/src-testing/src/loaders/ObjectLoader.d.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { AnimationClip } from "../animation/AnimationClip.js"; -import { BufferGeometry } from "../core/BufferGeometry.js"; -import { InstancedBufferGeometry } from "../core/InstancedBufferGeometry.js"; -import { Object3D } from "../core/Object3D.js"; -import { Material } from "../materials/Material.js"; -import { Source } from "../textures/Source.js"; -import { Texture } from "../textures/Texture.js"; -import { Loader } from "./Loader.js"; -import { LoadingManager } from "./LoadingManager.js"; - -export class ObjectLoader extends Loader { - constructor(manager?: LoadingManager); - - load( - url: string, - onLoad?: (data: Object3D) => void, - onProgress?: (event: ProgressEvent) => void, - onError?: (err: unknown) => void, - ): void; - - parse(json: unknown, onLoad?: (object: Object3D) => void): Object3D; - parseAsync(json: unknown): Promise; - parseGeometries(json: unknown): { [key: string]: InstancedBufferGeometry | BufferGeometry }; - parseMaterials(json: unknown, textures: { [key: string]: Texture }): { [key: string]: Material }; - parseAnimations(json: unknown): { [key: string]: AnimationClip }; - parseImages(json: unknown, onLoad?: () => void): { [key: string]: Source }; - parseImagesAsync(json: unknown): Promise<{ [key: string]: Source }>; - parseTextures(json: unknown, images: { [key: string]: Source }): { [key: string]: Texture }; - parseObject( - data: unknown, - geometries: { [key: string]: InstancedBufferGeometry | BufferGeometry }, - materials: { [key: string]: Material }, - animations: { [key: string]: AnimationClip }, - ): Object3D; -} diff --git a/src-testing/src/loaders/TextureLoader.d.ts b/src-testing/src/loaders/TextureLoader.d.ts deleted file mode 100644 index 3cc07f5c3..000000000 --- a/src-testing/src/loaders/TextureLoader.d.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Texture } from "../textures/Texture.js"; -import { Loader } from "./Loader.js"; -import { LoadingManager } from "./LoadingManager.js"; - -/** - * Class for loading a texture. - * Unlike other loaders, this one emits events instead of using predefined callbacks. So if you're interested in getting notified when things happen, you need to add listeners to the object. - */ -export class TextureLoader extends Loader { - constructor(manager?: LoadingManager); - - load( - url: string, - onLoad?: (data: Texture) => void, - onProgress?: (event: ProgressEvent) => void, - onError?: (err: unknown) => void, - ): Texture; -} diff --git a/src-testing/src/loaders/nodes/NodeLoader.d.ts b/src-testing/src/loaders/nodes/NodeLoader.d.ts deleted file mode 100644 index 9083b2315..000000000 --- a/src-testing/src/loaders/nodes/NodeLoader.d.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { Node } from "../../nodes/Nodes.js"; -import { Texture } from "../../textures/Texture.js"; -import { Loader } from "../Loader.js"; -import { LoadingManager } from "../LoadingManager.js"; - -export interface NodeLoaderResult { - [hash: string]: Node; -} - -export default class NodeLoader extends Loader { - textures: { [key: string]: Texture }; - nodes: { [type: string]: Node }; - - constructor(manager?: LoadingManager); - - parseNodes(json: unknown): NodeLoaderResult; - parse(json: unknown): Node; - setTextures(textures: { [key: string]: Texture }): this; - setNodes(value: { [type: string]: Node }): this; - createNodeFromType(type: string): Node; -} diff --git a/src-testing/src/loaders/nodes/NodeMaterialLoader.d.ts b/src-testing/src/loaders/nodes/NodeMaterialLoader.d.ts deleted file mode 100644 index 89dee9c6a..000000000 --- a/src-testing/src/loaders/nodes/NodeMaterialLoader.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -import NodeMaterial from "../../materials/nodes/NodeMaterial.js"; -import { MaterialLoader } from "../MaterialLoader.js"; -import { NodeLoaderResult } from "./NodeLoader.js"; - -export default class NodeMaterialLoader extends MaterialLoader { - nodes: NodeLoaderResult; - nodeMaterials: { [type: string]: NodeMaterial }; - - setNodes(value: NodeLoaderResult): this; - setNodeMaterials(value: { [type: string]: NodeMaterial }): this; -} diff --git a/src-testing/src/loaders/nodes/NodeObjectLoader.d.ts b/src-testing/src/loaders/nodes/NodeObjectLoader.d.ts deleted file mode 100644 index 0dbcef8a5..000000000 --- a/src-testing/src/loaders/nodes/NodeObjectLoader.d.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Material } from "../../materials/Material.js"; -import NodeMaterial from "../../materials/nodes/NodeMaterial.js"; -import { Node } from "../../nodes/Nodes.js"; -import { Texture } from "../../textures/Texture.js"; -import { LoadingManager } from "../LoadingManager.js"; -import { ObjectLoader } from "../ObjectLoader.js"; -import { NodeLoaderResult } from "./NodeLoader.js"; - -export default class NodeObjectLoader extends ObjectLoader { - nodes: { [type: string]: Node }; - nodeMaterials: { [type: string]: NodeMaterial }; - - constructor(manager?: LoadingManager); - - setNodes(value: { [type: string]: Node }): this; - - setNodeMaterials(value: { [type: string]: NodeMaterial }): this; - - parseNodes(json: unknown, textures: { [key: string]: Texture }): NodeLoaderResult; - - parseMaterials(json: unknown, textures: { [key: string]: Texture }): { [key: string]: Material }; -} diff --git a/src-testing/src/materials/LineBasicMaterial.d.ts b/src-testing/src/materials/LineBasicMaterial.d.ts deleted file mode 100644 index 7f8bac230..000000000 --- a/src-testing/src/materials/LineBasicMaterial.d.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { Color, ColorRepresentation } from "../math/Color.js"; -import { Texture } from "../textures/Texture.js"; -import { Material, MaterialParameters } from "./Material.js"; - -export interface LineBasicMaterialParameters extends MaterialParameters { - color?: ColorRepresentation | undefined; - fog?: boolean | undefined; - linewidth?: number | undefined; - linecap?: string | undefined; - linejoin?: string | undefined; -} - -export class LineBasicMaterial extends Material { - constructor(parameters?: LineBasicMaterialParameters); - - /** - * Read-only flag to check if a given object is of type {@link LineBasicMaterial}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isLineBasicMaterial: true; - - /** - * @default 0xffffff - */ - color: Color; - - /** - * Whether the material is affected by fog. Default is true. - * @default true - */ - fog: boolean; - - /** - * @default 1 - */ - linewidth: number; - - /** - * @default 'round' - */ - linecap: string; - - /** - * @default 'round' - */ - linejoin: string; - - /** - * Sets the color of the lines using data from a {@link Texture}. - */ - map: Texture | null; - - setValues(parameters: LineBasicMaterialParameters): void; -} diff --git a/src-testing/src/materials/LineDashedMaterial.d.ts b/src-testing/src/materials/LineDashedMaterial.d.ts deleted file mode 100644 index 514bb3f93..000000000 --- a/src-testing/src/materials/LineDashedMaterial.d.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { LineBasicMaterial, LineBasicMaterialParameters } from "./LineBasicMaterial.js"; - -export interface LineDashedMaterialParameters extends LineBasicMaterialParameters { - scale?: number | undefined; - dashSize?: number | undefined; - gapSize?: number | undefined; -} - -export class LineDashedMaterial extends LineBasicMaterial { - constructor(parameters?: LineDashedMaterialParameters); - - /** - * Read-only flag to check if a given object is of type {@link LineDashedMaterial}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isLineDashedMaterial: true; - - /** - * @default 1 - */ - scale: number; - - /** - * @default 1 - */ - dashSize: number; - - /** - * @default 1 - */ - gapSize: number; - - setValues(parameters: LineDashedMaterialParameters): void; -} diff --git a/src-testing/src/materials/Material.d.ts b/src-testing/src/materials/Material.d.ts deleted file mode 100644 index 731bcc89e..000000000 --- a/src-testing/src/materials/Material.d.ts +++ /dev/null @@ -1,629 +0,0 @@ -import { Camera } from "../cameras/Camera.js"; -import { - Blending, - BlendingDstFactor, - BlendingEquation, - BlendingSrcFactor, - Combine, - DepthModes, - NormalMapTypes, - PixelFormat, - Side, - StencilFunc, - StencilOp, -} from "../constants.js"; -import { BufferGeometry } from "../core/BufferGeometry.js"; -import { EventDispatcher } from "../core/EventDispatcher.js"; -import { JSONMeta, Object3D } from "../core/Object3D.js"; -import { Color, ColorRepresentation } from "../math/Color.js"; -import { Plane } from "../math/Plane.js"; -import { Group } from "../objects/Group.js"; -import { WebGLProgramParametersWithUniforms } from "../renderers/webgl/WebGLPrograms.js"; -import { WebGLRenderer } from "../renderers/WebGLRenderer.js"; -import { Scene } from "../scenes/Scene.js"; -import { EulerTuple, SourceJSON, TextureJSON, Vector2Tuple } from "../Three.js"; - -export interface MaterialParameters { - alphaHash?: boolean | undefined; - alphaTest?: number | undefined; - alphaToCoverage?: boolean | undefined; - blendAlpha?: number | undefined; - blendColor?: ColorRepresentation | undefined; - blendDst?: BlendingDstFactor | undefined; - blendDstAlpha?: number | undefined; - blendEquation?: BlendingEquation | undefined; - blendEquationAlpha?: number | undefined; - blending?: Blending | undefined; - blendSrc?: BlendingSrcFactor | BlendingDstFactor | undefined; - blendSrcAlpha?: number | undefined; - clipIntersection?: boolean | undefined; - clippingPlanes?: Plane[] | undefined; - clipShadows?: boolean | undefined; - colorWrite?: boolean | undefined; - defines?: any; - depthFunc?: DepthModes | undefined; - depthTest?: boolean | undefined; - depthWrite?: boolean | undefined; - name?: string | undefined; - opacity?: number | undefined; - polygonOffset?: boolean | undefined; - polygonOffsetFactor?: number | undefined; - polygonOffsetUnits?: number | undefined; - precision?: "highp" | "mediump" | "lowp" | null | undefined; - premultipliedAlpha?: boolean | undefined; - forceSinglePass?: boolean | undefined; - dithering?: boolean | undefined; - side?: Side | undefined; - shadowSide?: Side | undefined; - toneMapped?: boolean | undefined; - transparent?: boolean | undefined; - vertexColors?: boolean | undefined; - visible?: boolean | undefined; - format?: PixelFormat | undefined; - stencilWrite?: boolean | undefined; - stencilFunc?: StencilFunc | undefined; - stencilRef?: number | undefined; - stencilWriteMask?: number | undefined; - stencilFuncMask?: number | undefined; - stencilFail?: StencilOp | undefined; - stencilZFail?: StencilOp | undefined; - stencilZPass?: StencilOp | undefined; - userData?: Record | undefined; -} - -export interface MaterialJSON { - metadata: { version: number; type: string; generator: string }; - - uuid: string; - type: string; - - name?: string; - - color?: number; - roughness?: number; - metalness?: number; - - sheen?: number; - sheenColor?: number; - sheenRoughness?: number; - emissive?: number; - emissiveIntensity?: number; - - specular?: number; - specularIntensity?: number; - specularColor?: number; - shininess?: number; - clearcoat?: number; - clearcoatRoughness?: number; - clearcoatMap?: string; - clearcoatRoughnessMap?: string; - clearcoatNormalMap?: string; - clearcoatNormalScale?: Vector2Tuple; - - dispersion?: number; - - iridescence?: number; - iridescenceIOR?: number; - iridescenceThicknessRange?: number; - iridescenceMap?: string; - iridescenceThicknessMap?: string; - - anisotropy?: number; - anisotropyRotation?: number; - anisotropyMap?: string; - - map?: string; - matcap?: string; - alphaMap?: string; - - lightMap?: string; - lightMapIntensity?: number; - - aoMap?: string; - aoMapIntensity?: number; - - bumpMap?: string; - bumpScale?: number; - - normalMap?: string; - normalMapType?: NormalMapTypes; - normalScale?: Vector2Tuple; - - displacementMap?: string; - displacementScale?: number; - displacementBias?: number; - - roughnessMap?: string; - metalnessMap?: string; - - emissiveMap?: string; - specularMap?: string; - specularIntensityMap?: string; - specularColorMap?: string; - - envMap?: string; - combine?: Combine; - - envMapRotation?: EulerTuple; - envMapIntensity?: number; - reflectivity?: number; - refractionRatio?: number; - - gradientMap?: string; - - transmission?: number; - transmissionMap?: string; - thickness?: number; - thicknessMap?: string; - attenuationDistance?: number; - attenuationColor?: number; - - size?: number; - shadowSide?: number; - sizeAttenuation?: boolean; - - blending?: Blending; - side?: Side; - vertexColors?: boolean; - - opacity?: number; - transparent?: boolean; - - blendSrc?: BlendingSrcFactor; - blendDst?: BlendingDstFactor; - blendEquation?: BlendingEquation; - blendSrcAlpha?: number | null; - blendDstAlpha?: number | null; - blendEquationAlpha?: number | null; - blendColor?: number; - blendAlpha?: number; - - depthFunc?: DepthModes; - depthTest?: boolean; - depthWrite?: boolean; - colorWrite?: boolean; - - stencilWriteMask?: number; - stencilFunc?: StencilFunc; - stencilRef?: number; - stencilFuncMask?: number; - stencilFail?: StencilOp; - stencilZFail?: StencilOp; - stencilZPass?: StencilOp; - stencilWrite?: boolean; - - rotation?: number; - - polygonOffset?: boolean; - polygonOffsetFactor?: number; - polygonOffsetUnits?: number; - - linewidth?: number; - dashSize?: number; - gapSize?: number; - scale?: number; - - dithering?: boolean; - - alphaTest?: number; - alphaHash?: boolean; - alphaToCoverage?: boolean; - premultipliedAlpha?: boolean; - forceSinglePass?: boolean; - - wireframe?: boolean; - wireframeLinewidth?: number; - wireframeLinecap?: string; - wireframeLinejoin?: string; - - flatShading?: boolean; - - visible?: boolean; - - toneMapped?: boolean; - - fog?: boolean; - - userData?: Record; - - textures?: Array>; - images?: SourceJSON[]; -} - -/** - * Materials describe the appearance of objects. They are defined in a (mostly) renderer-independent way, so you don't have to rewrite materials if you decide to use a different renderer. - */ -export class Material extends EventDispatcher<{ dispose: {} }> { - static get type(): string; - - get type(): string; - - constructor(); - - /** - * Read-only flag to check if a given object is of type {@link Material}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isMaterial: true; - - /** - * Enables alpha hashed transparency, an alternative to {@link .transparent} or {@link .alphaTest}. The material - * will not be rendered if opacity is lower than a random threshold. Randomization introduces some grain or noise, - * but approximates alpha blending without the associated problems of sorting. Using TAARenderPass can reduce the - * resulting noise. - */ - alphaHash: boolean; - - /** - * Enables alpha to coverage. Can only be used with MSAA-enabled rendering contexts (meaning when the renderer was - * created with *antialias* parameter set to `true`). Enabling this will smooth aliasing on clip plane edges and - * alphaTest-clipped edges. - * @default false - */ - alphaToCoverage: boolean; - - /** - * Represents the alpha value of the constant blend color. This property has only an effect when using custom - * blending with {@link ConstantAlphaFactor} or {@link OneMinusConstantAlphaFactor}. - * @default 0 - */ - blendAlpha: number; - - /** - * Represent the RGB values of the constant blend color. This property has only an effect when using custom - * blending with {@link ConstantColorFactor} or {@link OneMinusConstantColorFactor}. - * @default 0x000000 - */ - blendColor: Color; - - /** - * Blending destination. It's one of the blending mode constants defined in Three.js. Default is {@link OneMinusSrcAlphaFactor}. - * @default THREE.OneMinusSrcAlphaFactor - */ - blendDst: BlendingDstFactor; - - /** - * The tranparency of the .blendDst. Default is null. - * @default null - */ - blendDstAlpha: number | null; - - /** - * Blending equation to use when applying blending. It's one of the constants defined in Three.js. Default is {@link AddEquation}. - * @default THREE.AddEquation - */ - blendEquation: BlendingEquation; - - /** - * The tranparency of the .blendEquation. Default is null. - * @default null - */ - blendEquationAlpha: number | null; - - /** - * Which blending to use when displaying objects with this material. Default is {@link NormalBlending}. - * @default THREE.NormalBlending - */ - blending: Blending; - - /** - * Blending source. It's one of the blending mode constants defined in Three.js. Default is {@link SrcAlphaFactor}. - * @default THREE.SrcAlphaFactor - */ - blendSrc: BlendingSrcFactor | BlendingDstFactor; - - /** - * The tranparency of the .blendSrc. Default is null. - * @default null - */ - blendSrcAlpha: number | null; - - /** - * Changes the behavior of clipping planes so that only their intersection is clipped, rather than their union. Default is false. - * @default false - */ - clipIntersection: boolean; - - /** - * User-defined clipping planes specified as THREE.Plane objects in world space. - * These planes apply to the objects this material is attached to. - * Points in space whose signed distance to the plane is negative are clipped (not rendered). - * See the WebGL / clipping /intersection example. Default is null. - * @default null - */ - clippingPlanes: Plane[] | null; - - /** - * Defines whether to clip shadows according to the clipping planes specified on this material. Default is false. - * @default false - */ - clipShadows: boolean; - - /** - * Whether to render the material's color. This can be used in conjunction with a mesh's .renderOrder property to create invisible objects that occlude other objects. Default is true. - * @default true - */ - colorWrite: boolean; - - /** - * Custom defines to be injected into the shader. These are passed in form of an object literal, with key/value pairs. { MY_CUSTOM_DEFINE: '' , PI2: Math.PI * 2 }. - * The pairs are defined in both vertex and fragment shaders. Default is undefined. - * @default undefined - */ - defines: undefined | { [key: string]: any }; - - /** - * Which depth function to use. Default is {@link LessEqualDepth}. See the depth mode constants for all possible values. - * @default THREE.LessEqualDepth - */ - depthFunc: DepthModes; - - /** - * Whether to have depth test enabled when rendering this material. When the depth test is disabled, the depth write - * will also be implicitly disabled. - * @default true - */ - depthTest: boolean; - - /** - * Whether rendering this material has any effect on the depth buffer. Default is true. - * When drawing 2D overlays it can be useful to disable the depth writing in order to layer several things together without creating z-index artifacts. - * @default true - */ - depthWrite: boolean; - - /** - * Unique number of this material instance. - */ - id: number; - - /** - * Whether rendering this material has any effect on the stencil buffer. Default is *false*. - * @default false - */ - stencilWrite: boolean; - - /** - * The stencil comparison function to use. Default is {@link AlwaysStencilFunc}. See stencil operation constants for all possible values. - * @default THREE.AlwaysStencilFunc - */ - stencilFunc: StencilFunc; - - /** - * The value to use when performing stencil comparisons or stencil operations. Default is *0*. - * @default 0 - */ - stencilRef: number; - - /** - * The bit mask to use when writing to the stencil buffer. Default is *0xFF*. - * @default 0xff - */ - stencilWriteMask: number; - - /** - * The bit mask to use when comparing against the stencil buffer. Default is *0xFF*. - * @default 0xff - */ - stencilFuncMask: number; - - /** - * Which stencil operation to perform when the comparison function returns false. Default is {@link KeepStencilOp}. See the stencil operation constants for all possible values. - * @default THREE.KeepStencilOp - */ - stencilFail: StencilOp; - - /** - * Which stencil operation to perform when the comparison function returns true but the depth test fails. - * Default is {@link KeepStencilOp}. - * See the stencil operation constants for all possible values. - * @default THREE.KeepStencilOp - */ - stencilZFail: StencilOp; - - /** - * Which stencil operation to perform when the comparison function returns true and the depth test passes. - * Default is {@link KeepStencilOp}. - * See the stencil operation constants for all possible values. - * @default THREE.KeepStencilOp - */ - stencilZPass: StencilOp; - - /** - * Material name. Default is an empty string. - * @default '' - */ - name: string; - - /** - * Opacity. Default is 1. - * @default 1 - */ - opacity: number; - - /** - * Whether to use polygon offset. Default is false. This corresponds to the POLYGON_OFFSET_FILL WebGL feature. - * @default false - */ - polygonOffset: boolean; - - /** - * Sets the polygon offset factor. Default is 0. - * @default 0 - */ - polygonOffsetFactor: number; - - /** - * Sets the polygon offset units. Default is 0. - * @default 0 - */ - polygonOffsetUnits: number; - - /** - * Override the renderer's default precision for this material. Can be "highp", "mediump" or "lowp". Defaults is null. - * @default null - */ - precision: "highp" | "mediump" | "lowp" | null; - - /** - * Whether to premultiply the alpha (transparency) value. See WebGL / Materials / Transparency for an example of the difference. Default is false. - * @default false - */ - premultipliedAlpha: boolean; - - /** - * @default false - */ - forceSinglePass: boolean; - - /** - * Whether to apply dithering to the color to remove the appearance of banding. Default is false. - * @default false - */ - dithering: boolean; - - /** - * Defines which of the face sides will be rendered - front, back or both. - * Default is {@link THREE.FrontSide}. Other options are {@link THREE.BackSide} and {@link THREE.DoubleSide}. - * - * @default {@link THREE.FrontSide} - */ - side: Side; - - /** - * Defines which of the face sides will cast shadows. Default is *null*. - * If *null*, the value is opposite that of side, above. - * @default null - */ - shadowSide: Side | null; - - /** - * Defines whether this material is tone mapped according to the renderer's - * {@link WebGLRenderer.toneMapping toneMapping} setting. It is ignored when rendering to a render target or using - * post processing. - * @default true - */ - toneMapped: boolean; - - /** - * Defines whether this material is transparent. This has an effect on rendering as transparent objects need special treatment and are rendered after non-transparent objects. - * When set to true, the extent to which the material is transparent is controlled by setting it's .opacity property. - * @default false - */ - transparent: boolean; - - /** - * UUID of this material instance. This gets automatically assigned, so this shouldn't be edited. - */ - uuid: string; - - /** - * Defines whether vertex coloring is used. Default is false. - * @default false - */ - vertexColors: boolean; - - /** - * Defines whether this material is visible. Default is true. - * @default true - */ - visible: boolean; - - /** - * An object that can be used to store custom data about the Material. It should not hold references to functions as these will not be cloned. - * @default {} - */ - userData: Record; - - /** - * This starts at 0 and counts how many times .needsUpdate is set to true. - * @default 0 - */ - version: number; - - /** - * Gets the alpha value to be used when running an alpha test. Default is 0. - * @default 0 - */ - get alphaTest(): number; - - /** - * Sets the alpha value to be used when running an alpha test. Default is 0. - * @default 0 - */ - set alphaTest(value: number); - - /** - * An optional callback that is executed immediately before the material is used to render a 3D object. - * Unlike properties, the callback is not supported by {@link .clone()}, {@link .copy()} and {@link .toJSON()}. - * This callback is only supported in `WebGLRenderer` (not `WebGPURenderer`). - */ - onBeforeRender( - renderer: WebGLRenderer, - scene: Scene, - camera: Camera, - geometry: BufferGeometry, - object: Object3D, - group: Group, - ): void; - - /** - * An optional callback that is executed immediately before the shader program is compiled. - * This function is called with the shader source code as a parameter. - * Useful for the modification of built-in materials. - * Unlike properties, the callback is not supported by {@link .clone()}, {@link .copy()} and {@link .toJSON()}. - * This callback is only supported in `WebGLRenderer` (not `WebGPURenderer`). - * @param parameters WebGL program parameters - * @param renderer WebGLRenderer context that is initializing the material - */ - onBeforeCompile(parameters: WebGLProgramParametersWithUniforms, renderer: WebGLRenderer): void; - - /** - * In case onBeforeCompile is used, this callback can be used to identify values of settings used in onBeforeCompile, so three.js can reuse a cached shader or recompile the shader as needed. - */ - customProgramCacheKey(): string; - - /** - * Sets the properties based on the values. - * @param values A container with parameters. - */ - setValues(values: MaterialParameters): void; - - /** - * Convert the material to three.js JSON format. - * @param meta Object containing metadata such as textures or images for the material. - */ - toJSON(meta?: JSONMeta): MaterialJSON; - - /** - * Return a new material with the same parameters as this material. - */ - clone(): this; - - /** - * Copy the parameters from the passed material into this material. - * @param material - */ - copy(material: Material): this; - - /** - * Frees the GPU-related resources allocated by this instance. Call this method whenever this instance is no longer - * used in your app. - * - * Material textures must be disposed of by the dispose() method of {@link Texture}. - */ - dispose(): void; - - /** - * Specifies that the material needs to be updated, WebGL wise. Set it to true if you made changes that need to be reflected in WebGL. - * This property is automatically set to true when instancing a new material. - * @default false - */ - set needsUpdate(value: boolean); - - /** - * @deprecated onBuild() has been removed. - */ - onBuild(object: Object3D, parameters: WebGLProgramParametersWithUniforms, renderer: WebGLRenderer): void; -} diff --git a/src-testing/src/materials/Materials.d.ts b/src-testing/src/materials/Materials.d.ts deleted file mode 100644 index dbca5e5b7..000000000 --- a/src-testing/src/materials/Materials.d.ts +++ /dev/null @@ -1,18 +0,0 @@ -export * from "./LineBasicMaterial.js"; -export * from "./LineDashedMaterial.js"; -export * from "./Material.js"; -export * from "./MeshBasicMaterial.js"; -export * from "./MeshDepthMaterial.js"; -export * from "./MeshDistanceMaterial.js"; -export * from "./MeshLambertMaterial.js"; -export * from "./MeshMatcapMaterial.js"; -export * from "./MeshNormalMaterial.js"; -export * from "./MeshPhongMaterial.js"; -export * from "./MeshPhysicalMaterial.js"; -export * from "./MeshStandardMaterial.js"; -export * from "./MeshToonMaterial.js"; -export * from "./PointsMaterial.js"; -export * from "./RawShaderMaterial.js"; -export * from "./ShaderMaterial.js"; -export * from "./ShadowMaterial.js"; -export * from "./SpriteMaterial.js"; diff --git a/src-testing/src/materials/MeshBasicMaterial.d.ts b/src-testing/src/materials/MeshBasicMaterial.d.ts deleted file mode 100644 index 37ca083d7..000000000 --- a/src-testing/src/materials/MeshBasicMaterial.d.ts +++ /dev/null @@ -1,134 +0,0 @@ -import { Combine } from "../constants.js"; -import { Color, ColorRepresentation } from "../math/Color.js"; -import { Euler } from "../math/Euler.js"; -import { Texture } from "../textures/Texture.js"; -import { Material, MaterialParameters } from "./Material.js"; - -/** - * parameters is an object with one or more properties defining the material's appearance. - */ -export interface MeshBasicMaterialParameters extends MaterialParameters { - color?: ColorRepresentation | undefined; - opacity?: number | undefined; - map?: Texture | null | undefined; - lightMap?: Texture | null; - lightMapIntensity?: number | undefined; - aoMap?: Texture | null | undefined; - aoMapIntensity?: number | undefined; - specularMap?: Texture | null | undefined; - alphaMap?: Texture | null | undefined; - fog?: boolean | undefined; - envMap?: Texture | null | undefined; - envMapRotation?: Euler | undefined; - combine?: Combine | undefined; - reflectivity?: number | undefined; - refractionRatio?: number | undefined; - wireframe?: boolean | undefined; - wireframeLinewidth?: number | undefined; - wireframeLinecap?: string | undefined; - wireframeLinejoin?: string | undefined; -} - -export class MeshBasicMaterial extends Material { - constructor(parameters?: MeshBasicMaterialParameters); - - /** - * Read-only flag to check if a given object is of type {@link MeshBasicMaterial}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isMeshBasicMaterial: true; - - /** - * @default new THREE.Color( 0xffffff ) - */ - color: Color; - - /** - * @default null - */ - map: Texture | null; - - /** - * @default null - */ - lightMap: Texture | null; - - /** - * @default 1 - */ - lightMapIntensity: number; - - /** - * @default null - */ - aoMap: Texture | null; - - /** - * @default 1 - */ - aoMapIntensity: number; - - /** - * @default null - */ - specularMap: Texture | null; - - /** - * @default null - */ - alphaMap: Texture | null; - - /** - * @default null - */ - envMap: Texture | null; - - /** - * The rotation of the environment map in radians. Default is `(0,0,0)`. - */ - envMapRotation: Euler; - - /** - * @default THREE.MultiplyOperation - */ - combine: Combine; - - /** - * @default 1 - */ - reflectivity: number; - - /** - * @default 0.98 - */ - refractionRatio: number; - - /** - * @default false - */ - wireframe: boolean; - - /** - * @default 1 - */ - wireframeLinewidth: number; - - /** - * @default 'round' - */ - wireframeLinecap: string; - - /** - * @default 'round' - */ - wireframeLinejoin: string; - - /** - * Whether the material is affected by fog. Default is true. - * @default fog - */ - fog: boolean; - - setValues(parameters: MeshBasicMaterialParameters): void; -} diff --git a/src-testing/src/materials/MeshDepthMaterial.d.ts b/src-testing/src/materials/MeshDepthMaterial.d.ts deleted file mode 100644 index dcdcd18b6..000000000 --- a/src-testing/src/materials/MeshDepthMaterial.d.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { DepthPackingStrategies } from "../constants.js"; -import { Texture } from "../textures/Texture.js"; -import { Material, MaterialParameters } from "./Material.js"; - -export interface MeshDepthMaterialParameters extends MaterialParameters { - map?: Texture | null | undefined; - alphaMap?: Texture | null | undefined; - depthPacking?: DepthPackingStrategies | undefined; - displacementMap?: Texture | null | undefined; - displacementScale?: number | undefined; - displacementBias?: number | undefined; - wireframe?: boolean | undefined; - wireframeLinewidth?: number | undefined; -} - -export class MeshDepthMaterial extends Material { - constructor(parameters?: MeshDepthMaterialParameters); - /** - * Read-only flag to check if a given object is of type {@link MeshDepthMaterial}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isMeshDepthMaterial: true; - - /** - * @default null - */ - map: Texture | null; - - /** - * @default null - */ - alphaMap: Texture | null; - - /** - * @default THREE.BasicDepthPacking - */ - depthPacking: DepthPackingStrategies; - - /** - * @default null - */ - displacementMap: Texture | null; - - /** - * @default 1 - */ - displacementScale: number; - - /** - * @default 0 - */ - displacementBias: number; - - /** - * @default false - */ - wireframe: boolean; - - /** - * @default 1 - */ - wireframeLinewidth: number; - - /** - * @default false - */ - fog: boolean; - - setValues(parameters: MeshDepthMaterialParameters): void; -} diff --git a/src-testing/src/materials/MeshDistanceMaterial.d.ts b/src-testing/src/materials/MeshDistanceMaterial.d.ts deleted file mode 100644 index 4e6a8754b..000000000 --- a/src-testing/src/materials/MeshDistanceMaterial.d.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { Vector3 } from "../math/Vector3.js"; -import { Texture } from "../textures/Texture.js"; -import { Material, MaterialParameters } from "./Material.js"; - -export interface MeshDistanceMaterialParameters extends MaterialParameters { - map?: Texture | null | undefined; - alphaMap?: Texture | null | undefined; - displacementMap?: Texture | null | undefined; - displacementScale?: number | undefined; - displacementBias?: number | undefined; - farDistance?: number | undefined; - nearDistance?: number | undefined; - referencePosition?: Vector3 | undefined; -} - -export class MeshDistanceMaterial extends Material { - constructor(parameters?: MeshDistanceMaterialParameters); - - /** - * Read-only flag to check if a given object is of type {@link MeshDistanceMaterial}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isMeshDistanceMaterial: true; - - /** - * @default null - */ - map: Texture | null; - - /** - * @default null - */ - alphaMap: Texture | null; - - /** - * @default null - */ - displacementMap: Texture | null; - - /** - * @default 1 - */ - displacementScale: number; - - /** - * @default 0 - */ - displacementBias: number; - - /** - * @default false - */ - fog: boolean; - - setValues(parameters: MeshDistanceMaterialParameters): void; -} diff --git a/src-testing/src/materials/MeshLambertMaterial.d.ts b/src-testing/src/materials/MeshLambertMaterial.d.ts deleted file mode 100644 index 868fbbbe0..000000000 --- a/src-testing/src/materials/MeshLambertMaterial.d.ts +++ /dev/null @@ -1,199 +0,0 @@ -import { Combine, NormalMapTypes } from "../constants.js"; -import { Color, ColorRepresentation } from "../math/Color.js"; -import { Euler } from "../math/Euler.js"; -import { Vector2 } from "../math/Vector2.js"; -import { Texture } from "../textures/Texture.js"; -import { Material, MaterialParameters } from "./Material.js"; - -export interface MeshLambertMaterialParameters extends MaterialParameters { - bumpMap?: Texture | undefined; - bumpScale?: number | undefined; - color?: ColorRepresentation | undefined; - displacementMap?: Texture | undefined; - displacementScale?: number | undefined; - displacementBias?: number | undefined; - emissive?: ColorRepresentation | undefined; - emissiveIntensity?: number | undefined; - emissiveMap?: Texture | null | undefined; - flatShading?: boolean | undefined; - map?: Texture | null | undefined; - lightMap?: Texture | null | undefined; - lightMapIntensity?: number | undefined; - normalMap?: Texture | undefined; - normalScale?: Vector2 | undefined; - aoMap?: Texture | null | undefined; - aoMapIntensity?: number | undefined; - specularMap?: Texture | null | undefined; - alphaMap?: Texture | null | undefined; - envMap?: Texture | null | undefined; - envMapRotation?: Euler | undefined; - combine?: Combine | undefined; - reflectivity?: number | undefined; - refractionRatio?: number | undefined; - wireframe?: boolean | undefined; - wireframeLinewidth?: number | undefined; - wireframeLinecap?: string | undefined; - wireframeLinejoin?: string | undefined; - fog?: boolean | undefined; -} - -export class MeshLambertMaterial extends Material { - constructor(parameters?: MeshLambertMaterialParameters); - - /** - * Read-only flag to check if a given object is of type {@link MeshLambertMaterial}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isMeshLambertMaterial: true; - - /** - * @default new THREE.Color( 0xffffff ) - */ - color: Color; - - /** - * @default null - */ - bumpMap: Texture | null; - - /** - * @default 1 - */ - bumpScale: number; - - /** - * @default null - */ - displacementMap: Texture | null; - - /** - * @default 1 - */ - displacementScale: number; - - /** - * @default 0 - */ - displacementBias: number; - - /** - * @default new THREE.Color( 0x000000 ) - */ - emissive: Color; - - /** - * @default 1 - */ - emissiveIntensity: number; - - /** - * @default null - */ - emissiveMap: Texture | null; - - /** - * @default false - */ - flatShading: boolean; - - /** - * @default null - */ - map: Texture | null; - - /** - * @default null - */ - lightMap: Texture | null; - - /** - * @default 1 - */ - lightMapIntensity: number; - - /** - * @default null - */ - normalMap: Texture | null; - - normalMapType: NormalMapTypes; - - /** - * @default new THREE.Vector2( 1, 1 ) - */ - normalScale: Vector2; - - /** - * @default null - */ - aoMap: Texture | null; - - /** - * @default 1 - */ - aoMapIntensity: number; - - /** - * @default null - */ - specularMap: Texture | null; - - /** - * @default null - */ - alphaMap: Texture | null; - - /** - * @default null - */ - envMap: Texture | null; - - /** - * The rotation of the environment map in radians. Default is `(0,0,0)`. - */ - envMapRotation: Euler; - - /** - * @default THREE.MultiplyOperation - */ - combine: Combine; - - /** - * @default 1 - */ - reflectivity: number; - - /** - * @default 0.98 - */ - refractionRatio: number; - - /** - * @default false - */ - wireframe: boolean; - - /** - * @default 1 - */ - wireframeLinewidth: number; - - /** - * @default 'round' - */ - wireframeLinecap: string; - - /** - * @default 'round' - */ - wireframeLinejoin: string; - - /** - * Whether the material is affected by fog. Default is true. - * @default fog - */ - fog: boolean; - - setValues(parameters: MeshLambertMaterialParameters): void; -} diff --git a/src-testing/src/materials/MeshMatcapMaterial.d.ts b/src-testing/src/materials/MeshMatcapMaterial.d.ts deleted file mode 100644 index 7f7334d4b..000000000 --- a/src-testing/src/materials/MeshMatcapMaterial.d.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { NormalMapTypes } from "../constants.js"; -import { Color, ColorRepresentation } from "../math/Color.js"; -import { Vector2 } from "../math/Vector2.js"; -import { Texture } from "../textures/Texture.js"; -import { Material, MaterialParameters } from "./Material.js"; - -export interface MeshMatcapMaterialParameters extends MaterialParameters { - color?: ColorRepresentation | undefined; - matcap?: Texture | null | undefined; - map?: Texture | null | undefined; - bumpMap?: Texture | null | undefined; - bumpScale?: number | undefined; - normalMap?: Texture | null | undefined; - normalMapType?: NormalMapTypes | undefined; - normalScale?: Vector2 | undefined; - displacementMap?: Texture | null | undefined; - displacementScale?: number | undefined; - displacementBias?: number | undefined; - alphaMap?: Texture | null | undefined; - fog?: boolean | undefined; - flatShading?: boolean | undefined; -} - -export class MeshMatcapMaterial extends Material { - constructor(parameters?: MeshMatcapMaterialParameters); - - /** - * Read-only flag to check if a given object is of type {@link MeshMatcapMaterial}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isMeshMatcapMaterial: true; - - /** - * @default { 'MATCAP': '' } - */ - defines: { [key: string]: any }; - - /** - * @default new THREE.Color( 0xffffff ) - */ - color: Color; - - /** - * @default null - */ - matcap: Texture | null; - - /** - * @default null - */ - map: Texture | null; - - /** - * @default null - */ - bumpMap: Texture | null; - - /** - * @default 1 - */ - bumpScale: number; - - /** - * @default null - */ - normalMap: Texture | null; - - /** - * @default THREE.TangentSpaceNormalMap - */ - normalMapType: NormalMapTypes; - - /** - * @default new Vector2( 1, 1 ) - */ - normalScale: Vector2; - - /** - * @default null - */ - displacementMap: Texture | null; - - /** - * @default 1 - */ - displacementScale: number; - - /** - * @default 0 - */ - displacementBias: number; - - /** - * @default null - */ - alphaMap: Texture | null; - - /** - * Define whether the material is rendered with flat shading. Default is false. - * @default false - */ - flatShading: boolean; - - /** - * Whether the material is affected by fog. Default is true. - * @default fog - */ - fog: boolean; - - setValues(parameters: MeshMatcapMaterialParameters): void; -} diff --git a/src-testing/src/materials/MeshNormalMaterial.d.ts b/src-testing/src/materials/MeshNormalMaterial.d.ts deleted file mode 100644 index 715ada4e6..000000000 --- a/src-testing/src/materials/MeshNormalMaterial.d.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { NormalMapTypes } from "../constants.js"; -import { Vector2 } from "../math/Vector2.js"; -import { Texture } from "../textures/Texture.js"; -import { Material, MaterialParameters } from "./Material.js"; - -export interface MeshNormalMaterialParameters extends MaterialParameters { - bumpMap?: Texture | null | undefined; - bumpScale?: number | undefined; - normalMap?: Texture | null | undefined; - normalMapType?: NormalMapTypes | undefined; - normalScale?: Vector2 | undefined; - displacementMap?: Texture | null | undefined; - displacementScale?: number | undefined; - displacementBias?: number | undefined; - wireframe?: boolean | undefined; - wireframeLinewidth?: number | undefined; - - flatShading?: boolean | undefined; -} - -export class MeshNormalMaterial extends Material { - constructor(parameters?: MeshNormalMaterialParameters); - - /** - * Read-only flag to check if a given object is of type {@link MeshNormalMaterial}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isMeshNormalMaterial: true; - - /** - * @default null - */ - bumpMap: Texture | null; - - /** - * @default 1 - */ - bumpScale: number; - - /** - * @default null - */ - normalMap: Texture | null; - - /** - * @default THREE.TangentSpaceNormalMap - */ - normalMapType: NormalMapTypes; - - /** - * @default new THREE.Vector2( 1, 1 ) - */ - normalScale: Vector2; - - /** - * @default null - */ - displacementMap: Texture | null; - - /** - * @default 1 - */ - displacementScale: number; - - /** - * @default 0 - */ - displacementBias: number; - - /** - * @default false - */ - wireframe: boolean; - - /** - * @default 1 - */ - wireframeLinewidth: number; - - /** - * Define whether the material is rendered with flat shading. Default is false. - * @default false - */ - flatShading: boolean; - - setValues(parameters: MeshNormalMaterialParameters): void; -} diff --git a/src-testing/src/materials/MeshPhongMaterial.d.ts b/src-testing/src/materials/MeshPhongMaterial.d.ts deleted file mode 100644 index 2b002524b..000000000 --- a/src-testing/src/materials/MeshPhongMaterial.d.ts +++ /dev/null @@ -1,223 +0,0 @@ -import { Combine, NormalMapTypes } from "../constants.js"; -import { Color, ColorRepresentation } from "../math/Color.js"; -import { Euler } from "../math/Euler.js"; -import { Vector2 } from "../math/Vector2.js"; -import { Texture } from "../textures/Texture.js"; -import { Material, MaterialParameters } from "./Material.js"; - -export interface MeshPhongMaterialParameters extends MaterialParameters { - /** geometry color in hexadecimal. Default is 0xffffff. */ - color?: ColorRepresentation | undefined; - specular?: ColorRepresentation | undefined; - shininess?: number | undefined; - opacity?: number | undefined; - map?: Texture | null | undefined; - lightMap?: Texture | null | undefined; - lightMapIntensity?: number | undefined; - aoMap?: Texture | null | undefined; - aoMapIntensity?: number | undefined; - emissive?: ColorRepresentation | undefined; - emissiveIntensity?: number | undefined; - emissiveMap?: Texture | null | undefined; - bumpMap?: Texture | null | undefined; - bumpScale?: number | undefined; - normalMap?: Texture | null | undefined; - normalMapType?: NormalMapTypes | undefined; - normalScale?: Vector2 | undefined; - displacementMap?: Texture | null | undefined; - displacementScale?: number | undefined; - displacementBias?: number | undefined; - specularMap?: Texture | null | undefined; - alphaMap?: Texture | null | undefined; - envMap?: Texture | null | undefined; - envMapRotation?: Euler | undefined; - combine?: Combine | undefined; - reflectivity?: number | undefined; - refractionRatio?: number | undefined; - wireframe?: boolean | undefined; - wireframeLinewidth?: number | undefined; - wireframeLinecap?: string | undefined; - wireframeLinejoin?: string | undefined; - fog?: boolean | undefined; - flatShading?: boolean | undefined; -} - -export class MeshPhongMaterial extends Material { - constructor(parameters?: MeshPhongMaterialParameters); - - /** - * Read-only flag to check if a given object is of type {@link MeshPhongMaterial}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isMeshPhongMaterial: true; - - /** - * @default new THREE.Color( 0xffffff ) - */ - color: Color; - - /** - * @default new THREE.Color( 0x111111 ) - */ - specular: Color; - - /** - * @default 30 - */ - shininess: number; - - /** - * @default null - */ - map: Texture | null; - - /** - * @default null - */ - lightMap: Texture | null; - - /** - * @default null - */ - lightMapIntensity: number; - - /** - * @default null - */ - aoMap: Texture | null; - - /** - * @default null - */ - aoMapIntensity: number; - - /** - * @default new THREE.Color( 0x000000 ) - */ - emissive: Color; - - /** - * @default 1 - */ - emissiveIntensity: number; - - /** - * @default null - */ - emissiveMap: Texture | null; - - /** - * @default null - */ - bumpMap: Texture | null; - - /** - * @default 1 - */ - bumpScale: number; - - /** - * @default null - */ - normalMap: Texture | null; - - /** - * @default THREE.TangentSpaceNormalMap - */ - normalMapType: NormalMapTypes; - - /** - * @default new Vector2( 1, 1 ) - */ - normalScale: Vector2; - - /** - * @default null - */ - displacementMap: Texture | null; - - /** - * @default 1 - */ - displacementScale: number; - - /** - * @default 0 - */ - displacementBias: number; - - /** - * @default null - */ - specularMap: Texture | null; - - /** - * @default null - */ - alphaMap: Texture | null; - - /** - * @default null - */ - envMap: Texture | null; - - /** - * The rotation of the environment map in radians. Default is `(0,0,0)`. - */ - envMapRotation: Euler; - - /** - * @default THREE.MultiplyOperation - */ - combine: Combine; - - /** - * @default 1 - */ - reflectivity: number; - - /** - * @default 0.98 - */ - refractionRatio: number; - - /** - * @default false - */ - wireframe: boolean; - - /** - * @default 1 - */ - wireframeLinewidth: number; - - /** - * @default 'round' - */ - wireframeLinecap: string; - - /** - * @default 'round' - */ - wireframeLinejoin: string; - - /** - * Define whether the material is rendered with flat shading. Default is false. - * @default false - */ - flatShading: boolean; - - /** - * @deprecated Use {@link MeshStandardMaterial THREE.MeshStandardMaterial} instead. - */ - metal: boolean; - - /** - * Whether the material is affected by fog. Default is true. - * @default fog - */ - fog: boolean; - - setValues(parameters: MeshPhongMaterialParameters): void; -} diff --git a/src-testing/src/materials/MeshPhysicalMaterial.d.ts b/src-testing/src/materials/MeshPhysicalMaterial.d.ts deleted file mode 100644 index f201ad662..000000000 --- a/src-testing/src/materials/MeshPhysicalMaterial.d.ts +++ /dev/null @@ -1,231 +0,0 @@ -import { Color, ColorRepresentation } from "../math/Color.js"; -import { Vector2 } from "../math/Vector2.js"; -import { Texture } from "../textures/Texture.js"; -import { MeshStandardMaterial, MeshStandardMaterialParameters } from "./MeshStandardMaterial.js"; - -export interface MeshPhysicalMaterialParameters extends MeshStandardMaterialParameters { - anisotropyRotation?: number | undefined; - anisotropyMap?: Texture | null | undefined; - - clearcoatMap?: Texture | null | undefined; - clearcoatRoughness?: number | undefined; - clearcoatRoughnessMap?: Texture | null | undefined; - clearcoatNormalScale?: Vector2 | undefined; - clearcoatNormalMap?: Texture | null | undefined; - - ior?: number | undefined; - - reflectivity?: number | undefined; - - iridescenceMap?: Texture | null | undefined; - iridescenceIOR?: number | undefined; - iridescenceThicknessRange?: [number, number] | undefined; - iridescenceThicknessMap?: Texture | null | undefined; - - sheenColor?: ColorRepresentation | undefined; - sheenColorMap?: Texture | null | undefined; - sheenRoughness?: number | undefined; - sheenRoughnessMap?: Texture | null | undefined; - - transmissionMap?: Texture | null | undefined; - - thickness?: number | undefined; - thicknessMap?: Texture | null | undefined; - attenuationDistance?: number | undefined; - attenuationColor?: ColorRepresentation | undefined; - - specularIntensity?: number | undefined; - specularIntensityMap?: Texture | null | undefined; - specularColor?: ColorRepresentation | undefined; - specularColorMap?: Texture | null | undefined; - - anisotropy?: number | undefined; - clearcoat?: number | undefined; - iridescence?: number | undefined; - dispersion?: number | undefined; - sheen?: number | undefined; - transmission?: number | undefined; -} - -export class MeshPhysicalMaterial extends MeshStandardMaterial { - constructor(parameters?: MeshPhysicalMaterialParameters); - - /** - * Read-only flag to check if a given object is of type {@link MeshPhysicalMaterial}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isMeshPhysicalMaterial: true; - - /** - * @default { 'STANDARD': '', 'PHYSICAL': '' } - */ - defines: { [key: string]: any }; - - /** - * @default 0 - */ - anisotropyRotation?: number; - - /** - * @default null - */ - anisotropyMap?: Texture | null; - - /** - * @default null - */ - clearcoatMap: Texture | null; - - /** - * @default 0 - */ - clearcoatRoughness: number; - - /** - * @default null - */ - clearcoatRoughnessMap: Texture | null; - - /** - * @default new THREE.Vector2( 1, 1 ) - */ - clearcoatNormalScale: Vector2; - - /** - * @default null - */ - clearcoatNormalMap: Texture | null; - - /** - * @default 1.5 - */ - ior: number; - - /** - * @default 0.5 - */ - get reflectivity(): number; - set reflectivity(reflectivity: number); - - /** - * @default null - */ - iridescenceMap: Texture | null; - - /** - * @default 1.3 - */ - iridescenceIOR: number; - - /** - * @default [100, 400] - */ - iridescenceThicknessRange: [number, number]; - - /** - * @default null - */ - iridescenceThicknessMap: Texture | null; - - /** - * @default Color( 0x000000 ) - */ - sheenColor: Color; - - /** - * @default null - */ - sheenColorMap: Texture | null; - - /** - * @default 1.0 - */ - sheenRoughness: number; - - /** - * @default null - */ - sheenRoughnessMap: Texture | null; - - /** - * @default null - */ - transmissionMap: Texture | null; - - /** - * @default 0.01 - */ - thickness: number; - - /** - * @default null - */ - thicknessMap: Texture | null; - - /** - * @default 0.0 - */ - attenuationDistance: number; - - /** - * @default Color( 1, 1, 1 ) - */ - attenuationColor: Color; - - /** - * @default 1.0 - */ - specularIntensity: number; - - /** - * @default null - */ - specularIntensityMap: Texture | null; - - /** - * @default Color(1, 1, 1) - */ - specularColor: Color; - - /** - * @default null - */ - specularColorMap: Texture | null; - - /** - * @default 0 - */ - get anisotropy(): number; - set anisotropy(value: number); - - /** - * @default 0 - */ - get clearcoat(): number; - set clearcoat(value: number); - - /** - * @default 0 - */ - get iridescence(): number; - set iridescence(value: number); - - /** - * @default 0 - */ - get dispersion(): number; - set dispersion(value: number); - - /** - * @default 0.0 - */ - get sheen(): number; - set sheen(value: number); - - /** - * @default 0 - */ - get transmission(): number; - set transmission(value: number); -} diff --git a/src-testing/src/materials/MeshStandardMaterial.d.ts b/src-testing/src/materials/MeshStandardMaterial.d.ts deleted file mode 100644 index b4493a1d7..000000000 --- a/src-testing/src/materials/MeshStandardMaterial.d.ts +++ /dev/null @@ -1,213 +0,0 @@ -import { NormalMapTypes } from "../constants.js"; -import { Color, ColorRepresentation } from "../math/Color.js"; -import { Euler } from "../math/Euler.js"; -import { Vector2 } from "../math/Vector2.js"; -import { Texture } from "../textures/Texture.js"; -import { Material, MaterialParameters } from "./Material.js"; - -export interface MeshStandardMaterialParameters extends MaterialParameters { - color?: ColorRepresentation | undefined; - roughness?: number | undefined; - metalness?: number | undefined; - map?: Texture | null | undefined; - lightMap?: Texture | null | undefined; - lightMapIntensity?: number | undefined; - aoMap?: Texture | null | undefined; - aoMapIntensity?: number | undefined; - emissive?: ColorRepresentation | undefined; - emissiveIntensity?: number | undefined; - emissiveMap?: Texture | null | undefined; - bumpMap?: Texture | null | undefined; - bumpScale?: number | undefined; - normalMap?: Texture | null | undefined; - normalMapType?: NormalMapTypes | undefined; - normalScale?: Vector2 | undefined; - displacementMap?: Texture | null | undefined; - displacementScale?: number | undefined; - displacementBias?: number | undefined; - roughnessMap?: Texture | null | undefined; - metalnessMap?: Texture | null | undefined; - alphaMap?: Texture | null | undefined; - envMap?: Texture | null | undefined; - envMapRotation?: Euler | undefined; - envMapIntensity?: number | undefined; - wireframe?: boolean | undefined; - wireframeLinewidth?: number | undefined; - fog?: boolean | undefined; - flatShading?: boolean | undefined; -} - -export class MeshStandardMaterial extends Material { - constructor(parameters?: MeshStandardMaterialParameters); - - /** - * Read-only flag to check if a given object is of type {@link MeshStandardMaterial}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isMeshStandardMaterial: true; - - /** - * @default { 'STANDARD': '' } - */ - defines: { [key: string]: any }; - - /** - * @default new THREE.Color( 0xffffff ) - */ - color: Color; - - /** - * @default 1 - */ - roughness: number; - - /** - * @default 0 - */ - metalness: number; - - /** - * @default null - */ - map: Texture | null; - - /** - * @default null - */ - lightMap: Texture | null; - - /** - * @default 1 - */ - lightMapIntensity: number; - - /** - * @default null - */ - aoMap: Texture | null; - - /** - * @default 1 - */ - aoMapIntensity: number; - - /** - * @default new THREE.Color( 0x000000 ) - */ - emissive: Color; - - /** - * @default 1 - */ - emissiveIntensity: number; - - /** - * @default null - */ - emissiveMap: Texture | null; - - /** - * @default null - */ - bumpMap: Texture | null; - - /** - * @default 1 - */ - bumpScale: number; - - /** - * @default null - */ - normalMap: Texture | null; - - /** - * @default THREE.TangentSpaceNormalMap - */ - normalMapType: NormalMapTypes; - - /** - * @default new THREE.Vector2( 1, 1 ) - */ - normalScale: Vector2; - - /** - * @default null - */ - displacementMap: Texture | null; - - /** - * @default 1 - */ - displacementScale: number; - - /** - * @default 0 - */ - displacementBias: number; - - /** - * @default null - */ - roughnessMap: Texture | null; - - /** - * @default null - */ - metalnessMap: Texture | null; - - /** - * @default null - */ - alphaMap: Texture | null; - - /** - * @default null - */ - envMap: Texture | null; - - /** - * The rotation of the environment map in radians. Default is `(0,0,0)`. - */ - envMapRotation: Euler; - - /** - * @default 1 - */ - envMapIntensity: number; - - /** - * @default false - */ - wireframe: boolean; - - /** - * @default 1 - */ - wireframeLinewidth: number; - - /** - * @default 'round' - */ - wireframeLinecap: string; - - /** - * @default 'round' - */ - wireframeLinejoin: string; - - /** - * Define whether the material is rendered with flat shading. Default is false. - * @default false - */ - flatShading: boolean; - - /** - * Whether the material is affected by fog. Default is true. - * @default fog - */ - fog: boolean; - - setValues(parameters: MeshStandardMaterialParameters): void; -} diff --git a/src-testing/src/materials/MeshToonMaterial.d.ts b/src-testing/src/materials/MeshToonMaterial.d.ts deleted file mode 100644 index 14c71b27a..000000000 --- a/src-testing/src/materials/MeshToonMaterial.d.ts +++ /dev/null @@ -1,173 +0,0 @@ -import { NormalMapTypes } from "../constants.js"; -import { Color, ColorRepresentation } from "../math/Color.js"; -import { Vector2 } from "../math/Vector2.js"; -import { Texture } from "../textures/Texture.js"; -import { Material, MaterialParameters } from "./Material.js"; - -export interface MeshToonMaterialParameters extends MaterialParameters { - /** geometry color in hexadecimal. Default is 0xffffff. */ - color?: ColorRepresentation | undefined; - opacity?: number | undefined; - gradientMap?: Texture | null | undefined; - map?: Texture | null | undefined; - lightMap?: Texture | null | undefined; - lightMapIntensity?: number | undefined; - aoMap?: Texture | null | undefined; - aoMapIntensity?: number | undefined; - emissive?: ColorRepresentation | undefined; - emissiveIntensity?: number | undefined; - emissiveMap?: Texture | null | undefined; - bumpMap?: Texture | null | undefined; - bumpScale?: number | undefined; - normalMap?: Texture | null | undefined; - normalMapType?: NormalMapTypes | undefined; - normalScale?: Vector2 | undefined; - displacementMap?: Texture | null | undefined; - displacementScale?: number | undefined; - displacementBias?: number | undefined; - alphaMap?: Texture | null | undefined; - wireframe?: boolean | undefined; - wireframeLinewidth?: number | undefined; - wireframeLinecap?: string | undefined; - wireframeLinejoin?: string | undefined; - fog?: boolean | undefined; -} - -export class MeshToonMaterial extends Material { - constructor(parameters?: MeshToonMaterialParameters); - - /** - * Read-only flag to check if a given object is of type {@link MeshToonMaterial}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isMeshToonMaterial: true; - - /** - * @default { 'TOON': '' } - */ - defines: { [key: string]: any }; - - /** - * @default new THREE.Color( 0xffffff ) - */ - color: Color; - - /** - * @default null - */ - gradientMap: Texture | null; - - /** - * @default null - */ - map: Texture | null; - - /** - * @default null - */ - lightMap: Texture | null; - - /** - * @default 1 - */ - lightMapIntensity: number; - - /** - * @default null - */ - aoMap: Texture | null; - - /** - * @default 1 - */ - aoMapIntensity: number; - - /** - * @default new THREE.Color( 0x000000 ) - */ - emissive: Color; - - /** - * @default 1 - */ - emissiveIntensity: number; - - /** - * @default null - */ - emissiveMap: Texture | null; - - /** - * @default null - */ - bumpMap: Texture | null; - - /** - * @default 1 - */ - bumpScale: number; - - /** - * @default null - */ - normalMap: Texture | null; - - /** - * @default THREE.TangentSpaceNormalMap - */ - normalMapType: NormalMapTypes; - - /** - * @default new THREE.Vector2( 1, 1 ) - */ - normalScale: Vector2; - - /** - * @default null - */ - displacementMap: Texture | null; - - /** - * @default 1 - */ - displacementScale: number; - - /** - * @default 0 - */ - displacementBias: number; - - /** - * @default null - */ - alphaMap: Texture | null; - - /** - * @default false - */ - wireframe: boolean; - - /** - * @default 1 - */ - wireframeLinewidth: number; - - /** - * @default 'round' - */ - wireframeLinecap: string; - - /** - * @default 'round' - */ - wireframeLinejoin: string; - - /** - * Whether the material is affected by fog. Default is true. - * @default fog - */ - fog: boolean; - - setValues(parameters: MeshToonMaterialParameters): void; -} diff --git a/src-testing/src/materials/PointsMaterial.d.ts b/src-testing/src/materials/PointsMaterial.d.ts deleted file mode 100644 index a47a0817b..000000000 --- a/src-testing/src/materials/PointsMaterial.d.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { Color, ColorRepresentation } from "../math/Color.js"; -import { Texture } from "../textures/Texture.js"; -import { Material, MaterialParameters } from "./Material.js"; - -export interface PointsMaterialParameters extends MaterialParameters { - color?: ColorRepresentation | undefined; - map?: Texture | null | undefined; - alphaMap?: Texture | null | undefined; - size?: number | undefined; - sizeAttenuation?: boolean | undefined; - fog?: boolean | undefined; -} - -export class PointsMaterial extends Material { - constructor(parameters?: PointsMaterialParameters); - - /** - * Read-only flag to check if a given object is of type {@link PointsMaterial}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isPointsMaterial: true; - - /** - * @default new THREE.Color( 0xffffff ) - */ - color: Color; - - /** - * @default null - */ - map: Texture | null; - - /** - * @default null - */ - alphaMap: Texture | null; - - /** - * @default 1 - */ - size: number; - - /** - * @default true - */ - sizeAttenuation: boolean; - - /** - * Whether the material is affected by fog. Default is true. - * @default fog - */ - fog: boolean; - - setValues(parameters: PointsMaterialParameters): void; -} diff --git a/src-testing/src/materials/RawShaderMaterial.d.ts b/src-testing/src/materials/RawShaderMaterial.d.ts deleted file mode 100644 index 6ff6b67f0..000000000 --- a/src-testing/src/materials/RawShaderMaterial.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { ShaderMaterial, ShaderMaterialParameters } from "./ShaderMaterial.js"; - -export class RawShaderMaterial extends ShaderMaterial { - constructor(parameters?: ShaderMaterialParameters); - - /** - * Read-only flag to check if a given object is of type {@link RawShaderMaterial}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isRawShaderMaterial: true; -} diff --git a/src-testing/src/materials/ShaderMaterial.d.ts b/src-testing/src/materials/ShaderMaterial.d.ts deleted file mode 100644 index 53e07a821..000000000 --- a/src-testing/src/materials/ShaderMaterial.d.ts +++ /dev/null @@ -1,162 +0,0 @@ -import { GLSLVersion } from "../constants.js"; -import { JSONMeta } from "../core/Object3D.js"; -import { UniformsGroup } from "../core/UniformsGroup.js"; -import { Matrix3, Matrix3Tuple } from "../math/Matrix3.js"; -import { Matrix4, Matrix4Tuple } from "../math/Matrix4.js"; -import { Vector2Tuple } from "../math/Vector2.js"; -import { Vector3Tuple } from "../math/Vector3.js"; -import { Vector4Tuple } from "../math/Vector4.js"; -import { IUniform } from "../renderers/shaders/UniformsLib.js"; -import { Material, MaterialJSON, MaterialParameters } from "./Material.js"; - -export interface ShaderMaterialParameters extends MaterialParameters { - uniforms?: { [uniform: string]: IUniform } | undefined; - uniformsGroups?: UniformsGroup[] | undefined; - vertexShader?: string | undefined; - fragmentShader?: string | undefined; - linewidth?: number | undefined; - wireframe?: boolean | undefined; - wireframeLinewidth?: number | undefined; - lights?: boolean | undefined; - clipping?: boolean | undefined; - fog?: boolean | undefined; - extensions?: - | { - clipCullDistance?: boolean | undefined; - multiDraw?: boolean | undefined; - } - | undefined; - glslVersion?: GLSLVersion | undefined; -} - -export type ShaderMaterialUniformJSON = { - type: "t"; - value: string; -} | { - type: "c"; - value: number; -} | { - type: "v2"; - value: Vector2Tuple; -} | { - type: "v3"; - value: Vector3Tuple; -} | { - type: "v4"; - value: Vector4Tuple; -} | { - type: "m3"; - value: Matrix3Tuple; -} | { - type: "m4"; - value: Matrix4Tuple; -} | { - value: unknown; -}; - -export interface ShaderMaterialJSON extends MaterialJSON { - glslVersion: number | null; - uniforms: Record; - - defines?: Record; - - vertexShader: string; - ragmentShader: string; - - lights: boolean; - clipping: boolean; - - extensions?: Record; -} - -export class ShaderMaterial extends Material { - constructor(parameters?: ShaderMaterialParameters); - - /** - * Read-only flag to check if a given object is of type {@link ShaderMaterial}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isShaderMaterial: true; - - /** - * @default {} - */ - defines: { [key: string]: any }; - - /** - * @default {} - */ - uniforms: { [uniform: string]: IUniform }; - - uniformsGroups: UniformsGroup[]; - - vertexShader: string; - - fragmentShader: string; - - /** - * @default 1 - */ - linewidth: number; - - /** - * @default false - */ - wireframe: boolean; - - /** - * @default 1 - */ - wireframeLinewidth: number; - - /** - * @default false - */ - fog: boolean; - - /** - * @default false - */ - lights: boolean; - - /** - * @default false - */ - clipping: boolean; - - /** - * @default { - * clipCullDistance: false, - * multiDraw: false - * } - */ - extensions: { - clipCullDistance: boolean; - multiDraw: boolean; - }; - - /** - * @default { 'color': [ 1, 1, 1 ], 'uv': [ 0, 0 ], 'uv1': [ 0, 0 ] } - */ - defaultAttributeValues: any; - - /** - * @default undefined - */ - index0AttributeName: string | undefined; - - /** - * @default false - */ - uniformsNeedUpdate: boolean; - - /** - * @default null - */ - glslVersion: GLSLVersion | null; - - setValues(parameters: ShaderMaterialParameters): void; - - toJSON(meta?: JSONMeta): ShaderMaterialJSON; -} diff --git a/src-testing/src/materials/ShadowMaterial.d.ts b/src-testing/src/materials/ShadowMaterial.d.ts deleted file mode 100644 index fc7a7ae06..000000000 --- a/src-testing/src/materials/ShadowMaterial.d.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { Color, ColorRepresentation } from "../math/Color.js"; -import { Material, MaterialParameters } from "./Material.js"; - -export interface ShadowMaterialParameters extends MaterialParameters { - color?: ColorRepresentation | undefined; - fog?: boolean | undefined; -} - -export class ShadowMaterial extends Material { - constructor(parameters?: ShadowMaterialParameters); - - /** - * Read-only flag to check if a given object is of type {@link ShadowMaterial}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isShadowMaterial: true; - - /** - * @default new THREE.Color( 0x000000 ) - */ - color: Color; - - /** - * @default true - */ - transparent: boolean; - - /** - * Whether the material is affected by fog. Default is true. - * @default fog - */ - fog: boolean; -} diff --git a/src-testing/src/materials/SpriteMaterial.d.ts b/src-testing/src/materials/SpriteMaterial.d.ts deleted file mode 100644 index 4fa5db8a0..000000000 --- a/src-testing/src/materials/SpriteMaterial.d.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { Color, ColorRepresentation } from "../math/Color.js"; -import { Texture } from "../textures/Texture.js"; -import { Material, MaterialParameters } from "./Material.js"; - -export interface SpriteMaterialParameters extends MaterialParameters { - color?: ColorRepresentation | undefined; - map?: Texture | null | undefined; - alphaMap?: Texture | null | undefined; - rotation?: number | undefined; - sizeAttenuation?: boolean | undefined; - fog?: boolean | undefined; -} - -export class SpriteMaterial extends Material { - constructor(parameters?: SpriteMaterialParameters); - /** - * Read-only flag to check if a given object is of type {@link SpriteMaterial}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isSpriteMaterial: true; - - /** - * @default new THREE.Color( 0xffffff ) - */ - color: Color; - - /** - * @default null - */ - map: Texture | null; - - /** - * @default null - */ - alphaMap: Texture | null; - - /** - * @default 0 - */ - rotation: number; - - /** - * @default true - */ - sizeAttenuation: boolean; - - /** - * @default true - */ - transparent: boolean; - - /** - * Whether the material is affected by fog. Default is true. - * @default fog - */ - fog: boolean; - - setValues(parameters: SpriteMaterialParameters): void; - copy(source: SpriteMaterial): this; -} diff --git a/src-testing/src/materials/nodes/InstancedPointsNodeMaterial.d.ts b/src-testing/src/materials/nodes/InstancedPointsNodeMaterial.d.ts deleted file mode 100644 index 9784e7f52..000000000 --- a/src-testing/src/materials/nodes/InstancedPointsNodeMaterial.d.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { Color } from "../../math/Color.js"; -import Node from "../../nodes/core/Node.js"; -import { Texture } from "../../textures/Texture.js"; -import { PointsMaterialParameters } from "../PointsMaterial.js"; -import NodeMaterial, { NodeMaterialParameters } from "./NodeMaterial.js"; - -export interface InstancedPointsNodeMaterialParameters extends NodeMaterialParameters, PointsMaterialParameters { - useAlphaToCoverage?: boolean | undefined; - useColor?: boolean | undefined; - pointWidth?: number | undefined; - pointColorNode?: Node | null | undefined; - pointWidthNode?: Node | null | undefined; -} - -declare class InstancedPointsNodeMaterial extends NodeMaterial { - useAlphaToCoverage: boolean; - useColor: boolean | undefined; - pointWidth: number; - pointColorNode: Node | null; - pointWidthNode: Node | null; - - // Properties from LineDashedMaterial - readonly isPointsMaterial: true; - color: Color; - map: Texture | null; - alphaMap: Texture | null; - size: number; - sizeAttenuation: boolean; - - constructor(params?: InstancedPointsNodeMaterialParameters); -} - -export default InstancedPointsNodeMaterial; diff --git a/src-testing/src/materials/nodes/Line2NodeMaterial.d.ts b/src-testing/src/materials/nodes/Line2NodeMaterial.d.ts deleted file mode 100644 index 13c65ffd6..000000000 --- a/src-testing/src/materials/nodes/Line2NodeMaterial.d.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { Color } from "../../math/Color.js"; -import Node from "../../nodes/core/Node.js"; -import { Texture } from "../../textures/Texture.js"; -import { LineDashedMaterialParameters } from "../LineDashedMaterial.js"; -import NodeMaterial, { NodeMaterialParameters } from "./NodeMaterial.js"; - -export interface Line2NodeMaterialParameters extends NodeMaterialParameters, LineDashedMaterialParameters { - dashed?: boolean | undefined; -} - -export default class Line2NodeMaterial extends NodeMaterial { - lights: boolean; - - // Properties from LineDashedMaterial - readonly isLineDashedMaterial: true; - scale: number; - dashSize: number; - gapSize: number; - - // Properties from LineBasicMaterial - readonly isLineBasicMaterial: true; - color: Color; - fog: boolean; - linewidth: number; - linecap: string; - linejoin: string; - map: Texture | null; - - useAlphaToCoverage: boolean; - useColor: boolean; - useDash: boolean; - useWorldUnits: boolean; - - dashOffset: number; - lineWidth: number; - - lineColorNode: Node | null; - - offsetNode: Node | null; - dashScaleNode: Node | null; - dashSizeNode: Node | null; - gapSizeNode: Node | null; - - constructor(parameters?: Line2NodeMaterialParameters); - - setupShaders(): void; - - get worldUnits(): boolean; - set worldUnits(value: boolean); - - get dashed(): boolean; - set dashed(value: boolean); -} diff --git a/src-testing/src/materials/nodes/LineBasicNodeMaterial.d.ts b/src-testing/src/materials/nodes/LineBasicNodeMaterial.d.ts deleted file mode 100644 index 84b8db897..000000000 --- a/src-testing/src/materials/nodes/LineBasicNodeMaterial.d.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Color } from "../../math/Color.js"; -import { Texture } from "../../textures/Texture.js"; -import { LineBasicMaterialParameters } from "../LineBasicMaterial.js"; -import NodeMaterial, { NodeMaterialParameters } from "./NodeMaterial.js"; - -export interface LineBasicNodeMaterialParameters extends NodeMaterialParameters, LineBasicMaterialParameters { -} - -export default class LineBasicNodeMaterial extends NodeMaterial { - readonly isLineBasicNodeMaterial: true; - - // Properties from LineBasicMaterial - readonly isLineBasicMaterial: true; - color: Color; - fog: boolean; - linewidth: number; - linecap: string; - linejoin: string; - map: Texture | null; - - constructor(parameters?: LineBasicNodeMaterialParameters); -} diff --git a/src-testing/src/materials/nodes/LineDashedNodeMaterial.d.ts b/src-testing/src/materials/nodes/LineDashedNodeMaterial.d.ts deleted file mode 100644 index 10715e2cd..000000000 --- a/src-testing/src/materials/nodes/LineDashedNodeMaterial.d.ts +++ /dev/null @@ -1,29 +0,0 @@ -import Node from "../../nodes/core/Node.js"; -import { LineDashedMaterialParameters } from "../LineDashedMaterial.js"; -import NodeMaterial, { NodeMaterialParameters } from "./NodeMaterial.js"; - -export interface LineDashedNodeMaterialParameters extends NodeMaterialParameters, LineDashedMaterialParameters { - offsetNode?: Node | null | undefined; - dashScaleNode?: Node | null | undefined; - dashSizeNode?: Node | null | undefined; - gapSizeNode?: Node | null | undefined; -} - -declare class LineDashedNodeMaterial extends NodeMaterial { - readonly isLineDashedNodeMaterial: true; - - offsetNode: Node | null; - dashScaleNode: Node | null; - dashSizeNode: Node | null; - gapSizeNode: Node | null; - - // Properties from LineDashedMaterial - readonly isLineDashedMaterial: true; - scale: number; - dashSize: number; - gapSize: number; - - constructor(parameters?: LineDashedMaterialParameters); -} - -export default LineDashedNodeMaterial; diff --git a/src-testing/src/materials/nodes/MeshBasicNodeMaterial.d.ts b/src-testing/src/materials/nodes/MeshBasicNodeMaterial.d.ts deleted file mode 100644 index 515fa5f67..000000000 --- a/src-testing/src/materials/nodes/MeshBasicNodeMaterial.d.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { Combine } from "../../constants.js"; -import { Color } from "../../math/Color.js"; -import { Euler } from "../../math/Euler.js"; -import { Texture } from "../../textures/Texture.js"; -import { MeshBasicMaterialParameters } from "../MeshBasicMaterial.js"; -import NodeMaterial, { NodeMaterialParameters } from "./NodeMaterial.js"; - -export interface MeshBasicNodeMaterialParameters extends NodeMaterialParameters, MeshBasicMaterialParameters { -} - -export default class MeshBasicNodeMaterial extends NodeMaterial { - readonly isMeshBasicNodeMaterial: true; - - // Properties from MeshBasicMaterial - readonly isMeshBasicMaterial: true; - color: Color; - map: Texture | null; - lightMap: Texture | null; - lightMapIntensity: number; - aoMap: Texture | null; - aoMapIntensity: number; - specularMap: Texture | null; - alphaMap: Texture | null; - envMap: Texture | null; - envMapRotation: Euler; - combine: Combine; - reflectivity: number; - refractionRatio: number; - wireframe: boolean; - wireframeLinewidth: number; - wireframeLinecap: string; - wireframeLinejoin: string; - fog: boolean; - - constructor(parameters?: MeshBasicNodeMaterialParameters); -} diff --git a/src-testing/src/materials/nodes/MeshLambertNodeMaterial.d.ts b/src-testing/src/materials/nodes/MeshLambertNodeMaterial.d.ts deleted file mode 100644 index aedda10a7..000000000 --- a/src-testing/src/materials/nodes/MeshLambertNodeMaterial.d.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { Combine, NormalMapTypes } from "../../constants.js"; -import { Color } from "../../math/Color.js"; -import { Euler } from "../../math/Euler.js"; -import { Vector2 } from "../../math/Vector2.js"; -import { Texture } from "../../textures/Texture.js"; -import { MeshLambertMaterialParameters } from "../MeshLambertMaterial.js"; -import NodeMaterial, { NodeMaterialParameters } from "./NodeMaterial.js"; - -export interface MeshLambertNodeMaterialParameters extends NodeMaterialParameters, MeshLambertMaterialParameters {} - -declare class MeshLambertNodeMaterial extends NodeMaterial { - readonly isMeshLambertNodeMaterial: true; - - // Properties from MeshLambertMaterial - readonly isMeshLambertMaterial: true; - color: Color; - bumpMap: Texture | null; - bumpScale: number; - displacementMap: Texture | null; - displacementScale: number; - displacementBias: number; - emissive: Color; - emissiveIntensity: number; - emissiveMap: Texture | null; - flatShading: boolean; - map: Texture | null; - lightMap: Texture | null; - lightMapIntensity: number; - normalMap: Texture | null; - normalMapType: NormalMapTypes; - normalScale: Vector2; - aoMap: Texture | null; - aoMapIntensity: number; - specularMap: Texture | null; - alphaMap: Texture | null; - envMap: Texture | null; - envMapRotation: Euler; - combine: Combine; - reflectivity: number; - refractionRatio: number; - wireframe: boolean; - wireframeLinewidth: number; - wireframeLinecap: string; - wireframeLinejoin: string; - - constructor(parameters?: MeshLambertNodeMaterialParameters); -} - -export default MeshLambertNodeMaterial; diff --git a/src-testing/src/materials/nodes/MeshMatcapNodeMaterial.d.ts b/src-testing/src/materials/nodes/MeshMatcapNodeMaterial.d.ts deleted file mode 100644 index cc0d2f9a0..000000000 --- a/src-testing/src/materials/nodes/MeshMatcapNodeMaterial.d.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { NormalMapTypes } from "../../constants.js"; -import { Color } from "../../math/Color.js"; -import { Vector2 } from "../../math/Vector2.js"; -import { Texture } from "../../textures/Texture.js"; -import { MeshMatcapMaterialParameters } from "../MeshMatcapMaterial.js"; -import NodeMaterial, { NodeMaterialParameters } from "./NodeMaterial.js"; - -export interface MeshMatcapNodeMaterialParameters extends NodeMaterialParameters, MeshMatcapMaterialParameters { -} - -export default class MeshMatcapNodeMaterial extends NodeMaterial { - readonly isMeshMatcapNodeMaterial: true; - - // Properties from MeshMatcapMaterial - readonly isMeshMatcapMaterial: true; - color: Color; - matcap: Texture | null; - map: Texture | null; - bumpMap: Texture | null; - bumpScale: number; - normalMap: Texture | null; - normalMapType: NormalMapTypes; - normalScale: Vector2; - displacementMap: Texture | null; - displacementScale: number; - displacementBias: number; - alphaMap: Texture | null; - flatShading: boolean; - fog: boolean; - - constructor(parameters?: MeshMatcapNodeMaterialParameters); -} diff --git a/src-testing/src/materials/nodes/MeshNormalNodeMaterial.d.ts b/src-testing/src/materials/nodes/MeshNormalNodeMaterial.d.ts deleted file mode 100644 index 761998bac..000000000 --- a/src-testing/src/materials/nodes/MeshNormalNodeMaterial.d.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { NormalMapTypes } from "../../constants.js"; -import { Vector2 } from "../../math/Vector2.js"; -import { Texture } from "../../textures/Texture.js"; -import { MeshNormalMaterialParameters } from "../MeshNormalMaterial.js"; -import NodeMaterial, { NodeMaterialParameters } from "./NodeMaterial.js"; - -export interface MeshBasicNodeMaterialParameters extends NodeMaterialParameters, MeshNormalMaterialParameters { -} - -export default class MeshNormalNodeMaterial extends NodeMaterial { - readonly isMeshNormalNodeMaterial: true; - - // Properties from MeshNormalMaterial - readonly isMeshNormalMaterial: true; - bumpMap: Texture | null; - bumpScale: number; - normalMap: Texture | null; - normalMapType: NormalMapTypes; - normalScale: Vector2; - displacementMap: Texture | null; - displacementScale: number; - displacementBias: number; - wireframe: boolean; - wireframeLinewidth: number; - flatShading: boolean; - - constructor(parameters?: MeshBasicNodeMaterialParameters); -} diff --git a/src-testing/src/materials/nodes/MeshPhongNodeMaterial.d.ts b/src-testing/src/materials/nodes/MeshPhongNodeMaterial.d.ts deleted file mode 100644 index 3680e533c..000000000 --- a/src-testing/src/materials/nodes/MeshPhongNodeMaterial.d.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { Combine, NormalMapTypes } from "../../constants.js"; -import { Color } from "../../math/Color.js"; -import { Euler } from "../../math/Euler.js"; -import { Vector2 } from "../../math/Vector2.js"; -import Node from "../../nodes/core/Node.js"; -import { Texture } from "../../textures/Texture.js"; -import { MeshPhongMaterialParameters } from "../MeshPhongMaterial.js"; -import NodeMaterial, { NodeMaterialParameters } from "./NodeMaterial.js"; - -export interface MeshPhongNodeMaterialParameters extends NodeMaterialParameters, MeshPhongMaterialParameters { -} - -export default class MeshPhongNodeMaterial extends NodeMaterial { - readonly isMeshPhongNodeMaterial: true; - - shininessNode: Node | null; - specularNode: Node | null; - - // Properties from MeshPhongMaterial - readonly isMeshPhongMaterial: true; - color: Color; - specular: Color; - shininess: number; - map: Texture | null; - lightMap: Texture | null; - lightMapIntensity: number; - aoMap: Texture | null; - aoMapIntensity: number; - emissive: Color; - emissiveIntensity: number; - emissiveMap: Texture | null; - bumpMap: Texture | null; - bumpScale: number; - normalMap: Texture | null; - normalMapType: NormalMapTypes; - normalScale: Vector2; - displacementMap: Texture | null; - displacementScale: number; - displacementBias: number; - specularMap: Texture | null; - alphaMap: Texture | null; - envMap: Texture | null; - envMapRotation: Euler; - combine: Combine; - reflectivity: number; - refractionRatio: number; - wireframe: boolean; - wireframeLinewidth: number; - wireframeLinecap: string; - wireframeLinejoin: string; - flatShading: boolean; - metal: boolean; - fog: boolean; - - constructor(parameters?: MeshPhongNodeMaterialParameters); -} diff --git a/src-testing/src/materials/nodes/MeshPhysicalNodeMaterial.d.ts b/src-testing/src/materials/nodes/MeshPhysicalNodeMaterial.d.ts deleted file mode 100644 index e7da3ee90..000000000 --- a/src-testing/src/materials/nodes/MeshPhysicalNodeMaterial.d.ts +++ /dev/null @@ -1,93 +0,0 @@ -import { Color } from "../../math/Color.js"; -import { Vector2 } from "../../math/Vector2.js"; -import Node from "../../nodes/core/Node.js"; -import { ShaderNodeObject } from "../../nodes/tsl/TSLCore.js"; -import { Texture } from "../../textures/Texture.js"; -import { MeshPhysicalMaterialParameters } from "../MeshPhysicalMaterial.js"; -import MeshStandardNodeMaterial, { MeshStandardNodeMaterialParameters } from "./MeshStandardNodeMaterial.js"; - -export interface MeshPhysicalNodeMaterialParameters - extends MeshStandardNodeMaterialParameters, MeshPhysicalMaterialParameters -{ -} - -export default class MeshPhysicalNodeMaterial extends MeshStandardNodeMaterial { - readonly isMeshPhysicalNodeMaterial: true; - - clearcoatNode: Node | null; - clearcoatRoughnessNode: Node | null; - clearcoatNormalNode: Node | null; - - sheenNode: Node | null; - sheenRoughnessNode: Node | null; - - iridescenceNode: Node | null; - iridescenceIORNode: Node | null; - iridescenceThicknessNode: Node | null; - - iorNode: Node | null; - - specularIntensityNode: Node | null; - specularColorNode: Node | null; - - transmissionNode: Node | null; - thicknessNode: Node | null; - attenuationDistanceNode: Node | null; - attenuationColorNode: Node | null; - dispersionNode: Node | null; - - anisotropyNode: Node | null; - - // Properties from MeshPhysicalMaterial - readonly isMeshPhysicalMaterial: true; - anisotropyRotation: number; - anisotropyMap: Texture | null; - clearcoatMap: Texture | null; - clearcoatRoughness: number; - clearcoatRoughnessMap: Texture | null; - clearcoatNormalScale: Vector2; - clearcoatNormalMap: Texture | null; - ior: number; - get reflectivity(): number; - set reflectivity(reflectivity: number); - iridescenceMap: Texture | null; - iridescenceIOR: number; - iridescenceThicknessRange: [number, number]; - iridescenceThicknessMap: Texture | null; - sheenColor: Color; - sheenColorMap: Texture | null; - sheenRoughness: number; - sheenRoughnessMap: Texture | null; - transmissionMap: Texture | null; - thickness: number; - thicknessMap: Texture | null; - attenuationDistance: number; - attenuationColor: Color; - specularIntensity: number; - specularIntensityMap: Texture | null; - specularColor: Color; - specularColorMap: Texture | null; - get anisotropy(): number; - set anisotropy(value: number); - get clearcoat(): number; - set clearcoat(value: number); - get iridescence(): number; - set iridescence(value: number); - get dispersion(): number; - set dispersion(value: number); - get sheen(): number; - set sheen(value: number); - get transmission(): number; - set transmission(value: number); - - constructor(parameters?: MeshPhysicalNodeMaterialParameters); - - get useClearcoat(): boolean; - get useIridescence(): boolean; - get useSheen(): boolean; - get useAnisotropy(): boolean; - get useTransmission(): boolean; - get useDispersion(): boolean; - - setupClearcoatNormal(): ShaderNodeObject; -} diff --git a/src-testing/src/materials/nodes/MeshSSSNodeMaterial.d.ts b/src-testing/src/materials/nodes/MeshSSSNodeMaterial.d.ts deleted file mode 100644 index bccbec30c..000000000 --- a/src-testing/src/materials/nodes/MeshSSSNodeMaterial.d.ts +++ /dev/null @@ -1,16 +0,0 @@ -import ConstNode from "../../nodes/core/ConstNode.js"; -import Node from "../../nodes/core/Node.js"; -import MeshPhysicalNodeMaterial, { MeshPhysicalNodeMaterialParameters } from "./MeshPhysicalNodeMaterial.js"; - -export default class MeshSSSNodeMaterial extends MeshPhysicalNodeMaterial { - thicknessColorNode: Node | null; - thicknessDistortionNode: ConstNode; - thicknessAmbientNode: ConstNode; - thicknessAttenuationNode: ConstNode; - thicknessPowerNode: ConstNode; - thicknessScaleNode: ConstNode; - - constructor(parameters?: MeshPhysicalNodeMaterialParameters); - - get useSSS(): boolean; -} diff --git a/src-testing/src/materials/nodes/MeshStandardNodeMaterial.d.ts b/src-testing/src/materials/nodes/MeshStandardNodeMaterial.d.ts deleted file mode 100644 index 9c3329042..000000000 --- a/src-testing/src/materials/nodes/MeshStandardNodeMaterial.d.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { NormalMapTypes } from "../../constants.js"; -import { Color } from "../../math/Color.js"; -import { Euler } from "../../math/Euler.js"; -import { Vector2 } from "../../math/Vector2.js"; -import Node from "../../nodes/core/Node.js"; -import { Texture } from "../../textures/Texture.js"; -import { MeshStandardMaterialParameters } from "../MeshStandardMaterial.js"; -import NodeMaterial, { NodeMaterialParameters } from "./NodeMaterial.js"; - -export interface MeshStandardNodeMaterialParameters extends NodeMaterialParameters, MeshStandardMaterialParameters { -} - -export default class MeshStandardNodeMaterial extends NodeMaterial { - readonly isMeshStandardNodeMaterial: true; - - emissiveNode: Node | null; - - metalnessNode: Node | null; - roughnessNode: Node | null; - - // Properties from MeshStandardMaterial - readonly isMeshStandardMaterial: true; - color: Color; - roughness: number; - metalness: number; - map: Texture | null; - lightMap: Texture | null; - lightMapIntensity: number; - aoMap: Texture | null; - aoMapIntensity: number; - emissive: Color; - emissiveIntensity: number; - emissiveMap: Texture | null; - bumpMap: Texture | null; - bumpScale: number; - normalMap: Texture | null; - normalMapType: NormalMapTypes; - normalScale: Vector2; - displacementMap: Texture | null; - displacementScale: number; - displacementBias: number; - roughnessMap: Texture | null; - metalnessMap: Texture | null; - alphaMap: Texture | null; - envMap: Texture | null; - envMapRotation: Euler; - envMapIntensity: number; - wireframe: boolean; - wireframeLinewidth: number; - wireframeLinecap: string; - wireframeLinejoin: string; - flatShading: boolean; - fog: boolean; - - constructor(parameters?: MeshStandardNodeMaterialParameters); -} diff --git a/src-testing/src/materials/nodes/MeshToonNodeMaterial.d.ts b/src-testing/src/materials/nodes/MeshToonNodeMaterial.d.ts deleted file mode 100644 index e1dee0fb3..000000000 --- a/src-testing/src/materials/nodes/MeshToonNodeMaterial.d.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { NormalMapTypes } from "../../constants.js"; -import { Color } from "../../math/Color.js"; -import { Vector2 } from "../../math/Vector2.js"; -import { Texture } from "../../textures/Texture.js"; -import { MeshToonMaterialParameters } from "../MeshToonMaterial.js"; -import NodeMaterial, { NodeMaterialParameters } from "./NodeMaterial.js"; - -export interface MeshToonNodeMaterialParameters extends NodeMaterialParameters, MeshToonMaterialParameters { -} - -export default class MeshToonNodeMaterial extends NodeMaterial { - readonly isMeshToonNodeMaterial: true; - - // Properties from MeshToonMaterial - readonly isMeshToonMaterial: true; - color: Color; - gradientMap: Texture | null; - map: Texture | null; - lightMap: Texture | null; - lightMapIntensity: number; - aoMap: Texture | null; - aoMapIntensity: number; - emissive: Color; - emissiveIntensity: number; - emissiveMap: Texture | null; - bumpMap: Texture | null; - bumpScale: number; - normalMap: Texture | null; - normalMapType: NormalMapTypes; - normalScale: Vector2; - displacementMap: Texture | null; - displacementScale: number; - displacementBias: number; - alphaMap: Texture | null; - wireframe: boolean; - wireframeLinewidth: number; - wireframeLinecap: string; - wireframeLinejoin: string; - fog: boolean; - - constructor(parameters?: MeshToonNodeMaterialParameters); -} diff --git a/src-testing/src/materials/nodes/NodeMaterial.ts b/src-testing/src/materials/nodes/NodeMaterial.ts deleted file mode 100644 index 3c77c74e6..000000000 --- a/src-testing/src/materials/nodes/NodeMaterial.ts +++ /dev/null @@ -1,535 +0,0 @@ -import { Material } from '../Material.js'; -import { NormalBlending } from '../../constants.js'; - -import { getNodeChildren, getCacheKey } from '../../nodes/core/NodeUtils.js'; -import { attribute } from '../../nodes/core/AttributeNode.js'; -import { output, diffuseColor, emissive, varyingProperty } from '../../nodes/core/PropertyNode.js'; -import { - materialAlphaTest, - materialColor, - materialOpacity, - materialEmissive, - materialNormal, - materialLightMap, - materialAOMap, -} from '../../nodes/accessors/MaterialNode.js'; -import { modelViewProjection } from '../../nodes/accessors/ModelViewProjectionNode.js'; -import { normalLocal } from '../../nodes/accessors/Normal.js'; -import { instance } from '../../nodes/accessors/InstanceNode.js'; -import { batch } from '../../nodes/accessors/BatchNode.js'; -import { materialReference } from '../../nodes/accessors/MaterialReferenceNode.js'; -import { positionLocal, positionView } from '../../nodes/accessors/Position.js'; -import { skinningReference } from '../../nodes/accessors/SkinningNode.js'; -import { morphReference } from '../../nodes/accessors/MorphNode.js'; -import { mix } from '../../nodes/math/MathNode.js'; -import { float, vec3, vec4 } from '../../nodes/tsl/TSLBase.js'; -import AONode from '../../nodes/lighting/AONode.js'; -import { lightingContext } from '../../nodes/lighting/LightingContextNode.js'; -import IrradianceNode from '../../nodes/lighting/IrradianceNode.js'; -import { - depth, - perspectiveDepthToLogarithmicDepth, - viewZToOrthographicDepth, -} from '../../nodes/display/ViewportDepthNode.js'; -import { cameraFar, cameraNear } from '../../nodes/accessors/Camera.js'; -import { clipping, clippingAlpha } from '../../nodes/accessors/ClippingNode.js'; -import NodeMaterialObserver from './manager/NodeMaterialObserver.js'; - -class NodeMaterial extends Material { - static get type() { - return 'NodeMaterial'; - } - - constructor() { - super(); - - this.isNodeMaterial = true; - - this.type = this.constructor.type; - - this.forceSinglePass = false; - - this.fog = true; - this.lights = false; - - this.lightsNode = null; - this.envNode = null; - this.aoNode = null; - - this.colorNode = null; - this.normalNode = null; - this.opacityNode = null; - this.backdropNode = null; - this.backdropAlphaNode = null; - this.alphaTestNode = null; - - this.positionNode = null; - this.geometryNode = null; - - this.depthNode = null; - this.shadowNode = null; - this.shadowPositionNode = null; - - this.outputNode = null; - this.mrtNode = null; - - this.fragmentNode = null; - this.vertexNode = null; - } - - customProgramCacheKey() { - return this.type + getCacheKey(this); - } - - build(builder) { - this.setup(builder); - } - - setupObserver(builder) { - return new NodeMaterialObserver(builder); - } - - setup(builder) { - builder.context.setupNormal = () => this.setupNormal(builder); - - // < VERTEX STAGE > - - builder.addStack(); - - builder.stack.outputNode = this.vertexNode || this.setupPosition(builder); - - if (this.geometryNode !== null) { - builder.stack.outputNode = builder.stack.outputNode.bypass(this.geometryNode); - } - - builder.addFlow('vertex', builder.removeStack()); - - // < FRAGMENT STAGE > - - builder.addStack(); - - let resultNode; - - const clippingNode = this.setupClipping(builder); - - if (this.depthWrite === true) this.setupDepth(builder); - - if (this.fragmentNode === null) { - this.setupDiffuseColor(builder); - this.setupVariants(builder); - - const outgoingLightNode = this.setupLighting(builder); - - if (clippingNode !== null) builder.stack.add(clippingNode); - - // force unsigned floats - useful for RenderTargets - - const basicOutput = vec4(outgoingLightNode, diffuseColor.a).max(0); - - resultNode = this.setupOutput(builder, basicOutput); - - // OUTPUT NODE - - output.assign(resultNode); - - // - - if (this.outputNode !== null) resultNode = this.outputNode; - - // MRT - - const renderTarget = builder.renderer.getRenderTarget(); - - if (renderTarget !== null) { - const mrt = builder.renderer.getMRT(); - const materialMRT = this.mrtNode; - - if (mrt !== null) { - resultNode = mrt; - - if (materialMRT !== null) { - resultNode = mrt.merge(materialMRT); - } - } else if (materialMRT !== null) { - resultNode = materialMRT; - } - } - } else { - let fragmentNode = this.fragmentNode; - - if (fragmentNode.isOutputStructNode !== true) { - fragmentNode = vec4(fragmentNode); - } - - resultNode = this.setupOutput(builder, fragmentNode); - } - - builder.stack.outputNode = resultNode; - - builder.addFlow('fragment', builder.removeStack()); - - // < MONITOR > - - builder.monitor = this.setupObserver(builder); - } - - setupClipping(builder) { - if (builder.clippingContext === null) return null; - - const { globalClippingCount, localClippingCount } = builder.clippingContext; - - let result = null; - - if (globalClippingCount || localClippingCount) { - const samples = builder.renderer.samples; - - if (this.alphaToCoverage && samples > 1) { - // to be added to flow when the color/alpha value has been determined - result = clippingAlpha(); - } else { - builder.stack.add(clipping()); - } - } - - return result; - } - - setupDepth(builder) { - const { renderer, camera } = builder; - - // Depth - - let depthNode = this.depthNode; - - if (depthNode === null) { - const mrt = renderer.getMRT(); - - if (mrt && mrt.has('depth')) { - depthNode = mrt.get('depth'); - } else if (renderer.logarithmicDepthBuffer === true) { - if (camera.isPerspectiveCamera) { - depthNode = perspectiveDepthToLogarithmicDepth(modelViewProjection().w, cameraNear, cameraFar); - } else { - depthNode = viewZToOrthographicDepth(positionView.z, cameraNear, cameraFar); - } - } - } - - if (depthNode !== null) { - depth.assign(depthNode).append(); - } - } - - setupPosition(builder) { - const { object } = builder; - const geometry = object.geometry; - - builder.addStack(); - - // Vertex - - if (geometry.morphAttributes.position || geometry.morphAttributes.normal || geometry.morphAttributes.color) { - morphReference(object).append(); - } - - if (object.isSkinnedMesh === true) { - skinningReference(object).append(); - } - - if (this.displacementMap) { - const displacementMap = materialReference('displacementMap', 'texture'); - const displacementScale = materialReference('displacementScale', 'float'); - const displacementBias = materialReference('displacementBias', 'float'); - - positionLocal.addAssign( - normalLocal.normalize().mul(displacementMap.x.mul(displacementScale).add(displacementBias)), - ); - } - - if (object.isBatchedMesh) { - batch(object).append(); - } - - if (object.instanceMatrix && object.instanceMatrix.isInstancedBufferAttribute === true) { - instance(object).append(); - } - - if (this.positionNode !== null) { - positionLocal.assign(this.positionNode); - } - - const mvp = modelViewProjection(); - - builder.context.vertex = builder.removeStack(); - builder.context.mvp = mvp; - - return mvp; - } - - setupDiffuseColor({ object, geometry }) { - let colorNode = this.colorNode ? vec4(this.colorNode) : materialColor; - - // VERTEX COLORS - - if (this.vertexColors === true && geometry.hasAttribute('color')) { - colorNode = vec4(colorNode.xyz.mul(attribute('color', 'vec3')), colorNode.a); - } - - // Instanced colors - - if (object.instanceColor) { - const instanceColor = varyingProperty('vec3', 'vInstanceColor'); - - colorNode = instanceColor.mul(colorNode); - } - - if (object.isBatchedMesh && object._colorsTexture) { - const batchColor = varyingProperty('vec3', 'vBatchColor'); - - colorNode = batchColor.mul(colorNode); - } - - // COLOR - - diffuseColor.assign(colorNode); - - // OPACITY - - const opacityNode = this.opacityNode ? float(this.opacityNode) : materialOpacity; - diffuseColor.a.assign(diffuseColor.a.mul(opacityNode)); - - // ALPHA TEST - - if (this.alphaTestNode !== null || this.alphaTest > 0) { - const alphaTestNode = this.alphaTestNode !== null ? float(this.alphaTestNode) : materialAlphaTest; - - diffuseColor.a.lessThanEqual(alphaTestNode).discard(); - } - - if (this.transparent === false && this.blending === NormalBlending && this.alphaToCoverage === false) { - diffuseColor.a.assign(1.0); - } - } - - setupVariants(/*builder*/) { - // Interface function. - } - - setupOutgoingLight() { - return this.lights === true ? vec3(0) : diffuseColor.rgb; - } - - setupNormal() { - return this.normalNode ? vec3(this.normalNode) : materialNormal; - } - - setupEnvironment(/*builder*/) { - let node = null; - - if (this.envNode) { - node = this.envNode; - } else if (this.envMap) { - node = this.envMap.isCubeTexture - ? materialReference('envMap', 'cubeTexture') - : materialReference('envMap', 'texture'); - } - - return node; - } - - setupLightMap(builder) { - let node = null; - - if (builder.material.lightMap) { - node = new IrradianceNode(materialLightMap); - } - - return node; - } - - setupLights(builder) { - const materialLightsNode = []; - - // - - const envNode = this.setupEnvironment(builder); - - if (envNode && envNode.isLightingNode) { - materialLightsNode.push(envNode); - } - - const lightMapNode = this.setupLightMap(builder); - - if (lightMapNode && lightMapNode.isLightingNode) { - materialLightsNode.push(lightMapNode); - } - - if (this.aoNode !== null || builder.material.aoMap) { - const aoNode = this.aoNode !== null ? this.aoNode : materialAOMap; - - materialLightsNode.push(new AONode(aoNode)); - } - - let lightsN = this.lightsNode || builder.lightsNode; - - if (materialLightsNode.length > 0) { - lightsN = builder.renderer.lighting.createNode([...lightsN.getLights(), ...materialLightsNode]); - } - - return lightsN; - } - - setupLightingModel(/*builder*/) { - // Interface function. - } - - setupLighting(builder) { - const { material } = builder; - const { backdropNode, backdropAlphaNode, emissiveNode } = this; - - // OUTGOING LIGHT - - const lights = this.lights === true || this.lightsNode !== null; - - const lightsNode = lights ? this.setupLights(builder) : null; - - let outgoingLightNode = this.setupOutgoingLight(builder); - - if (lightsNode && lightsNode.getScope().hasLights) { - const lightingModel = this.setupLightingModel(builder); - - outgoingLightNode = lightingContext(lightsNode, lightingModel, backdropNode, backdropAlphaNode); - } else if (backdropNode !== null) { - outgoingLightNode = vec3( - backdropAlphaNode !== null ? mix(outgoingLightNode, backdropNode, backdropAlphaNode) : backdropNode, - ); - } - - // EMISSIVE - - if ( - (emissiveNode && emissiveNode.isNode === true) || - (material.emissive && material.emissive.isColor === true) - ) { - emissive.assign(vec3(emissiveNode ? emissiveNode : materialEmissive)); - - outgoingLightNode = outgoingLightNode.add(emissive); - } - - return outgoingLightNode; - } - - setupOutput(builder, outputNode) { - // FOG - - if (this.fog === true) { - const fogNode = builder.fogNode; - - if (fogNode) outputNode = vec4(fogNode.mix(outputNode.rgb, fogNode.colorNode), outputNode.a); - } - - return outputNode; - } - - setDefaultValues(material) { - // This approach is to reuse the native refreshUniforms* - // and turn available the use of features like transmission and environment in core - - for (const property in material) { - const value = material[property]; - - if (this[property] === undefined) { - this[property] = value; - - if (value && value.clone) this[property] = value.clone(); - } - } - - const descriptors = Object.getOwnPropertyDescriptors(material.constructor.prototype); - - for (const key in descriptors) { - if ( - Object.getOwnPropertyDescriptor(this.constructor.prototype, key) === undefined && - descriptors[key].get !== undefined - ) { - Object.defineProperty(this.constructor.prototype, key, descriptors[key]); - } - } - } - - toJSON(meta) { - const isRoot = meta === undefined || typeof meta === 'string'; - - if (isRoot) { - meta = { - textures: {}, - images: {}, - nodes: {}, - }; - } - - const data = Material.prototype.toJSON.call(this, meta); - const nodeChildren = getNodeChildren(this); - - data.inputNodes = {}; - - for (const { property, childNode } of nodeChildren) { - data.inputNodes[property] = childNode.toJSON(meta).uuid; - } - - // TODO: Copied from Object3D.toJSON - - function extractFromCache(cache) { - const values = []; - - for (const key in cache) { - const data = cache[key]; - delete data.metadata; - values.push(data); - } - - return values; - } - - if (isRoot) { - const textures = extractFromCache(meta.textures); - const images = extractFromCache(meta.images); - const nodes = extractFromCache(meta.nodes); - - if (textures.length > 0) data.textures = textures; - if (images.length > 0) data.images = images; - if (nodes.length > 0) data.nodes = nodes; - } - - return data; - } - - copy(source) { - this.lightsNode = source.lightsNode; - this.envNode = source.envNode; - - this.colorNode = source.colorNode; - this.normalNode = source.normalNode; - this.opacityNode = source.opacityNode; - this.backdropNode = source.backdropNode; - this.backdropAlphaNode = source.backdropAlphaNode; - this.alphaTestNode = source.alphaTestNode; - - this.positionNode = source.positionNode; - this.geometryNode = source.geometryNode; - - this.depthNode = source.depthNode; - this.shadowNode = source.shadowNode; - this.shadowPositionNode = source.shadowPositionNode; - - this.outputNode = source.outputNode; - this.mrtNode = source.mrtNode; - - this.fragmentNode = source.fragmentNode; - this.vertexNode = source.vertexNode; - - return super.copy(source); - } -} - -export default NodeMaterial; diff --git a/src-testing/src/materials/nodes/NodeMaterials.d.ts b/src-testing/src/materials/nodes/NodeMaterials.d.ts deleted file mode 100644 index 395273cd9..000000000 --- a/src-testing/src/materials/nodes/NodeMaterials.d.ts +++ /dev/null @@ -1,18 +0,0 @@ -export { default as InstancedPointsNodeMaterial } from "./InstancedPointsNodeMaterial.js"; -export { default as Line2NodeMaterial } from "./Line2NodeMaterial.js"; -export { default as LineBasicNodeMaterial } from "./LineBasicNodeMaterial.js"; -export { default as LineDashedNodeMaterial } from "./LineDashedNodeMaterial.js"; -export { default as MeshBasicNodeMaterial } from "./MeshBasicNodeMaterial.js"; -export { default as MeshLambertNodeMaterial } from "./MeshLambertNodeMaterial.js"; -export { default as MeshMatcapNodeMaterial } from "./MeshMatcapNodeMaterial.js"; -export { default as MeshNormalNodeMaterial } from "./MeshNormalNodeMaterial.js"; -export { default as MeshPhongNodeMaterial } from "./MeshPhongNodeMaterial.js"; -export { default as MeshPhysicalNodeMaterial } from "./MeshPhysicalNodeMaterial.js"; -export { default as MeshSSSNodeMaterial } from "./MeshSSSNodeMaterial.js"; -export { default as MeshStandardNodeMaterial } from "./MeshStandardNodeMaterial.js"; -export { default as MeshToonNodeMaterial } from "./MeshToonNodeMaterial.js"; -export { default as NodeMaterial } from "./NodeMaterial.js"; -export { default as PointsNodeMaterial } from "./PointsNodeMaterial.js"; -export { default as ShadowNodeMaterial } from "./ShadowNodeMaterial.js"; -export { default as SpriteNodeMaterial } from "./SpriteNodeMaterial.js"; -export { default as VolumeNodeMaterial } from "./VolumeNodeMaterial.js"; diff --git a/src-testing/src/materials/nodes/PointsNodeMaterial.d.ts b/src-testing/src/materials/nodes/PointsNodeMaterial.d.ts deleted file mode 100644 index 836f55a6d..000000000 --- a/src-testing/src/materials/nodes/PointsNodeMaterial.d.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { Color } from "../../math/Color.js"; -import { Texture } from "../../textures/Texture.js"; -import { PointsMaterialParameters } from "../PointsMaterial.js"; -import NodeMaterial, { NodeMaterialParameters } from "./NodeMaterial.js"; - -export interface PointsNodeMaterialParameters extends NodeMaterialParameters, PointsMaterialParameters { -} - -export default class PointsNodeMaterial extends NodeMaterial { - readonly isPointsNodeMaterial: true; - - // Properties from PointsMaterial - readonly isPointsMaterial: true; - color: Color; - map: Texture | null; - alphaMap: Texture | null; - size: number; - sizeAttenuation: boolean; - - constructor(parameters?: PointsNodeMaterialParameters); -} diff --git a/src-testing/src/materials/nodes/ShadowNodeMaterial.d.ts b/src-testing/src/materials/nodes/ShadowNodeMaterial.d.ts deleted file mode 100644 index c53d92437..000000000 --- a/src-testing/src/materials/nodes/ShadowNodeMaterial.d.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { Color } from "../../math/Color.js"; -import { ShadowMaterialParameters } from "../ShadowMaterial.js"; -import NodeMaterial, { NodeMaterialParameters } from "./NodeMaterial.js"; - -export interface ShadowNodeMaterialParameters extends NodeMaterialParameters, ShadowMaterialParameters { -} - -export default class ShadowNodeMaterial extends NodeMaterial { - readonly isShadowNodeMaterial: true; - - // Properties from ShadowMaterial - readonly isShadowMaterial: true; - color: Color; - fog: boolean; - - constructor(parameters?: ShadowNodeMaterialParameters); -} diff --git a/src-testing/src/materials/nodes/SpriteNodeMaterial.d.ts b/src-testing/src/materials/nodes/SpriteNodeMaterial.d.ts deleted file mode 100644 index e34845d78..000000000 --- a/src-testing/src/materials/nodes/SpriteNodeMaterial.d.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Color } from "../../math/Color.js"; -import Node from "../../nodes/core/Node.js"; -import { Texture } from "../../textures/Texture.js"; -import { SpriteMaterialParameters } from "../SpriteMaterial.js"; -import NodeMaterial, { NodeMaterialParameters } from "./NodeMaterial.js"; - -export interface SpriteNodeMaterialParameters extends NodeMaterialParameters, SpriteMaterialParameters { -} - -export default class SpriteNodeMaterial extends NodeMaterial { - isSpriteNodeMaterial: true; - - rotationNode: Node | null; - scaleNode: Node | null; - - // Properties from SpriteMaterial - readonly isSpriteMaterial: true; - color: Color; - map: Texture | null; - alphaMap: Texture | null; - rotation: number; - sizeAttenuation: boolean; - fog: boolean; - - constructor(parameters?: SpriteNodeMaterialParameters); -} diff --git a/src-testing/src/materials/nodes/VolumeNodeMaterial.d.ts b/src-testing/src/materials/nodes/VolumeNodeMaterial.d.ts deleted file mode 100644 index 4f2c6e260..000000000 --- a/src-testing/src/materials/nodes/VolumeNodeMaterial.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import Node from "../../nodes/core/Node.js"; -import NodeMaterial, { NodeMaterialParameters } from "./NodeMaterial.js"; - -export default class VolumeNodeMaterial extends NodeMaterial { - lights: boolean; - readonly isVolumeNodeMaterial: true; - testNode: Node | null; - - constructor(parameters?: NodeMaterialParameters); -} diff --git a/src-testing/src/materials/nodes/manager/NodeMaterialObserver.ts b/src-testing/src/materials/nodes/manager/NodeMaterialObserver.ts deleted file mode 100644 index 8ab1a6d67..000000000 --- a/src-testing/src/materials/nodes/manager/NodeMaterialObserver.ts +++ /dev/null @@ -1,308 +0,0 @@ -const refreshUniforms = [ - 'alphaMap', - 'alphaTest', - 'anisotropy', - 'anisotropyMap', - 'anisotropyRotation', - 'aoMap', - 'attenuationColor', - 'attenuationDistance', - 'bumpMap', - 'clearcoat', - 'clearcoatMap', - 'clearcoatNormalMap', - 'clearcoatNormalScale', - 'clearcoatRoughness', - 'color', - 'dispersion', - 'displacementMap', - 'emissive', - 'emissiveMap', - 'envMap', - 'gradientMap', - 'ior', - 'iridescence', - 'iridescenceIOR', - 'iridescenceMap', - 'iridescenceThicknessMap', - 'lightMap', - 'map', - 'matcap', - 'metalness', - 'metalnessMap', - 'normalMap', - 'normalScale', - 'opacity', - 'roughness', - 'roughnessMap', - 'sheen', - 'sheenColor', - 'sheenColorMap', - 'sheenRoughnessMap', - 'shininess', - 'specular', - 'specularColor', - 'specularColorMap', - 'specularIntensity', - 'specularIntensityMap', - 'specularMap', - 'thickness', - 'transmission', - 'transmissionMap', -]; - -class NodeMaterialObserver { - constructor(builder) { - this.renderObjects = new WeakMap(); - this.hasNode = this.containsNode(builder); - this.hasAnimation = builder.object.isSkinnedMesh === true; - this.refreshUniforms = refreshUniforms; - this.renderId = 0; - } - - firstInitialization(renderObject) { - const hasInitialized = this.renderObjects.has(renderObject); - - if (hasInitialized === false) { - this.getRenderObjectData(renderObject); - - return true; - } - - return false; - } - - getRenderObjectData(renderObject) { - let data = this.renderObjects.get(renderObject); - - if (data === undefined) { - const { geometry, material } = renderObject; - - data = { - material: this.getMaterialData(material), - geometry: { - attributes: this.getAttributesData(geometry.attributes), - indexVersion: geometry.index ? geometry.index.version : null, - drawRange: { start: geometry.drawRange.start, count: geometry.drawRange.count }, - }, - worldMatrix: renderObject.object.matrixWorld.clone(), - }; - - if (renderObject.object.center) { - data.center = renderObject.object.center.clone(); - } - - if (renderObject.object.morphTargetInfluences) { - data.morphTargetInfluences = renderObject.object.morphTargetInfluences.slice(); - } - - if (renderObject.bundle !== null) { - data.version = renderObject.bundle.version; - } - - this.renderObjects.set(renderObject, data); - } - - return data; - } - - getAttributesData(attributes) { - const attributesData = {}; - - for (const name in attributes) { - const attribute = attributes[name]; - - attributesData[name] = { - version: attribute.version, - }; - } - - return attributesData; - } - - containsNode(builder) { - const material = builder.material; - - for (const property in material) { - if (material[property] && material[property].isNode) return true; - } - - if (builder.renderer.nodes.modelViewMatrix !== null || builder.renderer.nodes.modelNormalViewMatrix !== null) - return true; - - return false; - } - - getMaterialData(material) { - const data = {}; - - for (const property of this.refreshUniforms) { - const value = material[property]; - - if (value === null || value === undefined) continue; - - if (typeof value === 'object' && value.clone !== undefined) { - if (value.isTexture === true) { - data[property] = { id: value.id, version: value.version }; - } else { - data[property] = value.clone(); - } - } else { - data[property] = value; - } - } - - return data; - } - - equals(renderObject) { - const { object, material, geometry } = renderObject; - - const renderObjectData = this.getRenderObjectData(renderObject); - - // world matrix - - if (renderObjectData.worldMatrix.equals(object.matrixWorld) !== true) { - renderObjectData.worldMatrix.copy(object.matrixWorld); - - return false; - } - - // material - - const materialData = renderObjectData.material; - - for (const property in materialData) { - const value = materialData[property]; - const mtlValue = material[property]; - - if (value.equals !== undefined) { - if (value.equals(mtlValue) === false) { - value.copy(mtlValue); - - return false; - } - } else if (mtlValue.isTexture === true) { - if (value.id !== mtlValue.id || value.version !== mtlValue.version) { - value.id = mtlValue.id; - value.version = mtlValue.version; - - return false; - } - } else if (value !== mtlValue) { - materialData[property] = mtlValue; - - return false; - } - } - - // geometry - - const storedGeometryData = renderObjectData.geometry; - const attributes = geometry.attributes; - const storedAttributes = storedGeometryData.attributes; - - const storedAttributeNames = Object.keys(storedAttributes); - const currentAttributeNames = Object.keys(attributes); - - if (storedAttributeNames.length !== currentAttributeNames.length) { - renderObjectData.geometry.attributes = this.getAttributesData(attributes); - return false; - } - - // Compare each attribute - for (const name of storedAttributeNames) { - const storedAttributeData = storedAttributes[name]; - const attribute = attributes[name]; - - if (attribute === undefined) { - // Attribute was removed - delete storedAttributes[name]; - return false; - } - - if (storedAttributeData.version !== attribute.version) { - storedAttributeData.version = attribute.version; - return false; - } - } - - // Check index - const index = geometry.index; - const storedIndexVersion = storedGeometryData.indexVersion; - const currentIndexVersion = index ? index.version : null; - - if (storedIndexVersion !== currentIndexVersion) { - storedGeometryData.indexVersion = currentIndexVersion; - return false; - } - - // Check drawRange - if ( - storedGeometryData.drawRange.start !== geometry.drawRange.start || - storedGeometryData.drawRange.count !== geometry.drawRange.count - ) { - storedGeometryData.drawRange.start = geometry.drawRange.start; - storedGeometryData.drawRange.count = geometry.drawRange.count; - return false; - } - - // morph targets - - if (renderObjectData.morphTargetInfluences) { - let morphChanged = false; - - for (let i = 0; i < renderObjectData.morphTargetInfluences.length; i++) { - if (renderObjectData.morphTargetInfluences[i] !== object.morphTargetInfluences[i]) { - morphChanged = true; - } - } - - if (morphChanged) return true; - } - - // center - - if (renderObjectData.center) { - if (renderObjectData.center.equals(object.center) === false) { - renderObjectData.center.copy(object.center); - - return true; - } - } - - // bundle - - if (renderObject.bundle !== null) { - renderObjectData.version = renderObject.bundle.version; - } - - return true; - } - - needsRefresh(renderObject, nodeFrame) { - if (this.hasNode || this.hasAnimation || this.firstInitialization(renderObject)) return true; - - const { renderId } = nodeFrame; - - if (this.renderId !== renderId) { - this.renderId = renderId; - - return true; - } - - const isStatic = renderObject.object.static === true; - const isBundle = - renderObject.bundle !== null && - renderObject.bundle.static === true && - this.getRenderObjectData(renderObject).version === renderObject.bundle.version; - - if (isStatic || isBundle) return false; - - const notEqual = this.equals(renderObject) !== true; - - return notEqual; - } -} - -export default NodeMaterialObserver; diff --git a/src-testing/src/math/Box2.d.ts b/src-testing/src/math/Box2.d.ts deleted file mode 100644 index de05083d0..000000000 --- a/src-testing/src/math/Box2.d.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { Vector2 } from "./Vector2.js"; - -// Math ////////////////////////////////////////////////////////////////////////////////// - -export class Box2 { - constructor(min?: Vector2, max?: Vector2); - - /** - * @default new THREE.Vector2( + Infinity, + Infinity ) - */ - min: Vector2; - - /** - * @default new THREE.Vector2( - Infinity, - Infinity ) - */ - max: Vector2; - - set(min: Vector2, max: Vector2): Box2; - setFromPoints(points: Vector2[]): Box2; - setFromCenterAndSize(center: Vector2, size: Vector2): Box2; - clone(): this; - copy(box: Box2): this; - makeEmpty(): Box2; - isEmpty(): boolean; - getCenter(target: Vector2): Vector2; - getSize(target: Vector2): Vector2; - expandByPoint(point: Vector2): Box2; - expandByVector(vector: Vector2): Box2; - expandByScalar(scalar: number): Box2; - containsPoint(point: Vector2): boolean; - containsBox(box: Box2): boolean; - getParameter(point: Vector2, target: Vector2): Vector2; - intersectsBox(box: Box2): boolean; - clampPoint(point: Vector2, target: Vector2): Vector2; - distanceToPoint(point: Vector2): number; - intersect(box: Box2): Box2; - union(box: Box2): Box2; - translate(offset: Vector2): Box2; - equals(box: Box2): boolean; - /** - * @deprecated Use {@link Box2#isEmpty .isEmpty()} instead. - */ - empty(): any; - /** - * @deprecated Use {@link Box2#intersectsBox .intersectsBox()} instead. - */ - isIntersectionBox(b: any): any; -} diff --git a/src-testing/src/math/Box3.d.ts b/src-testing/src/math/Box3.d.ts deleted file mode 100644 index 2e7b11bc9..000000000 --- a/src-testing/src/math/Box3.d.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { BufferAttribute } from "../core/BufferAttribute.js"; -import { Object3D } from "../core/Object3D.js"; -import { Matrix4 } from "./Matrix4.js"; -import { Plane } from "./Plane.js"; -import { Sphere } from "./Sphere.js"; -import { Triangle } from "./Triangle.js"; -import { Vector3 } from "./Vector3.js"; - -export class Box3 { - constructor(min?: Vector3, max?: Vector3); - - /** - * @default new THREE.Vector3( + Infinity, + Infinity, + Infinity ) - */ - min: Vector3; - - /** - * @default new THREE.Vector3( - Infinity, - Infinity, - Infinity ) - */ - max: Vector3; - readonly isBox3: true; - - set(min: Vector3, max: Vector3): this; - setFromArray(array: ArrayLike): this; - setFromBufferAttribute(bufferAttribute: BufferAttribute): this; - setFromPoints(points: Vector3[]): this; - setFromCenterAndSize(center: Vector3, size: Vector3): this; - setFromObject(object: Object3D, precise?: boolean): this; - clone(): this; - copy(box: Box3): this; - makeEmpty(): this; - isEmpty(): boolean; - getCenter(target: Vector3): Vector3; - getSize(target: Vector3): Vector3; - expandByPoint(point: Vector3): this; - expandByVector(vector: Vector3): this; - expandByScalar(scalar: number): this; - expandByObject(object: Object3D, precise?: boolean): this; - containsPoint(point: Vector3): boolean; - containsBox(box: Box3): boolean; - getParameter(point: Vector3, target: Vector3): Vector3; - intersectsBox(box: Box3): boolean; - intersectsSphere(sphere: Sphere): boolean; - intersectsPlane(plane: Plane): boolean; - intersectsTriangle(triangle: Triangle): boolean; - clampPoint(point: Vector3, target: Vector3): Vector3; - distanceToPoint(point: Vector3): number; - getBoundingSphere(target: Sphere): Sphere; - intersect(box: Box3): this; - union(box: Box3): this; - applyMatrix4(matrix: Matrix4): this; - translate(offset: Vector3): this; - equals(box: Box3): boolean; - /** - * @deprecated Use {@link Box3#isEmpty .isEmpty()} instead. - */ - empty(): any; - /** - * @deprecated Use {@link Box3#intersectsBox .intersectsBox()} instead. - */ - isIntersectionBox(b: any): any; - /** - * @deprecated Use {@link Box3#intersectsSphere .intersectsSphere()} instead. - */ - isIntersectionSphere(s: any): any; -} diff --git a/src-testing/src/math/Color.d.ts b/src-testing/src/math/Color.d.ts deleted file mode 100644 index a0e265f83..000000000 --- a/src-testing/src/math/Color.d.ts +++ /dev/null @@ -1,375 +0,0 @@ -import { Matrix3 } from "./Matrix3.js"; -import { Vector3 } from "./Vector3.js"; - -import { BufferAttribute } from "../core/BufferAttribute.js"; -import { InterleavedBufferAttribute } from "../core/InterleavedBufferAttribute.js"; - -export { SRGBToLinear } from "./ColorManagement.js"; - -declare const _colorKeywords: { - aliceblue: 0xf0f8ff; - antiquewhite: 0xfaebd7; - aqua: 0x00ffff; - aquamarine: 0x7fffd4; - azure: 0xf0ffff; - beige: 0xf5f5dc; - bisque: 0xffe4c4; - black: 0x000000; - blanchedalmond: 0xffebcd; - blue: 0x0000ff; - blueviolet: 0x8a2be2; - brown: 0xa52a2a; - burlywood: 0xdeb887; - cadetblue: 0x5f9ea0; - chartreuse: 0x7fff00; - chocolate: 0xd2691e; - coral: 0xff7f50; - cornflowerblue: 0x6495ed; - cornsilk: 0xfff8dc; - crimson: 0xdc143c; - cyan: 0x00ffff; - darkblue: 0x00008b; - darkcyan: 0x008b8b; - darkgoldenrod: 0xb8860b; - darkgray: 0xa9a9a9; - darkgreen: 0x006400; - darkgrey: 0xa9a9a9; - darkkhaki: 0xbdb76b; - darkmagenta: 0x8b008b; - darkolivegreen: 0x556b2f; - darkorange: 0xff8c00; - darkorchid: 0x9932cc; - darkred: 0x8b0000; - darksalmon: 0xe9967a; - darkseagreen: 0x8fbc8f; - darkslateblue: 0x483d8b; - darkslategray: 0x2f4f4f; - darkslategrey: 0x2f4f4f; - darkturquoise: 0x00ced1; - darkviolet: 0x9400d3; - deeppink: 0xff1493; - deepskyblue: 0x00bfff; - dimgray: 0x696969; - dimgrey: 0x696969; - dodgerblue: 0x1e90ff; - firebrick: 0xb22222; - floralwhite: 0xfffaf0; - forestgreen: 0x228b22; - fuchsia: 0xff00ff; - gainsboro: 0xdcdcdc; - ghostwhite: 0xf8f8ff; - gold: 0xffd700; - goldenrod: 0xdaa520; - gray: 0x808080; - green: 0x008000; - greenyellow: 0xadff2f; - grey: 0x808080; - honeydew: 0xf0fff0; - hotpink: 0xff69b4; - indianred: 0xcd5c5c; - indigo: 0x4b0082; - ivory: 0xfffff0; - khaki: 0xf0e68c; - lavender: 0xe6e6fa; - lavenderblush: 0xfff0f5; - lawngreen: 0x7cfc00; - lemonchiffon: 0xfffacd; - lightblue: 0xadd8e6; - lightcoral: 0xf08080; - lightcyan: 0xe0ffff; - lightgoldenrodyellow: 0xfafad2; - lightgray: 0xd3d3d3; - lightgreen: 0x90ee90; - lightgrey: 0xd3d3d3; - lightpink: 0xffb6c1; - lightsalmon: 0xffa07a; - lightseagreen: 0x20b2aa; - lightskyblue: 0x87cefa; - lightslategray: 0x778899; - lightslategrey: 0x778899; - lightsteelblue: 0xb0c4de; - lightyellow: 0xffffe0; - lime: 0x00ff00; - limegreen: 0x32cd32; - linen: 0xfaf0e6; - magenta: 0xff00ff; - maroon: 0x800000; - mediumaquamarine: 0x66cdaa; - mediumblue: 0x0000cd; - mediumorchid: 0xba55d3; - mediumpurple: 0x9370db; - mediumseagreen: 0x3cb371; - mediumslateblue: 0x7b68ee; - mediumspringgreen: 0x00fa9a; - mediumturquoise: 0x48d1cc; - mediumvioletred: 0xc71585; - midnightblue: 0x191970; - mintcream: 0xf5fffa; - mistyrose: 0xffe4e1; - moccasin: 0xffe4b5; - navajowhite: 0xffdead; - navy: 0x000080; - oldlace: 0xfdf5e6; - olive: 0x808000; - olivedrab: 0x6b8e23; - orange: 0xffa500; - orangered: 0xff4500; - orchid: 0xda70d6; - palegoldenrod: 0xeee8aa; - palegreen: 0x98fb98; - paleturquoise: 0xafeeee; - palevioletred: 0xdb7093; - papayawhip: 0xffefd5; - peachpuff: 0xffdab9; - peru: 0xcd853f; - pink: 0xffc0cb; - plum: 0xdda0dd; - powderblue: 0xb0e0e6; - purple: 0x800080; - rebeccapurple: 0x663399; - red: 0xff0000; - rosybrown: 0xbc8f8f; - royalblue: 0x4169e1; - saddlebrown: 0x8b4513; - salmon: 0xfa8072; - sandybrown: 0xf4a460; - seagreen: 0x2e8b57; - seashell: 0xfff5ee; - sienna: 0xa0522d; - silver: 0xc0c0c0; - skyblue: 0x87ceeb; - slateblue: 0x6a5acd; - slategray: 0x708090; - slategrey: 0x708090; - snow: 0xfffafa; - springgreen: 0x00ff7f; - steelblue: 0x4682b4; - tan: 0xd2b48c; - teal: 0x008080; - thistle: 0xd8bfd8; - tomato: 0xff6347; - turquoise: 0x40e0d0; - violet: 0xee82ee; - wheat: 0xf5deb3; - white: 0xffffff; - whitesmoke: 0xf5f5f5; - yellow: 0xffff00; - yellowgreen: 0x9acd32; -}; - -export type ColorRepresentation = Color | string | number; - -export interface HSL { - h: number; - s: number; - l: number; -} - -export interface RGB { - r: number; - g: number; - b: number; -} - -/** - * Class representing a color. - * - * A Color instance is represented by RGB components in the linear working color space, which defaults to - * `LinearSRGBColorSpace`. Inputs conventionally using `SRGBColorSpace` (such as hexadecimals and CSS strings) are - * converted to the working color space automatically. - * - * ``` - * // converted automatically from SRGBColorSpace to LinearSRGBColorSpace - * const color = new THREE.Color().setHex( 0x112233 ); - * ``` - * - * Source color spaces may be specified explicitly, to ensure correct conversions. - * - * ``` - * // assumed already LinearSRGBColorSpace; no conversion - * const color = new THREE.Color().setRGB( 0.5, 0.5, 0.5 ); - * - * // converted explicitly from SRGBColorSpace to LinearSRGBColorSpace - * const color = new THREE.Color().setRGB( 0.5, 0.5, 0.5, SRGBColorSpace ); - * ``` - * - * If THREE.ColorManagement is disabled, no conversions occur. For details, see Color management. - * - * Iterating through a Color instance will yield its components (r, g, b) in the corresponding order. - */ -export class Color { - constructor(color?: ColorRepresentation); - constructor(r: number, g: number, b: number); - - readonly isColor: true; - - /** - * Red channel value between `0.0` and `1.0`. Default is `1`. - * @default 1 - */ - r: number; - - /** - * Green channel value between `0.0` and `1.0`. Default is `1`. - * @default 1 - */ - g: number; - - /** - * Blue channel value between `0.0` and `1.0`. Default is `1`. - * @default 1 - */ - b: number; - - set(...args: [color: ColorRepresentation] | [r: number, g: number, b: number]): this; - - /** - * Sets this color's {@link r}, {@link g} and {@link b} components from the x, y, and z components of the specified - * {@link Vector3 | vector}. - */ - setFromVector3(vector: Vector3): this; - - setScalar(scalar: number): Color; - setHex(hex: number, colorSpace?: string): Color; - - /** - * Sets this color from RGB values. - * @param r Red channel value between 0 and 1. - * @param g Green channel value between 0 and 1. - * @param b Blue channel value between 0 and 1. - */ - setRGB(r: number, g: number, b: number, colorSpace?: string): Color; - - /** - * Sets this color from HSL values. - * Based on MochiKit implementation by Bob Ippolito. - * - * @param h Hue channel value between 0 and 1. - * @param s Saturation value channel between 0 and 1. - * @param l Value channel value between 0 and 1. - */ - setHSL(h: number, s: number, l: number, colorSpace?: string): Color; - - /** - * Sets this color from a CSS context style string. - * @param contextStyle Color in CSS context style format. - */ - setStyle(style: string, colorSpace?: string): Color; - - /** - * Sets this color from a color name. - * Faster than {@link Color#setStyle .setStyle()} method if you don't need the other CSS-style formats. - * @param style Color name in X11 format. - */ - setColorName(style: string, colorSpace?: string): Color; - - /** - * Clones this color. - */ - clone(): this; - - /** - * Copies given color. - * @param color Color to copy. - */ - copy(color: Color): this; - - /** - * Copies given color making conversion from `SRGBColorSpace` to `LinearSRGBColorSpace`. - * @param color Color to copy. - */ - copySRGBToLinear(color: Color): Color; - - /** - * Copies given color making conversion from `LinearSRGBColorSpace` to `SRGBColorSpace`. - * @param color Color to copy. - */ - copyLinearToSRGB(color: Color): Color; - - /** - * Converts this color from `SRGBColorSpace` to `LinearSRGBColorSpace`. - */ - convertSRGBToLinear(): Color; - - /** - * Converts this color from `LinearSRGBColorSpace` to `SRGBColorSpace`. - */ - convertLinearToSRGB(): Color; - - /** - * Returns the hexadecimal value of this color. - */ - getHex(colorSpace?: string): number; - - /** - * Returns the string formated hexadecimal value of this color. - */ - getHexString(colorSpace?: string): string; - - getHSL(target: HSL, colorSpace?: string): HSL; - - getRGB(target: RGB, colorSpace?: string): RGB; - - /** - * Returns the value of this color in CSS context style. - * Example: rgb(r, g, b) - */ - getStyle(colorSpace?: string): string; - - offsetHSL(h: number, s: number, l: number): this; - - add(color: Color): this; - addColors(color1: Color, color2: Color): this; - addScalar(s: number): this; - - /** - * Applies the transform {@link Matrix3 | m} to this color's RGB components. - */ - applyMatrix3(m: Matrix3): this; - - sub(color: Color): this; - multiply(color: Color): this; - multiplyScalar(s: number): this; - lerp(color: Color, alpha: number): this; - lerpColors(color1: Color, color2: Color, alpha: number): this; - lerpHSL(color: Color, alpha: number): this; - equals(color: Color): boolean; - - /** - * Sets this color's red, green and blue value from the provided array or array-like. - * @param array the source array or array-like. - * @param offset (optional) offset into the array-like. Default is 0. - */ - fromArray(array: number[] | ArrayLike, offset?: number): this; - - /** - * Returns an array [red, green, blue], or copies red, green and blue into the provided array. - * @param array (optional) array to store the color to. If this is not provided, a new array will be created. - * @param offset (optional) optional offset into the array. - * @return The created or provided array. - */ - toArray(array?: number[], offset?: number): number[]; - - /** - * Copies red, green and blue into the provided array-like. - * @param array array-like to store the color to. - * @param offset (optional) optional offset into the array-like. - * @return The provided array-like. - */ - toArray(xyz: ArrayLike, offset?: number): ArrayLike; - - /** - * This method defines the serialization result of Color. - * @return The color as a hexadecimal value. - */ - toJSON(): number; - - fromBufferAttribute(attribute: BufferAttribute | InterleavedBufferAttribute, index: number): this; - - [Symbol.iterator](): Generator; - - /** - * List of X11 color names. - */ - static NAMES: typeof _colorKeywords; -} diff --git a/src-testing/src/math/ColorManagement.d.ts b/src-testing/src/math/ColorManagement.d.ts deleted file mode 100644 index eaa520d8c..000000000 --- a/src-testing/src/math/ColorManagement.d.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { ColorSpaceTransfer } from "../constants.js"; -import { Color } from "./Color.js"; -import { Matrix3 } from "./Matrix3.js"; -import { Vector3 } from "./Vector3.js"; - -export interface ColorSpaceDefinition { - primaries: [number, number, number, number, number, number]; - whitePoint: [number, number]; - transfer: ColorSpaceTransfer; - toXYZ: Matrix3; - fromXYZ: Matrix3; - luminanceCoefficients: [number, number, number]; - workingColorSpaceConfig?: { unpackColorSpace: string }; - outputColorSpaceConfig?: { drawingBufferColorSpace: string }; -} - -export interface ColorManagement { - /** - * @default true - */ - enabled: boolean; - - /** - * @default LinearSRGBColorSpace - */ - workingColorSpace: string; - - spaces: Record; - - convert: (color: Color, sourceColorSpace: string, targetColorSpace: string) => Color; - - fromWorkingColorSpace: (color: Color, targetColorSpace: string) => Color; - - toWorkingColorSpace: (color: Color, sourceColorSpace: string) => Color; - - getPrimaries: (colorSpace: string) => [number, number, number, number, number, number]; - - getTransfer: (colorSpace: string) => ColorSpaceTransfer; - - getLuminanceCoefficients: (target: Vector3, colorSpace?: string) => [number, number, number]; - - define: (colorSpaces: Record) => void; -} - -export const ColorManagement: ColorManagement; - -export function SRGBToLinear(c: number): number; - -export function LinearToSRGB(c: number): number; diff --git a/src-testing/src/math/Cylindrical.d.ts b/src-testing/src/math/Cylindrical.d.ts deleted file mode 100644 index 6764f8154..000000000 --- a/src-testing/src/math/Cylindrical.d.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Vector3 } from "./Vector3.js"; - -export class Cylindrical { - constructor(radius?: number, theta?: number, y?: number); - - /** - * @default 1 - */ - radius: number; - - /** - * @default 0 - */ - theta: number; - - /** - * @default 0 - */ - y: number; - - clone(): this; - copy(other: Cylindrical): this; - set(radius: number, theta: number, y: number): this; - setFromVector3(vec3: Vector3): this; - setFromCartesianCoords(x: number, y: number, z: number): this; -} diff --git a/src-testing/src/math/Euler.d.ts b/src-testing/src/math/Euler.d.ts deleted file mode 100644 index 81be13d82..000000000 --- a/src-testing/src/math/Euler.d.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { Matrix4 } from "./Matrix4.js"; -import { Quaternion } from "./Quaternion.js"; -import { Vector3 } from "./Vector3.js"; - -export type EulerOrder = "XYZ" | "YXZ" | "ZXY" | "ZYX" | "YZX" | "XZY"; - -export type EulerTuple = [x: number, y: number, z: number, order?: EulerOrder]; - -export class Euler { - constructor(x?: number, y?: number, z?: number, order?: EulerOrder); - - /** - * @default 0 - */ - x: number; - - /** - * @default 0 - */ - y: number; - - /** - * @default 0 - */ - z: number; - - /** - * @default THREE.Euler.DEFAULT_ORDER - */ - order: EulerOrder; - readonly isEuler: true; - - _onChangeCallback: () => void; - - set(x: number, y: number, z: number, order?: EulerOrder): Euler; - clone(): this; - copy(euler: Euler): this; - setFromRotationMatrix(m: Matrix4, order?: EulerOrder, update?: boolean): Euler; - setFromQuaternion(q: Quaternion, order?: EulerOrder, update?: boolean): Euler; - setFromVector3(v: Vector3, order?: EulerOrder): Euler; - reorder(newOrder: EulerOrder): Euler; - equals(euler: Euler): boolean; - fromArray(array: EulerTuple): Euler; - toArray(array?: Partial, offset?: number): EulerTuple; - _onChange(callback: () => void): this; - - static DEFAULT_ORDER: "XYZ"; - - [Symbol.iterator](): Generator; -} diff --git a/src-testing/src/math/Frustum.d.ts b/src-testing/src/math/Frustum.d.ts deleted file mode 100644 index 364c8e926..000000000 --- a/src-testing/src/math/Frustum.d.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { CoordinateSystem } from "../constants.js"; -import { Object3D } from "../core/Object3D.js"; -import { Sprite } from "../objects/Sprite.js"; -import { Box3 } from "./Box3.js"; -import { Matrix4 } from "./Matrix4.js"; -import { Plane } from "./Plane.js"; -import { Sphere } from "./Sphere.js"; -import { Vector3 } from "./Vector3.js"; - -/** - * Frustums are used to determine what is inside the camera's field of view. They help speed up the rendering process. - */ -export class Frustum { - constructor(p0?: Plane, p1?: Plane, p2?: Plane, p3?: Plane, p4?: Plane, p5?: Plane); - - /** - * Array of 6 vectors. - */ - planes: Plane[]; - - set(p0: Plane, p1: Plane, p2: Plane, p3: Plane, p4: Plane, p5: Plane): Frustum; - clone(): this; - copy(frustum: Frustum): this; - setFromProjectionMatrix(m: Matrix4, coordinateSystem?: CoordinateSystem): this; - intersectsObject(object: Object3D): boolean; - intersectsSprite(sprite: Sprite): boolean; - intersectsSphere(sphere: Sphere): boolean; - intersectsBox(box: Box3): boolean; - containsPoint(point: Vector3): boolean; -} diff --git a/src-testing/src/math/Interpolant.d.ts b/src-testing/src/math/Interpolant.d.ts deleted file mode 100644 index 9d2b1aced..000000000 --- a/src-testing/src/math/Interpolant.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -export abstract class Interpolant { - constructor(parameterPositions: any, sampleValues: any, sampleSize: number, resultBuffer?: any); - - parameterPositions: any; - sampleValues: any; - valueSize: number; - resultBuffer: any; - - evaluate(time: number): any; -} diff --git a/src-testing/src/math/Line3.d.ts b/src-testing/src/math/Line3.d.ts deleted file mode 100644 index ab7e749bc..000000000 --- a/src-testing/src/math/Line3.d.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { Matrix4 } from "./Matrix4.js"; -import { Vector3 } from "./Vector3.js"; - -export class Line3 { - constructor(start?: Vector3, end?: Vector3); - - /** - * @default new THREE.Vector3() - */ - start: Vector3; - - /** - * @default new THREE.Vector3() - */ - end: Vector3; - - set(start?: Vector3, end?: Vector3): Line3; - clone(): this; - copy(line: Line3): this; - getCenter(target: Vector3): Vector3; - delta(target: Vector3): Vector3; - distanceSq(): number; - distance(): number; - at(t: number, target: Vector3): Vector3; - closestPointToPointParameter(point: Vector3, clampToLine?: boolean): number; - closestPointToPoint(point: Vector3, clampToLine: boolean, target: Vector3): Vector3; - applyMatrix4(matrix: Matrix4): Line3; - equals(line: Line3): boolean; -} diff --git a/src-testing/src/math/MathUtils.d.ts b/src-testing/src/math/MathUtils.d.ts deleted file mode 100644 index 48f10a3c3..000000000 --- a/src-testing/src/math/MathUtils.d.ts +++ /dev/null @@ -1,137 +0,0 @@ -import { Quaternion } from "./Quaternion.js"; - -/** - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/math/MathUtils.js|src/math/MathUtils.js} - */ - -export const DEG2RAD: number; - -export const RAD2DEG: number; - -export function generateUUID(): string; - -/** - * Clamps the x to be between a and b. - * - * @param value Value to be clamped. - * @param min Minimum value. - * @param max Maximum value. - */ -export function clamp(value: number, min: number, max: number): number; - -export function euclideanModulo(n: number, m: number): number; - -/** - * Linear mapping of x from range [a1, a2] to range [b1, b2]. - * - * @param x Value to be mapped. - * @param a1 Minimum value for range A. - * @param a2 Maximum value for range A. - * @param b1 Minimum value for range B. - * @param b2 Maximum value for range B. - */ -export function mapLinear(x: number, a1: number, a2: number, b1: number, b2: number): number; - -export function inverseLerp(x: number, y: number, t: number): number; - -/** - * Returns a value linearly interpolated from two known points based - * on the given interval - t = 0 will return x and t = 1 will return y. - * - * @param x Start point. - * @param y End point. - * @param t interpolation factor in the closed interval [0, 1] - */ -export function lerp(x: number, y: number, t: number): number; - -/** - * Smoothly interpolate a number from x toward y in a spring-like - * manner using the dt to maintain frame rate independent movement. - * - * @param x Current point. - * @param y Target point. - * @param lambda A higher lambda value will make the movement more sudden, and a lower value will make the movement more gradual. - * @param dt Delta time in seconds. - */ -export function damp(x: number, y: number, lambda: number, dt: number): number; - -/** - * Returns a value that alternates between 0 and length. - * - * @param x The value to pingpong. - * @param length The positive value the export function will pingpong to. Default is 1. - */ -export function pingpong(x: number, length?: number): number; - -export function smoothstep(x: number, min: number, max: number): number; - -export function smootherstep(x: number, min: number, max: number): number; - -/** - * Random integer from low to high interval. - */ -export function randInt(low: number, high: number): number; - -/** - * Random float from low to high interval. - */ -export function randFloat(low: number, high: number): number; - -/** - * Random float from - range / 2 to range / 2 interval. - */ -export function randFloatSpread(range: number): number; - -/** - * Deterministic pseudo-random float in the interval [ 0, 1 ]. - */ -export function seededRandom(seed?: number): number; - -export function degToRad(degrees: number): number; - -export function radToDeg(radians: number): number; - -export function isPowerOfTwo(value: number): boolean; - -export function ceilPowerOfTwo(value: number): number; - -export function floorPowerOfTwo(value: number): number; - -export function setQuaternionFromProperEuler(q: Quaternion, a: number, b: number, c: number, order: string): void; - -export function denormalize( - value: number, - array: Float32Array | Uint32Array | Uint16Array | Uint8Array | Int32Array | Int16Array | Int8Array, -): number; - -export function normalize( - value: number, - array: Float32Array | Uint32Array | Uint16Array | Uint8Array | Int32Array | Int16Array | Int8Array, -): number; - -export const MathUtils: { - DEG2RAD: typeof DEG2RAD; - RAD2DEG: typeof RAD2DEG; - generateUUID: typeof generateUUID; - clamp: typeof clamp; - euclideanModulo: typeof euclideanModulo; - mapLinear: typeof mapLinear; - inverseLerp: typeof inverseLerp; - lerp: typeof lerp; - damp: typeof damp; - pingpong: typeof pingpong; - smoothstep: typeof smoothstep; - smootherstep: typeof smootherstep; - randInt: typeof randInt; - randFloat: typeof randFloat; - randFloatSpread: typeof randFloatSpread; - seededRandom: typeof seededRandom; - degToRad: typeof degToRad; - radToDeg: typeof radToDeg; - isPowerOfTwo: typeof isPowerOfTwo; - ceilPowerOfTwo: typeof ceilPowerOfTwo; - floorPowerOfTwo: typeof floorPowerOfTwo; - setQuaternionFromProperEuler: typeof setQuaternionFromProperEuler; - normalize: typeof normalize; - denormalize: typeof denormalize; -}; diff --git a/src-testing/src/math/Matrix2.d.ts b/src-testing/src/math/Matrix2.d.ts deleted file mode 100644 index 40ed4c8aa..000000000 --- a/src-testing/src/math/Matrix2.d.ts +++ /dev/null @@ -1,53 +0,0 @@ -export type Matrix2Tuple = [ - n11: number, - n12: number, - n21: number, - n22: number, -]; - -/** - * A class representing a 2x2 {@link https://en.wikipedia.org/wiki/Matrix_(mathematics) matrix}. - * - * @example - * const m = new Matrix2(); - */ -export class Matrix2 { - readonly isMatrix2: true; - - /** - * A {@link https://en.wikipedia.org/wiki/Row-_and_column-major_order column-major} list of matrix values. - */ - elements: Matrix2Tuple; - - /** - * Creates a 2x2 {@link https://en.wikipedia.org/wiki/Identity_matrix identity matrix}. - */ - constructor(); - - /** - * Creates a 2x2 matrix with the given arguments in row-major order. - */ - constructor(n11: number, n12: number, n21: number, n22: number); - - /** - * Resets this matrix to the 2x2 identity matrix: - */ - identity(): this; - - /** - * Sets the elements of this matrix based on an array in - * {@link https://en.wikipedia.org/wiki/Row-_and_column-major_order#Column-major_order column-major} format. - * - * @param array the array to read the elements from - * @param offset (optional) index of first element in the array. Default is `0`. - */ - fromArray(array: ArrayLike, offset?: number): this; - - /** - * Sets the 2x2 matrix values to the given - * {@link https://en.wikipedia.org/wiki/Row-_and_column-major_order row-major} sequence of values: - * [n11, n12, - * n21, n22] - */ - set(n11: number, n12: number, n21: number, n22: number): this; -} diff --git a/src-testing/src/math/Matrix3.d.ts b/src-testing/src/math/Matrix3.d.ts deleted file mode 100644 index 0b593fcb8..000000000 --- a/src-testing/src/math/Matrix3.d.ts +++ /dev/null @@ -1,184 +0,0 @@ -// https://threejs.org/docs/#api/en/math/Matrix3 - -import { Matrix4 } from "./Matrix4.js"; -import { Vector2 } from "./Vector2.js"; -import { Vector3 } from "./Vector3.js"; - -export type Matrix3Tuple = [ - n11: number, - n12: number, - n13: number, - n21: number, - n22: number, - n23: number, - n31: number, - n32: number, - n33: number, -]; - -export class Matrix3 { - readonly isMatrix3: true; - - /** - * Array with matrix values. - * @default [1, 0, 0, 0, 1, 0, 0, 0, 1] - */ - elements: Matrix3Tuple; - - /** - * Creates an identity matrix. - */ - constructor(); - /** - * Creates a 3x3 matrix with the given arguments in row-major order. - */ - constructor( - n11: number, - n12: number, - n13: number, - n21: number, - n22: number, - n23: number, - n31: number, - n32: number, - n33: number, - ); - - set( - n11: number, - n12: number, - n13: number, - n21: number, - n22: number, - n23: number, - n31: number, - n32: number, - n33: number, - ): Matrix3; - - identity(): this; - - copy(m: Matrix3): this; - - extractBasis(xAxis: Vector3, yAxis: Vector3, zAxis: Vector3): this; - - setFromMatrix4(m: Matrix4): Matrix3; - - /** - * Multiplies this matrix by m. - */ - multiply(m: Matrix3): this; - - premultiply(m: Matrix3): this; - - /** - * Sets this matrix to a x b. - */ - multiplyMatrices(a: Matrix3, b: Matrix3): this; - - multiplyScalar(s: number): this; - - determinant(): number; - - /** - * Inverts this matrix in place. - */ - invert(): this; - - /** - * Transposes this matrix in place. - */ - transpose(): this; - - getNormalMatrix(matrix4: Matrix4): this; - - /** - * Transposes this matrix into the supplied array r, and returns itself. - */ - transposeIntoArray(r: number[]): this; - - setUvTransform(tx: number, ty: number, sx: number, sy: number, rotation: number, cx: number, cy: number): this; - - scale(sx: number, sy: number): this; - - rotate(theta: number): this; - - translate(tx: number, ty: number): this; - - /** - * Sets this matrix as a 2D translation transform: - * - * ``` - * 1, 0, x, - * 0, 1, y, - * 0, 0, 1 - * ``` - * - * @param v the amount to translate. - */ - makeTranslation(v: Vector2): this; - /** - * Sets this matrix as a 2D translation transform: - * - * ``` - * 1, 0, x, - * 0, 1, y, - * 0, 0, 1 - * ``` - * - * @param x the amount to translate in the X axis. - * @param y the amount to translate in the Y axis. - */ - makeTranslation(x: number, y: number): this; - - /** - * Sets this matrix as a 2D rotational transformation by theta radians. The resulting matrix will be: - * - * ``` - * cos(θ) -sin(θ) 0 - * sin(θ) cos(θ) 0 - * 0 0 1 - * ``` - * - * @param theta Rotation angle in radians. Positive values rotate counterclockwise. - */ - makeRotation(theta: number): this; - - /** - * Sets this matrix as a 2D scale transform: - * - * ``` - * x, 0, 0, - * 0, y, 0, - * 0, 0, 1 - * ``` - * - * @param x the amount to scale in the X axis. - * @param y the amount to scale in the Y axis. - */ - makeScale(x: number, y: number): this; - - equals(matrix: Matrix3): boolean; - - /** - * Sets the values of this matrix from the provided array or array-like. - * @param array the source array or array-like. - * @param offset (optional) offset into the array-like. Default is 0. - */ - fromArray(array: ArrayLike, offset?: number): this; - - /** - * Writes the elements of this matrix to an array in - * {@link https://en.wikipedia.org/wiki/Row-_and_column-major_order#Column-major_order column-major} format. - */ - toArray(): Matrix3Tuple; - /** - * Writes the elements of this matrix to an array in - * {@link https://en.wikipedia.org/wiki/Row-_and_column-major_order#Column-major_order column-major} format. - * @param array array to store the resulting vector in. If not given a new array will be created. - * @param offset (optional) offset in the array at which to put the result. - */ - toArray>(array: TArray, offset?: number): TArray; - - clone(): this; -} diff --git a/src-testing/src/math/Matrix4.d.ts b/src-testing/src/math/Matrix4.d.ts deleted file mode 100644 index 9ef2a9ceb..000000000 --- a/src-testing/src/math/Matrix4.d.ts +++ /dev/null @@ -1,284 +0,0 @@ -import { CoordinateSystem } from "../constants.js"; -import { Euler } from "./Euler.js"; -import { Matrix3 } from "./Matrix3.js"; -import { Quaternion } from "./Quaternion.js"; -import { Vector3 } from "./Vector3.js"; - -export type Matrix4Tuple = [ - n11: number, - n12: number, - n13: number, - n14: number, - n21: number, - n22: number, - n23: number, - n24: number, - n31: number, - n32: number, - n33: number, - n34: number, - n41: number, - n42: number, - n43: number, - n44: number, -]; - -/** - * A 4x4 Matrix. - * - * @example - * // Simple rig for rotating around 3 axes - * const m = new THREE.Matrix4(); - * const m1 = new THREE.Matrix4(); - * const m2 = new THREE.Matrix4(); - * const m3 = new THREE.Matrix4(); - * const alpha = 0; - * const beta = Math.PI; - * const gamma = Math.PI/2; - * m1.makeRotationX( alpha ); - * m2.makeRotationY( beta ); - * m3.makeRotationZ( gamma ); - * m.multiplyMatrices( m1, m2 ); - * m.multiply( m3 ); - */ -export class Matrix4 { - readonly isMatrix4: true; - - /** - * Array with matrix values. - * @default [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] - */ - elements: Matrix4Tuple; - - /** - * Creates an identity matrix. - */ - constructor(); - /** - * Creates a 4x4 matrix with the given arguments in row-major order. - */ - constructor( - n11: number, - n12: number, - n13: number, - n14: number, - n21: number, - n22: number, - n23: number, - n24: number, - n31: number, - n32: number, - n33: number, - n34: number, - n41: number, - n42: number, - n43: number, - n44: number, - ); - - /** - * Sets all fields of this matrix. - */ - set( - n11: number, - n12: number, - n13: number, - n14: number, - n21: number, - n22: number, - n23: number, - n24: number, - n31: number, - n32: number, - n33: number, - n34: number, - n41: number, - n42: number, - n43: number, - n44: number, - ): this; - - /** - * Resets this matrix to identity. - */ - identity(): this; - - clone(): Matrix4; - - copy(m: Matrix4): this; - - copyPosition(m: Matrix4): this; - - /** - * Set the upper 3x3 elements of this matrix to the values of the Matrix3 m. - */ - setFromMatrix3(m: Matrix3): this; - - extractBasis(xAxis: Vector3, yAxis: Vector3, zAxis: Vector3): this; - - makeBasis(xAxis: Vector3, yAxis: Vector3, zAxis: Vector3): this; - - /** - * Copies the rotation component of the supplied matrix m into this matrix rotation component. - */ - extractRotation(m: Matrix4): this; - - makeRotationFromEuler(euler: Euler): this; - - makeRotationFromQuaternion(q: Quaternion): this; - - /** - * Constructs a rotation matrix, looking from eye towards center with defined up vector. - */ - lookAt(eye: Vector3, target: Vector3, up: Vector3): this; - - /** - * Multiplies this matrix by m. - */ - multiply(m: Matrix4): this; - - premultiply(m: Matrix4): this; - - /** - * Sets this matrix to a x b. - */ - multiplyMatrices(a: Matrix4, b: Matrix4): this; - - /** - * Multiplies this matrix by s. - */ - multiplyScalar(s: number): this; - - /** - * Computes determinant of this matrix. - * Based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm - */ - determinant(): number; - - /** - * Transposes this matrix. - */ - transpose(): this; - - /** - * Sets the position component for this matrix from vector v. - */ - setPosition(v: Vector3): this; - setPosition(x: number, y: number, z: number): this; - - /** - * Inverts this matrix. - */ - invert(): this; - - /** - * Multiplies the columns of this matrix by vector v. - */ - scale(v: Vector3): this; - - getMaxScaleOnAxis(): number; - - /** - * Sets this matrix as translation transform. - */ - makeTranslation(v: Vector3): this; - makeTranslation(x: number, y: number, z: number): this; - - /** - * Sets this matrix as rotation transform around x axis by theta radians. - * - * @param theta Rotation angle in radians. - */ - makeRotationX(theta: number): this; - - /** - * Sets this matrix as rotation transform around y axis by theta radians. - * - * @param theta Rotation angle in radians. - */ - makeRotationY(theta: number): this; - - /** - * Sets this matrix as rotation transform around z axis by theta radians. - * - * @param theta Rotation angle in radians. - */ - makeRotationZ(theta: number): this; - - /** - * Sets this matrix as rotation transform around axis by angle radians. - * Based on http://www.gamedev.net/reference/articles/article1199.asp. - * - * @param axis Rotation axis. - * @param angle Rotation angle in radians. - */ - makeRotationAxis(axis: Vector3, angle: number): this; - - /** - * Sets this matrix as scale transform. - */ - makeScale(x: number, y: number, z: number): this; - - /** - * Sets this matrix as shear transform. - */ - makeShear(xy: number, xz: number, yx: number, yz: number, zx: number, zy: number): this; - - /** - * Sets this matrix to the transformation composed of translation, rotation and scale. - */ - compose(position: Vector3, quaternion: Quaternion, scale: Vector3): this; - - /** - * Decomposes this matrix into it's position, quaternion and scale components. - */ - decompose(position: Vector3, quaternion: Quaternion, scale: Vector3): this; - - /** - * Creates a perspective projection matrix. - */ - makePerspective( - left: number, - right: number, - top: number, - bottom: number, - near: number, - far: number, - coordinateSystem?: CoordinateSystem, - ): this; - - /** - * Creates an orthographic projection matrix. - */ - makeOrthographic( - left: number, - right: number, - top: number, - bottom: number, - near: number, - far: number, - coordinateSystem?: CoordinateSystem, - ): this; - - equals(matrix: Matrix4): boolean; - - /** - * Sets the values of this matrix from the provided array or array-like. - * @param array the source array or array-like. - * @param offset (optional) offset into the array-like. Default is 0. - */ - fromArray(array: ArrayLike, offset?: number): this; - - /** - * Writes the elements of this matrix to an array in - * {@link https://en.wikipedia.org/wiki/Row-_and_column-major_order#Column-major_order column-major} format. - */ - toArray(): Matrix4Tuple; - /** - * Writes the elements of this matrix to an array in - * {@link https://en.wikipedia.org/wiki/Row-_and_column-major_order#Column-major_order column-major} format. - * @param array array to store the resulting vector in. - * @param offset (optional) offset in the array at which to put the result. - */ - toArray>(array: TArray, offset?: number): TArray; -} diff --git a/src-testing/src/math/Plane.d.ts b/src-testing/src/math/Plane.d.ts deleted file mode 100644 index 59fa23912..000000000 --- a/src-testing/src/math/Plane.d.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { Box3 } from "./Box3.js"; -import { Line3 } from "./Line3.js"; -import { Matrix3 } from "./Matrix3.js"; -import { Matrix4 } from "./Matrix4.js"; -import { Sphere } from "./Sphere.js"; -import { Vector3 } from "./Vector3.js"; - -export class Plane { - constructor(normal?: Vector3, constant?: number); - - /** - * @default new THREE.Vector3( 1, 0, 0 ) - */ - normal: Vector3; - - /** - * @default 0 - */ - constant: number; - - readonly isPlane: true; - - set(normal: Vector3, constant: number): Plane; - setComponents(x: number, y: number, z: number, w: number): Plane; - setFromNormalAndCoplanarPoint(normal: Vector3, point: Vector3): Plane; - setFromCoplanarPoints(a: Vector3, b: Vector3, c: Vector3): Plane; - clone(): this; - copy(plane: Plane): this; - normalize(): Plane; - negate(): Plane; - distanceToPoint(point: Vector3): number; - distanceToSphere(sphere: Sphere): number; - projectPoint(point: Vector3, target: Vector3): Vector3; - intersectLine(line: Line3, target: Vector3): Vector3 | null; - intersectsLine(line: Line3): boolean; - intersectsBox(box: Box3): boolean; - intersectsSphere(sphere: Sphere): boolean; - coplanarPoint(target: Vector3): Vector3; - applyMatrix4(matrix: Matrix4, optionalNormalMatrix?: Matrix3): Plane; - translate(offset: Vector3): Plane; - equals(plane: Plane): boolean; - - /** - * @deprecated Use {@link Plane#intersectsLine .intersectsLine()} instead. - */ - isIntersectionLine(l: any): any; -} diff --git a/src-testing/src/math/Quaternion.d.ts b/src-testing/src/math/Quaternion.d.ts deleted file mode 100644 index 7485b6956..000000000 --- a/src-testing/src/math/Quaternion.d.ts +++ /dev/null @@ -1,189 +0,0 @@ -import { BufferAttribute } from "../core/BufferAttribute.js"; -import { InterleavedBufferAttribute } from "../core/InterleavedBufferAttribute.js"; -import { Euler } from "./Euler.js"; -import { Matrix4 } from "./Matrix4.js"; -import { Vector3, Vector3Like } from "./Vector3.js"; - -export interface QuaternionLike { - readonly x: number; - readonly y: number; - readonly z: number; - readonly w: number; -} - -export type QuaternionTuple = [x: number, y: number, z: number, w: number]; - -/** - * Implementation of a quaternion. This is used for rotating things without incurring in the dreaded gimbal lock issue, amongst other advantages. - * - * @example - * const quaternion = new THREE.Quaternion(); - * quaternion.setFromAxisAngle( new THREE.Vector3( 0, 1, 0 ), Math.PI / 2 ); - * const vector = new THREE.Vector3( 1, 0, 0 ); - * vector.applyQuaternion( quaternion ); - */ -export class Quaternion { - /** - * @param x x coordinate - * @param y y coordinate - * @param z z coordinate - * @param w w coordinate - */ - constructor(x?: number, y?: number, z?: number, w?: number); - - /** - * @default 0 - */ - x: number; - - /** - * @default 0 - */ - y: number; - - /** - * @default 0 - */ - z: number; - - /** - * @default 1 - */ - w: number; - readonly isQuaternion: true; - - /** - * Sets values of this quaternion. - */ - set(x: number, y: number, z: number, w: number): this; - - /** - * Clones this quaternion. - */ - clone(): this; - - /** - * Copies values of q to this quaternion. - */ - copy(q: QuaternionLike): this; - - /** - * Sets this quaternion from rotation specified by Euler angles. - */ - setFromEuler(euler: Euler, update?: boolean): this; - - /** - * Sets this quaternion from rotation specified by axis and angle. - * Adapted from http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm. - * Axis have to be normalized, angle is in radians. - */ - setFromAxisAngle(axis: Vector3Like, angle: number): this; - - /** - * Sets this quaternion from rotation component of m. Adapted from http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm. - */ - setFromRotationMatrix(m: Matrix4): this; - setFromUnitVectors(vFrom: Vector3, vTo: Vector3Like): this; - angleTo(q: Quaternion): number; - rotateTowards(q: Quaternion, step: number): this; - - identity(): this; - - /** - * Inverts this quaternion. - */ - invert(): this; - - conjugate(): this; - dot(v: Quaternion): number; - lengthSq(): number; - - /** - * Computes length of this quaternion. - */ - length(): number; - - /** - * Normalizes this quaternion. - */ - normalize(): this; - - /** - * Multiplies this quaternion by b. - */ - multiply(q: Quaternion): this; - premultiply(q: Quaternion): this; - - /** - * Sets this quaternion to a x b - * Adapted from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm. - */ - multiplyQuaternions(a: Quaternion, b: Quaternion): this; - - slerp(qb: Quaternion, t: number): this; - slerpQuaternions(qa: Quaternion, qb: Quaternion, t: number): this; - equals(v: Quaternion): boolean; - - /** - * Sets this quaternion's x, y, z and w value from the provided array or array-like. - * @param array the source array or array-like. - * @param offset (optional) offset into the array. Default is 0. - */ - fromArray(array: number[] | ArrayLike, offset?: number): this; - - /** - * Returns an array [x, y, z, w], or copies x, y, z and w into the provided array. - * @param array (optional) array to store the quaternion to. If this is not provided, a new array will be created. - * @param offset (optional) optional offset into the array. - * @return The created or provided array. - */ - toArray(array?: number[], offset?: number): number[]; - toArray(array?: QuaternionTuple, offset?: 0): QuaternionTuple; - - /** - * Copies x, y, z and w into the provided array-like. - * @param array array-like to store the quaternion to. - * @param offset (optional) optional offset into the array. - * @return The provided array-like. - */ - toArray(array: ArrayLike, offset?: number): ArrayLike; - - /** - * This method defines the serialization result of Quaternion. - * @return The numerical elements of this quaternion in an array of format [x, y, z, w]. - */ - toJSON(): [number, number, number, number]; - - /** - * Sets x, y, z, w properties of this quaternion from the attribute. - * @param attribute the source attribute. - * @param index index in the attribute. - */ - fromBufferAttribute(attribute: BufferAttribute | InterleavedBufferAttribute, index: number): this; - - _onChange(callback: () => void): this; - _onChangeCallback: () => void; - - static slerpFlat( - dst: number[], - dstOffset: number, - src0: number[], - srcOffset: number, - src1: number[], - stcOffset1: number, - t: number, - ): void; - - static multiplyQuaternionsFlat( - dst: number[], - dstOffset: number, - src0: number[], - srcOffset: number, - src1: number[], - stcOffset1: number, - ): number[]; - - random(): this; - - [Symbol.iterator](): Generator; -} diff --git a/src-testing/src/math/Ray.d.ts b/src-testing/src/math/Ray.d.ts deleted file mode 100644 index 98b9fd70f..000000000 --- a/src-testing/src/math/Ray.d.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { Box3 } from "./Box3.js"; -import { Matrix4 } from "./Matrix4.js"; -import { Plane } from "./Plane.js"; -import { Sphere } from "./Sphere.js"; -import { Vector3 } from "./Vector3.js"; - -export class Ray { - constructor(origin?: Vector3, direction?: Vector3); - - /** - * @default new THREE.Vector3() - */ - origin: Vector3; - - /** - * @default new THREE.Vector3( 0, 0, - 1 ) - */ - direction: Vector3; - - set(origin: Vector3, direction: Vector3): Ray; - clone(): this; - copy(ray: Ray): this; - at(t: number, target: Vector3): Vector3; - lookAt(v: Vector3): Ray; - recast(t: number): Ray; - closestPointToPoint(point: Vector3, target: Vector3): Vector3; - distanceToPoint(point: Vector3): number; - distanceSqToPoint(point: Vector3): number; - distanceSqToSegment( - v0: Vector3, - v1: Vector3, - optionalPointOnRay?: Vector3, - optionalPointOnSegment?: Vector3, - ): number; - intersectSphere(sphere: Sphere, target: Vector3): Vector3 | null; - intersectsSphere(sphere: Sphere): boolean; - distanceToPlane(plane: Plane): number; - intersectPlane(plane: Plane, target: Vector3): Vector3 | null; - intersectsPlane(plane: Plane): boolean; - intersectBox(box: Box3, target: Vector3): Vector3 | null; - intersectsBox(box: Box3): boolean; - intersectTriangle(a: Vector3, b: Vector3, c: Vector3, backfaceCulling: boolean, target: Vector3): Vector3 | null; - applyMatrix4(matrix4: Matrix4): Ray; - equals(ray: Ray): boolean; - - /** - * @deprecated Use {@link Ray#intersectsBox .intersectsBox()} instead. - */ - isIntersectionBox(b: any): any; - - /** - * @deprecated Use {@link Ray#intersectsPlane .intersectsPlane()} instead. - */ - isIntersectionPlane(p: any): any; - - /** - * @deprecated Use {@link Ray#intersectsSphere .intersectsSphere()} instead. - */ - isIntersectionSphere(s: any): any; -} diff --git a/src-testing/src/math/Sphere.d.ts b/src-testing/src/math/Sphere.d.ts deleted file mode 100644 index a423a6f97..000000000 --- a/src-testing/src/math/Sphere.d.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { Box3 } from "./Box3.js"; -import { Matrix4 } from "./Matrix4.js"; -import { Plane } from "./Plane.js"; -import { Vector3 } from "./Vector3.js"; - -export class Sphere { - constructor(center?: Vector3, radius?: number); - - /** - * Read-only flag to check if a given object is of type {@link Sphere}. - */ - readonly isSphere: true; - - /** - * @default new Vector3() - */ - center: Vector3; - - /** - * @default 1 - */ - radius: number; - - set(center: Vector3, radius: number): Sphere; - setFromPoints(points: Vector3[], optionalCenter?: Vector3): Sphere; - clone(): this; - copy(sphere: Sphere): this; - expandByPoint(point: Vector3): this; - isEmpty(): boolean; - makeEmpty(): this; - containsPoint(point: Vector3): boolean; - distanceToPoint(point: Vector3): number; - intersectsSphere(sphere: Sphere): boolean; - intersectsBox(box: Box3): boolean; - intersectsPlane(plane: Plane): boolean; - clampPoint(point: Vector3, target: Vector3): Vector3; - getBoundingBox(target: Box3): Box3; - applyMatrix4(matrix: Matrix4): Sphere; - translate(offset: Vector3): Sphere; - equals(sphere: Sphere): boolean; - union(sphere: Sphere): this; - - /** - * @deprecated Use {@link Sphere#isEmpty .isEmpty()} instead. - */ - empty(): any; -} diff --git a/src-testing/src/math/Spherical.d.ts b/src-testing/src/math/Spherical.d.ts deleted file mode 100644 index 8d4815a17..000000000 --- a/src-testing/src/math/Spherical.d.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { Vector3 } from "./Vector3.js"; - -export class Spherical { - constructor(radius?: number, phi?: number, theta?: number); - - /** - * @default 1 - */ - radius: number; - - /** - * @default 0 - */ - phi: number; - - /** - * @default 0 - */ - theta: number; - - set(radius: number, phi: number, theta: number): this; - clone(): this; - copy(other: Spherical): this; - makeSafe(): this; - setFromVector3(v: Vector3): this; - setFromCartesianCoords(x: number, y: number, z: number): this; -} diff --git a/src-testing/src/math/SphericalHarmonics3.d.ts b/src-testing/src/math/SphericalHarmonics3.d.ts deleted file mode 100644 index 5981a0b48..000000000 --- a/src-testing/src/math/SphericalHarmonics3.d.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { Vector3 } from "./Vector3.js"; - -export class SphericalHarmonics3 { - constructor(); - - /** - * @default [new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3(), - * new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3()] - */ - coefficients: Vector3[]; - readonly isSphericalHarmonics3: true; - - set(coefficients: Vector3[]): SphericalHarmonics3; - zero(): SphericalHarmonics3; - add(sh: SphericalHarmonics3): SphericalHarmonics3; - addScaledSH(sh: SphericalHarmonics3, s: number): SphericalHarmonics3; - scale(s: number): SphericalHarmonics3; - lerp(sh: SphericalHarmonics3, alpha: number): SphericalHarmonics3; - equals(sh: SphericalHarmonics3): boolean; - copy(sh: SphericalHarmonics3): SphericalHarmonics3; - clone(): this; - - /** - * Sets the values of this spherical harmonics from the provided array or array-like. - * @param array the source array or array-like. - * @param offset (optional) offset into the array. Default is 0. - */ - fromArray(array: number[] | ArrayLike, offset?: number): this; - - /** - * Returns an array with the values of this spherical harmonics, or copies them into the provided array. - * @param array (optional) array to store the spherical harmonics to. If this is not provided, a new array will be created. - * @param offset (optional) optional offset into the array. - * @return The created or provided array. - */ - toArray(array?: number[], offset?: number): number[]; - - /** - * Returns an array with the values of this spherical harmonics, or copies them into the provided array-like. - * @param array array-like to store the spherical harmonics to. - * @param offset (optional) optional offset into the array-like. - * @return The provided array-like. - */ - toArray(array: ArrayLike, offset?: number): ArrayLike; - - getAt(normal: Vector3, target: Vector3): Vector3; - getIrradianceAt(normal: Vector3, target: Vector3): Vector3; - - static getBasisAt(normal: Vector3, shBasis: number[]): void; -} diff --git a/src-testing/src/math/Triangle.d.ts b/src-testing/src/math/Triangle.d.ts deleted file mode 100644 index 9f0e7935b..000000000 --- a/src-testing/src/math/Triangle.d.ts +++ /dev/null @@ -1,110 +0,0 @@ -import { Box3 } from "./Box3.js"; -import { Plane } from "./Plane.js"; -import { Vector2 } from "./Vector2.js"; -import { Vector3 } from "./Vector3.js"; -import { Vector4 } from "./Vector4.js"; - -import { BufferAttribute } from "../core/BufferAttribute.js"; -import { InterleavedBufferAttribute } from "../core/InterleavedBufferAttribute.js"; - -export class Triangle { - constructor(a?: Vector3, b?: Vector3, c?: Vector3); - - /** - * @default new THREE.Vector3() - */ - a: Vector3; - - /** - * @default new THREE.Vector3() - */ - b: Vector3; - - /** - * @default new THREE.Vector3() - */ - c: Vector3; - - set(a: Vector3, b: Vector3, c: Vector3): Triangle; - setFromPointsAndIndices(points: Vector3[], i0: number, i1: number, i2: number): this; - setFromAttributeAndIndices( - attribute: BufferAttribute | InterleavedBufferAttribute, - i0: number, - i1: number, - i2: number, - ): this; - clone(): this; - copy(triangle: Triangle): this; - getArea(): number; - getMidpoint(target: Vector3): Vector3; - getNormal(target: Vector3): Vector3; - getPlane(target: Plane): Plane; - getBarycoord(point: Vector3, target: Vector3): Vector3 | null; - getInterpolation(point: Vector3, v1: Vector2, v2: Vector2, v3: Vector2, target: Vector2): Vector2 | null; - getInterpolation(point: Vector3, v1: Vector3, v2: Vector3, v3: Vector3, target: Vector3): Vector3 | null; - getInterpolation(point: Vector3, v1: Vector4, v2: Vector4, v3: Vector4, target: Vector4): Vector4 | null; - containsPoint(point: Vector3): boolean; - intersectsBox(box: Box3): boolean; - isFrontFacing(direction: Vector3): boolean; - closestPointToPoint(point: Vector3, target: Vector3): Vector3; - equals(triangle: Triangle): boolean; - - static getNormal(a: Vector3, b: Vector3, c: Vector3, target: Vector3): Vector3; - static getBarycoord(point: Vector3, a: Vector3, b: Vector3, c: Vector3, target: Vector3): Vector3 | null; - static containsPoint(point: Vector3, a: Vector3, b: Vector3, c: Vector3): boolean; - static getInterpolation( - point: Vector3, - p1: Vector3, - p2: Vector3, - p3: Vector3, - v1: Vector2, - v2: Vector2, - v3: Vector2, - target: Vector2, - ): Vector2 | null; - static getInterpolation( - point: Vector3, - p1: Vector3, - p2: Vector3, - p3: Vector3, - v1: Vector3, - v2: Vector3, - v3: Vector3, - target: Vector3, - ): Vector3 | null; - static getInterpolation( - point: Vector3, - p1: Vector3, - p2: Vector3, - p3: Vector3, - v1: Vector4, - v2: Vector4, - v3: Vector4, - target: Vector4, - ): Vector4 | null; - static getInterpolatedAttribute( - attr: BufferAttribute, - i1: number, - i2: number, - i3: number, - barycoord: Vector3, - target: Vector2, - ): Vector2; - static getInterpolatedAttribute( - attr: BufferAttribute, - i1: number, - i2: number, - i3: number, - barycoord: Vector3, - target: Vector3, - ): Vector3; - static getInterpolatedAttribute( - attr: BufferAttribute, - i1: number, - i2: number, - i3: number, - barycoord: Vector3, - target: Vector4, - ): Vector4; - static isFrontFacing(a: Vector3, b: Vector3, c: Vector3, direction: Vector3): boolean; -} diff --git a/src-testing/src/math/Vector2.d.ts b/src-testing/src/math/Vector2.d.ts deleted file mode 100644 index fd2a84a1d..000000000 --- a/src-testing/src/math/Vector2.d.ts +++ /dev/null @@ -1,321 +0,0 @@ -import { BufferAttribute } from "../core/BufferAttribute.js"; -import { Matrix3 } from "./Matrix3.js"; - -export type Vector2Tuple = [x: number, y: number]; - -export interface Vector2Like { - readonly x: number; - readonly y: number; -} - -/** - * 2D vector. - */ -export class Vector2 { - constructor(x?: number, y?: number); - - /** - * @default 0 - */ - x: number; - - /** - * @default 0 - */ - y: number; - width: number; - height: number; - readonly isVector2: true; - - /** - * Sets value of this vector. - */ - set(x: number, y: number): this; - - /** - * Sets the x and y values of this vector both equal to scalar. - */ - setScalar(scalar: number): this; - - /** - * Sets X component of this vector. - */ - setX(x: number): this; - - /** - * Sets Y component of this vector. - */ - setY(y: number): this; - - /** - * Sets a component of this vector. - */ - setComponent(index: number, value: number): this; - - /** - * Gets a component of this vector. - */ - getComponent(index: number): number; - - /** - * Returns a new Vector2 instance with the same `x` and `y` values. - */ - clone(): this; - - /** - * Copies value of v to this vector. - */ - copy(v: Vector2Like): this; - - /** - * Adds v to this vector. - */ - add(v: Vector2Like): this; - - /** - * Adds the scalar value s to this vector's x and y values. - */ - addScalar(s: number): this; - - /** - * Sets this vector to a + b. - */ - addVectors(a: Vector2Like, b: Vector2Like): this; - - /** - * Adds the multiple of v and s to this vector. - */ - addScaledVector(v: Vector2Like, s: number): this; - - /** - * Subtracts v from this vector. - */ - sub(v: Vector2Like): this; - - /** - * Subtracts s from this vector's x and y components. - */ - subScalar(s: number): this; - - /** - * Sets this vector to a - b. - */ - subVectors(a: Vector2Like, b: Vector2Like): this; - - /** - * Multiplies this vector by v. - */ - multiply(v: Vector2Like): this; - - /** - * Multiplies this vector by scalar s. - */ - multiplyScalar(scalar: number): this; - - /** - * Divides this vector by v. - */ - divide(v: Vector2Like): this; - - /** - * Divides this vector by scalar s. - * Set vector to ( 0, 0 ) if s == 0. - */ - divideScalar(s: number): this; - - /** - * Multiplies this vector (with an implicit 1 as the 3rd component) by m. - */ - applyMatrix3(m: Matrix3): this; - - /** - * If this vector's x or y value is greater than v's x or y value, replace that value with the corresponding min value. - */ - min(v: Vector2Like): this; - - /** - * If this vector's x or y value is less than v's x or y value, replace that value with the corresponding max value. - */ - max(v: Vector2Like): this; - - /** - * If this vector's x or y value is greater than the max vector's x or y value, it is replaced by the corresponding value. - * If this vector's x or y value is less than the min vector's x or y value, it is replaced by the corresponding value. - * @param min the minimum x and y values. - * @param max the maximum x and y values in the desired range. - */ - clamp(min: Vector2Like, max: Vector2Like): this; - - /** - * If this vector's x or y values are greater than the max value, they are replaced by the max value. - * If this vector's x or y values are less than the min value, they are replaced by the min value. - * @param min the minimum value the components will be clamped to. - * @param max the maximum value the components will be clamped to. - */ - clampScalar(min: number, max: number): this; - - /** - * If this vector's length is greater than the max value, it is replaced by the max value. - * If this vector's length is less than the min value, it is replaced by the min value. - * @param min the minimum value the length will be clamped to. - * @param max the maximum value the length will be clamped to. - */ - clampLength(min: number, max: number): this; - - /** - * The components of the vector are rounded down to the nearest integer value. - */ - floor(): this; - - /** - * The x and y components of the vector are rounded up to the nearest integer value. - */ - ceil(): this; - - /** - * The components of the vector are rounded to the nearest integer value. - */ - round(): this; - - /** - * The components of the vector are rounded towards zero (up if negative, down if positive) to an integer value. - */ - roundToZero(): this; - - /** - * Inverts this vector. - */ - negate(): this; - - /** - * Computes dot product of this vector and v. - */ - dot(v: Vector2Like): number; - - /** - * Computes cross product of this vector and v. - */ - cross(v: Vector2Like): number; - - /** - * Computes squared length of this vector. - */ - lengthSq(): number; - - /** - * Computes length of this vector. - */ - length(): number; - - /** - * Computes the Manhattan length of this vector. - * - * see {@link http://en.wikipedia.org/wiki/Taxicab_geometry|Wikipedia: Taxicab Geometry} - */ - manhattanLength(): number; - - /** - * Normalizes this vector. - */ - normalize(): this; - - /** - * computes the angle in radians with respect to the positive x-axis - */ - angle(): number; - - /** - * Returns the angle between this vector and vector {@link Vector2 | v} in radians. - */ - angleTo(v: Vector2): number; - - /** - * Computes distance of this vector to v. - */ - distanceTo(v: Vector2Like): number; - - /** - * Computes squared distance of this vector to v. - */ - distanceToSquared(v: Vector2Like): number; - - /** - * Computes the Manhattan length (distance) from this vector to the given vector v - * - * see {@link http://en.wikipedia.org/wiki/Taxicab_geometry|Wikipedia: Taxicab Geometry} - */ - manhattanDistanceTo(v: Vector2Like): number; - - /** - * Normalizes this vector and multiplies it by l. - */ - setLength(length: number): this; - - /** - * Linearly interpolates between this vector and v, where alpha is the distance along the line - alpha = 0 will be this vector, and alpha = 1 will be v. - * @param v vector to interpolate towards. - * @param alpha interpolation factor in the closed interval [0, 1]. - */ - lerp(v: Vector2Like, alpha: number): this; - - /** - * Sets this vector to be the vector linearly interpolated between v1 and v2 where alpha is the distance along the line connecting the two vectors - alpha = 0 will be v1, and alpha = 1 will be v2. - * @param v1 the starting vector. - * @param v2 vector to interpolate towards. - * @param alpha interpolation factor in the closed interval [0, 1]. - */ - lerpVectors(v1: Vector2Like, v2: Vector2Like, alpha: number): this; - - /** - * Checks for strict equality of this vector and v. - */ - equals(v: Vector2Like): boolean; - - /** - * Sets this vector's x and y value from the provided array or array-like. - * @param array the source array or array-like. - * @param offset (optional) offset into the array. Default is 0. - */ - fromArray(array: number[] | ArrayLike, offset?: number): this; - - /** - * Returns an array [x, y], or copies x and y into the provided array. - * @param array (optional) array to store the vector to. If this is not provided, a new array will be created. - * @param offset (optional) optional offset into the array. - * @return The created or provided array. - */ - toArray(array?: number[], offset?: number): number[]; - toArray(array?: Vector2Tuple, offset?: 0): Vector2Tuple; - - /** - * Copies x and y into the provided array-like. - * @param array array-like to store the vector to. - * @param offset (optional) optional offset into the array. - * @return The provided array-like. - */ - toArray(array: ArrayLike, offset?: number): ArrayLike; - - /** - * Sets this vector's x and y values from the attribute. - * @param attribute the source attribute. - * @param index index in the attribute. - */ - fromBufferAttribute(attribute: BufferAttribute, index: number): this; - - /** - * Rotates the vector around center by angle radians. - * @param center the point around which to rotate. - * @param angle the angle to rotate, in radians. - */ - rotateAround(center: Vector2Like, angle: number): this; - - /** - * Sets this vector's x and y from Math.random - */ - random(): this; - - /** - * Iterating through a Vector2 instance will yield its components (x, y) in the corresponding order. - */ - [Symbol.iterator](): Iterator; -} diff --git a/src-testing/src/math/Vector3.d.ts b/src-testing/src/math/Vector3.d.ts deleted file mode 100644 index 56e907ceb..000000000 --- a/src-testing/src/math/Vector3.d.ts +++ /dev/null @@ -1,301 +0,0 @@ -import { Camera } from "../cameras/Camera.js"; -import { BufferAttribute } from "../core/BufferAttribute.js"; -import { InterleavedBufferAttribute } from "../core/InterleavedBufferAttribute.js"; -import { RGB } from "./Color.js"; -import { Cylindrical } from "./Cylindrical.js"; -import { Euler } from "./Euler.js"; -import { Matrix3 } from "./Matrix3.js"; -import { Matrix4 } from "./Matrix4.js"; -import { QuaternionLike } from "./Quaternion.js"; -import { Spherical } from "./Spherical.js"; - -export type Vector3Tuple = [number, number, number]; - -export interface Vector3Like { - readonly x: number; - readonly y: number; - readonly z: number; -} - -/** - * 3D vector. - * - * see {@link https://github.com/mrdoob/three.js/blob/master/src/math/Vector3.js} - * - * @example - * const a = new THREE.Vector3( 1, 0, 0 ); - * const b = new THREE.Vector3( 0, 1, 0 ); - * const c = new THREE.Vector3(); - * c.crossVectors( a, b ); - */ -export class Vector3 { - constructor(x?: number, y?: number, z?: number); - - /** - * @default 0 - */ - x: number; - - /** - * @default 0 - */ - y: number; - - /** - * @default 0 - */ - z: number; - readonly isVector3: true; - - /** - * Sets value of this vector. - */ - set(x: number, y: number, z: number): this; - - /** - * Sets all values of this vector. - */ - setScalar(scalar: number): this; - - /** - * Sets x value of this vector. - */ - setX(x: number): this; - - /** - * Sets y value of this vector. - */ - setY(y: number): this; - - /** - * Sets z value of this vector. - */ - setZ(z: number): this; - - setComponent(index: number, value: number): this; - - getComponent(index: number): number; - - /** - * Clones this vector. - */ - clone(): this; - - /** - * Copies value of v to this vector. - */ - copy(v: Vector3Like): this; - - /** - * Adds v to this vector. - */ - add(v: Vector3Like): this; - - addScalar(s: number): this; - - /** - * Sets this vector to a + b. - */ - addVectors(a: Vector3Like, b: Vector3Like): this; - - addScaledVector(v: Vector3, s: number): this; - - /** - * Subtracts v from this vector. - */ - sub(a: Vector3Like): this; - - subScalar(s: number): this; - - /** - * Sets this vector to a - b. - */ - subVectors(a: Vector3Like, b: Vector3Like): this; - - multiply(v: Vector3Like): this; - - /** - * Multiplies this vector by scalar s. - */ - multiplyScalar(s: number): this; - - multiplyVectors(a: Vector3Like, b: Vector3Like): this; - - applyEuler(euler: Euler): this; - - applyAxisAngle(axis: Vector3, angle: number): this; - - applyMatrix3(m: Matrix3): this; - - applyNormalMatrix(m: Matrix3): this; - - applyMatrix4(m: Matrix4): this; - - applyQuaternion(q: QuaternionLike): this; - - project(camera: Camera): this; - - unproject(camera: Camera): this; - - transformDirection(m: Matrix4): this; - - divide(v: Vector3Like): this; - - /** - * Divides this vector by scalar s. - * Set vector to ( 0, 0, 0 ) if s == 0. - */ - divideScalar(s: number): this; - - min(v: Vector3Like): this; - - max(v: Vector3Like): this; - - clamp(min: Vector3Like, max: Vector3Like): this; - - clampScalar(min: number, max: number): this; - - clampLength(min: number, max: number): this; - - floor(): this; - - ceil(): this; - - round(): this; - - roundToZero(): this; - - /** - * Inverts this vector. - */ - negate(): this; - - /** - * Computes dot product of this vector and v. - */ - dot(v: Vector3Like): number; - - /** - * Computes squared length of this vector. - */ - lengthSq(): number; - - /** - * Computes length of this vector. - */ - length(): number; - - /** - * Computes the Manhattan length of this vector. - * - * see {@link http://en.wikipedia.org/wiki/Taxicab_geometry|Wikipedia: Taxicab Geometry} - */ - manhattanLength(): number; - - /** - * Normalizes this vector. - */ - normalize(): this; - - /** - * Normalizes this vector and multiplies it by l. - */ - setLength(l: number): this; - lerp(v: Vector3Like, alpha: number): this; - - lerpVectors(v1: Vector3Like, v2: Vector3Like, alpha: number): this; - - /** - * Sets this vector to cross product of itself and v. - */ - cross(a: Vector3Like): this; - - /** - * Sets this vector to cross product of a and b. - */ - crossVectors(a: Vector3Like, b: Vector3Like): this; - projectOnVector(v: Vector3): this; - projectOnPlane(planeNormal: Vector3): this; - reflect(vector: Vector3Like): this; - angleTo(v: Vector3): number; - - /** - * Computes distance of this vector to v. - */ - distanceTo(v: Vector3Like): number; - - /** - * Computes squared distance of this vector to v. - */ - distanceToSquared(v: Vector3Like): number; - - /** - * Computes the Manhattan length (distance) from this vector to the given vector v - * - * see {@link http://en.wikipedia.org/wiki/Taxicab_geometry|Wikipedia: Taxicab Geometry} - */ - manhattanDistanceTo(v: Vector3Like): number; - - setFromSpherical(s: Spherical): this; - setFromSphericalCoords(r: number, phi: number, theta: number): this; - setFromCylindrical(s: Cylindrical): this; - setFromCylindricalCoords(radius: number, theta: number, y: number): this; - setFromMatrixPosition(m: Matrix4): this; - setFromMatrixScale(m: Matrix4): this; - setFromMatrixColumn(matrix: Matrix4, index: number): this; - setFromMatrix3Column(matrix: Matrix3, index: number): this; - - /** - * Sets this vector's {@link x}, {@link y} and {@link z} components from the x, y, and z components of the specified {@link Euler Euler Angle}. - */ - setFromEuler(e: Euler): this; - - /** - * Sets this vector's {@link x}, {@link y} and {@link z} components from the r, g, and b components of the specified - * {@link Color | color}. - */ - setFromColor(color: RGB): this; - - /** - * Checks for strict equality of this vector and v. - */ - equals(v: Vector3Like): boolean; - - /** - * Sets this vector's x, y and z value from the provided array or array-like. - * @param array the source array or array-like. - * @param offset (optional) offset into the array. Default is 0. - */ - fromArray(array: number[] | ArrayLike, offset?: number): this; - - /** - * Returns an array [x, y, z], or copies x, y and z into the provided array. - * @param array (optional) array to store the vector to. If this is not provided, a new array will be created. - * @param offset (optional) optional offset into the array. - * @return The created or provided array. - */ - toArray(array?: number[], offset?: number): number[]; - toArray(array?: Vector3Tuple, offset?: 0): Vector3Tuple; - - /** - * Copies x, y and z into the provided array-like. - * @param array array-like to store the vector to. - * @param offset (optional) optional offset into the array-like. - * @return The provided array-like. - */ - toArray(array: ArrayLike, offset?: number): ArrayLike; - - fromBufferAttribute(attribute: BufferAttribute | InterleavedBufferAttribute, index: number): this; - - /** - * Sets this vector's x, y and z from Math.random - */ - random(): this; - - randomDirection(): this; - - /** - * Iterating through a Vector3 instance will yield its components (x, y, z) in the corresponding order. - */ - [Symbol.iterator](): Iterator; -} diff --git a/src-testing/src/math/Vector4.d.ts b/src-testing/src/math/Vector4.d.ts deleted file mode 100644 index 88cf74ff2..000000000 --- a/src-testing/src/math/Vector4.d.ts +++ /dev/null @@ -1,239 +0,0 @@ -import { BufferAttribute } from "../core/BufferAttribute.js"; -import { Matrix4 } from "./Matrix4.js"; -import { QuaternionLike } from "./Quaternion.js"; - -export type Vector4Tuple = [number, number, number, number]; - -export interface Vector4Like { - readonly x: number; - readonly y: number; - readonly z: number; - readonly w: number; -} - -/** - * 4D vector. - */ -export class Vector4 { - constructor(x?: number, y?: number, z?: number, w?: number); - - /** - * @default 0 - */ - x: number; - - /** - * @default 0 - */ - y: number; - - /** - * @default 0 - */ - z: number; - - /** - * @default 0 - */ - w: number; - - width: number; - height: number; - readonly isVector4: true; - - /** - * Sets value of this vector. - */ - set(x: number, y: number, z: number, w: number): this; - - /** - * Sets all values of this vector. - */ - setScalar(scalar: number): this; - - /** - * Sets X component of this vector. - */ - setX(x: number): this; - - /** - * Sets Y component of this vector. - */ - setY(y: number): this; - - /** - * Sets Z component of this vector. - */ - setZ(z: number): this; - - /** - * Sets w component of this vector. - */ - setW(w: number): this; - - setComponent(index: number, value: number): this; - - getComponent(index: number): number; - - /** - * Clones this vector. - */ - clone(): this; - - /** - * Copies value of v to this vector. - */ - copy(v: Vector4Like): this; - - /** - * Adds v to this vector. - */ - add(v: Vector4Like): this; - - addScalar(scalar: number): this; - - /** - * Sets this vector to a + b. - */ - addVectors(a: Vector4Like, b: Vector4Like): this; - - addScaledVector(v: Vector4Like, s: number): this; - /** - * Subtracts v from this vector. - */ - sub(v: Vector4Like): this; - - subScalar(s: number): this; - - /** - * Sets this vector to a - b. - */ - subVectors(a: Vector4Like, b: Vector4Like): this; - - multiply(v: Vector4Like): this; - - /** - * Multiplies this vector by scalar s. - */ - multiplyScalar(s: number): this; - - applyMatrix4(m: Matrix4): this; - - /** - * Divides this vector by scalar s. - * Set vector to ( 0, 0, 0 ) if s == 0. - */ - divideScalar(s: number): this; - - /** - * http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm - * @param q is assumed to be normalized - */ - setAxisAngleFromQuaternion(q: QuaternionLike): this; - - /** - * http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/index.htm - * @param m assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) - */ - setAxisAngleFromRotationMatrix(m: Matrix4): this; - - /** - * Sets this vector to the position elements of the - * [transformation matrix]{@link https://en.wikipedia.org/wiki/Transformation_matrix} m. - */ - setFromMatrixPosition(m: Matrix4): this; - - min(v: Vector4Like): this; - max(v: Vector4Like): this; - clamp(min: Vector4Like, max: Vector4Like): this; - clampScalar(min: number, max: number): this; - floor(): this; - ceil(): this; - round(): this; - roundToZero(): this; - - /** - * Inverts this vector. - */ - negate(): this; - - /** - * Computes dot product of this vector and v. - */ - dot(v: Vector4Like): number; - - /** - * Computes squared length of this vector. - */ - lengthSq(): number; - - /** - * Computes length of this vector. - */ - length(): number; - - /** - * Computes the Manhattan length of this vector. - * - * see {@link http://en.wikipedia.org/wiki/Taxicab_geometry|Wikipedia: Taxicab Geometry} - */ - manhattanLength(): number; - - /** - * Normalizes this vector. - */ - normalize(): this; - - /** - * Normalizes this vector and multiplies it by l. - */ - setLength(length: number): this; - - /** - * Linearly interpolate between this vector and v with alpha factor. - */ - lerp(v: Vector4Like, alpha: number): this; - - lerpVectors(v1: Vector4Like, v2: Vector4Like, alpha: number): this; - - /** - * Checks for strict equality of this vector and v. - */ - equals(v: Vector4Like): boolean; - - /** - * Sets this vector's x, y, z and w value from the provided array or array-like. - * @param array the source array or array-like. - * @param offset (optional) offset into the array. Default is 0. - */ - fromArray(array: number[] | ArrayLike, offset?: number): this; - - /** - * Returns an array [x, y, z, w], or copies x, y, z and w into the provided array. - * @param array (optional) array to store the vector to. If this is not provided, a new array will be created. - * @param offset (optional) optional offset into the array. - * @return The created or provided array. - */ - toArray(array?: number[], offset?: number): number[]; - toArray(array?: Vector4Tuple, offset?: 0): Vector4Tuple; - - /** - * Copies x, y, z and w into the provided array-like. - * @param array array-like to store the vector to. - * @param offset (optional) optional offset into the array-like. - * @return The provided array-like. - */ - toArray(array: ArrayLike, offset?: number): ArrayLike; - - fromBufferAttribute(attribute: BufferAttribute, index: number): this; - - /** - * Sets this vector's x, y, z and w from Math.random - */ - random(): this; - - /** - * Iterating through a Vector4 instance will yield its components (x, y, z, w) in the corresponding order. - */ - [Symbol.iterator](): Iterator; -} diff --git a/src-testing/src/math/interpolants/CubicInterpolant.d.ts b/src-testing/src/math/interpolants/CubicInterpolant.d.ts deleted file mode 100644 index 282b98d7e..000000000 --- a/src-testing/src/math/interpolants/CubicInterpolant.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { Interpolant } from "../Interpolant.js"; - -export class CubicInterpolant extends Interpolant { - constructor(parameterPositions: any, samplesValues: any, sampleSize: number, resultBuffer?: any); - - interpolate_(i1: number, t0: number, t: number, t1: number): any; -} diff --git a/src-testing/src/math/interpolants/DiscreteInterpolant.d.ts b/src-testing/src/math/interpolants/DiscreteInterpolant.d.ts deleted file mode 100644 index 28bd458b8..000000000 --- a/src-testing/src/math/interpolants/DiscreteInterpolant.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { Interpolant } from "../Interpolant.js"; - -export class DiscreteInterpolant extends Interpolant { - constructor(parameterPositions: any, samplesValues: any, sampleSize: number, resultBuffer?: any); - - interpolate_(i1: number, t0: number, t: number, t1: number): any; -} diff --git a/src-testing/src/math/interpolants/LinearInterpolant.d.ts b/src-testing/src/math/interpolants/LinearInterpolant.d.ts deleted file mode 100644 index e6ff11c0b..000000000 --- a/src-testing/src/math/interpolants/LinearInterpolant.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { Interpolant } from "../Interpolant.js"; - -export class LinearInterpolant extends Interpolant { - constructor(parameterPositions: any, samplesValues: any, sampleSize: number, resultBuffer?: any); - - interpolate_(i1: number, t0: number, t: number, t1: number): any; -} diff --git a/src-testing/src/math/interpolants/QuaternionLinearInterpolant.d.ts b/src-testing/src/math/interpolants/QuaternionLinearInterpolant.d.ts deleted file mode 100644 index dccb66976..000000000 --- a/src-testing/src/math/interpolants/QuaternionLinearInterpolant.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { Interpolant } from "../Interpolant.js"; - -export class QuaternionLinearInterpolant extends Interpolant { - constructor(parameterPositions: any, samplesValues: any, sampleSize: number, resultBuffer?: any); - - interpolate_(i1: number, t0: number, t: number, t1: number): any; -} diff --git a/src-testing/src/nodes/Nodes.ts b/src-testing/src/nodes/Nodes.ts deleted file mode 100644 index 648eec734..000000000 --- a/src-testing/src/nodes/Nodes.ts +++ /dev/null @@ -1,144 +0,0 @@ -// constants -export * from './core/constants.js'; - -// core -export { default as AssignNode } from './core/AssignNode.js'; -export { default as AttributeNode } from './core/AttributeNode.js'; -export { default as BypassNode } from './core/BypassNode.js'; -export { default as CacheNode } from './core/CacheNode.js'; -export { default as ConstNode } from './core/ConstNode.js'; -export { default as ContextNode } from './core/ContextNode.js'; -export { default as IndexNode } from './core/IndexNode.js'; -export { default as LightingModel } from './core/LightingModel.js'; -export { default as Node } from './core/Node.js'; -export { default as VarNode } from './core/VarNode.js'; -export { default as NodeAttribute } from './core/NodeAttribute.js'; -export { default as NodeBuilder } from './core/NodeBuilder.js'; -export { default as NodeCache } from './core/NodeCache.js'; -export { default as NodeCode } from './core/NodeCode.js'; -export { default as NodeFrame } from './core/NodeFrame.js'; -export { default as NodeFunctionInput } from './core/NodeFunctionInput.js'; -export { default as NodeUniform } from './core/NodeUniform.js'; -export { default as NodeVar } from './core/NodeVar.js'; -export { default as NodeVarying } from './core/NodeVarying.js'; -export { default as ParameterNode } from './core/ParameterNode.js'; -export { default as PropertyNode } from './core/PropertyNode.js'; -export { default as StackNode } from './core/StackNode.js'; -export { default as TempNode } from './core/TempNode.js'; -export { default as UniformGroupNode } from './core/UniformGroupNode.js'; -export { default as UniformNode } from './core/UniformNode.js'; -export { default as VaryingNode } from './core/VaryingNode.js'; -export { default as OutputStructNode } from './core/OutputStructNode.js'; -export { default as MRTNode } from './core/MRTNode.js'; - -import * as NodeUtils from './core/NodeUtils.js'; -export { NodeUtils }; - -// utils -export { default as ArrayElementNode } from './utils/ArrayElementNode.js'; -export { default as ConvertNode } from './utils/ConvertNode.js'; -export { default as EquirectUVNode } from './utils/EquirectUVNode.js'; -export { default as FunctionOverloadingNode } from './utils/FunctionOverloadingNode.js'; -export { default as JoinNode } from './utils/JoinNode.js'; -export { default as LoopNode } from './utils/LoopNode.js'; -export { default as MatcapUVNode } from './utils/MatcapUVNode.js'; -export { default as MaxMipLevelNode } from './utils/MaxMipLevelNode.js'; -export { default as RemapNode } from './utils/RemapNode.js'; -export { default as RotateNode } from './utils/RotateNode.js'; -export { default as SetNode } from './utils/SetNode.js'; -export { default as SplitNode } from './utils/SplitNode.js'; -export { default as SpriteSheetUVNode } from './utils/SpriteSheetUVNode.js'; -export { default as StorageArrayElementNode } from './utils/StorageArrayElementNode.js'; -export { default as TriplanarTexturesNode } from './utils/TriplanarTexturesNode.js'; -export { default as ReflectorNode } from './utils/ReflectorNode.js'; -export { default as RTTNode } from './utils/RTTNode.js'; - -// accessors -export { default as UniformArrayNode } from './accessors/UniformArrayNode.js'; -export { default as BufferAttributeNode } from './accessors/BufferAttributeNode.js'; -export { default as BufferNode } from './accessors/BufferNode.js'; -export { default as VertexColorNode } from './accessors/VertexColorNode.js'; -export { default as CubeTextureNode } from './accessors/CubeTextureNode.js'; -export { default as InstanceNode } from './accessors/InstanceNode.js'; -export { default as BatchNode } from './accessors/BatchNode.js'; -export { default as MaterialNode } from './accessors/MaterialNode.js'; -export { default as MaterialReferenceNode } from './accessors/MaterialReferenceNode.js'; -export { default as RendererReferenceNode } from './accessors/RendererReferenceNode.js'; -export { default as MorphNode } from './accessors/MorphNode.js'; -export { default as ModelNode } from './accessors/ModelNode.js'; -export { default as ModelViewProjectionNode } from './accessors/ModelViewProjectionNode.js'; -export { default as Object3DNode } from './accessors/Object3DNode.js'; -export { default as PointUVNode } from './accessors/PointUVNode.js'; -export { default as ReferenceNode } from './accessors/ReferenceNode.js'; -export { default as SkinningNode } from './accessors/SkinningNode.js'; -export { default as SceneNode } from './accessors/SceneNode.js'; -export { default as StorageBufferNode } from './accessors/StorageBufferNode.js'; -export { default as TextureNode } from './accessors/TextureNode.js'; -export { default as TextureSizeNode } from './accessors/TextureSizeNode.js'; -export { default as StorageTextureNode } from './accessors/StorageTextureNode.js'; -export { default as Texture3DNode } from './accessors/Texture3DNode.js'; -export { default as UserDataNode } from './accessors/UserDataNode.js'; - -// display -export { default as BumpMapNode } from './display/BumpMapNode.js'; -export { default as ColorSpaceNode } from './display/ColorSpaceNode.js'; -export { default as FrontFacingNode } from './display/FrontFacingNode.js'; -export { default as NormalMapNode } from './display/NormalMapNode.js'; -export { default as PosterizeNode } from './display/PosterizeNode.js'; -export { default as ToneMappingNode } from './display/ToneMappingNode.js'; -export { default as ScreenNode } from './display/ScreenNode.js'; -export { default as ViewportTextureNode } from './display/ViewportTextureNode.js'; -export { default as ViewportSharedTextureNode } from './display/ViewportSharedTextureNode.js'; -export { default as ViewportDepthTextureNode } from './display/ViewportDepthTextureNode.js'; -export { default as ViewportDepthNode } from './display/ViewportDepthNode.js'; -export { default as RenderOutputNode } from './display/RenderOutputNode.js'; -export { default as PassNode } from './display/PassNode.js'; -export { default as ToonOutlinePassNode } from './display/ToonOutlinePassNode.js'; - -// code -export { default as ExpressionNode } from './code/ExpressionNode.js'; -export { default as CodeNode } from './code/CodeNode.js'; -export { default as FunctionCallNode } from './code/FunctionCallNode.js'; -export { default as FunctionNode } from './code/FunctionNode.js'; -export { default as ScriptableNode } from './code/ScriptableNode.js'; -export { default as ScriptableValueNode } from './code/ScriptableValueNode.js'; - -// fog -export { default as FogNode } from './fog/FogNode.js'; -export { default as FogRangeNode } from './fog/FogRangeNode.js'; -export { default as FogExp2Node } from './fog/FogExp2Node.js'; - -// geometry -export { default as RangeNode } from './geometry/RangeNode.js'; - -// gpgpu -export { default as ComputeNode } from './gpgpu/ComputeNode.js'; - -// lighting -export { default as PointLightNode } from './lighting/PointLightNode.js'; -export { default as DirectionalLightNode } from './lighting/DirectionalLightNode.js'; -export { default as RectAreaLightNode } from './lighting/RectAreaLightNode.js'; -export { default as SpotLightNode } from './lighting/SpotLightNode.js'; -export { default as IESSpotLightNode } from './lighting/IESSpotLightNode.js'; -export { default as AmbientLightNode } from './lighting/AmbientLightNode.js'; -export { default as LightsNode } from './lighting/LightsNode.js'; -export { default as LightingNode } from './lighting/LightingNode.js'; -export { default as LightingContextNode } from './lighting/LightingContextNode.js'; -export { default as HemisphereLightNode } from './lighting/HemisphereLightNode.js'; -export { default as LightProbeNode } from './lighting/LightProbeNode.js'; -export { default as EnvironmentNode } from './lighting/EnvironmentNode.js'; -export { default as BasicEnvironmentNode } from './lighting/BasicEnvironmentNode.js'; -export { default as IrradianceNode } from './lighting/IrradianceNode.js'; -export { default as AONode } from './lighting/AONode.js'; -export { default as AnalyticLightNode } from './lighting/AnalyticLightNode.js'; -export { default as ShadowNode } from './lighting/ShadowNode.js'; - -// pmrem -export { default as PMREMNode } from './pmrem/PMREMNode.js'; - -// parsers -export { default as GLSLNodeParser } from './parsers/GLSLNodeParser.js'; // @TODO: Move to jsm/renderers/webgl. - -// lighting models -export { default as PhongLightingModel } from './functions/PhongLightingModel.js'; -export { default as PhysicalLightingModel } from './functions/PhysicalLightingModel.js'; diff --git a/src-testing/src/nodes/TSL.d.ts b/src-testing/src/nodes/TSL.d.ts deleted file mode 100644 index e3e3e439b..000000000 --- a/src-testing/src/nodes/TSL.d.ts +++ /dev/null @@ -1,156 +0,0 @@ -// constants -export * from "./core/constants.js"; - -// core -export * from "./core/AssignNode.js"; -export * from "./core/AttributeNode.js"; -export * from "./core/BypassNode.js"; -export * from "./core/CacheNode.js"; -export * from "./core/ContextNode.js"; -export * from "./core/IndexNode.js"; -export * from "./core/MRTNode.js"; -export * from "./core/OutputStructNode.js"; -export * from "./core/ParameterNode.js"; -export * from "./core/PropertyNode.js"; -export * from "./core/StackNode.js"; -export * from "./core/UniformGroupNode.js"; -export * from "./core/UniformNode.js"; -export * from "./core/VaryingNode.js"; - -// math -export * from "./math/Hash.js"; -export * from "./math/MathUtils.js"; -export * from "./math/TriNoise3D.js"; - -// utils -export * from "./utils/EquirectUVNode.js"; -export * from "./utils/FunctionOverloadingNode.js"; -export * from "./utils/LoopNode.js"; -export * from "./utils/MatcapUVNode.js"; -export * from "./utils/MaxMipLevelNode.js"; -export * from "./utils/Oscillators.js"; -export * from "./utils/Packing.js"; -export * from "./utils/PostProcessingUtils.js"; -export * from "./utils/ReflectorNode.js"; -export * from "./utils/RemapNode.js"; -export * from "./utils/RotateNode.js"; -export * from "./utils/RTTNode.js"; -export * from "./utils/SpriteSheetUVNode.js"; -export * from "./utils/SpriteUtils.js"; -export * from "./utils/Timer.js"; -export * from "./utils/TriplanarTexturesNode.js"; -export * from "./utils/UVUtils.js"; -export * from "./utils/ViewportUtils.js"; - -// three.js shading language -export * from "./tsl/TSLBase.js"; - -// accessors -export * from "./accessors/AccessorsUtils.js"; -export * from "./accessors/BatchNode.js"; -export * from "./accessors/Bitangent.js"; -export * from "./accessors/BufferAttributeNode.js"; -export * from "./accessors/BufferNode.js"; -export * from "./accessors/Camera.js"; -export * from "./accessors/CubeTextureNode.js"; -export * from "./accessors/InstanceNode.js"; -export * from "./accessors/MaterialNode.js"; -export * from "./accessors/MaterialProperties.js"; -export * from "./accessors/MaterialReferenceNode.js"; -export * from "./accessors/ModelNode.js"; -export * from "./accessors/ModelViewProjectionNode.js"; -export * from "./accessors/MorphNode.js"; -export * from "./accessors/Normal.js"; -export * from "./accessors/Object3DNode.js"; -export * from "./accessors/PointUVNode.js"; -export * from "./accessors/Position.js"; -export * from "./accessors/ReferenceNode.js"; -export * from "./accessors/ReflectVector.js"; -export * from "./accessors/RendererReferenceNode.js"; -export * from "./accessors/SceneNode.js"; -export * from "./accessors/SkinningNode.js"; -export * from "./accessors/StorageBufferNode.js"; -export * from "./accessors/StorageTextureNode.js"; -export * from "./accessors/Tangent.js"; -export * from "./accessors/Texture3DNode.js"; -export * from "./accessors/TextureBicubic.js"; -export * from "./accessors/TextureNode.js"; -export * from "./accessors/TextureSizeNode.js"; -export * from "./accessors/UniformArrayNode.js"; -export * from "./accessors/UserDataNode.js"; -export * from "./accessors/UV.js"; -export * from "./accessors/VelocityNode.js"; -export * from "./accessors/VertexColorNode.js"; - -// display -export * from "./display/BlendMode.js"; -export * from "./display/BumpMapNode.js"; -export * from "./display/ColorAdjustment.js"; -export * from "./display/ColorSpaceNode.js"; -export * from "./display/FrontFacingNode.js"; -export * from "./display/NormalMapNode.js"; -export * from "./display/PosterizeNode.js"; -export * from "./display/RenderOutputNode.js"; -export * from "./display/ScreenNode.js"; -export * from "./display/ToneMappingNode.js"; -export * from "./display/ToonOutlinePassNode.js"; -export * from "./display/ViewportDepthNode.js"; -export * from "./display/ViewportDepthTextureNode.js"; -export * from "./display/ViewportSharedTextureNode.js"; -export * from "./display/ViewportTextureNode.js"; - -export * from "./display/PassNode.js"; - -export * from "./display/ColorSpaceFunctions.js"; -export * from "./display/ToneMappingFunctions.js"; - -// code -export * from "./code/CodeNode.js"; -export * from "./code/ExpressionNode.js"; -export * from "./code/FunctionCallNode.js"; -export * from "./code/FunctionNode.js"; -export * from "./code/ScriptableNode.js"; -export * from "./code/ScriptableValueNode.js"; - -// fog -export * from "./fog/FogExp2Node.js"; -export * from "./fog/FogNode.js"; -export * from "./fog/FogRangeNode.js"; - -// geometry -export * from "./geometry/RangeNode.js"; - -// gpgpu -export * from "./gpgpu/ComputeNode.js"; - -// lighting -export * from "./lighting/LightingContextNode.js"; -export * from "./lighting/LightNode.js"; -export * from "./lighting/LightsNode.js"; -export * from "./lighting/PointLightNode.js"; -export * from "./lighting/ShadowNode.js"; - -// pmrem -export * from "./pmrem/PMREMNode.js"; -export * from "./pmrem/PMREMUtils.js"; - -// procedural -export * from "./procedural/Checker.js"; - -// materialX -export * from "./materialx/MaterialXNodes.js"; - -// functions -export { default as BRDF_GGX } from "./functions/BSDF/BRDF_GGX.js"; -export { default as BRDF_Lambert } from "./functions/BSDF/BRDF_Lambert.js"; -export { default as D_GGX } from "./functions/BSDF/D_GGX.js"; -export { default as DFGApprox } from "./functions/BSDF/DFGApprox.js"; -export { default as F_Schlick } from "./functions/BSDF/F_Schlick.js"; -export { default as Schlick_to_F0 } from "./functions/BSDF/Schlick_to_F0.js"; -export { default as V_GGX_SmithCorrelated } from "./functions/BSDF/V_GGX_SmithCorrelated.js"; - -export * from "./lighting/LightUtils.js"; - -export { default as getGeometryRoughness } from "./functions/material/getGeometryRoughness.js"; -export { default as getRoughness } from "./functions/material/getRoughness.js"; -export { default as getShIrradianceAt } from "./functions/material/getShIrradianceAt.js"; diff --git a/src-testing/src/nodes/accessors/AccessorsUtils.d.ts b/src-testing/src/nodes/accessors/AccessorsUtils.d.ts deleted file mode 100644 index e42044673..000000000 --- a/src-testing/src/nodes/accessors/AccessorsUtils.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -export const TBNViewMatrix: ShaderNodeObject; - -export const parallaxDirection: ShaderNodeObject; -export const parallaxUV: (uv: ShaderNodeObject, scale: NodeRepresentation) => ShaderNodeObject; - -export const transformedBentNormalView: ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/BatchNode.d.ts b/src-testing/src/nodes/accessors/BatchNode.d.ts deleted file mode 100644 index 51db8b6bb..000000000 --- a/src-testing/src/nodes/accessors/BatchNode.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { BatchedMesh } from "../../objects/BatchedMesh.js"; -import Node from "../core/Node.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -export default class BatchNode extends Node { - batchMesh: BatchedMesh; - - batchingIdNode: Node | null; - - constructor(batchMesh: BatchedMesh); -} - -export const batch: (batchMesh: BatchedMesh) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/Bitangent.d.ts b/src-testing/src/nodes/accessors/Bitangent.d.ts deleted file mode 100644 index bcdc4d6e2..000000000 --- a/src-testing/src/nodes/accessors/Bitangent.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import MathNode from "../math/MathNode.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -export const bitangentGeometry: ShaderNodeObject; -export const bitangentLocal: ShaderNodeObject; -export const bitangentView: ShaderNodeObject; -export const bitangentWorld: ShaderNodeObject; -export const transformedBitangentView: ShaderNodeObject; -export const transformedBitangentWorld: ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/BufferAttributeNode.ts b/src-testing/src/nodes/accessors/BufferAttributeNode.ts deleted file mode 100644 index 97456dbc2..000000000 --- a/src-testing/src/nodes/accessors/BufferAttributeNode.ts +++ /dev/null @@ -1,135 +0,0 @@ -import InputNode from '../core/InputNode.js'; -import { nodeObject, addMethodChaining } from '../tsl/TSLCore.js'; -import { varying } from '../core/VaryingNode.js'; - -import { InterleavedBufferAttribute } from '../../core/InterleavedBufferAttribute.js'; -import { InterleavedBuffer } from '../../core/InterleavedBuffer.js'; -import { StaticDrawUsage, DynamicDrawUsage } from '../../constants.js'; - -class BufferAttributeNode extends InputNode { - static get type() { - return 'BufferAttributeNode'; - } - - constructor(value, bufferType = null, bufferStride = 0, bufferOffset = 0) { - super(value, bufferType); - - this.isBufferNode = true; - - this.bufferType = bufferType; - this.bufferStride = bufferStride; - this.bufferOffset = bufferOffset; - - this.usage = StaticDrawUsage; - this.instanced = false; - - this.attribute = null; - - this.global = true; - - if (value && value.isBufferAttribute === true) { - this.attribute = value; - this.usage = value.usage; - this.instanced = value.isInstancedBufferAttribute; - } - } - - getHash(builder) { - if (this.bufferStride === 0 && this.bufferOffset === 0) { - let bufferData = builder.globalCache.getData(this.value); - - if (bufferData === undefined) { - bufferData = { - node: this, - }; - - builder.globalCache.setData(this.value, bufferData); - } - - return bufferData.node.uuid; - } - - return this.uuid; - } - - getNodeType(builder) { - if (this.bufferType === null) { - this.bufferType = builder.getTypeFromAttribute(this.attribute); - } - - return this.bufferType; - } - - setup(builder) { - if (this.attribute !== null) return; - - const type = this.getNodeType(builder); - const array = this.value; - const itemSize = builder.getTypeLength(type); - const stride = this.bufferStride || itemSize; - const offset = this.bufferOffset; - - const buffer = array.isInterleavedBuffer === true ? array : new InterleavedBuffer(array, stride); - const bufferAttribute = new InterleavedBufferAttribute(buffer, itemSize, offset); - - buffer.setUsage(this.usage); - - this.attribute = bufferAttribute; - this.attribute.isInstancedBufferAttribute = this.instanced; // @TODO: Add a possible: InstancedInterleavedBufferAttribute - } - - generate(builder) { - const nodeType = this.getNodeType(builder); - - const nodeAttribute = builder.getBufferAttributeFromNode(this, nodeType); - const propertyName = builder.getPropertyName(nodeAttribute); - - let output = null; - - if (builder.shaderStage === 'vertex' || builder.shaderStage === 'compute') { - this.name = propertyName; - - output = propertyName; - } else { - const nodeVarying = varying(this); - - output = nodeVarying.build(builder, nodeType); - } - - return output; - } - - getInputType(/*builder*/) { - return 'bufferAttribute'; - } - - setUsage(value) { - this.usage = value; - - if (this.attribute && this.attribute.isBufferAttribute === true) { - this.attribute.usage = value; - } - - return this; - } - - setInstanced(value) { - this.instanced = value; - - return this; - } -} - -export default BufferAttributeNode; - -export const bufferAttribute = (array, type, stride, offset) => - nodeObject(new BufferAttributeNode(array, type, stride, offset)); -export const dynamicBufferAttribute = (array, type, stride, offset) => - bufferAttribute(array, type, stride, offset).setUsage(DynamicDrawUsage); - -export const instancedBufferAttribute = (array, type, stride, offset) => - bufferAttribute(array, type, stride, offset).setInstanced(true); -export const instancedDynamicBufferAttribute = (array, type, stride, offset) => - dynamicBufferAttribute(array, type, stride, offset).setInstanced(true); - -addMethodChaining('toAttribute', bufferNode => bufferAttribute(bufferNode.value)); diff --git a/src-testing/src/nodes/accessors/BufferNode.d.ts b/src-testing/src/nodes/accessors/BufferNode.d.ts deleted file mode 100644 index 4db9ccccd..000000000 --- a/src-testing/src/nodes/accessors/BufferNode.d.ts +++ /dev/null @@ -1,17 +0,0 @@ -import UniformNode from "../core/UniformNode.js"; -import { NodeOrType, ShaderNodeObject } from "../tsl/TSLCore.js"; - -export default class BufferNode extends UniformNode { - isBufferNode: true; - - bufferType: string; - bufferCount: number; - - constructor(value: unknown, bufferType: string, bufferCount?: number); -} - -export const buffer: ( - value: unknown, - nodeOrType: NodeOrType, - count: number, -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/Camera.d.ts b/src-testing/src/nodes/accessors/Camera.d.ts deleted file mode 100644 index 6fd332889..000000000 --- a/src-testing/src/nodes/accessors/Camera.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Matrix3 } from "../../math/Matrix3.js"; -import { Matrix4 } from "../../math/Matrix4.js"; -import { Vector3 } from "../../math/Vector3.js"; -import UniformNode from "../core/UniformNode.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -export const cameraNear: ShaderNodeObject>; -export const cameraFar: ShaderNodeObject>; -export const cameraProjectionMatrix: ShaderNodeObject>; -export const cameraProjectionMatrixInverse: ShaderNodeObject>; -export const cameraViewMatrix: ShaderNodeObject>; -export const cameraWorldMatrix: ShaderNodeObject>; -export const cameraNormalMatrix: ShaderNodeObject>; -export const cameraPosition: ShaderNodeObject>; diff --git a/src-testing/src/nodes/accessors/ClippingNode.d.ts b/src-testing/src/nodes/accessors/ClippingNode.d.ts deleted file mode 100644 index bb2cac1cd..000000000 --- a/src-testing/src/nodes/accessors/ClippingNode.d.ts +++ /dev/null @@ -1,16 +0,0 @@ -import Node from "../core/Node.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -export type ClippingNodeScope = typeof ClippingNode.ALPHA_TO_COVERAGE | typeof ClippingNode.DEFAULT; - -export default class ClippingNode extends Node { - scope: ClippingNodeScope; - - constructor(scope?: ClippingNodeScope); - - static ALPHA_TO_COVERAGE: "alphaToCoverage"; - static DEFAULT: "default"; -} - -export const clipping: () => ShaderNodeObject; -export const clippingAlpha: () => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/CubeTextureNode.d.ts b/src-testing/src/nodes/accessors/CubeTextureNode.d.ts deleted file mode 100644 index c25d51999..000000000 --- a/src-testing/src/nodes/accessors/CubeTextureNode.d.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { CubeTexture } from "../../textures/CubeTexture.js"; -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; -import TextureNode from "./TextureNode.js"; - -declare class CubeTextureNode extends TextureNode { - isCubeTextureNode: boolean; - uvNode: ShaderNodeObject | null; - levelNode: ShaderNodeObject | null; - - constructor( - value: CubeTexture, - uvNode?: ShaderNodeObject | null, - levelNode?: ShaderNodeObject | null, - biasNode?: ShaderNodeObject | null, - ); - - getDefaultUV(): Node; -} - -export default CubeTextureNode; - -export const cubeTexture: ( - value: CubeTexture, - uvNode?: NodeRepresentation, - levelNode?: NodeRepresentation, - biasNode?: NodeRepresentation, -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/InstanceNode.d.ts b/src-testing/src/nodes/accessors/InstanceNode.d.ts deleted file mode 100644 index c6cd43993..000000000 --- a/src-testing/src/nodes/accessors/InstanceNode.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { InstancedMesh } from "../../objects/InstancedMesh.js"; -import Node from "../core/Node.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -export default class InstanceNode extends Node { - instanceMesh: InstancedMesh; - instanceMatrixNode: Node | null; - instanceColorNode: Node | null; - - constructor(instanceMesh: InstancedMesh); -} - -export const instance: (instanceMesh: InstancedMesh) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/MaterialNode.d.ts b/src-testing/src/nodes/accessors/MaterialNode.d.ts deleted file mode 100644 index a29160b0e..000000000 --- a/src-testing/src/nodes/accessors/MaterialNode.d.ts +++ /dev/null @@ -1,129 +0,0 @@ -import { Vector2 } from "../../math/Vector2.js"; -import Node from "../core/Node.js"; -import UniformNode from "../core/UniformNode.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -export type MaterialNodeScope = - | typeof MaterialNode.ALPHA_TEST - | typeof MaterialNode.COLOR - | typeof MaterialNode.OPACITY - | typeof MaterialNode.SHININESS - | typeof MaterialNode.SPECULAR - | typeof MaterialNode.SPECULAR_STRENGTH - | typeof MaterialNode.SPECULAR_INTENSITY - | typeof MaterialNode.SPECULAR_COLOR - | typeof MaterialNode.REFLECTIVITY - | typeof MaterialNode.ROUGHNESS - | typeof MaterialNode.METALNESS - | typeof MaterialNode.NORMAL - | typeof MaterialNode.CLEARCOAT - | typeof MaterialNode.CLEARCOAT_ROUGHNESS - | typeof MaterialNode.CLEARCOAT_NORMAL - | typeof MaterialNode.EMISSIVE - | typeof MaterialNode.ROTATION - | typeof MaterialNode.SHEEN - | typeof MaterialNode.SHEEN_ROUGHNESS - | typeof MaterialNode.ANISOTROPY - | typeof MaterialNode.IRIDESCENCE - | typeof MaterialNode.IRIDESCENCE_IOR - | typeof MaterialNode.IRIDESCENCE_THICKNESS - | typeof MaterialNode.IOR - | typeof MaterialNode.TRANSMISSION - | typeof MaterialNode.THICKNESS - | typeof MaterialNode.ATTENUATION_DISTANCE - | typeof MaterialNode.ATTENUATION_COLOR - | typeof MaterialNode.LINE_SCALE - | typeof MaterialNode.LINE_DASH_SIZE - | typeof MaterialNode.LINE_GAP_SIZE - | typeof MaterialNode.LINE_WIDTH - | typeof MaterialNode.LINE_DASH_OFFSET - | typeof MaterialNode.POINT_WIDTH - | typeof MaterialNode.DISPERSION - | typeof MaterialNode.LIGHT_MAP - | typeof MaterialNode.AO_MAP - | typeof MaterialNode.REFRACTION_RATIO; - -export default class MaterialNode extends Node { - static ALPHA_TEST: "alphaTest"; - static COLOR: "color"; - static OPACITY: "opacity"; - static SHININESS: "shininess"; - static SPECULAR: "specular"; - static SPECULAR_STRENGTH: "specularStrength"; - static SPECULAR_INTENSITY: "specularIntensity"; - static SPECULAR_COLOR: "specularColor"; - static REFLECTIVITY: "reflectivity"; - static ROUGHNESS: "roughness"; - static METALNESS: "metalness"; - static NORMAL: "normal"; - static CLEARCOAT: "clearcoat"; - static CLEARCOAT_ROUGHNESS: "clearcoatRoughness"; - static CLEARCOAT_NORMAL: "clearcoatNormal"; - static EMISSIVE: "emissive"; - static ROTATION: "rotation"; - static SHEEN: "sheen"; - static SHEEN_ROUGHNESS: "sheenRoughness"; - static ANISOTROPY: "anisotropy"; - static IRIDESCENCE: "iridescence"; - static IRIDESCENCE_IOR: "iridescenceIOR"; - static IRIDESCENCE_THICKNESS: "iridescenceThickness"; - static IOR: "ior"; - static TRANSMISSION: "transmission"; - static THICKNESS: "thickness"; - static ATTENUATION_DISTANCE: "attenuationDistance"; - static ATTENUATION_COLOR: "attenuationColor"; - static LINE_SCALE: "scale"; - static LINE_DASH_SIZE: "dashSize"; - static LINE_GAP_SIZE: "gapSize"; - static LINE_WIDTH: "linewidth"; - static LINE_DASH_OFFSET: "dashOffset"; - static POINT_WIDTH: "pointWidth"; - static DISPERSION: "dispersion"; - static LIGHT_MAP: "light"; - static AO_MAP: "ao"; - static REFRACTION_RATIO: "refractionRatio"; - - scope: MaterialNodeScope; - constructor(scope?: MaterialNodeScope); -} - -export const materialAlphaTest: ShaderNodeObject; -export const materialColor: ShaderNodeObject; -export const materialShininess: ShaderNodeObject; -export const materialEmissive: ShaderNodeObject; -export const materialOpacity: ShaderNodeObject; -export const materialSpecular: ShaderNodeObject; - -export const materialSpecularIntensity: ShaderNodeObject; -export const materialSpecularColor: ShaderNodeObject; - -export const materialSpecularStrength: ShaderNodeObject; -export const materialReflectivity: ShaderNodeObject; -export const materialRoughness: ShaderNodeObject; -export const materialMetalness: ShaderNodeObject; -export const materialNormal: ShaderNodeObject; -export const materialClearcoat: ShaderNodeObject; -export const materialClearcoatRoughness: ShaderNodeObject; -export const materialClearcoatNormal: ShaderNodeObject; -export const materialRotation: ShaderNodeObject; -export const materialSheen: ShaderNodeObject; -export const materialSheenRoughness: ShaderNodeObject; -export const materialAnisotropy: ShaderNodeObject; -export const materialIridescence: ShaderNodeObject; -export const materialIridescenceIOR: ShaderNodeObject; -export const materialIridescenceThickness: ShaderNodeObject; -export const materialTransmission: ShaderNodeObject; -export const materialThickness: ShaderNodeObject; -export const materialIOR: ShaderNodeObject; -export const materialAttenuationDistance: ShaderNodeObject; -export const materialAttenuationColor: ShaderNodeObject; -export const materialLineScale: ShaderNodeObject; -export const materialLineDashSize: ShaderNodeObject; -export const materialLineGapSize: ShaderNodeObject; -export const materialLineWidth: ShaderNodeObject; -export const materialLineDashOffset: ShaderNodeObject; -export const materialPointWidth: ShaderNodeObject; -export const materialDispersion: ShaderNodeObject; -export const materialLightMap: ShaderNodeObject; -export const materialAOMap: ShaderNodeObject; -export const materialAnisotropyVector: ShaderNodeObject>; diff --git a/src-testing/src/nodes/accessors/MaterialProperties.d.ts b/src-testing/src/nodes/accessors/MaterialProperties.d.ts deleted file mode 100644 index 3e07ecf0b..000000000 --- a/src-testing/src/nodes/accessors/MaterialProperties.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -import UniformNode from "../core/UniformNode.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -export const materialRefractionRatio: ShaderNodeObject>; diff --git a/src-testing/src/nodes/accessors/MaterialReferenceNode.d.ts b/src-testing/src/nodes/accessors/MaterialReferenceNode.d.ts deleted file mode 100644 index 7b0cdf4ac..000000000 --- a/src-testing/src/nodes/accessors/MaterialReferenceNode.d.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Material } from "../../materials/Material.js"; -import { NodeOrType, ShaderNodeObject } from "../tsl/TSLCore.js"; -import ReferenceNode from "./ReferenceNode.js"; - -export default class MaterialReferenceNode extends ReferenceNode { - readonly isMaterialReferenceNode: true; - - constructor(property: string, inputType: string, material?: Material | null); -} - -export const materialReference: ( - name: string, - nodeOrType: NodeOrType, - material?: Material | null, -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/ModelNode.d.ts b/src-testing/src/nodes/accessors/ModelNode.d.ts deleted file mode 100644 index 12280a2b6..000000000 --- a/src-testing/src/nodes/accessors/ModelNode.d.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { Matrix4 } from "../../math/Matrix4.js"; -import Node from "../core/Node.js"; -import { UniformNode } from "../Nodes.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; -import Object3DNode from "./Object3DNode.js"; - -/** - * Similar to {@link Object3DNode} but the object comes from {@link NodeFrame} - */ -export default class ModelNode extends Object3DNode { - constructor(scope: string); -} - -export const modelDirection: ShaderNodeObject; -export const modelWorldMatrix: ShaderNodeObject; -export const modelPosition: ShaderNodeObject; -export const modelScale: ShaderNodeObject; -export const modelViewPosition: ShaderNodeObject; -export const modelNormalMatrix: ShaderNodeObject; -export const modelWorldMatrixInverse: ShaderNodeObject>; -export const modelViewMatrix: ShaderNodeObject; - -export const highPrecisionModelViewMatrix: ShaderNodeObject; -export const highPrecisionModelNormalViewMatrix: ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/ModelViewProjectionNode.d.ts b/src-testing/src/nodes/accessors/ModelViewProjectionNode.d.ts deleted file mode 100644 index 18302d638..000000000 --- a/src-testing/src/nodes/accessors/ModelViewProjectionNode.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -export default class ModelViewProjectionNode extends Node { - constructor(positionNode?: Node); -} - -export const modelViewProjection: (position?: NodeRepresentation) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/MorphNode.d.ts b/src-testing/src/nodes/accessors/MorphNode.d.ts deleted file mode 100644 index 8987acf6e..000000000 --- a/src-testing/src/nodes/accessors/MorphNode.d.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Mesh } from "../../objects/Mesh.js"; -import Node from "../core/Node.js"; -import UniformNode from "../core/UniformNode.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -declare class MorphNode extends Node { - mesh: Mesh; - morphBaseInfluence: UniformNode; - - constructor(mesh: Mesh); -} - -export default MorphNode; - -export const morphReference: (mesh: Mesh) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/Normal.d.ts b/src-testing/src/nodes/accessors/Normal.d.ts deleted file mode 100644 index 706130a8d..000000000 --- a/src-testing/src/nodes/accessors/Normal.d.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { Matrix4 } from "../../math/Matrix4.js"; -import AttributeNode from "../core/AttributeNode.js"; -import Node from "../core/Node.js"; -import VarNode from "../core/VarNode.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -export const normalGeometry: ShaderNodeObject; - -export const normalLocal: ShaderNodeObject; - -export const normalFlat: ShaderNodeObject; - -export const normalView: ShaderNodeObject; - -export const normalWorld: ShaderNodeObject; - -export const transformedNormalView: ShaderNodeObject; - -export const transformedNormalWorld: ShaderNodeObject; - -export const transformedClearcoatNormalView: ShaderNodeObject; - -export const transformNormal: (normal: Node, matrix?: Node) => ShaderNodeObject; - -export const transformNormalToView: (normal: Node) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/Object3DNode.d.ts b/src-testing/src/nodes/accessors/Object3DNode.d.ts deleted file mode 100644 index 21e6776c9..000000000 --- a/src-testing/src/nodes/accessors/Object3DNode.d.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Object3D } from "../../core/Object3D.js"; -import Node from "../core/Node.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -export default class Object3DNode extends Node { - scope: string; - object3d: Object3D | null; - - constructor(scope: string, object3d?: Object3D | null); - - static WORLD_MATRIX: "worldMatrix"; - static POSITION: "position"; - static SCALE: "scale"; - static VIEW_POSITION: "viewPosition"; - static DIRECTION: "direction"; -} - -export const objectDirection: (object3d: Object3D) => ShaderNodeObject; -export const objectWorldMatrix: (object3d: Object3D) => ShaderNodeObject; -export const objectPosition: (object3d: Object3D) => ShaderNodeObject; -export const objectScale: (object3d: Object3D) => ShaderNodeObject; -export const objectViewPosition: (object3d: Object3D) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/PointUVNode.d.ts b/src-testing/src/nodes/accessors/PointUVNode.d.ts deleted file mode 100644 index 2220e5563..000000000 --- a/src-testing/src/nodes/accessors/PointUVNode.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import Node from "../core/Node.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -export default class PointUVNode extends Node { - isPointUVNode: true; - - constructor(); -} - -export const pointUV: ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/Position.d.ts b/src-testing/src/nodes/accessors/Position.d.ts deleted file mode 100644 index a9f6fc811..000000000 --- a/src-testing/src/nodes/accessors/Position.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import Node from "../core/Node.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -export const positionGeometry: ShaderNodeObject; -export const positionLocal: ShaderNodeObject; -export const positionPrevious: ShaderNodeObject; -export const positionWorld: ShaderNodeObject; -export const positionWorldDirection: ShaderNodeObject; -export const positionView: ShaderNodeObject; -export const positionViewDirection: ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/ReferenceBaseNode.d.ts b/src-testing/src/nodes/accessors/ReferenceBaseNode.d.ts deleted file mode 100644 index 586fde349..000000000 --- a/src-testing/src/nodes/accessors/ReferenceBaseNode.d.ts +++ /dev/null @@ -1,27 +0,0 @@ -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -declare class ReferenceBaseNode extends Node { - property: string; - uniformType: string; - object: T; - count: number | null; - - properties: string[]; - reference: T | null; - node: Node | null; - - constructor(property: string, uniformType: string, object?: T | null, count?: number | null); - - setNodeType(uniformType: string): void; -} - -export default ReferenceBaseNode; - -export const reference: (name: string, type: string, object: T) => ShaderNodeObject>; -export const referenceBuffer: ( - name: string, - type: string, - count: number, - object: T, -) => ShaderNodeObject>; diff --git a/src-testing/src/nodes/accessors/ReferenceNode.d.ts b/src-testing/src/nodes/accessors/ReferenceNode.d.ts deleted file mode 100644 index 1dea4d31f..000000000 --- a/src-testing/src/nodes/accessors/ReferenceNode.d.ts +++ /dev/null @@ -1,29 +0,0 @@ -import Node from "../core/Node.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -declare class ReferenceNode extends Node { - property: string; - - uniformType: string; - - object: T; - count: number | null; - - properties: string[]; - reference: T | null; - node: Node | null; - - constructor(property: string, uniformType: string, object?: T | null, count?: number | null); - - setNodeType(uniformType: string): void; -} - -export default ReferenceNode; - -export const reference: (name: string, type: string, object: T) => ShaderNodeObject>; -export const referenceBuffer: ( - name: string, - type: string, - count: number, - object: T, -) => ShaderNodeObject>; diff --git a/src-testing/src/nodes/accessors/ReflectVector.d.ts b/src-testing/src/nodes/accessors/ReflectVector.d.ts deleted file mode 100644 index 4978b4975..000000000 --- a/src-testing/src/nodes/accessors/ReflectVector.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import Node from "../core/Node.js"; -import VarNode from "../core/VarNode.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -export const reflectView: ShaderNodeObject; -export const refractView: ShaderNodeObject; - -export const reflectVector: ShaderNodeObject; -export const refractVector: ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/RendererReferenceNode.d.ts b/src-testing/src/nodes/accessors/RendererReferenceNode.d.ts deleted file mode 100644 index 0e100b049..000000000 --- a/src-testing/src/nodes/accessors/RendererReferenceNode.d.ts +++ /dev/null @@ -1,15 +0,0 @@ -import Renderer from "../../renderers/common/Renderer.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; -import ReferenceNode from "./ReferenceNode.js"; - -export default class RendererReferenceNode extends ReferenceNode { - renderer: Renderer | null; - - constructor(property: string, inputType: string, renderer?: Renderer | null); -} - -export const rendererReference: ( - name: string, - type: string, - renderer?: Renderer | null, -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/SceneNode.d.ts b/src-testing/src/nodes/accessors/SceneNode.d.ts deleted file mode 100644 index 34bdea1be..000000000 --- a/src-testing/src/nodes/accessors/SceneNode.d.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Scene } from "../../scenes/Scene.js"; -import Node from "../core/Node.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -export type SceneNodeScope = typeof SceneNode.BACKGROUND_BLURRINESS | typeof SceneNode.BACKGROUND_INTENSITY; - -declare class SceneNode extends Node { - scope: SceneNodeScope; - scene: Scene | null; - - constructor(scope?: SceneNodeScope, scene?: Scene | null); - - static BACKGROUND_BLURRINESS: "backgroundBlurriness"; - static BACKGROUND_INTENSITY: "backgroundIntensity"; -} - -export default SceneNode; - -export const backgroundBlurriness: ShaderNodeObject; -export const backgroundIntensity: ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/SkinningNode.d.ts b/src-testing/src/nodes/accessors/SkinningNode.d.ts deleted file mode 100644 index 3bef01c33..000000000 --- a/src-testing/src/nodes/accessors/SkinningNode.d.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { SkinnedMesh } from "../../objects/SkinnedMesh.js"; -import Node from "../core/Node.js"; -import NodeBuilder from "../core/NodeBuilder.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -export default class SkinningNode extends Node { - skinnedMesh: SkinnedMesh; - useReference: boolean; - - skinIndexNode: Node; - skinWeightNode: Node; - - bindMatrixNode: Node; - bindMatrixInverseNode: Node; - boneMatricesNode: Node; - previousBoneMatricesNode: Node | null; - - constructor(skinnedMesh: SkinnedMesh, useReference?: boolean); - - getSkinnedPosition(boneMatrices?: Node, position?: Node): ShaderNodeObject; - - getSkinnedNormal(boneMatrices?: Node, normal?: Node): ShaderNodeObject; - - getPreviousSkinnedPosition(builder: NodeBuilder): ShaderNodeObject; - - needsPreviousBoneMatrices(builder: NodeBuilder): boolean; -} - -export const skinning: (skinnedMesh: SkinnedMesh) => ShaderNodeObject; -export const skinningReference: (skinnedMesh: SkinnedMesh) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/StorageBufferNode.d.ts b/src-testing/src/nodes/accessors/StorageBufferNode.d.ts deleted file mode 100644 index d56cac59a..000000000 --- a/src-testing/src/nodes/accessors/StorageBufferNode.d.ts +++ /dev/null @@ -1,38 +0,0 @@ -import StorageBufferAttribute from "../../renderers/common/StorageBufferAttribute.js"; -import StorageInstancedBufferAttribute from "../../renderers/common/StorageInstancedBufferAttribute.js"; -import { GPUBufferBindingType } from "../../renderers/webgpu/utils/WebGPUConstants.js"; -import { NodeOrType, NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; -import StorageArrayElementNode from "../utils/StorageArrayElementNode.js"; -import BufferNode from "./BufferNode.js"; - -export default class StorageBufferNode extends BufferNode { - readonly isStorageBufferNode: true; - bufferObject: boolean; - - access: GPUBufferBindingType; - - constructor( - value: StorageBufferAttribute | StorageInstancedBufferAttribute, - bufferType: string, - bufferCount?: number, - ); - - element(indexNode: NodeRepresentation): ShaderNodeObject; - - setBufferObject(value: boolean): this; - - setAccess(value: GPUBufferBindingType): this; - - toReadOnly(): this; -} - -export const storage: ( - value: StorageBufferAttribute | StorageInstancedBufferAttribute, - nodeOrType: NodeOrType, - count: number, -) => ShaderNodeObject; -export const storageObject: ( - value: StorageBufferAttribute | StorageInstancedBufferAttribute, - nodeOrType: NodeOrType, - count: number, -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/StorageTextureNode.d.ts b/src-testing/src/nodes/accessors/StorageTextureNode.d.ts deleted file mode 100644 index 0b4acdceb..000000000 --- a/src-testing/src/nodes/accessors/StorageTextureNode.d.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { GPUStorageTextureAccess } from "../../renderers/webgpu/utils/WebGPUConstants.js"; -import { Texture } from "../../textures/Texture.js"; -import Node from "../core/Node.js"; -import NodeBuilder from "../core/NodeBuilder.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; -import TextureNode from "./TextureNode.js"; - -export default class StorageTextureNode extends TextureNode { - storeNode: Node | null; - - readonly isStorageTextureNode: true; - - access: GPUStorageTextureAccess; - - constructor( - value: Texture, - uvNode?: ShaderNodeObject | null, - storeNode?: Node | null, - ); - - setAccess(value: GPUStorageTextureAccess): this; - - toReadOnly(): this; - - toWriteOnly(): this; - - generateStore(builder: NodeBuilder): void; -} - -export const storageTexture: ( - value: Texture, - uvNode?: NodeRepresentation, - storeNode?: NodeRepresentation, -) => ShaderNodeObject; - -export const textureStore: ( - value: Texture, - uvNode?: NodeRepresentation, - storeNode?: NodeRepresentation, -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/Tangent.d.ts b/src-testing/src/nodes/accessors/Tangent.d.ts deleted file mode 100644 index 94ec48330..000000000 --- a/src-testing/src/nodes/accessors/Tangent.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -import AttributeNode from "../core/AttributeNode.js"; -import VarNode from "../core/VarNode.js"; -import VaryingNode from "../core/VaryingNode.js"; -import MathNode from "../math/MathNode.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -export const tangentGeometry: ShaderNodeObject; -export const tangentLocal: ShaderNodeObject; -export const tangentView: ShaderNodeObject; -export const tangentWorld: ShaderNodeObject; -export const transformedTangentView: ShaderNodeObject; -export const transformedTangentWorld: ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/Texture3DNode.d.ts b/src-testing/src/nodes/accessors/Texture3DNode.d.ts deleted file mode 100644 index da589f034..000000000 --- a/src-testing/src/nodes/accessors/Texture3DNode.d.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { CubeTexture } from "../../textures/CubeTexture.js"; -import { Texture } from "../../textures/Texture.js"; -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; -import TextureNode from "./TextureNode.js"; - -export default class Texture3DNode extends TextureNode { - readonly isTexture3DNode: true; - - constructor(value: Texture, uvNode?: ShaderNodeObject | null, levelNode?: ShaderNodeObject | null); -} - -export const texture3D: ( - value: Texture, - uvNode?: NodeRepresentation, - levelNode?: NodeRepresentation, -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/TextureBicubic.d.ts b/src-testing/src/nodes/accessors/TextureBicubic.d.ts deleted file mode 100644 index b55ca57e9..000000000 --- a/src-testing/src/nodes/accessors/TextureBicubic.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -export const textureBicubic: (textureNode: Node, lodNode?: NodeRepresentation) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/TextureNode.ts b/src-testing/src/nodes/accessors/TextureNode.ts deleted file mode 100644 index f97a04d11..000000000 --- a/src-testing/src/nodes/accessors/TextureNode.ts +++ /dev/null @@ -1,370 +0,0 @@ -import UniformNode, { uniform } from '../core/UniformNode.js'; -import { uv } from './UV.js'; -import { textureSize } from './TextureSizeNode.js'; -import { colorSpaceToWorking } from '../display/ColorSpaceNode.js'; -import { expression } from '../code/ExpressionNode.js'; -import { maxMipLevel } from '../utils/MaxMipLevelNode.js'; -import { nodeProxy, vec3, nodeObject, int } from '../tsl/TSLBase.js'; -import { NodeUpdateType } from '../core/constants.js'; - -import { IntType, UnsignedIntType } from '../../constants.js'; - -class TextureNode extends UniformNode { - static get type() { - return 'TextureNode'; - } - - constructor(value, uvNode = null, levelNode = null, biasNode = null) { - super(value); - - this.isTextureNode = true; - - this.uvNode = uvNode; - this.levelNode = levelNode; - this.biasNode = biasNode; - this.compareNode = null; - this.depthNode = null; - this.gradNode = null; - - this.sampler = true; - this.updateMatrix = false; - this.updateType = NodeUpdateType.NONE; - - this.referenceNode = null; - - this._value = value; - this._matrixUniform = null; - - this.setUpdateMatrix(uvNode === null); - } - - set value(value) { - if (this.referenceNode) { - this.referenceNode.value = value; - } else { - this._value = value; - } - } - - get value() { - return this.referenceNode ? this.referenceNode.value : this._value; - } - - getUniformHash(/*builder*/) { - return this.value.uuid; - } - - getNodeType(/*builder*/) { - if (this.value.isDepthTexture === true) return 'float'; - - if (this.value.type === UnsignedIntType) { - return 'uvec4'; - } else if (this.value.type === IntType) { - return 'ivec4'; - } - - return 'vec4'; - } - - getInputType(/*builder*/) { - return 'texture'; - } - - getDefaultUV() { - return uv(this.value.channel); - } - - updateReference(/*state*/) { - return this.value; - } - - getTransformedUV(uvNode) { - if (this._matrixUniform === null) this._matrixUniform = uniform(this.value.matrix); - - return this._matrixUniform.mul(vec3(uvNode, 1)).xy; - } - - setUpdateMatrix(value) { - this.updateMatrix = value; - this.updateType = value ? NodeUpdateType.FRAME : NodeUpdateType.NONE; - - return this; - } - - setupUV(builder, uvNode) { - const texture = this.value; - - if ( - builder.isFlipY() && - (texture.isRenderTargetTexture === true || - texture.isFramebufferTexture === true || - texture.isDepthTexture === true) - ) { - if (this.sampler) { - uvNode = uvNode.flipY(); - } else { - uvNode = uvNode.setY(int(textureSize(this, this.levelNode).y).sub(uvNode.y).sub(1)); - } - } - - return uvNode; - } - - setup(builder) { - const properties = builder.getNodeProperties(this); - properties.referenceNode = this.referenceNode; - - // - - let uvNode = this.uvNode; - - if ((uvNode === null || builder.context.forceUVContext === true) && builder.context.getUV) { - uvNode = builder.context.getUV(this); - } - - if (!uvNode) uvNode = this.getDefaultUV(); - - if (this.updateMatrix === true) { - uvNode = this.getTransformedUV(uvNode); - } - - uvNode = this.setupUV(builder, uvNode); - - // - - let levelNode = this.levelNode; - - if (levelNode === null && builder.context.getTextureLevel) { - levelNode = builder.context.getTextureLevel(this); - } - - // - - properties.uvNode = uvNode; - properties.levelNode = levelNode; - properties.biasNode = this.biasNode; - properties.compareNode = this.compareNode; - properties.gradNode = this.gradNode; - properties.depthNode = this.depthNode; - } - - generateUV(builder, uvNode) { - return uvNode.build(builder, this.sampler === true ? 'vec2' : 'ivec2'); - } - - generateSnippet( - builder, - textureProperty, - uvSnippet, - levelSnippet, - biasSnippet, - depthSnippet, - compareSnippet, - gradSnippet, - ) { - const texture = this.value; - - let snippet; - - if (levelSnippet) { - snippet = builder.generateTextureLevel(texture, textureProperty, uvSnippet, levelSnippet, depthSnippet); - } else if (biasSnippet) { - snippet = builder.generateTextureBias(texture, textureProperty, uvSnippet, biasSnippet, depthSnippet); - } else if (gradSnippet) { - snippet = builder.generateTextureGrad(texture, textureProperty, uvSnippet, gradSnippet, depthSnippet); - } else if (compareSnippet) { - snippet = builder.generateTextureCompare(texture, textureProperty, uvSnippet, compareSnippet, depthSnippet); - } else if (this.sampler === false) { - snippet = builder.generateTextureLoad(texture, textureProperty, uvSnippet, depthSnippet); - } else { - snippet = builder.generateTexture(texture, textureProperty, uvSnippet, depthSnippet); - } - - return snippet; - } - - generate(builder, output) { - const properties = builder.getNodeProperties(this); - - const texture = this.value; - - if (!texture || texture.isTexture !== true) { - throw new Error('TextureNode: Need a three.js texture.'); - } - - const textureProperty = super.generate(builder, 'property'); - - if (output === 'sampler') { - return textureProperty + '_sampler'; - } else if (builder.isReference(output)) { - return textureProperty; - } else { - const nodeData = builder.getDataFromNode(this); - - let propertyName = nodeData.propertyName; - - if (propertyName === undefined) { - const { uvNode, levelNode, biasNode, compareNode, depthNode, gradNode } = properties; - - const uvSnippet = this.generateUV(builder, uvNode); - const levelSnippet = levelNode ? levelNode.build(builder, 'float') : null; - const biasSnippet = biasNode ? biasNode.build(builder, 'float') : null; - const depthSnippet = depthNode ? depthNode.build(builder, 'int') : null; - const compareSnippet = compareNode ? compareNode.build(builder, 'float') : null; - const gradSnippet = gradNode - ? [gradNode[0].build(builder, 'vec2'), gradNode[1].build(builder, 'vec2')] - : null; - - const nodeVar = builder.getVarFromNode(this); - - propertyName = builder.getPropertyName(nodeVar); - - const snippet = this.generateSnippet( - builder, - textureProperty, - uvSnippet, - levelSnippet, - biasSnippet, - depthSnippet, - compareSnippet, - gradSnippet, - ); - - builder.addLineFlowCode(`${propertyName} = ${snippet}`, this); - - nodeData.snippet = snippet; - nodeData.propertyName = propertyName; - } - - let snippet = propertyName; - const nodeType = this.getNodeType(builder); - - if (builder.needsToWorkingColorSpace(texture)) { - snippet = colorSpaceToWorking(expression(snippet, nodeType), texture.colorSpace) - .setup(builder) - .build(builder, nodeType); - } - - return builder.format(snippet, nodeType, output); - } - } - - setSampler(value) { - this.sampler = value; - - return this; - } - - getSampler() { - return this.sampler; - } - - // @TODO: Move to TSL - - uv(uvNode) { - const textureNode = this.clone(); - textureNode.uvNode = nodeObject(uvNode); - textureNode.referenceNode = this.getSelf(); - - return nodeObject(textureNode); - } - - blur(amountNode) { - const textureNode = this.clone(); - textureNode.biasNode = nodeObject(amountNode).mul(maxMipLevel(textureNode)); - textureNode.referenceNode = this.getSelf(); - - return nodeObject(textureNode); - } - - level(levelNode) { - const textureNode = this.clone(); - textureNode.levelNode = nodeObject(levelNode); - textureNode.referenceNode = this.getSelf(); - - return nodeObject(textureNode); - } - - size(levelNode) { - return textureSize(this, levelNode); - } - - bias(biasNode) { - const textureNode = this.clone(); - textureNode.biasNode = nodeObject(biasNode); - textureNode.referenceNode = this.getSelf(); - - return nodeObject(textureNode); - } - - compare(compareNode) { - const textureNode = this.clone(); - textureNode.compareNode = nodeObject(compareNode); - textureNode.referenceNode = this.getSelf(); - - return nodeObject(textureNode); - } - - grad(gradNodeX, gradNodeY) { - const textureNode = this.clone(); - textureNode.gradNode = [nodeObject(gradNodeX), nodeObject(gradNodeY)]; - textureNode.referenceNode = this.getSelf(); - - return nodeObject(textureNode); - } - - depth(depthNode) { - const textureNode = this.clone(); - textureNode.depthNode = nodeObject(depthNode); - textureNode.referenceNode = this.getSelf(); - - return nodeObject(textureNode); - } - - // -- - - serialize(data) { - super.serialize(data); - - data.value = this.value.toJSON(data.meta).uuid; - data.sampler = this.sampler; - data.updateMatrix = this.updateMatrix; - data.updateType = this.updateType; - } - - deserialize(data) { - super.deserialize(data); - - this.value = data.meta.textures[data.value]; - this.sampler = data.sampler; - this.updateMatrix = data.updateMatrix; - this.updateType = data.updateType; - } - - update() { - const texture = this.value; - const matrixUniform = this._matrixUniform; - - if (matrixUniform !== null) matrixUniform.value = texture.matrix; - - if (texture.matrixAutoUpdate === true) { - texture.updateMatrix(); - } - } - - clone() { - const newNode = new this.constructor(this.value, this.uvNode, this.levelNode, this.biasNode); - newNode.sampler = this.sampler; - - return newNode; - } -} - -export default TextureNode; - -export const texture = /*@__PURE__*/ nodeProxy(TextureNode); -export const textureLoad = (...params) => texture(...params).setSampler(false); - -//export const textureLevel = ( value, uv, level ) => texture( value, uv ).level( level ); - -export const sampler = aTexture => (aTexture.isNode === true ? aTexture : texture(aTexture)).convert('sampler'); diff --git a/src-testing/src/nodes/accessors/TextureSizeNode.d.ts b/src-testing/src/nodes/accessors/TextureSizeNode.d.ts deleted file mode 100644 index 0b995fccf..000000000 --- a/src-testing/src/nodes/accessors/TextureSizeNode.d.ts +++ /dev/null @@ -1,18 +0,0 @@ -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -declare class TextureSizeNode extends Node { - readonly isTextureSizeNode: true; - - textureNode: Node; - levelNode: Node | null; - - constructor(textureNode: Node, levelNode?: Node | null); -} - -export default TextureSizeNode; - -export const textureSize: ( - textureNode: NodeRepresentation, - levelNode?: NodeRepresentation | null, -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/UV.d.ts b/src-testing/src/nodes/accessors/UV.d.ts deleted file mode 100644 index aedabbd02..000000000 --- a/src-testing/src/nodes/accessors/UV.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -import AttributeNode from "../core/AttributeNode.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -export const uv: (index?: number) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/UniformArrayNode.d.ts b/src-testing/src/nodes/accessors/UniformArrayNode.d.ts deleted file mode 100644 index 72e539cb4..000000000 --- a/src-testing/src/nodes/accessors/UniformArrayNode.d.ts +++ /dev/null @@ -1,30 +0,0 @@ -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; -import ArrayElementNode from "../utils/ArrayElementNode.js"; -import BufferNode from "./BufferNode.js"; - -declare class UniformArrayElementNode extends ArrayElementNode { - constructor(arrayBuffer: Node, indexNode: Node); -} - -declare class UniformArrayNode extends BufferNode { - array: unknown[]; - elementType: string | null; - - readonly isArrayBufferNode: true; - - constructor(value: unknown[], elementType?: string | null); - - getElementLength(): number; - - element(indexNode: NodeRepresentation): ShaderNodeObject; -} - -export default UniformArrayNode; - -export const uniformArray: (values: unknown[], nodeType?: string | null) => ShaderNodeObject; - -/** - * @deprecated uniforms() has been renamed to uniformArray(). - */ -export const uniforms: (values: unknown[], nodeType?: string | null) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/UserDataNode.d.ts b/src-testing/src/nodes/accessors/UserDataNode.d.ts deleted file mode 100644 index 647c18412..000000000 --- a/src-testing/src/nodes/accessors/UserDataNode.d.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { ShaderNodeObject } from "../tsl/TSLCore.js"; -import ReferenceNode from "./ReferenceNode.js"; - -export type NodeUserData = Record; - -export default class UserDataNode extends ReferenceNode { - userData: NodeUserData | null; - constructor(property: string, inputType: string, userData?: NodeUserData | null); -} - -export const userData: ( - name: string, - inputType: string, - userData?: NodeUserData, -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/VelocityNode.d.ts b/src-testing/src/nodes/accessors/VelocityNode.d.ts deleted file mode 100644 index 32c040c16..000000000 --- a/src-testing/src/nodes/accessors/VelocityNode.d.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Matrix4 } from "../../math/Matrix4.js"; -import TempNode from "../core/TempNode.js"; -import UniformNode from "../core/UniformNode.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -declare class VelocityNode extends TempNode { - projectionMatrix: Matrix4 | null; - - previousModelWorldMatrix: UniformNode; - previousProjectionMatrix: UniformNode; - previousCameraViewMatrix: UniformNode; - - constructor(); - - setProjectionMatrix(projectionMatrix: Matrix4 | null): void; -} - -export default VelocityNode; - -export const velocity: ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/VertexColorNode.d.ts b/src-testing/src/nodes/accessors/VertexColorNode.d.ts deleted file mode 100644 index b2bb76339..000000000 --- a/src-testing/src/nodes/accessors/VertexColorNode.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -import AttributeNode from "../core/AttributeNode.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -export default class VertexColorNode extends AttributeNode { - readonly isVertexColorNode: true; - - index: number; - - constructor(index?: number); -} - -export const vertexColor: (index?: number) => ShaderNodeObject; diff --git a/src-testing/src/nodes/code/CodeNode.ts b/src-testing/src/nodes/code/CodeNode.ts deleted file mode 100644 index 2f4c60511..000000000 --- a/src-testing/src/nodes/code/CodeNode.ts +++ /dev/null @@ -1,68 +0,0 @@ -import Node from '../core/Node.js'; -import { nodeProxy } from '../tsl/TSLBase.js'; - -class CodeNode extends Node { - static get type() { - return 'CodeNode'; - } - - constructor(code = '', includes = [], language = '') { - super('code'); - - this.isCodeNode = true; - - this.code = code; - this.language = language; - - this.includes = includes; - } - - isGlobal() { - return true; - } - - setIncludes(includes) { - this.includes = includes; - - return this; - } - - getIncludes(/*builder*/) { - return this.includes; - } - - generate(builder) { - const includes = this.getIncludes(builder); - - for (const include of includes) { - include.build(builder); - } - - const nodeCode = builder.getCodeFromNode(this, this.getNodeType(builder)); - nodeCode.code = this.code; - - return nodeCode.code; - } - - serialize(data) { - super.serialize(data); - - data.code = this.code; - data.language = this.language; - } - - deserialize(data) { - super.deserialize(data); - - this.code = data.code; - this.language = data.language; - } -} - -export default CodeNode; - -export const code = /*@__PURE__*/ nodeProxy(CodeNode); - -export const js = (src, includes) => code(src, includes, 'js'); -export const wgsl = (src, includes) => code(src, includes, 'wgsl'); -export const glsl = (src, includes) => code(src, includes, 'glsl'); diff --git a/src-testing/src/nodes/code/ExpressionNode.d.ts b/src-testing/src/nodes/code/ExpressionNode.d.ts deleted file mode 100644 index ce5fc783b..000000000 --- a/src-testing/src/nodes/code/ExpressionNode.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import TempNode from "../core/TempNode.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -export default class ExpressionNode extends TempNode { - snipped: string; /* sic */ - constructor(snipped?: string, nodeType?: string); -} - -export const expression: (snipped?: string, nodeType?: string) => ShaderNodeObject; diff --git a/src-testing/src/nodes/code/FunctionCallNode.d.ts b/src-testing/src/nodes/code/FunctionCallNode.d.ts deleted file mode 100644 index 7bf6d7360..000000000 --- a/src-testing/src/nodes/code/FunctionCallNode.d.ts +++ /dev/null @@ -1,25 +0,0 @@ -import Node from "../core/Node.js"; -import TempNode from "../core/TempNode.js"; -import { ProxiedObject, ShaderNodeObject } from "../tsl/TSLCore.js"; -import FunctionNode, { FunctionNodeArguments } from "./FunctionNode.js"; - -export default class FunctionCallNode

extends TempNode { - functionNode: FunctionNode

; - parameters: { [name: string]: Node }; - - constructor(functionNode?: FunctionNode

, parameters?: P); - - setParameters(parameters: P): this; - getParameters(): P; -} - -export const call:

( - functionNode?: FunctionNode

, - parameters?: ProxiedObject

, -) => ShaderNodeObject>; - -declare module "../tsl/TSLCore.js" { - interface NodeElements { - call: typeof call; - } -} diff --git a/src-testing/src/nodes/code/FunctionNode.ts b/src-testing/src/nodes/code/FunctionNode.ts deleted file mode 100644 index 54d8a5c54..000000000 --- a/src-testing/src/nodes/code/FunctionNode.ts +++ /dev/null @@ -1,87 +0,0 @@ -import CodeNode from './CodeNode.js'; -import { nodeObject } from '../tsl/TSLBase.js'; - -class FunctionNode extends CodeNode { - static get type() { - return 'FunctionNode'; - } - - constructor(code = '', includes = [], language = '') { - super(code, includes, language); - } - - getNodeType(builder) { - return this.getNodeFunction(builder).type; - } - - getInputs(builder) { - return this.getNodeFunction(builder).inputs; - } - - getNodeFunction(builder) { - const nodeData = builder.getDataFromNode(this); - - let nodeFunction = nodeData.nodeFunction; - - if (nodeFunction === undefined) { - nodeFunction = builder.parser.parseFunction(this.code); - - nodeData.nodeFunction = nodeFunction; - } - - return nodeFunction; - } - - generate(builder, output) { - super.generate(builder); - - const nodeFunction = this.getNodeFunction(builder); - - const name = nodeFunction.name; - const type = nodeFunction.type; - - const nodeCode = builder.getCodeFromNode(this, type); - - if (name !== '') { - // use a custom property name - - nodeCode.name = name; - } - - const propertyName = builder.getPropertyName(nodeCode); - - const code = this.getNodeFunction(builder).getCode(propertyName); - - nodeCode.code = code + '\n'; - - if (output === 'property') { - return propertyName; - } else { - return builder.format(`${propertyName}()`, type, output); - } - } -} - -export default FunctionNode; - -const nativeFn = (code, includes = [], language = '') => { - for (let i = 0; i < includes.length; i++) { - const include = includes[i]; - - // TSL Function: glslFn, wgslFn - - if (typeof include === 'function') { - includes[i] = include.functionNode; - } - } - - const functionNode = nodeObject(new FunctionNode(code, includes, language)); - - const fn = (...params) => functionNode.call(...params); - fn.functionNode = functionNode; - - return fn; -}; - -export const glslFn = (code, includes) => nativeFn(code, includes, 'glsl'); -export const wgslFn = (code, includes) => nativeFn(code, includes, 'wgsl'); diff --git a/src-testing/src/nodes/code/ScriptableNode.d.ts b/src-testing/src/nodes/code/ScriptableNode.d.ts deleted file mode 100644 index 7922afe12..000000000 --- a/src-testing/src/nodes/code/ScriptableNode.d.ts +++ /dev/null @@ -1,22 +0,0 @@ -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -declare class Resources extends Map { - get(key: string, callback?: ((...args: TArgs) => void) | null, ...params: TArgs): unknown; -} - -export const global: Resources; - -declare class ScriptableNode extends Node { - codeNode: Node | null; - parameters: Record; - - constructor(codeNode?: Node | null, parameters?: Record); -} - -export default ScriptableNode; - -export const scriptable: ( - codeNode?: NodeRepresentation | null, - parameters?: Record, -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/code/ScriptableValueNode.d.ts b/src-testing/src/nodes/code/ScriptableValueNode.d.ts deleted file mode 100644 index eccec90c6..000000000 --- a/src-testing/src/nodes/code/ScriptableValueNode.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import Node from "../core/Node.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -declare class ScriptableValueNode extends Node { - constructor(value: unknown); -} - -export default ScriptableValueNode; - -export const scriptableValue: (value?: unknown) => ShaderNodeObject; diff --git a/src-testing/src/nodes/core/AssignNode.d.ts b/src-testing/src/nodes/core/AssignNode.d.ts deleted file mode 100644 index a5628e76c..000000000 --- a/src-testing/src/nodes/core/AssignNode.d.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; -import Node from "./Node.js"; -import NodeBuilder from "./NodeBuilder.js"; -import TempNode from "./TempNode.js"; - -export default class AssignNode extends TempNode { - constructor(targetNode: Node, sourceNode: Node); - - needsSplitAssign(builder: NodeBuilder): boolean; -} - -export const assign: (targetNode: NodeRepresentation, sourceNode: NodeRepresentation) => ShaderNodeObject; - -declare module "../tsl/TSLCore.js" { - interface NodeElements { - assign: typeof assign; - } -} diff --git a/src-testing/src/nodes/core/AttributeNode.d.ts b/src-testing/src/nodes/core/AttributeNode.d.ts deleted file mode 100644 index 179f07b74..000000000 --- a/src-testing/src/nodes/core/AttributeNode.d.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; -import Node from "./Node.js"; -import NodeBuilder from "./NodeBuilder.js"; - -export default class AttributeNode extends Node { - constructor(attributeName: string, nodeType?: string | null); - - setAttributeName(attributeName: string): this; - - getAttributeName(builder: NodeBuilder): string; -} - -export const attribute: ( - name: string, - nodeType?: string | null, -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/core/BypassNode.d.ts b/src-testing/src/nodes/core/BypassNode.d.ts deleted file mode 100644 index 5d152654d..000000000 --- a/src-testing/src/nodes/core/BypassNode.d.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; -import Node from "./Node.js"; - -export default class BypassNode extends Node { - isBypassNode: true; - outputNode: Node; - callNode: Node; - - constructor(returnNode: Node, callNode: Node); -} - -export const bypass: (returnNode: NodeRepresentation, callNode: NodeRepresentation) => ShaderNodeObject; - -declare module "../tsl/TSLCore.js" { - interface NodeElements { - bypass: typeof bypass; - } -} diff --git a/src-testing/src/nodes/core/CacheNode.d.ts b/src-testing/src/nodes/core/CacheNode.d.ts deleted file mode 100644 index 4b7f173d1..000000000 --- a/src-testing/src/nodes/core/CacheNode.d.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { ShaderNodeObject } from "../tsl/TSLCore.js"; -import Node from "./Node.js"; -import NodeCache from "./NodeCache.js"; - -export default class CacheNode extends Node { - node: Node; - parent: boolean; - - readonly isCacheNode: true; - - constructor(node: Node, parent?: boolean); -} - -export const cache: (node: Node, cache?: NodeCache) => ShaderNodeObject; - -declare module "../tsl/TSLCore.js" { - interface NodeElements { - cache: typeof cache; - } -} diff --git a/src-testing/src/nodes/core/ConstNode.d.ts b/src-testing/src/nodes/core/ConstNode.d.ts deleted file mode 100644 index f866b0c0c..000000000 --- a/src-testing/src/nodes/core/ConstNode.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import InputNode from "./InputNode.js"; -import NodeBuilder from "./NodeBuilder.js"; - -export default class ConstNode extends InputNode { - isConstNode: true; - constructor(value: Value, nodeType?: string | null); - - generateConst(builder: NodeBuilder): string; -} diff --git a/src-testing/src/nodes/core/ContextNode.ts b/src-testing/src/nodes/core/ContextNode.ts deleted file mode 100644 index 32b8ac0af..000000000 --- a/src-testing/src/nodes/core/ContextNode.ts +++ /dev/null @@ -1,61 +0,0 @@ -import Node from './Node.js'; -import { addMethodChaining, nodeProxy } from '../tsl/TSLCore.js'; - -class ContextNode extends Node { - static get type() { - return 'ContextNode'; - } - - constructor(node, value = {}) { - super(); - - this.isContextNode = true; - - this.node = node; - this.value = value; - } - - getScope() { - return this.node.getScope(); - } - - getNodeType(builder) { - return this.node.getNodeType(builder); - } - - analyze(builder) { - this.node.build(builder); - } - - setup(builder) { - const previousContext = builder.getContext(); - - builder.setContext({ ...builder.context, ...this.value }); - - const node = this.node.build(builder); - - builder.setContext(previousContext); - - return node; - } - - generate(builder, output) { - const previousContext = builder.getContext(); - - builder.setContext({ ...builder.context, ...this.value }); - - const snippet = this.node.build(builder, output); - - builder.setContext(previousContext); - - return snippet; - } -} - -export default ContextNode; - -export const context = /*@__PURE__*/ nodeProxy(ContextNode); -export const label = (node, name) => context(node, { label: name }); - -addMethodChaining('context', context); -addMethodChaining('label', label); diff --git a/src-testing/src/nodes/core/IndexNode.d.ts b/src-testing/src/nodes/core/IndexNode.d.ts deleted file mode 100644 index ebaba50ae..000000000 --- a/src-testing/src/nodes/core/IndexNode.d.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { ShaderNodeObject } from "../tsl/TSLCore.js"; -import Node from "./Node.js"; - -export type IndexNodeScope = - | typeof IndexNode.VERTEX - | typeof IndexNode.INSTANCE - | typeof IndexNode.INVOCATION_LOCAL - | typeof IndexNode.DRAW; - -declare class IndexNode extends Node { - scope: IndexNodeScope; - - readonly isInstanceNode: true; - - constructor(scope: IndexNodeScope); - - static VERTEX: "vertex"; - static INSTANCE: "instance"; - static INVOCATION_LOCAL: "invocationLocal"; - static DRAW: "draw"; -} - -export default IndexNode; - -export const vertexIndex: ShaderNodeObject; -export const instanceIndex: ShaderNodeObject; -export const invocationLocalIndex: ShaderNodeObject; -export const drawIndex: ShaderNodeObject; diff --git a/src-testing/src/nodes/core/InputNode.ts b/src-testing/src/nodes/core/InputNode.ts deleted file mode 100644 index 07af45dc3..000000000 --- a/src-testing/src/nodes/core/InputNode.ts +++ /dev/null @@ -1,67 +0,0 @@ -import Node from './Node.js'; -import { getValueType, getValueFromType, arrayBufferToBase64 } from './NodeUtils.js'; - -class InputNode extends Node { - static get type() { - return 'InputNode'; - } - - constructor(value, nodeType = null) { - super(nodeType); - - this.isInputNode = true; - - this.value = value; - this.precision = null; - } - - getNodeType(/*builder*/) { - if (this.nodeType === null) { - return getValueType(this.value); - } - - return this.nodeType; - } - - getInputType(builder) { - return this.getNodeType(builder); - } - - setPrecision(precision) { - this.precision = precision; - - return this; - } - - serialize(data) { - super.serialize(data); - - data.value = this.value; - - if (this.value && this.value.toArray) data.value = this.value.toArray(); - - data.valueType = getValueType(this.value); - data.nodeType = this.nodeType; - - if (data.valueType === 'ArrayBuffer') data.value = arrayBufferToBase64(data.value); - - data.precision = this.precision; - } - - deserialize(data) { - super.deserialize(data); - - this.nodeType = data.nodeType; - this.value = Array.isArray(data.value) ? getValueFromType(data.valueType, ...data.value) : data.value; - - this.precision = data.precision || null; - - if (this.value && this.value.fromArray) this.value = this.value.fromArray(data.value); - } - - generate(/*builder, output*/) { - console.warn('Abstract function.'); - } -} - -export default InputNode; diff --git a/src-testing/src/nodes/core/LightingModel.d.ts b/src-testing/src/nodes/core/LightingModel.d.ts deleted file mode 100644 index f64dd07db..000000000 --- a/src-testing/src/nodes/core/LightingModel.d.ts +++ /dev/null @@ -1,46 +0,0 @@ -import Node from "./Node.js"; -import NodeBuilder from "./NodeBuilder.js"; -import StackNode from "./StackNode.js"; - -export interface LightingModelReflectedLight { - directDiffuse: Node; - directSpecular: Node; - indirectDiffuse: Node; - indirectSpecular: Node; -} - -export interface LightingModelDirectInput { - lightDirection: Node; - lightColor: Node; - reflectedLight: LightingModelReflectedLight; -} - -export interface LightingModelDirectRectAreaInput { - lightColor: Node; - lightPosition: Node; - halfWidth: Node; - halfHeight: Node; - reflectedLight: LightingModelReflectedLight; - ltc_1: Node; - ltc_2: Node; -} - -export interface LightingModelIndirectInput { - radiance: Node; - irradiance: Node; - iblIrradiance: Node; - ambientOcclusion: Node; - reflectedLight: LightingModelReflectedLight; - backdrop: Node; - backdropAlpha: Node; - outgoingLight: Node; -} - -export default class LightingModel { - start(input: LightingModelIndirectInput, stack: StackNode, builder: NodeBuilder): void; - finish(input: LightingModelIndirectInput, stack: StackNode, builder: NodeBuilder): void; - direct(input: LightingModelDirectInput, stack: StackNode, builder: NodeBuilder): void; - directRectArea(input: LightingModelDirectRectAreaInput, stack: StackNode, builder: NodeBuilder): void; - indirect(input: LightingModelIndirectInput, stack: StackNode, builder: NodeBuilder): void; - ambientOcclusion(input: LightingModelIndirectInput, stack: StackNode, builder: NodeBuilder): void; -} diff --git a/src-testing/src/nodes/core/MRTNode.d.ts b/src-testing/src/nodes/core/MRTNode.d.ts deleted file mode 100644 index ef223da73..000000000 --- a/src-testing/src/nodes/core/MRTNode.d.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { Texture } from "../../textures/Texture.js"; -import { Node } from "../Nodes.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; -import OutputStructNode from "./OutputStructNode.js"; - -export function getTextureIndex(textures: ReadonlyArray, name: string): number; - -declare class MRTNode extends OutputStructNode { - outputNodes: { [name: string]: Node }; - - readonly isMRTNode: true; - - constructor(outputNodes: { [name: string]: Node }); - - has(name: string): boolean; - - get(name: string): Node; - - merge(mrtNode: MRTNode): ShaderNodeObject; -} - -export default MRTNode; - -export const mrt: (outputNodes: { [name: string]: Node }) => ShaderNodeObject; diff --git a/src-testing/src/nodes/core/Node.ts b/src-testing/src/nodes/core/Node.ts deleted file mode 100644 index 2e54fce07..000000000 --- a/src-testing/src/nodes/core/Node.ts +++ /dev/null @@ -1,401 +0,0 @@ -import { NodeUpdateType } from './constants.js'; -import { getNodeChildren, getCacheKey } from './NodeUtils.js'; - -import { EventDispatcher } from '../../core/EventDispatcher.js'; -import { MathUtils } from '../../math/MathUtils.js'; - -let _nodeId = 0; - -class Node extends EventDispatcher { - static get type() { - return 'Node'; - } - - constructor(nodeType = null) { - super(); - - this.nodeType = nodeType; - - this.updateType = NodeUpdateType.NONE; - this.updateBeforeType = NodeUpdateType.NONE; - this.updateAfterType = NodeUpdateType.NONE; - - this.uuid = MathUtils.generateUUID(); - - this.version = 0; - - this._cacheKey = null; - this._cacheKeyVersion = 0; - - this.global = false; - - this.isNode = true; - - Object.defineProperty(this, 'id', { value: _nodeId++ }); - } - - set needsUpdate(value) { - if (value === true) { - this.version++; - } - } - - get type() { - return this.constructor.type; - } - - onUpdate(callback, updateType) { - this.updateType = updateType; - this.update = callback.bind(this.getSelf()); - - return this; - } - - onFrameUpdate(callback) { - return this.onUpdate(callback, NodeUpdateType.FRAME); - } - - onRenderUpdate(callback) { - return this.onUpdate(callback, NodeUpdateType.RENDER); - } - - onObjectUpdate(callback) { - return this.onUpdate(callback, NodeUpdateType.OBJECT); - } - - onReference(callback) { - this.updateReference = callback.bind(this.getSelf()); - - return this; - } - - getSelf() { - // Returns non-node object. - - return this.self || this; - } - - updateReference(/*state*/) { - return this; - } - - isGlobal(/*builder*/) { - return this.global; - } - - *getChildren() { - for (const { childNode } of getNodeChildren(this)) { - yield childNode; - } - } - - dispose() { - this.dispatchEvent({ type: 'dispose' }); - } - - traverse(callback) { - callback(this); - - for (const childNode of this.getChildren()) { - childNode.traverse(callback); - } - } - - getCacheKey(force = false) { - force = force || this.version !== this._cacheKeyVersion; - - if (force === true || this._cacheKey === null) { - this._cacheKey = getCacheKey(this, force); - this._cacheKeyVersion = this.version; - } - - return this._cacheKey; - } - - getScope() { - return this; - } - - getHash(/*builder*/) { - return this.uuid; - } - - getUpdateType() { - return this.updateType; - } - - getUpdateBeforeType() { - return this.updateBeforeType; - } - - getUpdateAfterType() { - return this.updateAfterType; - } - - getElementType(builder) { - const type = this.getNodeType(builder); - const elementType = builder.getElementType(type); - - return elementType; - } - - getNodeType(builder) { - const nodeProperties = builder.getNodeProperties(this); - - if (nodeProperties.outputNode) { - return nodeProperties.outputNode.getNodeType(builder); - } - - return this.nodeType; - } - - getShared(builder) { - const hash = this.getHash(builder); - const nodeFromHash = builder.getNodeFromHash(hash); - - return nodeFromHash || this; - } - - setup(builder) { - const nodeProperties = builder.getNodeProperties(this); - - let index = 0; - - for (const childNode of this.getChildren()) { - nodeProperties['node' + index++] = childNode; - } - - // return a outputNode if exists - return null; - } - - analyze(builder) { - const usageCount = builder.increaseUsage(this); - - if (usageCount === 1) { - // node flow children - - const nodeProperties = builder.getNodeProperties(this); - - for (const childNode of Object.values(nodeProperties)) { - if (childNode && childNode.isNode === true) { - childNode.build(builder); - } - } - } - } - - generate(builder, output) { - const { outputNode } = builder.getNodeProperties(this); - - if (outputNode && outputNode.isNode === true) { - return outputNode.build(builder, output); - } - } - - updateBefore(/*frame*/) { - console.warn('Abstract function.'); - } - - updateAfter(/*frame*/) { - console.warn('Abstract function.'); - } - - update(/*frame*/) { - console.warn('Abstract function.'); - } - - build(builder, output = null) { - const refNode = this.getShared(builder); - - if (this !== refNode) { - return refNode.build(builder, output); - } - - builder.addNode(this); - builder.addChain(this); - - /* Build stages expected results: - - "setup" -> Node - - "analyze" -> null - - "generate" -> String - */ - let result = null; - - const buildStage = builder.getBuildStage(); - - if (buildStage === 'setup') { - this.updateReference(builder); - - const properties = builder.getNodeProperties(this); - - if (properties.initialized !== true) { - const stackNodesBeforeSetup = builder.stack.nodes.length; - - properties.initialized = true; - properties.outputNode = this.setup(builder); - - if (properties.outputNode !== null && builder.stack.nodes.length !== stackNodesBeforeSetup) { - // !! no outputNode !! - //properties.outputNode = builder.stack; - } - - for (const childNode of Object.values(properties)) { - if (childNode && childNode.isNode === true) { - childNode.build(builder); - } - } - } - } else if (buildStage === 'analyze') { - this.analyze(builder); - } else if (buildStage === 'generate') { - const isGenerateOnce = this.generate.length === 1; - - if (isGenerateOnce) { - const type = this.getNodeType(builder); - const nodeData = builder.getDataFromNode(this); - - result = nodeData.snippet; - - if (result === undefined) { - result = this.generate(builder) || ''; - - nodeData.snippet = result; - } else if (nodeData.flowCodes !== undefined && builder.context.nodeBlock !== undefined) { - builder.addFlowCodeHierarchy(this, builder.context.nodeBlock); - } - - result = builder.format(result, type, output); - } else { - result = this.generate(builder, output) || ''; - } - } - - builder.removeChain(this); - builder.addSequentialNode(this); - - return result; - } - - getSerializeChildren() { - return getNodeChildren(this); - } - - serialize(json) { - const nodeChildren = this.getSerializeChildren(); - - const inputNodes = {}; - - for (const { property, index, childNode } of nodeChildren) { - if (index !== undefined) { - if (inputNodes[property] === undefined) { - inputNodes[property] = Number.isInteger(index) ? [] : {}; - } - - inputNodes[property][index] = childNode.toJSON(json.meta).uuid; - } else { - inputNodes[property] = childNode.toJSON(json.meta).uuid; - } - } - - if (Object.keys(inputNodes).length > 0) { - json.inputNodes = inputNodes; - } - } - - deserialize(json) { - if (json.inputNodes !== undefined) { - const nodes = json.meta.nodes; - - for (const property in json.inputNodes) { - if (Array.isArray(json.inputNodes[property])) { - const inputArray = []; - - for (const uuid of json.inputNodes[property]) { - inputArray.push(nodes[uuid]); - } - - this[property] = inputArray; - } else if (typeof json.inputNodes[property] === 'object') { - const inputObject = {}; - - for (const subProperty in json.inputNodes[property]) { - const uuid = json.inputNodes[property][subProperty]; - - inputObject[subProperty] = nodes[uuid]; - } - - this[property] = inputObject; - } else { - const uuid = json.inputNodes[property]; - - this[property] = nodes[uuid]; - } - } - } - } - - toJSON(meta) { - const { uuid, type } = this; - const isRoot = meta === undefined || typeof meta === 'string'; - - if (isRoot) { - meta = { - textures: {}, - images: {}, - nodes: {}, - }; - } - - // serialize - - let data = meta.nodes[uuid]; - - if (data === undefined) { - data = { - uuid, - type, - meta, - metadata: { - version: 4.6, - type: 'Node', - generator: 'Node.toJSON', - }, - }; - - if (isRoot !== true) meta.nodes[data.uuid] = data; - - this.serialize(data); - - delete data.meta; - } - - // TODO: Copied from Object3D.toJSON - - function extractFromCache(cache) { - const values = []; - - for (const key in cache) { - const data = cache[key]; - delete data.metadata; - values.push(data); - } - - return values; - } - - if (isRoot) { - const textures = extractFromCache(meta.textures); - const images = extractFromCache(meta.images); - const nodes = extractFromCache(meta.nodes); - - if (textures.length > 0) data.textures = textures; - if (images.length > 0) data.images = images; - if (nodes.length > 0) data.nodes = nodes; - } - - return data; - } -} - -export default Node; diff --git a/src-testing/src/nodes/core/NodeAttribute.ts b/src-testing/src/nodes/core/NodeAttribute.ts deleted file mode 100644 index 190fe8c51..000000000 --- a/src-testing/src/nodes/core/NodeAttribute.ts +++ /dev/null @@ -1,11 +0,0 @@ -class NodeAttribute { - constructor(name, type, node = null) { - this.isNodeAttribute = true; - - this.name = name; - this.type = type; - this.node = node; - } -} - -export default NodeAttribute; diff --git a/src-testing/src/nodes/core/NodeBuilder.ts b/src-testing/src/nodes/core/NodeBuilder.ts deleted file mode 100644 index 3003d1680..000000000 --- a/src-testing/src/nodes/core/NodeBuilder.ts +++ /dev/null @@ -1,1208 +0,0 @@ -import NodeUniform from './NodeUniform.js'; -import NodeAttribute from './NodeAttribute.js'; -import NodeVarying from './NodeVarying.js'; -import NodeVar from './NodeVar.js'; -import NodeCode from './NodeCode.js'; -import NodeCache from './NodeCache.js'; -import ParameterNode from './ParameterNode.js'; -import FunctionNode from '../code/FunctionNode.js'; -import NodeMaterial from '../../materials/nodes/NodeMaterial.js'; -import { NodeUpdateType, defaultBuildStages, shaderStages } from './constants.js'; - -import { - NumberNodeUniform, - Vector2NodeUniform, - Vector3NodeUniform, - Vector4NodeUniform, - ColorNodeUniform, - Matrix3NodeUniform, - Matrix4NodeUniform, -} from '../../renderers/common/nodes/NodeUniform.js'; - -import { stack } from './StackNode.js'; -import { getCurrentStack, setCurrentStack } from '../tsl/TSLBase.js'; - -import CubeRenderTarget from '../../renderers/common/CubeRenderTarget.js'; -import ChainMap from '../../renderers/common/ChainMap.js'; - -import PMREMGenerator from '../../renderers/common/extras/PMREMGenerator.js'; - -import BindGroup from '../../renderers/common/BindGroup.js'; - -import { REVISION } from '../../constants.js'; -import { RenderTarget } from '../../core/RenderTarget.js'; -import { Color } from '../../math/Color.js'; -import { Vector2 } from '../../math/Vector2.js'; -import { Vector3 } from '../../math/Vector3.js'; -import { Vector4 } from '../../math/Vector4.js'; -import { Float16BufferAttribute } from '../../core/BufferAttribute.js'; -import { - IntType, - UnsignedIntType, - LinearFilter, - LinearMipmapNearestFilter, - NearestMipmapLinearFilter, - LinearMipmapLinearFilter, -} from '../../constants.js'; - -const rendererCache = new WeakMap(); - -const typeFromLength = new Map([ - [2, 'vec2'], - [3, 'vec3'], - [4, 'vec4'], - [9, 'mat3'], - [16, 'mat4'], -]); - -const typeFromArray = new Map([ - [Int8Array, 'int'], - [Int16Array, 'int'], - [Int32Array, 'int'], - [Uint8Array, 'uint'], - [Uint16Array, 'uint'], - [Uint32Array, 'uint'], - [Float32Array, 'float'], -]); - -const toFloat = value => { - if (/e/g.test(value)) { - return String(value).replace(/\+/g, ''); - } else { - value = Number(value); - - return value + (value % 1 ? '' : '.0'); - } -}; - -class NodeBuilder { - constructor(object, renderer, parser) { - this.object = object; - this.material = (object && object.material) || null; - this.geometry = (object && object.geometry) || null; - this.renderer = renderer; - this.parser = parser; - this.scene = null; - this.camera = null; - - this.nodes = []; - this.sequentialNodes = []; - this.updateNodes = []; - this.updateBeforeNodes = []; - this.updateAfterNodes = []; - this.hashNodes = {}; - - this.monitor = null; - - this.lightsNode = null; - this.environmentNode = null; - this.fogNode = null; - - this.clippingContext = null; - - this.vertexShader = null; - this.fragmentShader = null; - this.computeShader = null; - - this.flowNodes = { vertex: [], fragment: [], compute: [] }; - this.flowCode = { vertex: '', fragment: '', compute: '' }; - this.uniforms = { vertex: [], fragment: [], compute: [], index: 0 }; - this.structs = { vertex: [], fragment: [], compute: [], index: 0 }; - this.bindings = { vertex: {}, fragment: {}, compute: {} }; - this.bindingsIndexes = {}; - this.bindGroups = null; - this.attributes = []; - this.bufferAttributes = []; - this.varyings = []; - this.codes = {}; - this.vars = {}; - this.flow = { code: '' }; - this.chaining = []; - this.stack = stack(); - this.stacks = []; - this.tab = '\t'; - - this.currentFunctionNode = null; - - this.context = { - material: this.material, - }; - - this.cache = new NodeCache(); - this.globalCache = this.cache; - - this.flowsData = new WeakMap(); - - this.shaderStage = null; - this.buildStage = null; - - this.useComparisonMethod = false; - } - - getBindGroupsCache() { - let bindGroupsCache = rendererCache.get(this.renderer); - - if (bindGroupsCache === undefined) { - bindGroupsCache = new ChainMap(); - - rendererCache.set(this.renderer, bindGroupsCache); - } - - return bindGroupsCache; - } - - createRenderTarget(width, height, options) { - return new RenderTarget(width, height, options); - } - - createCubeRenderTarget(size, options) { - return new CubeRenderTarget(size, options); - } - - createPMREMGenerator() { - // TODO: Move Materials.js to outside of the Nodes.js in order to remove this function and improve tree-shaking support - - return new PMREMGenerator(this.renderer); - } - - includes(node) { - return this.nodes.includes(node); - } - - _getBindGroup(groupName, bindings) { - const bindGroupsCache = this.getBindGroupsCache(); - - // - - const bindingsArray = []; - - let sharedGroup = true; - - for (const binding of bindings) { - bindingsArray.push(binding); - - sharedGroup = sharedGroup && binding.groupNode.shared !== true; - } - - // - - let bindGroup; - - if (sharedGroup) { - bindGroup = bindGroupsCache.get(bindingsArray); - - if (bindGroup === undefined) { - bindGroup = new BindGroup( - groupName, - bindingsArray, - this.bindingsIndexes[groupName].group, - bindingsArray, - ); - - bindGroupsCache.set(bindingsArray, bindGroup); - } - } else { - bindGroup = new BindGroup(groupName, bindingsArray, this.bindingsIndexes[groupName].group, bindingsArray); - } - - return bindGroup; - } - - getBindGroupArray(groupName, shaderStage) { - const bindings = this.bindings[shaderStage]; - - let bindGroup = bindings[groupName]; - - if (bindGroup === undefined) { - if (this.bindingsIndexes[groupName] === undefined) { - this.bindingsIndexes[groupName] = { binding: 0, group: Object.keys(this.bindingsIndexes).length }; - } - - bindings[groupName] = bindGroup = []; - } - - return bindGroup; - } - - getBindings() { - let bindingsGroups = this.bindGroups; - - if (bindingsGroups === null) { - const groups = {}; - const bindings = this.bindings; - - for (const shaderStage of shaderStages) { - for (const groupName in bindings[shaderStage]) { - const uniforms = bindings[shaderStage][groupName]; - - const groupUniforms = groups[groupName] || (groups[groupName] = []); - groupUniforms.push(...uniforms); - } - } - - bindingsGroups = []; - - for (const groupName in groups) { - const group = groups[groupName]; - - const bindingsGroup = this._getBindGroup(groupName, group); - - bindingsGroups.push(bindingsGroup); - } - - this.bindGroups = bindingsGroups; - } - - return bindingsGroups; - } - - sortBindingGroups() { - const bindingsGroups = this.getBindings(); - - bindingsGroups.sort((a, b) => a.bindings[0].groupNode.order - b.bindings[0].groupNode.order); - - for (let i = 0; i < bindingsGroups.length; i++) { - const bindingGroup = bindingsGroups[i]; - this.bindingsIndexes[bindingGroup.name].group = i; - - bindingGroup.index = i; - } - } - - setHashNode(node, hash) { - this.hashNodes[hash] = node; - } - - addNode(node) { - if (this.nodes.includes(node) === false) { - this.nodes.push(node); - - this.setHashNode(node, node.getHash(this)); - } - } - - addSequentialNode(node) { - if (this.sequentialNodes.includes(node) === false) { - this.sequentialNodes.push(node); - } - } - - buildUpdateNodes() { - for (const node of this.nodes) { - const updateType = node.getUpdateType(); - - if (updateType !== NodeUpdateType.NONE) { - this.updateNodes.push(node.getSelf()); - } - } - - for (const node of this.sequentialNodes) { - const updateBeforeType = node.getUpdateBeforeType(); - const updateAfterType = node.getUpdateAfterType(); - - if (updateBeforeType !== NodeUpdateType.NONE) { - this.updateBeforeNodes.push(node.getSelf()); - } - - if (updateAfterType !== NodeUpdateType.NONE) { - this.updateAfterNodes.push(node.getSelf()); - } - } - } - - get currentNode() { - return this.chaining[this.chaining.length - 1]; - } - - isFilteredTexture(texture) { - return ( - texture.magFilter === LinearFilter || - texture.magFilter === LinearMipmapNearestFilter || - texture.magFilter === NearestMipmapLinearFilter || - texture.magFilter === LinearMipmapLinearFilter || - texture.minFilter === LinearFilter || - texture.minFilter === LinearMipmapNearestFilter || - texture.minFilter === NearestMipmapLinearFilter || - texture.minFilter === LinearMipmapLinearFilter - ); - } - - addChain(node) { - /* - if ( this.chaining.indexOf( node ) !== - 1 ) { - - console.warn( 'Recursive node: ', node ); - - } - */ - - this.chaining.push(node); - } - - removeChain(node) { - const lastChain = this.chaining.pop(); - - if (lastChain !== node) { - throw new Error('NodeBuilder: Invalid node chaining!'); - } - } - - getMethod(method) { - return method; - } - - getNodeFromHash(hash) { - return this.hashNodes[hash]; - } - - addFlow(shaderStage, node) { - this.flowNodes[shaderStage].push(node); - - return node; - } - - setContext(context) { - this.context = context; - } - - getContext() { - return this.context; - } - - getSharedContext() { - const context = { ...this.context }; - - delete context.material; - - return this.context; - } - - setCache(cache) { - this.cache = cache; - } - - getCache() { - return this.cache; - } - - getCacheFromNode(node, parent = true) { - const data = this.getDataFromNode(node); - if (data.cache === undefined) data.cache = new NodeCache(parent ? this.getCache() : null); - - return data.cache; - } - - isAvailable(/*name*/) { - return false; - } - - getVertexIndex() { - console.warn('Abstract function.'); - } - - getInstanceIndex() { - console.warn('Abstract function.'); - } - - getDrawIndex() { - console.warn('Abstract function.'); - } - - getFrontFacing() { - console.warn('Abstract function.'); - } - - getFragCoord() { - console.warn('Abstract function.'); - } - - isFlipY() { - return false; - } - - increaseUsage(node) { - const nodeData = this.getDataFromNode(node); - nodeData.usageCount = nodeData.usageCount === undefined ? 1 : nodeData.usageCount + 1; - - return nodeData.usageCount; - } - - generateTexture(/* texture, textureProperty, uvSnippet */) { - console.warn('Abstract function.'); - } - - generateTextureLod(/* texture, textureProperty, uvSnippet, levelSnippet */) { - console.warn('Abstract function.'); - } - - generateConst(type, value = null) { - if (value === null) { - if (type === 'float' || type === 'int' || type === 'uint') value = 0; - else if (type === 'bool') value = false; - else if (type === 'color') value = new Color(); - else if (type === 'vec2') value = new Vector2(); - else if (type === 'vec3') value = new Vector3(); - else if (type === 'vec4') value = new Vector4(); - } - - if (type === 'float') return toFloat(value); - if (type === 'int') return `${Math.round(value)}`; - if (type === 'uint') return value >= 0 ? `${Math.round(value)}u` : '0u'; - if (type === 'bool') return value ? 'true' : 'false'; - if (type === 'color') - return `${this.getType('vec3')}( ${toFloat(value.r)}, ${toFloat(value.g)}, ${toFloat(value.b)} )`; - - const typeLength = this.getTypeLength(type); - - const componentType = this.getComponentType(type); - - const generateConst = value => this.generateConst(componentType, value); - - if (typeLength === 2) { - return `${this.getType(type)}( ${generateConst(value.x)}, ${generateConst(value.y)} )`; - } else if (typeLength === 3) { - return `${this.getType(type)}( ${generateConst(value.x)}, ${generateConst(value.y)}, ${generateConst(value.z)} )`; - } else if (typeLength === 4) { - return `${this.getType(type)}( ${generateConst(value.x)}, ${generateConst(value.y)}, ${generateConst(value.z)}, ${generateConst(value.w)} )`; - } else if (typeLength > 4 && value && (value.isMatrix3 || value.isMatrix4)) { - return `${this.getType(type)}( ${value.elements.map(generateConst).join(', ')} )`; - } else if (typeLength > 4) { - return `${this.getType(type)}()`; - } - - throw new Error(`NodeBuilder: Type '${type}' not found in generate constant attempt.`); - } - - getType(type) { - if (type === 'color') return 'vec3'; - - return type; - } - - hasGeometryAttribute(name) { - return this.geometry && this.geometry.getAttribute(name) !== undefined; - } - - getAttribute(name, type) { - const attributes = this.attributes; - - // find attribute - - for (const attribute of attributes) { - if (attribute.name === name) { - return attribute; - } - } - - // create a new if no exist - - const attribute = new NodeAttribute(name, type); - - attributes.push(attribute); - - return attribute; - } - - getPropertyName(node /*, shaderStage*/) { - return node.name; - } - - isVector(type) { - return /vec\d/.test(type); - } - - isMatrix(type) { - return /mat\d/.test(type); - } - - isReference(type) { - return ( - type === 'void' || - type === 'property' || - type === 'sampler' || - type === 'texture' || - type === 'cubeTexture' || - type === 'storageTexture' || - type === 'depthTexture' || - type === 'texture3D' - ); - } - - needsToWorkingColorSpace(/*texture*/) { - return false; - } - - getComponentTypeFromTexture(texture) { - const type = texture.type; - - if (texture.isDataTexture) { - if (type === IntType) return 'int'; - if (type === UnsignedIntType) return 'uint'; - } - - return 'float'; - } - - getElementType(type) { - if (type === 'mat2') return 'vec2'; - if (type === 'mat3') return 'vec3'; - if (type === 'mat4') return 'vec4'; - - return this.getComponentType(type); - } - - getComponentType(type) { - type = this.getVectorType(type); - - if (type === 'float' || type === 'bool' || type === 'int' || type === 'uint') return type; - - const componentType = /(b|i|u|)(vec|mat)([2-4])/.exec(type); - - if (componentType === null) return null; - - if (componentType[1] === 'b') return 'bool'; - if (componentType[1] === 'i') return 'int'; - if (componentType[1] === 'u') return 'uint'; - - return 'float'; - } - - getVectorType(type) { - if (type === 'color') return 'vec3'; - if (type === 'texture' || type === 'cubeTexture' || type === 'storageTexture' || type === 'texture3D') - return 'vec4'; - - return type; - } - - getTypeFromLength(length, componentType = 'float') { - if (length === 1) return componentType; - - const baseType = typeFromLength.get(length); - const prefix = componentType === 'float' ? '' : componentType[0]; - - return prefix + baseType; - } - - getTypeFromArray(array) { - return typeFromArray.get(array.constructor); - } - - getTypeFromAttribute(attribute) { - let dataAttribute = attribute; - - if (attribute.isInterleavedBufferAttribute) dataAttribute = attribute.data; - - const array = dataAttribute.array; - const itemSize = attribute.itemSize; - const normalized = attribute.normalized; - - let arrayType; - - if (!(attribute instanceof Float16BufferAttribute) && normalized !== true) { - arrayType = this.getTypeFromArray(array); - } - - return this.getTypeFromLength(itemSize, arrayType); - } - - getTypeLength(type) { - const vecType = this.getVectorType(type); - const vecNum = /vec([2-4])/.exec(vecType); - - if (vecNum !== null) return Number(vecNum[1]); - if (vecType === 'float' || vecType === 'bool' || vecType === 'int' || vecType === 'uint') return 1; - if (/mat2/.test(type) === true) return 4; - if (/mat3/.test(type) === true) return 9; - if (/mat4/.test(type) === true) return 16; - - return 0; - } - - getVectorFromMatrix(type) { - return type.replace('mat', 'vec'); - } - - changeComponentType(type, newComponentType) { - return this.getTypeFromLength(this.getTypeLength(type), newComponentType); - } - - getIntegerType(type) { - const componentType = this.getComponentType(type); - - if (componentType === 'int' || componentType === 'uint') return type; - - return this.changeComponentType(type, 'int'); - } - - addStack() { - this.stack = stack(this.stack); - - this.stacks.push(getCurrentStack() || this.stack); - setCurrentStack(this.stack); - - return this.stack; - } - - removeStack() { - const lastStack = this.stack; - this.stack = lastStack.parent; - - setCurrentStack(this.stacks.pop()); - - return lastStack; - } - - getDataFromNode(node, shaderStage = this.shaderStage, cache = null) { - cache = cache === null ? (node.isGlobal(this) ? this.globalCache : this.cache) : cache; - - let nodeData = cache.getData(node); - - if (nodeData === undefined) { - nodeData = {}; - - cache.setData(node, nodeData); - } - - if (nodeData[shaderStage] === undefined) nodeData[shaderStage] = {}; - - return nodeData[shaderStage]; - } - - getNodeProperties(node, shaderStage = 'any') { - const nodeData = this.getDataFromNode(node, shaderStage); - - return nodeData.properties || (nodeData.properties = { outputNode: null }); - } - - getBufferAttributeFromNode(node, type) { - const nodeData = this.getDataFromNode(node); - - let bufferAttribute = nodeData.bufferAttribute; - - if (bufferAttribute === undefined) { - const index = this.uniforms.index++; - - bufferAttribute = new NodeAttribute('nodeAttribute' + index, type, node); - - this.bufferAttributes.push(bufferAttribute); - - nodeData.bufferAttribute = bufferAttribute; - } - - return bufferAttribute; - } - - getStructTypeFromNode(node, shaderStage = this.shaderStage) { - const nodeData = this.getDataFromNode(node, shaderStage); - - if (nodeData.structType === undefined) { - const index = this.structs.index++; - - node.name = `StructType${index}`; - this.structs[shaderStage].push(node); - - nodeData.structType = node; - } - - return node; - } - - getUniformFromNode(node, type, shaderStage = this.shaderStage, name = null) { - const nodeData = this.getDataFromNode(node, shaderStage, this.globalCache); - - let nodeUniform = nodeData.uniform; - - if (nodeUniform === undefined) { - const index = this.uniforms.index++; - - nodeUniform = new NodeUniform(name || 'nodeUniform' + index, type, node); - - this.uniforms[shaderStage].push(nodeUniform); - - nodeData.uniform = nodeUniform; - } - - return nodeUniform; - } - - getVarFromNode(node, name = null, type = node.getNodeType(this), shaderStage = this.shaderStage) { - const nodeData = this.getDataFromNode(node, shaderStage); - - let nodeVar = nodeData.variable; - - if (nodeVar === undefined) { - const vars = this.vars[shaderStage] || (this.vars[shaderStage] = []); - - if (name === null) name = 'nodeVar' + vars.length; - - nodeVar = new NodeVar(name, type); - - vars.push(nodeVar); - - nodeData.variable = nodeVar; - } - - return nodeVar; - } - - getVaryingFromNode(node, name = null, type = node.getNodeType(this)) { - const nodeData = this.getDataFromNode(node, 'any'); - - let nodeVarying = nodeData.varying; - - if (nodeVarying === undefined) { - const varyings = this.varyings; - const index = varyings.length; - - if (name === null) name = 'nodeVarying' + index; - - nodeVarying = new NodeVarying(name, type); - - varyings.push(nodeVarying); - - nodeData.varying = nodeVarying; - } - - return nodeVarying; - } - - getCodeFromNode(node, type, shaderStage = this.shaderStage) { - const nodeData = this.getDataFromNode(node); - - let nodeCode = nodeData.code; - - if (nodeCode === undefined) { - const codes = this.codes[shaderStage] || (this.codes[shaderStage] = []); - const index = codes.length; - - nodeCode = new NodeCode('nodeCode' + index, type); - - codes.push(nodeCode); - - nodeData.code = nodeCode; - } - - return nodeCode; - } - - addFlowCodeHierarchy(node, nodeBlock) { - const { flowCodes, flowCodeBlock } = this.getDataFromNode(node); - - let needsFlowCode = true; - let nodeBlockHierarchy = nodeBlock; - - while (nodeBlockHierarchy) { - if (flowCodeBlock.get(nodeBlockHierarchy) === true) { - needsFlowCode = false; - break; - } - - nodeBlockHierarchy = this.getDataFromNode(nodeBlockHierarchy).parentNodeBlock; - } - - if (needsFlowCode) { - for (const flowCode of flowCodes) { - this.addLineFlowCode(flowCode); - } - } - } - - addLineFlowCodeBlock(node, code, nodeBlock) { - const nodeData = this.getDataFromNode(node); - const flowCodes = nodeData.flowCodes || (nodeData.flowCodes = []); - const codeBlock = nodeData.flowCodeBlock || (nodeData.flowCodeBlock = new WeakMap()); - - flowCodes.push(code); - codeBlock.set(nodeBlock, true); - } - - addLineFlowCode(code, node = null) { - if (code === '') return this; - - if (node !== null && this.context.nodeBlock) { - this.addLineFlowCodeBlock(node, code, this.context.nodeBlock); - } - - code = this.tab + code; - - if (!/;\s*$/.test(code)) { - code = code + ';\n'; - } - - this.flow.code += code; - - return this; - } - - addFlowCode(code) { - this.flow.code += code; - - return this; - } - - addFlowTab() { - this.tab += '\t'; - - return this; - } - - removeFlowTab() { - this.tab = this.tab.slice(0, -1); - - return this; - } - - getFlowData(node /*, shaderStage*/) { - return this.flowsData.get(node); - } - - flowNode(node) { - const output = node.getNodeType(this); - - const flowData = this.flowChildNode(node, output); - - this.flowsData.set(node, flowData); - - return flowData; - } - - buildFunctionNode(shaderNode) { - const fn = new FunctionNode(); - - const previous = this.currentFunctionNode; - - this.currentFunctionNode = fn; - - fn.code = this.buildFunctionCode(shaderNode); - - this.currentFunctionNode = previous; - - return fn; - } - - flowShaderNode(shaderNode) { - const layout = shaderNode.layout; - - const inputs = { - [Symbol.iterator]() { - let index = 0; - const values = Object.values(this); - return { - next: () => ({ - value: values[index], - done: index++ >= values.length, - }), - }; - }, - }; - - for (const input of layout.inputs) { - inputs[input.name] = new ParameterNode(input.type, input.name); - } - - // - - shaderNode.layout = null; - - const callNode = shaderNode.call(inputs); - const flowData = this.flowStagesNode(callNode, layout.type); - - shaderNode.layout = layout; - - return flowData; - } - - flowStagesNode(node, output = null) { - const previousFlow = this.flow; - const previousVars = this.vars; - const previousCache = this.cache; - const previousBuildStage = this.buildStage; - const previousStack = this.stack; - - const flow = { - code: '', - }; - - this.flow = flow; - this.vars = {}; - this.cache = new NodeCache(); - this.stack = stack(); - - for (const buildStage of defaultBuildStages) { - this.setBuildStage(buildStage); - - flow.result = node.build(this, output); - } - - flow.vars = this.getVars(this.shaderStage); - - this.flow = previousFlow; - this.vars = previousVars; - this.cache = previousCache; - this.stack = previousStack; - - this.setBuildStage(previousBuildStage); - - return flow; - } - - getFunctionOperator() { - return null; - } - - flowChildNode(node, output = null) { - const previousFlow = this.flow; - - const flow = { - code: '', - }; - - this.flow = flow; - - flow.result = node.build(this, output); - - this.flow = previousFlow; - - return flow; - } - - flowNodeFromShaderStage(shaderStage, node, output = null, propertyName = null) { - const previousShaderStage = this.shaderStage; - - this.setShaderStage(shaderStage); - - const flowData = this.flowChildNode(node, output); - - if (propertyName !== null) { - flowData.code += `${this.tab + propertyName} = ${flowData.result};\n`; - } - - this.flowCode[shaderStage] = this.flowCode[shaderStage] + flowData.code; - - this.setShaderStage(previousShaderStage); - - return flowData; - } - - getAttributesArray() { - return this.attributes.concat(this.bufferAttributes); - } - - getAttributes(/*shaderStage*/) { - console.warn('Abstract function.'); - } - - getVaryings(/*shaderStage*/) { - console.warn('Abstract function.'); - } - - getVar(type, name) { - return `${this.getType(type)} ${name}`; - } - - getVars(shaderStage) { - let snippet = ''; - - const vars = this.vars[shaderStage]; - - if (vars !== undefined) { - for (const variable of vars) { - snippet += `${this.getVar(variable.type, variable.name)}; `; - } - } - - return snippet; - } - - getUniforms(/*shaderStage*/) { - console.warn('Abstract function.'); - } - - getCodes(shaderStage) { - const codes = this.codes[shaderStage]; - - let code = ''; - - if (codes !== undefined) { - for (const nodeCode of codes) { - code += nodeCode.code + '\n'; - } - } - - return code; - } - - getHash() { - return this.vertexShader + this.fragmentShader + this.computeShader; - } - - setShaderStage(shaderStage) { - this.shaderStage = shaderStage; - } - - getShaderStage() { - return this.shaderStage; - } - - setBuildStage(buildStage) { - this.buildStage = buildStage; - } - - getBuildStage() { - return this.buildStage; - } - - buildCode() { - console.warn('Abstract function.'); - } - - build() { - const { object, material, renderer } = this; - - if (material !== null) { - let nodeMaterial = renderer.library.fromMaterial(material); - - if (nodeMaterial === null) { - console.error(`NodeMaterial: Material "${material.type}" is not compatible.`); - - nodeMaterial = new NodeMaterial(); - } - - nodeMaterial.build(this); - } else { - this.addFlow('compute', object); - } - - // setup() -> stage 1: create possible new nodes and returns an output reference node - // analyze() -> stage 2: analyze nodes to possible optimization and validation - // generate() -> stage 3: generate shader - - for (const buildStage of defaultBuildStages) { - this.setBuildStage(buildStage); - - if (this.context.vertex && this.context.vertex.isNode) { - this.flowNodeFromShaderStage('vertex', this.context.vertex); - } - - for (const shaderStage of shaderStages) { - this.setShaderStage(shaderStage); - - const flowNodes = this.flowNodes[shaderStage]; - - for (const node of flowNodes) { - if (buildStage === 'generate') { - this.flowNode(node); - } else { - node.build(this); - } - } - } - } - - this.setBuildStage(null); - this.setShaderStage(null); - - // stage 4: build code for a specific output - - this.buildCode(); - this.buildUpdateNodes(); - - return this; - } - - getNodeUniform(uniformNode, type) { - if (type === 'float' || type === 'int' || type === 'uint') return new NumberNodeUniform(uniformNode); - if (type === 'vec2' || type === 'ivec2' || type === 'uvec2') return new Vector2NodeUniform(uniformNode); - if (type === 'vec3' || type === 'ivec3' || type === 'uvec3') return new Vector3NodeUniform(uniformNode); - if (type === 'vec4' || type === 'ivec4' || type === 'uvec4') return new Vector4NodeUniform(uniformNode); - if (type === 'color') return new ColorNodeUniform(uniformNode); - if (type === 'mat3') return new Matrix3NodeUniform(uniformNode); - if (type === 'mat4') return new Matrix4NodeUniform(uniformNode); - - throw new Error(`Uniform "${type}" not declared.`); - } - - createNodeMaterial(type = 'NodeMaterial') { - // @deprecated, r168 - - throw new Error(`THREE.NodeBuilder: createNodeMaterial() was deprecated. Use new ${type}() instead.`); - } - - format(snippet, fromType, toType) { - fromType = this.getVectorType(fromType); - toType = this.getVectorType(toType); - - if (fromType === toType || toType === null || this.isReference(toType)) { - return snippet; - } - - const fromTypeLength = this.getTypeLength(fromType); - const toTypeLength = this.getTypeLength(toType); - - if (fromTypeLength === 16 && toTypeLength === 9) { - return `${this.getType(toType)}(${snippet}[0].xyz, ${snippet}[1].xyz, ${snippet}[2].xyz)`; - } - - if (fromTypeLength === 9 && toTypeLength === 4) { - return `${this.getType(toType)}(${snippet}[0].xy, ${snippet}[1].xy)`; - } - - if (fromTypeLength > 4) { - // fromType is matrix-like - - // @TODO: ignore for now - - return snippet; - } - - if (toTypeLength > 4 || toTypeLength === 0) { - // toType is matrix-like or unknown - - // @TODO: ignore for now - - return snippet; - } - - if (fromTypeLength === toTypeLength) { - return `${this.getType(toType)}( ${snippet} )`; - } - - if (fromTypeLength > toTypeLength) { - return this.format( - `${snippet}.${'xyz'.slice(0, toTypeLength)}`, - this.getTypeFromLength(toTypeLength, this.getComponentType(fromType)), - toType, - ); - } - - if (toTypeLength === 4 && fromTypeLength > 1) { - // toType is vec4-like - - return `${this.getType(toType)}( ${this.format(snippet, fromType, 'vec3')}, 1.0 )`; - } - - if (fromTypeLength === 2) { - // fromType is vec2-like and toType is vec3-like - - return `${this.getType(toType)}( ${this.format(snippet, fromType, 'vec2')}, 0.0 )`; - } - - if (fromTypeLength === 1 && toTypeLength > 1 && fromType !== this.getComponentType(toType)) { - // fromType is float-like - - // convert a number value to vector type, e.g: - // vec3( 1u ) -> vec3( float( 1u ) ) - - snippet = `${this.getType(this.getComponentType(toType))}( ${snippet} )`; - } - - return `${this.getType(toType)}( ${snippet} )`; // fromType is float-like - } - - getSignature() { - return `// Three.js r${REVISION} - Node System\n`; - } -} - -export default NodeBuilder; diff --git a/src-testing/src/nodes/core/NodeCache.ts b/src-testing/src/nodes/core/NodeCache.ts deleted file mode 100644 index ad72d50c5..000000000 --- a/src-testing/src/nodes/core/NodeCache.ts +++ /dev/null @@ -1,26 +0,0 @@ -let id = 0; - -class NodeCache { - constructor(parent = null) { - this.id = id++; - this.nodesData = new WeakMap(); - - this.parent = parent; - } - - getData(node) { - let data = this.nodesData.get(node); - - if (data === undefined && this.parent !== null) { - data = this.parent.getData(node); - } - - return data; - } - - setData(node, data) { - this.nodesData.set(node, data); - } -} - -export default NodeCache; diff --git a/src-testing/src/nodes/core/NodeCode.ts b/src-testing/src/nodes/core/NodeCode.ts deleted file mode 100644 index 2ee509037..000000000 --- a/src-testing/src/nodes/core/NodeCode.ts +++ /dev/null @@ -1,11 +0,0 @@ -class NodeCode { - constructor(name, type, code = '') { - this.name = name; - this.type = type; - this.code = code; - - Object.defineProperty(this, 'isNodeCode', { value: true }); - } -} - -export default NodeCode; diff --git a/src-testing/src/nodes/core/NodeFrame.ts b/src-testing/src/nodes/core/NodeFrame.ts deleted file mode 100644 index ee64620ca..000000000 --- a/src-testing/src/nodes/core/NodeFrame.ts +++ /dev/null @@ -1,127 +0,0 @@ -import { NodeUpdateType } from './constants.js'; - -class NodeFrame { - constructor() { - this.time = 0; - this.deltaTime = 0; - - this.frameId = 0; - this.renderId = 0; - - this.startTime = null; - - this.updateMap = new WeakMap(); - this.updateBeforeMap = new WeakMap(); - this.updateAfterMap = new WeakMap(); - - this.renderer = null; - this.material = null; - this.camera = null; - this.object = null; - this.scene = null; - } - - _getMaps(referenceMap, nodeRef) { - let maps = referenceMap.get(nodeRef); - - if (maps === undefined) { - maps = { - renderMap: new WeakMap(), - frameMap: new WeakMap(), - }; - - referenceMap.set(nodeRef, maps); - } - - return maps; - } - - updateBeforeNode(node) { - const updateType = node.getUpdateBeforeType(); - const reference = node.updateReference(this); - - if (updateType === NodeUpdateType.FRAME) { - const { frameMap } = this._getMaps(this.updateBeforeMap, reference); - - if (frameMap.get(reference) !== this.frameId) { - if (node.updateBefore(this) !== false) { - frameMap.set(reference, this.frameId); - } - } - } else if (updateType === NodeUpdateType.RENDER) { - const { renderMap } = this._getMaps(this.updateBeforeMap, reference); - - if (renderMap.get(reference) !== this.renderId) { - if (node.updateBefore(this) !== false) { - renderMap.set(reference, this.renderId); - } - } - } else if (updateType === NodeUpdateType.OBJECT) { - node.updateBefore(this); - } - } - - updateAfterNode(node) { - const updateType = node.getUpdateAfterType(); - const reference = node.updateReference(this); - - if (updateType === NodeUpdateType.FRAME) { - const { frameMap } = this._getMaps(this.updateAfterMap, reference); - - if (frameMap.get(reference) !== this.frameId) { - if (node.updateAfter(this) !== false) { - frameMap.set(reference, this.frameId); - } - } - } else if (updateType === NodeUpdateType.RENDER) { - const { renderMap } = this._getMaps(this.updateAfterMap, reference); - - if (renderMap.get(reference) !== this.renderId) { - if (node.updateAfter(this) !== false) { - renderMap.set(reference, this.renderId); - } - } - } else if (updateType === NodeUpdateType.OBJECT) { - node.updateAfter(this); - } - } - - updateNode(node) { - const updateType = node.getUpdateType(); - const reference = node.updateReference(this); - - if (updateType === NodeUpdateType.FRAME) { - const { frameMap } = this._getMaps(this.updateMap, reference); - - if (frameMap.get(reference) !== this.frameId) { - if (node.update(this) !== false) { - frameMap.set(reference, this.frameId); - } - } - } else if (updateType === NodeUpdateType.RENDER) { - const { renderMap } = this._getMaps(this.updateMap, reference); - - if (renderMap.get(reference) !== this.renderId) { - if (node.update(this) !== false) { - renderMap.set(reference, this.renderId); - } - } - } else if (updateType === NodeUpdateType.OBJECT) { - node.update(this); - } - } - - update() { - this.frameId++; - - if (this.lastTime === undefined) this.lastTime = performance.now(); - - this.deltaTime = (performance.now() - this.lastTime) / 1000; - - this.lastTime = performance.now(); - - this.time += this.deltaTime; - } -} - -export default NodeFrame; diff --git a/src-testing/src/nodes/core/NodeFunction.ts b/src-testing/src/nodes/core/NodeFunction.ts deleted file mode 100644 index d05afb5e6..000000000 --- a/src-testing/src/nodes/core/NodeFunction.ts +++ /dev/null @@ -1,16 +0,0 @@ -class NodeFunction { - constructor(type, inputs, name = '', precision = '') { - this.type = type; - this.inputs = inputs; - this.name = name; - this.precision = precision; - } - - getCode(/*name = this.name*/) { - console.warn('Abstract function.'); - } -} - -NodeFunction.isNodeFunction = true; - -export default NodeFunction; diff --git a/src-testing/src/nodes/core/NodeFunctionInput.d.ts b/src-testing/src/nodes/core/NodeFunctionInput.d.ts deleted file mode 100644 index a8231d126..000000000 --- a/src-testing/src/nodes/core/NodeFunctionInput.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -export default class NodeFunctionInput { - isNodeFunctionInput: true; - count: null | number; - qualifier: string; - isConst: boolean; - constructor(type: string, name: string, count?: number, qualifier?: string, isConst?: boolean); -} diff --git a/src-testing/src/nodes/core/NodeParser.ts b/src-testing/src/nodes/core/NodeParser.ts deleted file mode 100644 index 9849452f1..000000000 --- a/src-testing/src/nodes/core/NodeParser.ts +++ /dev/null @@ -1,7 +0,0 @@ -class NodeParser { - parseFunction(/*source*/) { - console.warn('Abstract function.'); - } -} - -export default NodeParser; diff --git a/src-testing/src/nodes/core/NodeUniform.ts b/src-testing/src/nodes/core/NodeUniform.ts deleted file mode 100644 index ca43958fc..000000000 --- a/src-testing/src/nodes/core/NodeUniform.ts +++ /dev/null @@ -1,27 +0,0 @@ -class NodeUniform { - constructor(name, type, node) { - this.isNodeUniform = true; - - this.name = name; - this.type = type; - this.node = node.getSelf(); - } - - get value() { - return this.node.value; - } - - set value(val) { - this.node.value = val; - } - - get id() { - return this.node.id; - } - - get groupNode() { - return this.node.groupNode; - } -} - -export default NodeUniform; diff --git a/src-testing/src/nodes/core/NodeUtils.ts b/src-testing/src/nodes/core/NodeUtils.ts deleted file mode 100644 index 7ebac01f9..000000000 --- a/src-testing/src/nodes/core/NodeUtils.ts +++ /dev/null @@ -1,171 +0,0 @@ -import { Color } from '../../math/Color.js'; -import { Matrix3 } from '../../math/Matrix3.js'; -import { Matrix4 } from '../../math/Matrix4.js'; -import { Vector2 } from '../../math/Vector2.js'; -import { Vector3 } from '../../math/Vector3.js'; -import { Vector4 } from '../../math/Vector4.js'; - -// cyrb53 (c) 2018 bryc (github.com/bryc). License: Public domain. Attribution appreciated. -// A fast and simple 64-bit (or 53-bit) string hash function with decent collision resistance. -// Largely inspired by MurmurHash2/3, but with a focus on speed/simplicity. -// See https://stackoverflow.com/questions/7616461/generate-a-hash-from-string-in-javascript/52171480#52171480 -// https://github.com/bryc/code/blob/master/jshash/experimental/cyrb53.js -function cyrb53(value, seed = 0) { - let h1 = 0xdeadbeef ^ seed, - h2 = 0x41c6ce57 ^ seed; - - if (value instanceof Array) { - for (let i = 0, val; i < value.length; i++) { - val = value[i]; - h1 = Math.imul(h1 ^ val, 2654435761); - h2 = Math.imul(h2 ^ val, 1597334677); - } - } else { - for (let i = 0, ch; i < value.length; i++) { - ch = value.charCodeAt(i); - h1 = Math.imul(h1 ^ ch, 2654435761); - h2 = Math.imul(h2 ^ ch, 1597334677); - } - } - - h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507); - h1 ^= Math.imul(h2 ^ (h2 >>> 13), 3266489909); - h2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507); - h2 ^= Math.imul(h1 ^ (h1 >>> 13), 3266489909); - - return 4294967296 * (2097151 & h2) + (h1 >>> 0); -} - -export const hashString = str => cyrb53(str); -export const hashArray = array => cyrb53(array); -export const hash = (...params) => cyrb53(params); - -export function getCacheKey(object, force = false) { - const values = []; - - if (object.isNode === true) { - values.push(object.id); - object = object.getSelf(); - } - - for (const { property, childNode } of getNodeChildren(object)) { - values.push(values, cyrb53(property.slice(0, -4)), childNode.getCacheKey(force)); - } - - return cyrb53(values); -} - -export function* getNodeChildren(node, toJSON = false) { - for (const property in node) { - // Ignore private properties. - if (property.startsWith('_') === true) continue; - - const object = node[property]; - - if (Array.isArray(object) === true) { - for (let i = 0; i < object.length; i++) { - const child = object[i]; - - if (child && (child.isNode === true || (toJSON && typeof child.toJSON === 'function'))) { - yield { property, index: i, childNode: child }; - } - } - } else if (object && object.isNode === true) { - yield { property, childNode: object }; - } else if (typeof object === 'object') { - for (const subProperty in object) { - const child = object[subProperty]; - - if (child && (child.isNode === true || (toJSON && typeof child.toJSON === 'function'))) { - yield { property, index: subProperty, childNode: child }; - } - } - } - } -} - -export function getValueType(value) { - if (value === undefined || value === null) return null; - - const typeOf = typeof value; - - if (value.isNode === true) { - return 'node'; - } else if (typeOf === 'number') { - return 'float'; - } else if (typeOf === 'boolean') { - return 'bool'; - } else if (typeOf === 'string') { - return 'string'; - } else if (typeOf === 'function') { - return 'shader'; - } else if (value.isVector2 === true) { - return 'vec2'; - } else if (value.isVector3 === true) { - return 'vec3'; - } else if (value.isVector4 === true) { - return 'vec4'; - } else if (value.isMatrix3 === true) { - return 'mat3'; - } else if (value.isMatrix4 === true) { - return 'mat4'; - } else if (value.isColor === true) { - return 'color'; - } else if (value instanceof ArrayBuffer) { - return 'ArrayBuffer'; - } - - return null; -} - -export function getValueFromType(type, ...params) { - const last4 = type ? type.slice(-4) : undefined; - - if (params.length === 1) { - // ensure same behaviour as in NodeBuilder.format() - - if (last4 === 'vec2') params = [params[0], params[0]]; - else if (last4 === 'vec3') params = [params[0], params[0], params[0]]; - else if (last4 === 'vec4') params = [params[0], params[0], params[0], params[0]]; - } - - if (type === 'color') { - return new Color(...params); - } else if (last4 === 'vec2') { - return new Vector2(...params); - } else if (last4 === 'vec3') { - return new Vector3(...params); - } else if (last4 === 'vec4') { - return new Vector4(...params); - } else if (last4 === 'mat3') { - return new Matrix3(...params); - } else if (last4 === 'mat4') { - return new Matrix4(...params); - } else if (type === 'bool') { - return params[0] || false; - } else if (type === 'float' || type === 'int' || type === 'uint') { - return params[0] || 0; - } else if (type === 'string') { - return params[0] || ''; - } else if (type === 'ArrayBuffer') { - return base64ToArrayBuffer(params[0]); - } - - return null; -} - -export function arrayBufferToBase64(arrayBuffer) { - let chars = ''; - - const array = new Uint8Array(arrayBuffer); - - for (let i = 0; i < array.length; i++) { - chars += String.fromCharCode(array[i]); - } - - return btoa(chars); -} - -export function base64ToArrayBuffer(base64) { - return Uint8Array.from(atob(base64), c => c.charCodeAt(0)).buffer; -} diff --git a/src-testing/src/nodes/core/NodeVar.ts b/src-testing/src/nodes/core/NodeVar.ts deleted file mode 100644 index e6e935b31..000000000 --- a/src-testing/src/nodes/core/NodeVar.ts +++ /dev/null @@ -1,10 +0,0 @@ -class NodeVar { - constructor(name, type) { - this.isNodeVar = true; - - this.name = name; - this.type = type; - } -} - -export default NodeVar; diff --git a/src-testing/src/nodes/core/NodeVarying.ts b/src-testing/src/nodes/core/NodeVarying.ts deleted file mode 100644 index a14823628..000000000 --- a/src-testing/src/nodes/core/NodeVarying.ts +++ /dev/null @@ -1,13 +0,0 @@ -import NodeVar from './NodeVar.js'; - -class NodeVarying extends NodeVar { - constructor(name, type) { - super(name, type); - - this.needsInterpolation = false; - - this.isNodeVarying = true; - } -} - -export default NodeVarying; diff --git a/src-testing/src/nodes/core/OutputStructNode.d.ts b/src-testing/src/nodes/core/OutputStructNode.d.ts deleted file mode 100644 index 5a7fc6e7b..000000000 --- a/src-testing/src/nodes/core/OutputStructNode.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { ShaderNodeObject } from "../tsl/TSLCore.js"; -import Node from "./Node.js"; - -export default class OutputStructNode extends Node { - members: Node[]; - - readonly isOutputStructNode: true; - - constructor(...members: Node[]); -} - -export const outputStruct: (...members: Node[]) => ShaderNodeObject; diff --git a/src-testing/src/nodes/core/ParameterNode.d.ts b/src-testing/src/nodes/core/ParameterNode.d.ts deleted file mode 100644 index 02629dbf5..000000000 --- a/src-testing/src/nodes/core/ParameterNode.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { ShaderNodeObject } from "../tsl/TSLCore.js"; -import PropertyNode from "./PropertyNode.js"; - -declare class ParameterNode extends PropertyNode { - readonly isParameterNode: true; - - constructor(nodeType: string, name?: string | null); -} - -export default ParameterNode; - -export const parameter: (type: string, name?: string | null) => ShaderNodeObject; diff --git a/src-testing/src/nodes/core/PropertyNode.d.ts b/src-testing/src/nodes/core/PropertyNode.d.ts deleted file mode 100644 index b365d107b..000000000 --- a/src-testing/src/nodes/core/PropertyNode.d.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { ShaderNodeObject } from "../tsl/TSLCore.js"; -import Node from "./Node.js"; - -export default class PropertyNode extends Node { - name: string | null; - varying: boolean; - - readonly isPropertyNode: true; - - constructor(nodeType?: string | null, name?: string | null, varying?: boolean); -} - -export const property: (type?: string | null, name?: string | null) => ShaderNodeObject; -export const varyingProperty: (type?: string | null, name?: string | null) => ShaderNodeObject; - -export const diffuseColor: ShaderNodeObject; -export const emissive: ShaderNodeObject; -export const roughness: ShaderNodeObject; -export const metalness: ShaderNodeObject; -export const clearcoat: ShaderNodeObject; -export const clearcoatRoughness: ShaderNodeObject; -export const sheen: ShaderNodeObject; -export const sheenRoughness: ShaderNodeObject; -export const iridescence: ShaderNodeObject; -export const iridescenceIOR: ShaderNodeObject; -export const iridescenceThickness: ShaderNodeObject; -export const alphaT: ShaderNodeObject; -export const anisotropy: ShaderNodeObject; -export const anisotropyT: ShaderNodeObject; -export const anisotropyB: ShaderNodeObject; -export const specularColor: ShaderNodeObject; -export const specularF90: ShaderNodeObject; -export const shininess: ShaderNodeObject; -export const output: ShaderNodeObject; -export const dashSize: ShaderNodeObject; -export const gapSize: ShaderNodeObject; -export const pointWidth: ShaderNodeObject; -export const ior: ShaderNodeObject; -export const transmission: ShaderNodeObject; -export const thickness: ShaderNodeObject; -export const attenuationDistance: ShaderNodeObject; -export const attenuationColor: ShaderNodeObject; -export const dispersion: ShaderNodeObject; diff --git a/src-testing/src/nodes/core/StackNode.ts b/src-testing/src/nodes/core/StackNode.ts deleted file mode 100644 index 79313afad..000000000 --- a/src-testing/src/nodes/core/StackNode.ts +++ /dev/null @@ -1,89 +0,0 @@ -import Node from './Node.js'; -import { select } from '../math/ConditionalNode.js'; -import { ShaderNode, nodeProxy, getCurrentStack, setCurrentStack } from '../tsl/TSLBase.js'; - -class StackNode extends Node { - static get type() { - return 'StackNode'; - } - - constructor(parent = null) { - super(); - - this.nodes = []; - this.outputNode = null; - - this.parent = parent; - - this._currentCond = null; - - this.isStackNode = true; - } - - getNodeType(builder) { - return this.outputNode ? this.outputNode.getNodeType(builder) : 'void'; - } - - add(node) { - this.nodes.push(node); - - return this; - } - - If(boolNode, method) { - const methodNode = new ShaderNode(method); - this._currentCond = select(boolNode, methodNode); - - return this.add(this._currentCond); - } - - ElseIf(boolNode, method) { - const methodNode = new ShaderNode(method); - const ifNode = select(boolNode, methodNode); - - this._currentCond.elseNode = ifNode; - this._currentCond = ifNode; - - return this; - } - - Else(method) { - this._currentCond.elseNode = new ShaderNode(method); - - return this; - } - - build(builder, ...params) { - const previousStack = getCurrentStack(); - - setCurrentStack(this); - - for (const node of this.nodes) { - node.build(builder, 'void'); - } - - setCurrentStack(previousStack); - - return this.outputNode ? this.outputNode.build(builder, ...params) : super.build(builder, ...params); - } - - // - - else(...params) { - // @deprecated, r168 - - console.warn('TSL.StackNode: .else() has been renamed to .Else().'); - return this.Else(...params); - } - - elseif(...params) { - // @deprecated, r168 - - console.warn('TSL.StackNode: .elseif() has been renamed to .ElseIf().'); - return this.ElseIf(...params); - } -} - -export default StackNode; - -export const stack = /*@__PURE__*/ nodeProxy(StackNode); diff --git a/src-testing/src/nodes/core/StructTypeNode.ts b/src-testing/src/nodes/core/StructTypeNode.ts deleted file mode 100644 index acadb07e1..000000000 --- a/src-testing/src/nodes/core/StructTypeNode.ts +++ /dev/null @@ -1,20 +0,0 @@ -import Node from './Node.js'; - -class StructTypeNode extends Node { - static get type() { - return 'StructTypeNode'; - } - - constructor(types) { - super(); - - this.types = types; - this.isStructTypeNode = true; - } - - getMemberTypes() { - return this.types; - } -} - -export default StructTypeNode; diff --git a/src-testing/src/nodes/core/TempNode.d.ts b/src-testing/src/nodes/core/TempNode.d.ts deleted file mode 100644 index 367f5ade1..000000000 --- a/src-testing/src/nodes/core/TempNode.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import Node from "./Node.js"; -import NodeBuilder from "./NodeBuilder.js"; - -export default class TempNode extends Node { - isTempNode: true; - - constructor(type: string | null); - - hasDependencies(builder: NodeBuilder): boolean; -} diff --git a/src-testing/src/nodes/core/UniformGroup.d.ts b/src-testing/src/nodes/core/UniformGroup.d.ts deleted file mode 100644 index 60339877b..000000000 --- a/src-testing/src/nodes/core/UniformGroup.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -export default class UniformGroup { - name: string; - - readonly isUniformGroup: true; - - constructor(name: string); -} diff --git a/src-testing/src/nodes/core/UniformGroupNode.ts b/src-testing/src/nodes/core/UniformGroupNode.ts deleted file mode 100644 index 829fd3ee8..000000000 --- a/src-testing/src/nodes/core/UniformGroupNode.ts +++ /dev/null @@ -1,47 +0,0 @@ -import Node from './Node.js'; - -class UniformGroupNode extends Node { - static get type() { - return 'UniformGroupNode'; - } - - constructor(name, shared = false, order = 1) { - super('string'); - - this.name = name; - this.version = 0; - - this.shared = shared; - this.order = order; - this.isUniformGroup = true; - } - - set needsUpdate(value) { - if (value === true) this.version++; - } - - serialize(data) { - super.serialize(data); - - data.name = this.name; - data.version = this.version; - data.shared = this.shared; - } - - deserialize(data) { - super.deserialize(data); - - this.name = data.name; - this.version = data.version; - this.shared = data.shared; - } -} - -export default UniformGroupNode; - -export const uniformGroup = name => new UniformGroupNode(name); -export const sharedUniformGroup = (name, order = 0) => new UniformGroupNode(name, true, order); - -export const frameGroup = /*@__PURE__*/ sharedUniformGroup('frame'); -export const renderGroup = /*@__PURE__*/ sharedUniformGroup('render'); -export const objectGroup = /*@__PURE__*/ uniformGroup('object'); diff --git a/src-testing/src/nodes/core/UniformNode.ts b/src-testing/src/nodes/core/UniformNode.ts deleted file mode 100644 index ec9fa9aee..000000000 --- a/src-testing/src/nodes/core/UniformNode.ts +++ /dev/null @@ -1,91 +0,0 @@ -import InputNode from './InputNode.js'; -import { objectGroup } from './UniformGroupNode.js'; -import { nodeObject, getConstNodeType } from '../tsl/TSLCore.js'; - -class UniformNode extends InputNode { - static get type() { - return 'UniformNode'; - } - - constructor(value, nodeType = null) { - super(value, nodeType); - - this.isUniformNode = true; - - this.name = ''; - this.groupNode = objectGroup; - } - - label(name) { - this.name = name; - - return this; - } - - setGroup(group) { - this.groupNode = group; - - return this; - } - - getGroup() { - return this.groupNode; - } - - getUniformHash(builder) { - return this.getHash(builder); - } - - onUpdate(callback, updateType) { - const self = this.getSelf(); - - callback = callback.bind(self); - - return super.onUpdate(frame => { - const value = callback(frame, self); - - if (value !== undefined) { - this.value = value; - } - }, updateType); - } - - generate(builder, output) { - const type = this.getNodeType(builder); - - const hash = this.getUniformHash(builder); - - let sharedNode = builder.getNodeFromHash(hash); - - if (sharedNode === undefined) { - builder.setHashNode(this, hash); - - sharedNode = this; - } - - const sharedNodeType = sharedNode.getInputType(builder); - - const nodeUniform = builder.getUniformFromNode( - sharedNode, - sharedNodeType, - builder.shaderStage, - this.name || builder.context.label, - ); - const propertyName = builder.getPropertyName(nodeUniform); - - if (builder.context.label !== undefined) delete builder.context.label; - - return builder.format(propertyName, type, output); - } -} - -export default UniformNode; - -export const uniform = (arg1, arg2) => { - const nodeType = getConstNodeType(arg2 || arg1); - - // @TODO: get ConstNode from .traverse() in the future - const value = arg1 && arg1.isNode === true ? (arg1.node && arg1.node.value) || arg1.value : arg1; - - return nodeObject(new UniformNode(value, nodeType)); -}; diff --git a/src-testing/src/nodes/core/VarNode.d.ts b/src-testing/src/nodes/core/VarNode.d.ts deleted file mode 100644 index 327df482a..000000000 --- a/src-testing/src/nodes/core/VarNode.d.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; -import Node from "./Node.js"; - -export default class VarNode extends Node { - node: Node; - name: string | null; - - readonly isVarNode: true; - - constructor(node: Node, name?: string | null); -} - -declare module "../tsl/TSLCore.js" { - interface NodeElements { - toVar: (node: NodeRepresentation, name?: string | null) => ShaderNodeObject; - } -} - -/** - * @deprecated Use ".toVar()" instead. - */ -export const temp: (node: NodeRepresentation, name?: string | null) => ShaderNodeObject; - -declare module "../tsl/TSLCore.js" { - interface NodeElements { - /** - * @deprecated Use ".toVar()" instead. - */ - temp: typeof temp; - } -} diff --git a/src-testing/src/nodes/core/VaryingNode.d.ts b/src-testing/src/nodes/core/VaryingNode.d.ts deleted file mode 100644 index f10077ce0..000000000 --- a/src-testing/src/nodes/core/VaryingNode.d.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; -import Node from "./Node.js"; -import NodeBuilder from "./NodeBuilder.js"; -import NodeVarying from "./NodeVarying.js"; - -export default class VaryingNode extends Node { - node: Node; - name: string | null; - - constructor(node: Node, name?: string | null); - - setupVarying(builder: NodeBuilder): NodeVarying; -} - -export const varying: (node: NodeRepresentation, name?: string) => ShaderNodeObject; - -declare module "../tsl/TSLCore.js" { - interface NodeElements { - varying: typeof varying; - } -} diff --git a/src-testing/src/nodes/core/constants.ts b/src-testing/src/nodes/core/constants.ts deleted file mode 100644 index 3b01a9a6d..000000000 --- a/src-testing/src/nodes/core/constants.ts +++ /dev/null @@ -1,28 +0,0 @@ -export const NodeShaderStage = { - VERTEX: 'vertex', - FRAGMENT: 'fragment', -}; - -export const NodeUpdateType = { - NONE: 'none', - FRAME: 'frame', - RENDER: 'render', - OBJECT: 'object', -}; - -export const NodeType = { - BOOLEAN: 'bool', - INTEGER: 'int', - FLOAT: 'float', - VECTOR2: 'vec2', - VECTOR3: 'vec3', - VECTOR4: 'vec4', - MATRIX2: 'mat2', - MATRIX3: 'mat3', - MATRIX4: 'mat4', -}; - -export const defaultShaderStages = ['fragment', 'vertex']; -export const defaultBuildStages = ['setup', 'analyze', 'generate']; -export const shaderStages = [...defaultShaderStages, 'compute']; -export const vectorComponents = ['x', 'y', 'z', 'w']; diff --git a/src-testing/src/nodes/display/BlendMode.d.ts b/src-testing/src/nodes/display/BlendMode.d.ts deleted file mode 100644 index 1f2d23991..000000000 --- a/src-testing/src/nodes/display/BlendMode.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -export const burn: (base: NodeRepresentation, blend: NodeRepresentation) => ShaderNodeObject; - -export const dodge: (base: NodeRepresentation, blend: NodeRepresentation) => ShaderNodeObject; - -export const screen: (base: NodeRepresentation, blend: NodeRepresentation) => ShaderNodeObject; - -export const overlay: (base: NodeRepresentation, blend: NodeRepresentation) => ShaderNodeObject; diff --git a/src-testing/src/nodes/display/BumpMapNode.d.ts b/src-testing/src/nodes/display/BumpMapNode.d.ts deleted file mode 100644 index 726f55685..000000000 --- a/src-testing/src/nodes/display/BumpMapNode.d.ts +++ /dev/null @@ -1,16 +0,0 @@ -import TempNode from "../core/TempNode.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -declare class BumpMapNode extends TempNode { - textureNode: Node; - scaleNode: Node | null; - - constructor(textureNode: Node, scaleNode?: Node | null); -} - -export default BumpMapNode; - -export const bumpMap: ( - textureNode: NodeRepresentation, - scaleNode?: NodeRepresentation | null, -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/display/ColorAdjustment.d.ts b/src-testing/src/nodes/display/ColorAdjustment.d.ts deleted file mode 100644 index 4de024be7..000000000 --- a/src-testing/src/nodes/display/ColorAdjustment.d.ts +++ /dev/null @@ -1,56 +0,0 @@ -import Node from "../core/Node.js"; -import MathNode from "../math/MathNode.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -export const grayscale: (color: NodeRepresentation) => ShaderNodeObject; - -export const saturation: ( - color: NodeRepresentation, - adjustment?: NodeRepresentation, -) => ShaderNodeObject; - -export const vibrance: ( - color: NodeRepresentation, - adjustment?: NodeRepresentation, -) => ShaderNodeObject; - -export const hue: ( - color: NodeRepresentation, - adjustment?: NodeRepresentation, -) => ShaderNodeObject; - -export const luminance: ( - color: NodeRepresentation, - luminanceCoefficients?: NodeRepresentation, -) => ShaderNodeObject; - -export const threshold: (color: NodeRepresentation, thershold: NodeRepresentation) => ShaderNodeObject; - -/** - * Color Decision List (CDL) v1.2 - * - * Compact representation of color grading information, defined by slope, offset, power, and saturation. The CDL should - * be typically be given input in a log space (such as LogC, ACEScc, or AgX Log), and will return output in the same - * space. Output may require clamping >=0. - * - * References: - * - ASC CDL v1.2 - * - https://blender.stackexchange.com/a/55239/43930 - * - https://docs.acescentral.com/specifications/acescc/ - * - * @param color Input (-Infinity < input < +Infinity) - * @param slope Slope (0 ≤ slope < +Infinity) - * @param offset Offset (-Infinity < offset < +Infinity; typically -1 < offset < 1) - * @param power Power (0 < power < +Infinity) - * @param saturation Saturation (0 ≤ saturation < +Infinity; typically 0 ≤ saturation < 4) - * @param luminanceCoefficients Luminance coefficients for saturation term, typically Rec. 709 - * @return Output, -Infinity < output < +Infinity - */ -export const cdl: ( - color: NodeRepresentation, - slope?: NodeRepresentation, - offset?: NodeRepresentation, - power?: NodeRepresentation, - saturation?: NodeRepresentation, - luminanceCoefficients?: NodeRepresentation, -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/display/ColorSpaceFunctions.d.ts b/src-testing/src/nodes/display/ColorSpaceFunctions.d.ts deleted file mode 100644 index a4bd01216..000000000 --- a/src-testing/src/nodes/display/ColorSpaceFunctions.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -export const sRGBTransferEOTF: (color: NodeRepresentation) => ShaderNodeObject; - -export const sRGBTransferOETF: (color: NodeRepresentation) => ShaderNodeObject; diff --git a/src-testing/src/nodes/display/ColorSpaceNode.d.ts b/src-testing/src/nodes/display/ColorSpaceNode.d.ts deleted file mode 100644 index c0de945da..000000000 --- a/src-testing/src/nodes/display/ColorSpaceNode.d.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { LinearSRGBColorSpace, SRGBColorSpace } from "../../constants.js"; -import Node from "../core/Node.js"; -import NodeBuilder from "../core/NodeBuilder.js"; -import TempNode from "../core/TempNode.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -export type WorkingOrOutputColorSpace = "WorkingColorSpace" | "OutputColorSpace"; - -export type ColorSpaceMethod = "LinearTosRGB" | "sRGBToLinear" | "LinearToLinear" | "sRGBTosRGB"; - -export function getColorSpaceMethod( - source: typeof LinearSRGBColorSpace | typeof SRGBColorSpace, - target: typeof LinearSRGBColorSpace | typeof SRGBColorSpace, -): ColorSpaceMethod; - -export default class ColorSpaceNode extends TempNode { - colorNode: Node; - source: string; - target: string; - - constructor( - colorNode: Node, - source: string, - target: string, - ); - - resolveColorSpace(nodeBuilder: NodeBuilder, colorSpace: WorkingOrOutputColorSpace): string; -} - -export const toOutputColorSpace: ( - node: NodeRepresentation, -) => ShaderNodeObject; -export const toWorkingColorSpace: ( - node: NodeRepresentation, -) => ShaderNodeObject; - -export const workingToColorSpace: ( - node: NodeRepresentation, - colorSpace: string, -) => ShaderNodeObject; -export const colorSpaceToWorking: ( - node: NodeRepresentation, - colorSpace: string, -) => ShaderNodeObject; - -export const convertColorSpace: ( - node: NodeRepresentation, - sourceColorSpace: string, - targetColorSpace: string, -) => ShaderNodeObject; - -declare module "../tsl/TSLCore.js" { - interface NodeElements { - toOutputColorSpace: typeof toOutputColorSpace; - toWorkingColorSpace: typeof toWorkingColorSpace; - - workingToColorSpace: typeof workingToColorSpace; - colorSpaceToWorking: typeof colorSpaceToWorking; - } -} diff --git a/src-testing/src/nodes/display/FrontFacingNode.d.ts b/src-testing/src/nodes/display/FrontFacingNode.d.ts deleted file mode 100644 index f550ecacf..000000000 --- a/src-testing/src/nodes/display/FrontFacingNode.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -import Node from "../core/Node.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -declare class FrontFacingNode extends Node { - isFrontFacingNode: true; - constructor(); -} - -export default FrontFacingNode; - -export const frontFacing: ShaderNodeObject; -export const faceDirection: ShaderNodeObject; diff --git a/src-testing/src/nodes/display/NormalMapNode.d.ts b/src-testing/src/nodes/display/NormalMapNode.d.ts deleted file mode 100644 index d06459502..000000000 --- a/src-testing/src/nodes/display/NormalMapNode.d.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { NormalMapTypes } from "../../constants.js"; -import Node from "../core/Node.js"; -import TempNode from "../core/TempNode.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -declare class NormalMapNode extends TempNode { - node: Node; - scaleNode: Node | null; - - normalMapType: NormalMapTypes; - - constructor(node: Node, scaleNode?: Node | null); -} - -export default NormalMapNode; - -export const normalMap: (node: Node, scaleNode?: Node) => ShaderNodeObject; diff --git a/src-testing/src/nodes/display/PassNode.d.ts b/src-testing/src/nodes/display/PassNode.d.ts deleted file mode 100644 index 97bad417f..000000000 --- a/src-testing/src/nodes/display/PassNode.d.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { Camera } from "../../cameras/Camera.js"; -import { RenderTarget, RenderTargetOptions } from "../../core/RenderTarget.js"; -import { Scene } from "../../scenes/Scene.js"; -import { Texture } from "../../textures/Texture.js"; -import TextureNode from "../accessors/TextureNode.js"; -import MRTNode from "../core/MRTNode.js"; -import Node from "../core/Node.js"; -import TempNode from "../core/TempNode.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -declare class PassTextureNode extends TextureNode { - passNode: PassNode; - - constructor(passNode: PassNode, texture: Texture); -} - -declare class PassMultipleTextureNode extends PassTextureNode { - textureName: string; - previousTexture: boolean; - - constructor(passNode: PassNode, textureName: string, previousTexture?: boolean); - - updateTexture(): void; -} - -declare class PassNode extends TempNode { - scope: PassNodeScope; - scene: Scene; - camera: Camera; - - renderTarget: RenderTarget; - - readonly isPassNode: true; - - constructor(scope: PassNodeScope, scene: Scene, camera: Camera, options?: RenderTargetOptions); - - setMRT(mrt: MRTNode | null): this; - - getMRT(): MRTNode | null; - - getTexture(name: string): Texture; - - getPreviousTexture(name: string): Texture; - - toggleTexture(name: string): void; - - getTextureNode(name?: string): ShaderNodeObject; - - getPreviousTextureNode(name?: string): ShaderNodeObject; - - getViewZNode(name?: string): ShaderNodeObject; - - getLinearDepthNode(name?: string): ShaderNodeObject; - - setSize(width: number, height: number): void; - - setPixelRatio(pixelRatio: number): void; - - dispose(): void; - - static COLOR: "color"; - static DEPTH: "depth"; -} - -export type PassNodeScope = typeof PassNode.COLOR | typeof PassNode.DEPTH; - -export default PassNode; - -export const pass: (scene: Scene, camera: Camera, options?: RenderTargetOptions) => ShaderNodeObject; -export const passTexture: (pass: PassNode, texture: Texture) => ShaderNodeObject; -export const depthPass: (scene: Scene, camera: Camera) => ShaderNodeObject; diff --git a/src-testing/src/nodes/display/PosterizeNode.d.ts b/src-testing/src/nodes/display/PosterizeNode.d.ts deleted file mode 100644 index 17eb0fe52..000000000 --- a/src-testing/src/nodes/display/PosterizeNode.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -export default class PosterizeNode extends Node { - sourceNode: Node; - stepsNode: Node; - - constructor(sourceNode: Node, stepsNode: Node); -} - -export const posterize: ( - sourceNode: NodeRepresentation, - stepsNode: NodeRepresentation, -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/display/RenderOutputNode.d.ts b/src-testing/src/nodes/display/RenderOutputNode.d.ts deleted file mode 100644 index b7edad754..000000000 --- a/src-testing/src/nodes/display/RenderOutputNode.d.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { ToneMapping } from "../../constants.js"; -import Node from "../core/Node.js"; -import TempNode from "../core/TempNode.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -declare class RenderOutputNode extends TempNode { - colorNode: Node; - toneMapping: ToneMapping | null; - outputColorSpace: string | null; - - readonly isRenderOutput: true; - - constructor(colorNode: Node, toneMapping?: ToneMapping | null, outputColorSpace?: string | null); -} - -export default RenderOutputNode; - -export const renderOutput: ( - color: NodeRepresentation, - toneMapping?: ToneMapping | null, - outputColorSpace?: string | null, -) => ShaderNodeObject; - -declare module "../tsl/TSLCore.js" { - interface NodeElements { - renderOutput: typeof renderOutput; - } -} diff --git a/src-testing/src/nodes/display/ScreenNode.d.ts b/src-testing/src/nodes/display/ScreenNode.d.ts deleted file mode 100644 index f9ed102fc..000000000 --- a/src-testing/src/nodes/display/ScreenNode.d.ts +++ /dev/null @@ -1,48 +0,0 @@ -import Node from "../core/Node.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -export type ScreenNodeScope = - | typeof ScreenNode.COORDINATE - | typeof ScreenNode.VIEWPORT - | typeof ScreenNode.SIZE - | typeof ScreenNode.UV; - -declare class ScreenNode extends Node { - scope: ScreenNodeScope; - - readonly isViewportNode: true; - - constructor(scope: ScreenNodeScope); - - static COORDINATE: "coordinate"; - static VIEWPORT: "viewport"; - static SIZE: "size"; - static UV: "uv"; -} - -export default ScreenNode; - -// Screen - -export const screenUV: ShaderNodeObject; -export const screenSize: ShaderNodeObject; -export const screenCoordinate: ShaderNodeObject; - -// Viewport - -export const viewport: ShaderNodeObject; -export const viewportSize: ShaderNodeObject; -export const viewportCoordinate: ShaderNodeObject; -export const viewportUV: ShaderNodeObject; - -// Deprecated - -/** - * @deprecated "viewportTopLeft" is deprecated. Use "viewportUV" instead. - */ -export const viewportTopLeft: ShaderNodeObject; - -/** - * @deprecated "viewportBottomLeft" is deprecated. Use "viewportUV.flipY()" instead. - */ -export const viewportBottomLeft: ShaderNodeObject; diff --git a/src-testing/src/nodes/display/ToneMappingFunctions.d.ts b/src-testing/src/nodes/display/ToneMappingFunctions.d.ts deleted file mode 100644 index b972d6b6f..000000000 --- a/src-testing/src/nodes/display/ToneMappingFunctions.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -export const linearToneMapping: (color: NodeRepresentation, exposure: NodeRepresentation) => ShaderNodeObject; - -export const reinhardToneMapping: (color: NodeRepresentation, exposure: NodeRepresentation) => ShaderNodeObject; - -export const cineonToneMapping: (color: NodeRepresentation, exposure: NodeRepresentation) => ShaderNodeObject; - -export const acesFilmicToneMapping: (color: NodeRepresentation, exposure: NodeRepresentation) => ShaderNodeObject; - -export const agxToneMapping: (color: NodeRepresentation, exposure: NodeRepresentation) => ShaderNodeObject; - -export const neutralToneMapping: (color: NodeRepresentation, exposure: NodeRepresentation) => ShaderNodeObject; diff --git a/src-testing/src/nodes/display/ToneMappingNode.d.ts b/src-testing/src/nodes/display/ToneMappingNode.d.ts deleted file mode 100644 index e4fdf9cf6..000000000 --- a/src-testing/src/nodes/display/ToneMappingNode.d.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { ToneMapping } from "../../constants.js"; -import RendererReferenceNode from "../accessors/RendererReferenceNode.js"; -import Node from "../core/Node.js"; -import TempNode from "../core/TempNode.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -declare class ToneMappingNode extends TempNode { - toneMapping: ToneMapping; - exposureNode: Node; - colorNode: Node | null; - - constructor(toneMapping: ToneMapping, exposureNode?: Node, colorNode?: Node | null); -} - -export default ToneMappingNode; - -export const toneMapping: ( - mapping: ToneMapping, - exposure: NodeRepresentation, - color?: NodeRepresentation, -) => ShaderNodeObject; -export const toneMappingExposure: ShaderNodeObject; - -declare module "../tsl/TSLCore.js" { - interface NodeElements { - toneMapping: ( - color: NodeRepresentation, - mapping?: NodeRepresentation, - exposure?: NodeRepresentation, - ) => ShaderNodeObject; - } -} diff --git a/src-testing/src/nodes/display/ToonOutlinePassNode.d.ts b/src-testing/src/nodes/display/ToonOutlinePassNode.d.ts deleted file mode 100644 index fe556b505..000000000 --- a/src-testing/src/nodes/display/ToonOutlinePassNode.d.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { Camera } from "../../cameras/Camera.js"; -import { Color } from "../../math/Color.js"; -import { Scene } from "../../scenes/Scene.js"; -import Node from "../core/Node.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; -import PassNode from "./PassNode.js"; - -declare class ToonOutlinePassNode extends PassNode { - colorNode: Node; - thicknessNode: Node; - alphaNode: Node; - - constructor(scene: Scene, camera: Camera, colorNode: Node, thicknessNode: Node, alphaNode: Node); -} - -export default ToonOutlinePassNode; - -export const toonOutlinePass: ( - scene: Scene, - camera: Camera, - color?: Color, - thickness?: number, - alpha?: number, -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/display/ViewportDepthNode.d.ts b/src-testing/src/nodes/display/ViewportDepthNode.d.ts deleted file mode 100644 index c741caba9..000000000 --- a/src-testing/src/nodes/display/ViewportDepthNode.d.ts +++ /dev/null @@ -1,36 +0,0 @@ -import Node from "../core/Node.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -declare class ViewportDepthNode extends Node { - scope: ViewportDepthNodeScope; - valueNode: Node; - - readonly isViewportDepthNode: true; - - constructor(scope: ViewportDepthNodeScope, valueNode?: Node | null); - - static DEPTH_BASE: "depthBase"; - static DEPTH: "depth"; - static LINEAR_DEPTH: "linearDepth"; -} - -export type ViewportDepthNodeScope = - | typeof ViewportDepthNode.DEPTH_BASE - | typeof ViewportDepthNode.DEPTH - | typeof ViewportDepthNode.LINEAR_DEPTH; - -export default ViewportDepthNode; - -export const viewZToOrthographicDepth: (viewZ: Node, near: Node, far: Node) => Node; - -export const orthographicDepthToViewZ: (depth: Node, near: Node, far: Node) => Node; - -export const viewZToPerspectiveDepth: (viewZ: Node, near: Node, far: Node) => Node; - -export const perspectiveDepthToViewZ: (depth: Node, near: Node, far: Node) => Node; - -export const perspectiveDepthToLogarithmicDepth: (perspectiveW: Node, near: Node, far: Node) => Node; - -export const depth: ShaderNodeObject; -export const linearDepth: (valueNode?: Node | null) => ShaderNodeObject; -export const viewportLinearDepth: ShaderNodeObject; diff --git a/src-testing/src/nodes/display/ViewportDepthTextureNode.d.ts b/src-testing/src/nodes/display/ViewportDepthTextureNode.d.ts deleted file mode 100644 index 7c1102e45..000000000 --- a/src-testing/src/nodes/display/ViewportDepthTextureNode.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; -import ViewportTextureNode from "./ViewportTextureNode.js"; - -declare class ViewportDepthTextureNode extends ViewportTextureNode { - constructor(uvNode?: Node, levelNode?: Node | null); -} - -export default ViewportDepthTextureNode; - -export const viewportDepthTexture: ( - uvNode?: NodeRepresentation, - levelNode?: NodeRepresentation, -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/display/ViewportSharedTextureNode.d.ts b/src-testing/src/nodes/display/ViewportSharedTextureNode.d.ts deleted file mode 100644 index 307bfbde5..000000000 --- a/src-testing/src/nodes/display/ViewportSharedTextureNode.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -import Node from "../core/Node.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; -import ViewportTextureNode from "./ViewportTextureNode.js"; - -declare class ViewportSharedTextureNode extends ViewportTextureNode { - constructor(uvNode?: Node, levelNode?: Node | null); -} - -export default ViewportSharedTextureNode; - -export const viewportSharedTexture: ( - uvNode?: Node, - levelNode?: Node | null, -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/display/ViewportTextureNode.d.ts b/src-testing/src/nodes/display/ViewportTextureNode.d.ts deleted file mode 100644 index ade4ea51e..000000000 --- a/src-testing/src/nodes/display/ViewportTextureNode.d.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { FramebufferTexture } from "../../textures/FramebufferTexture.js"; -import TextureNode from "../accessors/TextureNode.js"; -import { NodeUpdateType } from "../core/constants.js"; -import Node from "../core/Node.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -declare class ViewportTextureNode extends TextureNode { - generateMipmaps: boolean; - - readonly isOutputTextureNode: true; - - updateBeforeType: NodeUpdateType; - - constructor(uvNode?: Node, levelNode?: Node | null, framebufferTexture?: FramebufferTexture | null); -} - -export default ViewportTextureNode; - -export const viewportTexture: ( - uvNode?: Node, - levelNode?: Node | null, - framebufferTexture?: FramebufferTexture | null, -) => ShaderNodeObject; -export const viewportMipTexture: ( - uvNode?: Node, - levelNode?: Node | null, - framebufferTexture?: FramebufferTexture | null, -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/fog/FogExp2Node.d.ts b/src-testing/src/nodes/fog/FogExp2Node.d.ts deleted file mode 100644 index d129d2c72..000000000 --- a/src-testing/src/nodes/fog/FogExp2Node.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -import Node from "../core/Node.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; -import FogNode from "./FogNode.js"; - -declare class FogExp2Node extends FogNode { - isFogExp2Node: true; - densityNode: Node; - - constructor(colorNode: Node, densityNode: Node); -} - -export default FogExp2Node; - -export const densityFog: (colorNode: Node, densityNode: Node) => ShaderNodeObject; diff --git a/src-testing/src/nodes/fog/FogNode.ts b/src-testing/src/nodes/fog/FogNode.ts deleted file mode 100644 index f08efb700..000000000 --- a/src-testing/src/nodes/fog/FogNode.ts +++ /dev/null @@ -1,38 +0,0 @@ -import Node from '../core/Node.js'; -import { positionView } from '../accessors/Position.js'; -import { nodeProxy } from '../tsl/TSLBase.js'; - -class FogNode extends Node { - static get type() { - return 'FogNode'; - } - - constructor(colorNode, factorNode) { - super('float'); - - this.isFogNode = true; - - this.colorNode = colorNode; - this.factorNode = factorNode; - } - - getViewZNode(builder) { - let viewZ; - - const getViewZ = builder.context.getViewZ; - - if (getViewZ !== undefined) { - viewZ = getViewZ(this); - } - - return (viewZ || positionView.z).negate(); - } - - setup() { - return this.factorNode; - } -} - -export default FogNode; - -export const fog = /*@__PURE__*/ nodeProxy(FogNode); diff --git a/src-testing/src/nodes/fog/FogRangeNode.d.ts b/src-testing/src/nodes/fog/FogRangeNode.d.ts deleted file mode 100644 index d0e1c7cf2..000000000 --- a/src-testing/src/nodes/fog/FogRangeNode.d.ts +++ /dev/null @@ -1,19 +0,0 @@ -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; -import FogNode from "./FogNode.js"; - -declare class FogRangeNode extends FogNode { - isFogRangeNode: true; - nearNode: Node | null; - farNode: Node | null; - - constructor(colorNode: Node | null, nearNode: Node | null, farNode: Node | null); -} - -export default FogRangeNode; - -export const rangeFog: ( - colorNode: NodeRepresentation | null, - nearNode: NodeRepresentation | null, - farNode: NodeRepresentation | null, -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/functions/BSDF/BRDF_GGX.d.ts b/src-testing/src/nodes/functions/BSDF/BRDF_GGX.d.ts deleted file mode 100644 index a22bb480a..000000000 --- a/src-testing/src/nodes/functions/BSDF/BRDF_GGX.d.ts +++ /dev/null @@ -1,15 +0,0 @@ -import Node from "../../core/Node.js"; -import OperatorNode from "../../math/OperatorNode.js"; -import { ShaderNodeObject } from "../../tsl/TSLCore.js"; - -declare const BRDF_GGX: (args: { - lightDirection: Node; - f0: Node; - f90: Node; - roughness: Node; - f?: Node; - USE_IRIDESCENCE?: Node; - USE_ANISOTROPY?: Node; -}) => ShaderNodeObject; - -export default BRDF_GGX; diff --git a/src-testing/src/nodes/functions/BSDF/BRDF_Lambert.d.ts b/src-testing/src/nodes/functions/BSDF/BRDF_Lambert.d.ts deleted file mode 100644 index 591fc262d..000000000 --- a/src-testing/src/nodes/functions/BSDF/BRDF_Lambert.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -import Node from "../../core/Node.js"; -import OperatorNode from "../../math/OperatorNode.js"; -import { ShaderNodeObject } from "../../tsl/TSLCore.js"; - -declare const BRDF_Lambert: (args: { diffuseColor: Node }) => ShaderNodeObject; - -export default BRDF_Lambert; diff --git a/src-testing/src/nodes/functions/BSDF/BRDF_Sheen.d.ts b/src-testing/src/nodes/functions/BSDF/BRDF_Sheen.d.ts deleted file mode 100644 index 3e5b218e8..000000000 --- a/src-testing/src/nodes/functions/BSDF/BRDF_Sheen.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -import Node from "../../core/Node.js"; -import OperatorNode from "../../math/OperatorNode.js"; -import { ShaderNodeObject } from "../../tsl/TSLCore.js"; - -declare const BRDF_Sheen: (args: { lightDirection: Node }) => ShaderNodeObject; - -export default BRDF_Sheen; diff --git a/src-testing/src/nodes/functions/BSDF/DFGApprox.d.ts b/src-testing/src/nodes/functions/BSDF/DFGApprox.d.ts deleted file mode 100644 index 010b70ccc..000000000 --- a/src-testing/src/nodes/functions/BSDF/DFGApprox.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -import Node from "../../core/Node.js"; -import OperatorNode from "../../math/OperatorNode.js"; -import { ShaderNodeObject } from "../../tsl/TSLCore.js"; - -// Analytical approximation of the DFG LUT, one half of the -// split-sum approximation used in indirect specular lighting. -// via 'environmentBRDF' from "Physically Based Shading on Mobile" -// https://www.unrealengine.com/blog/physically-based-shading-on-mobile -declare const DFGApprox: (args: { roughness: Node; dotNV: Node }) => ShaderNodeObject; - -export default DFGApprox; diff --git a/src-testing/src/nodes/functions/BSDF/D_GGX.d.ts b/src-testing/src/nodes/functions/BSDF/D_GGX.d.ts deleted file mode 100644 index 71b673c6c..000000000 --- a/src-testing/src/nodes/functions/BSDF/D_GGX.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import Node from "../../core/Node.js"; -import OperatorNode from "../../math/OperatorNode.js"; -import { ShaderNodeObject } from "../../tsl/TSLCore.js"; - -// Microfacet Models for Refraction through Rough Surfaces - equation (33) -// http://graphicrants.blogspot.com/2013/08/specular-brdf-reference.html -// alpha is "roughness squared" in Disney’s reparameterization -declare const D_GGX: (args: { alpha: Node; dotNH: Node }) => ShaderNodeObject; - -export default D_GGX; diff --git a/src-testing/src/nodes/functions/BSDF/D_GGX_Anisotropic.d.ts b/src-testing/src/nodes/functions/BSDF/D_GGX_Anisotropic.d.ts deleted file mode 100644 index e296ea11d..000000000 --- a/src-testing/src/nodes/functions/BSDF/D_GGX_Anisotropic.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import Node from "../../core/Node.js"; -import OperatorNode from "../../math/OperatorNode.js"; -import { ShaderNodeObject } from "../../tsl/TSLCore.js"; - -// https://google.github.io/filament/Filament.md.html#materialsystem/anisotropicmodel/anisotropicspecularbrdf -declare const D_GGX_Anisotropic: ( - args: { alphaT: Node; alphaB: Node; dotNH: Node; dotTH: Node; dotBH: Node }, -) => ShaderNodeObject; - -export default D_GGX_Anisotropic; diff --git a/src-testing/src/nodes/functions/BSDF/F_Schlick.d.ts b/src-testing/src/nodes/functions/BSDF/F_Schlick.d.ts deleted file mode 100644 index 46940e6a3..000000000 --- a/src-testing/src/nodes/functions/BSDF/F_Schlick.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -import Node from "../../core/Node.js"; -import OperatorNode from "../../math/OperatorNode.js"; -import { ShaderNodeObject } from "../../tsl/TSLCore.js"; - -declare const F_Schlick: (args: { f0: Node; f90: Node; dotVH: Node }) => ShaderNodeObject; - -export default F_Schlick; diff --git a/src-testing/src/nodes/functions/BSDF/LTC.d.ts b/src-testing/src/nodes/functions/BSDF/LTC.d.ts deleted file mode 100644 index 4bd6d7f76..000000000 --- a/src-testing/src/nodes/functions/BSDF/LTC.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import Node from "../../core/Node.js"; - -declare const LTC_Uv: (args: { N: Node; V: Node; roughness: Node }) => Node; - -declare const LTC_Evaluate: ( - args: { N: Node; V: Node; P: Node; mInv: Node; p0: Node; p1: Node; p2: Node; p3: Node }, -) => Node; - -export { LTC_Evaluate, LTC_Uv }; diff --git a/src-testing/src/nodes/functions/BSDF/Schlick_to_F0.d.ts b/src-testing/src/nodes/functions/BSDF/Schlick_to_F0.d.ts deleted file mode 100644 index d0554ba2c..000000000 --- a/src-testing/src/nodes/functions/BSDF/Schlick_to_F0.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import Node from "../../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../../tsl/TSLCore.js"; - -declare const Schlick_to_F0: ( - f: NodeRepresentation, - f90: NodeRepresentation, - dotVH: NodeRepresentation, -) => ShaderNodeObject; - -export default Schlick_to_F0; diff --git a/src-testing/src/nodes/functions/BSDF/V_GGX_SmithCorrelated.d.ts b/src-testing/src/nodes/functions/BSDF/V_GGX_SmithCorrelated.d.ts deleted file mode 100644 index b6c1ca80c..000000000 --- a/src-testing/src/nodes/functions/BSDF/V_GGX_SmithCorrelated.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -import Node from "../../core/Node.js"; -import OperatorNode from "../../math/OperatorNode.js"; -import { ShaderNodeObject } from "../../tsl/TSLCore.js"; - -declare const V_GGX_SmithCorrelated: (inputs: { - alpha: Node; - dotNL: Node; - dotNV: Node; -}) => ShaderNodeObject; - -export default V_GGX_SmithCorrelated; diff --git a/src-testing/src/nodes/functions/BSDF/V_GGX_SmithCorrelated_Anisotropic.d.ts b/src-testing/src/nodes/functions/BSDF/V_GGX_SmithCorrelated_Anisotropic.d.ts deleted file mode 100644 index 5150bf6b1..000000000 --- a/src-testing/src/nodes/functions/BSDF/V_GGX_SmithCorrelated_Anisotropic.d.ts +++ /dev/null @@ -1,16 +0,0 @@ -import Node from "../../core/Node.js"; -import MathNode from "../../math/MathNode.js"; -import { ShaderNodeObject } from "../../tsl/TSLCore.js"; - -declare const V_GGX_SmithCorrelated: (inputs: { - alphaT: Node; - alphaB: Node; - dotTV: Node; - dotBV: Node; - dotTL: Node; - dotBL: Node; - dotNV: Node; - dotNL: Node; -}) => ShaderNodeObject; - -export default V_GGX_SmithCorrelated; diff --git a/src-testing/src/nodes/functions/BasicLightingModel.d.ts b/src-testing/src/nodes/functions/BasicLightingModel.d.ts deleted file mode 100644 index a64fafd44..000000000 --- a/src-testing/src/nodes/functions/BasicLightingModel.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -import LightingModel from "../core/LightingModel.js"; - -declare class BasicLightingModel extends LightingModel { - constructor(); -} - -export default BasicLightingModel; diff --git a/src-testing/src/nodes/functions/PhongLightingModel.d.ts b/src-testing/src/nodes/functions/PhongLightingModel.d.ts deleted file mode 100644 index 5df595269..000000000 --- a/src-testing/src/nodes/functions/PhongLightingModel.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -import BasicLightingModel from "./BasicLightingModel.js"; - -export default class PhongLightingModel extends BasicLightingModel { - specular: boolean; - - constructor(specular?: boolean); -} diff --git a/src-testing/src/nodes/functions/PhysicalLightingModel.d.ts b/src-testing/src/nodes/functions/PhysicalLightingModel.d.ts deleted file mode 100644 index bec381051..000000000 --- a/src-testing/src/nodes/functions/PhysicalLightingModel.d.ts +++ /dev/null @@ -1,30 +0,0 @@ -import LightingModel from "../core/LightingModel.js"; -import Node from "../core/Node.js"; - -export default class PhysicalLightingModel extends LightingModel { - clearcoat: boolean; - sheen: boolean; - iridescence: boolean; - anisotropy: boolean; - transmission: boolean; - dispersion: boolean; - - clearcoatRadiance: Node | null; - clearcoatSpecularDirect: Node | null; - clearcoatSpecularIndirect: Node | null; - sheenSpecularDirect: Node | null; - sheenSpecularIndirect: Node | null; - iridescenceFresnel: Node | null; - iridescenceF0: Node | null; - - constructor( - clearcoat?: boolean, - sheen?: boolean, - iridescence?: boolean, - anisotropy?: boolean, - transmission?: boolean, - dispersion?: boolean, - ); - - computeMultiscattering(singleScatter: Node, multiScatter: Node, specularF90: Node): void; -} diff --git a/src-testing/src/nodes/functions/ShadowMaskModel.d.ts b/src-testing/src/nodes/functions/ShadowMaskModel.d.ts deleted file mode 100644 index bcdee8b5c..000000000 --- a/src-testing/src/nodes/functions/ShadowMaskModel.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import LightingModel from "../core/LightingModel.js"; -import VarNode from "../core/VarNode.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -export default class ShadowMaskModel extends LightingModel { - shadowNode: ShaderNodeObject; - - constructor(); -} diff --git a/src-testing/src/nodes/functions/ToonLightingModel.d.ts b/src-testing/src/nodes/functions/ToonLightingModel.d.ts deleted file mode 100644 index d26db3457..000000000 --- a/src-testing/src/nodes/functions/ToonLightingModel.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -import LightingModel from "../core/LightingModel.js"; - -export default class ToonLightingModel extends LightingModel { -} diff --git a/src-testing/src/nodes/functions/material/getGeometryRoughness.d.ts b/src-testing/src/nodes/functions/material/getGeometryRoughness.d.ts deleted file mode 100644 index dd629cee0..000000000 --- a/src-testing/src/nodes/functions/material/getGeometryRoughness.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -import MathNode from "../../math/MathNode.js"; -import { ShaderNodeObject } from "../../tsl/TSLCore.js"; - -declare const getGeometryRoughness: () => ShaderNodeObject; - -export default getGeometryRoughness; diff --git a/src-testing/src/nodes/functions/material/getRoughness.d.ts b/src-testing/src/nodes/functions/material/getRoughness.d.ts deleted file mode 100644 index 7022672b0..000000000 --- a/src-testing/src/nodes/functions/material/getRoughness.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -import Node from "../../core/Node.js"; -import MathNode from "../../math/MathNode.js"; -import { ShaderNodeObject } from "../../tsl/TSLCore.js"; - -declare const getRoughness: (args: { roughness: Node }) => ShaderNodeObject; - -export default getRoughness; diff --git a/src-testing/src/nodes/functions/material/getShIrradianceAt.d.ts b/src-testing/src/nodes/functions/material/getShIrradianceAt.d.ts deleted file mode 100644 index 95c8d03c5..000000000 --- a/src-testing/src/nodes/functions/material/getShIrradianceAt.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -import Node from "../../core/Node.js"; -import { ShaderNodeObject } from "../../tsl/TSLCore.js"; - -declare const getShIrradianceAt: (normal: Node, shCoefficients: Node) => ShaderNodeObject; - -export default getShIrradianceAt; diff --git a/src-testing/src/nodes/geometry/RangeNode.d.ts b/src-testing/src/nodes/geometry/RangeNode.d.ts deleted file mode 100644 index c4c932486..000000000 --- a/src-testing/src/nodes/geometry/RangeNode.d.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Color } from "../../math/Color.js"; -import { Vector2 } from "../../math/Vector2.js"; -import { Vector3 } from "../../math/Vector3.js"; -import { Vector4 } from "../../math/Vector4.js"; -import Node from "../core/Node.js"; -import NodeBuilder from "../core/NodeBuilder.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -export type RangeModeBound = number | Color | Vector2 | Vector3 | Vector4; - -export default class RangeNode extends Node { - min: RangeModeBound; - max: RangeModeBound; - - constructor(min: RangeModeBound, max: RangeModeBound); - getVectorLength(builder: NodeBuilder): number; -} - -export const range: (min: RangeModeBound, max: RangeModeBound) => ShaderNodeObject; diff --git a/src-testing/src/nodes/gpgpu/ComputeNode.ts b/src-testing/src/nodes/gpgpu/ComputeNode.ts deleted file mode 100644 index 30d5be0b3..000000000 --- a/src-testing/src/nodes/gpgpu/ComputeNode.ts +++ /dev/null @@ -1,75 +0,0 @@ -import Node from '../core/Node.js'; -import { NodeUpdateType } from '../core/constants.js'; -import { addMethodChaining, nodeObject } from '../tsl/TSLCore.js'; - -class ComputeNode extends Node { - static get type() { - return 'ComputeNode'; - } - - constructor(computeNode, count, workgroupSize = [64]) { - super('void'); - - this.isComputeNode = true; - - this.computeNode = computeNode; - - this.count = count; - this.workgroupSize = workgroupSize; - this.dispatchCount = 0; - - this.version = 1; - this.updateBeforeType = NodeUpdateType.OBJECT; - - this.onInitFunction = null; - - this.updateDispatchCount(); - } - - dispose() { - this.dispatchEvent({ type: 'dispose' }); - } - - set needsUpdate(value) { - if (value === true) this.version++; - } - - updateDispatchCount() { - const { count, workgroupSize } = this; - - let size = workgroupSize[0]; - - for (let i = 1; i < workgroupSize.length; i++) size *= workgroupSize[i]; - - this.dispatchCount = Math.ceil(count / size); - } - - onInit(callback) { - this.onInitFunction = callback; - - return this; - } - - updateBefore({ renderer }) { - renderer.compute(this); - } - - generate(builder) { - const { shaderStage } = builder; - - if (shaderStage === 'compute') { - const snippet = this.computeNode.build(builder, 'void'); - - if (snippet !== '') { - builder.addLineFlowCode(snippet, this); - } - } - } -} - -export default ComputeNode; - -export const compute = (node, count, workgroupSize) => - nodeObject(new ComputeNode(nodeObject(node), count, workgroupSize)); - -addMethodChaining('compute', compute); diff --git a/src-testing/src/nodes/lighting/AONode.d.ts b/src-testing/src/nodes/lighting/AONode.d.ts deleted file mode 100644 index 998ec5236..000000000 --- a/src-testing/src/nodes/lighting/AONode.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import Node from "../core/Node.js"; -import LightingNode from "./LightingNode.js"; - -export default class AONode extends LightingNode { - aoNode: Node | null; - - constructor(aoNode?: Node | null); -} diff --git a/src-testing/src/nodes/lighting/AmbientLightNode.d.ts b/src-testing/src/nodes/lighting/AmbientLightNode.d.ts deleted file mode 100644 index 3b7cc6fb6..000000000 --- a/src-testing/src/nodes/lighting/AmbientLightNode.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { AmbientLight } from "../../lights/AmbientLight.js"; -import AnalyticLightNode from "./AnalyticLightNode.js"; - -declare class AmbientLightNode extends AnalyticLightNode { - constructor(light?: AmbientLight | null); -} - -export default AmbientLightNode; diff --git a/src-testing/src/nodes/lighting/AnalyticLightNode.d.ts b/src-testing/src/nodes/lighting/AnalyticLightNode.d.ts deleted file mode 100644 index d8cea32ef..000000000 --- a/src-testing/src/nodes/lighting/AnalyticLightNode.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Light } from "../../lights/Light.js"; -import LightingNode from "./LightingNode.js"; - -export default class AnalyticLightNode extends LightingNode { - light: T | null; - - constructor(light?: T | null); -} diff --git a/src-testing/src/nodes/lighting/BasicEnvironmentNode.d.ts b/src-testing/src/nodes/lighting/BasicEnvironmentNode.d.ts deleted file mode 100644 index de244562f..000000000 --- a/src-testing/src/nodes/lighting/BasicEnvironmentNode.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import Node from "../core/Node.js"; -import LightingNode from "./LightingNode.js"; - -declare class BasicEnvironmentNode extends LightingNode { - envNode: Node | null; - - constructor(envNode?: Node | null); -} - -export default BasicEnvironmentNode; diff --git a/src-testing/src/nodes/lighting/BasicLightMapNode.d.ts b/src-testing/src/nodes/lighting/BasicLightMapNode.d.ts deleted file mode 100644 index c759e8857..000000000 --- a/src-testing/src/nodes/lighting/BasicLightMapNode.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import Node from "../core/Node.js"; -import LightingNode from "./LightingNode.js"; - -declare class BasicLightMapNode extends LightingNode { - constructor(lightMapNode?: Node | null); -} - -export default BasicLightMapNode; diff --git a/src-testing/src/nodes/lighting/DirectionalLightNode.d.ts b/src-testing/src/nodes/lighting/DirectionalLightNode.d.ts deleted file mode 100644 index 41908abaf..000000000 --- a/src-testing/src/nodes/lighting/DirectionalLightNode.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { DirectionalLight } from "../../lights/DirectionalLight.js"; -import AnalyticLightNode from "./AnalyticLightNode.js"; - -declare class DirectionalLightNode extends AnalyticLightNode { - constructor(light?: DirectionalLight | null); -} - -export default DirectionalLightNode; diff --git a/src-testing/src/nodes/lighting/EnvironmentNode.ts b/src-testing/src/nodes/lighting/EnvironmentNode.ts deleted file mode 100644 index eab24fba0..000000000 --- a/src-testing/src/nodes/lighting/EnvironmentNode.ts +++ /dev/null @@ -1,114 +0,0 @@ -import LightingNode from './LightingNode.js'; -import { cache } from '../core/CacheNode.js'; -import { roughness, clearcoatRoughness } from '../core/PropertyNode.js'; -import { cameraViewMatrix } from '../accessors/Camera.js'; -import { transformedClearcoatNormalView, transformedNormalView, transformedNormalWorld } from '../accessors/Normal.js'; -import { positionViewDirection } from '../accessors/Position.js'; -import { float } from '../tsl/TSLBase.js'; -import { reference } from '../accessors/ReferenceNode.js'; -import { transformedBentNormalView } from '../accessors/AccessorsUtils.js'; -import { pmremTexture } from '../pmrem/PMREMNode.js'; - -const _envNodeCache = new WeakMap(); - -class EnvironmentNode extends LightingNode { - static get type() { - return 'EnvironmentNode'; - } - - constructor(envNode = null) { - super(); - - this.envNode = envNode; - } - - setup(builder) { - const { material } = builder; - - let envNode = this.envNode; - - if (envNode.isTextureNode || envNode.isMaterialReferenceNode) { - const value = envNode.isTextureNode ? envNode.value : material[envNode.property]; - - let cacheEnvNode = _envNodeCache.get(value); - - if (cacheEnvNode === undefined) { - cacheEnvNode = pmremTexture(value); - - _envNodeCache.set(value, cacheEnvNode); - } - - envNode = cacheEnvNode; - } - - // - - const envMap = material.envMap; - const intensity = envMap - ? reference('envMapIntensity', 'float', builder.material) - : reference('environmentIntensity', 'float', builder.scene); // @TODO: Add materialEnvIntensity in MaterialNode - - const useAnisotropy = material.useAnisotropy === true || material.anisotropy > 0; - const radianceNormalView = useAnisotropy ? transformedBentNormalView : transformedNormalView; - - const radiance = envNode.context(createRadianceContext(roughness, radianceNormalView)).mul(intensity); - const irradiance = envNode.context(createIrradianceContext(transformedNormalWorld)).mul(Math.PI).mul(intensity); - - const isolateRadiance = cache(radiance); - const isolateIrradiance = cache(irradiance); - - // - - builder.context.radiance.addAssign(isolateRadiance); - - builder.context.iblIrradiance.addAssign(isolateIrradiance); - - // - - const clearcoatRadiance = builder.context.lightingModel.clearcoatRadiance; - - if (clearcoatRadiance) { - const clearcoatRadianceContext = envNode - .context(createRadianceContext(clearcoatRoughness, transformedClearcoatNormalView)) - .mul(intensity); - const isolateClearcoatRadiance = cache(clearcoatRadianceContext); - - clearcoatRadiance.addAssign(isolateClearcoatRadiance); - } - } -} - -export default EnvironmentNode; - -const createRadianceContext = (roughnessNode, normalViewNode) => { - let reflectVec = null; - - return { - getUV: () => { - if (reflectVec === null) { - reflectVec = positionViewDirection.negate().reflect(normalViewNode); - - // Mixing the reflection with the normal is more accurate and keeps rough objects from gathering light from behind their tangent plane. - reflectVec = roughnessNode.mul(roughnessNode).mix(reflectVec, normalViewNode).normalize(); - - reflectVec = reflectVec.transformDirection(cameraViewMatrix); - } - - return reflectVec; - }, - getTextureLevel: () => { - return roughnessNode; - }, - }; -}; - -const createIrradianceContext = normalWorldNode => { - return { - getUV: () => { - return normalWorldNode; - }, - getTextureLevel: () => { - return float(1.0); - }, - }; -}; diff --git a/src-testing/src/nodes/lighting/HemisphereLightNode.d.ts b/src-testing/src/nodes/lighting/HemisphereLightNode.d.ts deleted file mode 100644 index 7cf38dd79..000000000 --- a/src-testing/src/nodes/lighting/HemisphereLightNode.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { HemisphereLight } from "../../lights/HemisphereLight.js"; -import Object3DNode from "../accessors/Object3DNode.js"; -import Node from "../core/Node.js"; -import AnalyticLightNode from "./AnalyticLightNode.js"; - -export default class HemisphereLightNode extends AnalyticLightNode { - lightPositionNode: Object3DNode; - lightDirectionNode: Node; - - groundColorNode: Node; - - constructor(light?: HemisphereLight | null); -} diff --git a/src-testing/src/nodes/lighting/IESSpotLightNode.d.ts b/src-testing/src/nodes/lighting/IESSpotLightNode.d.ts deleted file mode 100644 index 5906fe96d..000000000 --- a/src-testing/src/nodes/lighting/IESSpotLightNode.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -import SpotLightNode from "./SpotLightNode.js"; - -declare class IESSpotLightNode extends SpotLightNode {} - -export default IESSpotLightNode; diff --git a/src-testing/src/nodes/lighting/IrradianceNode.d.ts b/src-testing/src/nodes/lighting/IrradianceNode.d.ts deleted file mode 100644 index a59838044..000000000 --- a/src-testing/src/nodes/lighting/IrradianceNode.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import Node from "../core/Node.js"; -import LightingNode from "./LightingNode.js"; - -export default class IrradianceNode extends LightingNode { - node: Node | null; - - constructor(node?: Node | null); -} diff --git a/src-testing/src/nodes/lighting/LightNode.d.ts b/src-testing/src/nodes/lighting/LightNode.d.ts deleted file mode 100644 index de64bdb60..000000000 --- a/src-testing/src/nodes/lighting/LightNode.d.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Light } from "../../lights/Light.js"; -import Node from "../core/Node.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -export type LightNodeScope = typeof LightNode.TARGET_DIRECTION; - -declare class LightNode extends Node { - scope: LightNodeScope; - light: Light; - - constructor(scope?: LightNodeScope, light?: Light | null); - - static TARGET_DIRECTION: "targetDirection"; -} - -export default LightNode; - -export const lightTargetDirection: (light?: Light | null) => ShaderNodeObject; diff --git a/src-testing/src/nodes/lighting/LightProbeNode.d.ts b/src-testing/src/nodes/lighting/LightProbeNode.d.ts deleted file mode 100644 index 3a5b12963..000000000 --- a/src-testing/src/nodes/lighting/LightProbeNode.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { LightProbe } from "../../lights/LightProbe.js"; -import UniformArrayNode from "../accessors/UniformArrayNode.js"; -import AnalyticLightNode from "./AnalyticLightNode.js"; - -declare class LightProbeNode extends AnalyticLightNode { - lightProbe: UniformArrayNode; - - constructor(light?: LightProbe | null); -} - -export default LightProbeNode; diff --git a/src-testing/src/nodes/lighting/LightUtils.d.ts b/src-testing/src/nodes/lighting/LightUtils.d.ts deleted file mode 100644 index 4fd41ea55..000000000 --- a/src-testing/src/nodes/lighting/LightUtils.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import Node from "../core/Node.js"; -import ConditionalNode from "../math/ConditionalNode.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -export const getDistanceAttenuation: (args: { - lightDistance: Node; - cutoffDistance: Node; - decayExponent: Node; -}) => ShaderNodeObject; diff --git a/src-testing/src/nodes/lighting/LightingContextNode.ts b/src-testing/src/nodes/lighting/LightingContextNode.ts deleted file mode 100644 index f9dbf1a82..000000000 --- a/src-testing/src/nodes/lighting/LightingContextNode.ts +++ /dev/null @@ -1,57 +0,0 @@ -import ContextNode from '../core/ContextNode.js'; -import { nodeProxy, float, vec3 } from '../tsl/TSLBase.js'; - -class LightingContextNode extends ContextNode { - static get type() { - return 'LightingContextNode'; - } - - constructor(node, lightingModel = null, backdropNode = null, backdropAlphaNode = null) { - super(node); - - this.lightingModel = lightingModel; - this.backdropNode = backdropNode; - this.backdropAlphaNode = backdropAlphaNode; - - this._value = null; - } - - getContext() { - const { backdropNode, backdropAlphaNode } = this; - - const directDiffuse = vec3().toVar('directDiffuse'), - directSpecular = vec3().toVar('directSpecular'), - indirectDiffuse = vec3().toVar('indirectDiffuse'), - indirectSpecular = vec3().toVar('indirectSpecular'); - - const reflectedLight = { - directDiffuse, - directSpecular, - indirectDiffuse, - indirectSpecular, - }; - - const context = { - radiance: vec3().toVar('radiance'), - irradiance: vec3().toVar('irradiance'), - iblIrradiance: vec3().toVar('iblIrradiance'), - ambientOcclusion: float(1).toVar('ambientOcclusion'), - reflectedLight, - backdrop: backdropNode, - backdropAlpha: backdropAlphaNode, - }; - - return context; - } - - setup(builder) { - this.value = this._value || (this._value = this.getContext()); - this.value.lightingModel = this.lightingModel || builder.context.lightingModel; - - return super.setup(builder); - } -} - -export default LightingContextNode; - -export const lightingContext = /*@__PURE__*/ nodeProxy(LightingContextNode); diff --git a/src-testing/src/nodes/lighting/LightingNode.d.ts b/src-testing/src/nodes/lighting/LightingNode.d.ts deleted file mode 100644 index 3e8dd5424..000000000 --- a/src-testing/src/nodes/lighting/LightingNode.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -import Node from "../core/Node.js"; - -export default abstract class LightingNode extends Node { - readonly isLightingNode: true; - - constructor(); -} diff --git a/src-testing/src/nodes/lighting/LightsNode.ts b/src-testing/src/nodes/lighting/LightsNode.ts deleted file mode 100644 index 1cf0b19ac..000000000 --- a/src-testing/src/nodes/lighting/LightsNode.ts +++ /dev/null @@ -1,200 +0,0 @@ -import Node from '../core/Node.js'; -import { nodeObject, vec3 } from '../tsl/TSLBase.js'; - -const sortLights = lights => { - return lights.sort((a, b) => a.id - b.id); -}; - -const getLightNodeById = (id, lightNodes) => { - for (const lightNode of lightNodes) { - if (lightNode.isAnalyticLightNode && lightNode.light.id === id) { - return lightNode; - } - } - - return null; -}; - -const _lightsNodeRef = /*@__PURE__*/ new WeakMap(); - -class LightsNode extends Node { - static get type() { - return 'LightsNode'; - } - - constructor() { - super('vec3'); - - this.totalDiffuseNode = vec3().toVar('totalDiffuse'); - this.totalSpecularNode = vec3().toVar('totalSpecular'); - - this.outgoingLightNode = vec3().toVar('outgoingLight'); - - this._lights = []; - - this._lightNodes = null; - this._lightNodesHash = null; - - this.global = true; - } - - getHash(builder) { - if (this._lightNodesHash === null) { - if (this._lightNodes === null) this.setupLightsNode(builder); - - const hash = []; - - for (const lightNode of this._lightNodes) { - hash.push(lightNode.getSelf().getHash()); - } - - this._lightNodesHash = 'lights-' + hash.join(','); - } - - return this._lightNodesHash; - } - - analyze(builder) { - const properties = builder.getDataFromNode(this); - - for (const node of properties.nodes) { - node.build(builder); - } - } - - setupLightsNode(builder) { - const lightNodes = []; - - const previousLightNodes = this._lightNodes; - - const lights = sortLights(this._lights); - const nodeLibrary = builder.renderer.library; - - for (const light of lights) { - if (light.isNode) { - lightNodes.push(nodeObject(light)); - } else { - let lightNode = null; - - if (previousLightNodes !== null) { - lightNode = getLightNodeById(light.id, previousLightNodes); // resuse existing light node - } - - if (lightNode === null) { - const lightNodeClass = nodeLibrary.getLightNodeClass(light.constructor); - - if (lightNodeClass === null) { - console.warn(`LightsNode.setupNodeLights: Light node not found for ${light.constructor.name}`); - continue; - } - - let lightNode = null; - - if (!_lightsNodeRef.has(light)) { - lightNode = nodeObject(new lightNodeClass(light)); - _lightsNodeRef.set(light, lightNode); - } else { - lightNode = _lightsNodeRef.get(light); - } - - lightNodes.push(lightNode); - } - } - } - - this._lightNodes = lightNodes; - } - - setupLights(builder, lightNodes) { - for (const lightNode of lightNodes) { - lightNode.build(builder); - } - } - - setup(builder) { - if (this._lightNodes === null) this.setupLightsNode(builder); - - const context = builder.context; - const lightingModel = context.lightingModel; - - let outgoingLightNode = this.outgoingLightNode; - - if (lightingModel) { - const { _lightNodes, totalDiffuseNode, totalSpecularNode } = this; - - context.outgoingLight = outgoingLightNode; - - const stack = builder.addStack(); - - // - - const properties = builder.getDataFromNode(this); - properties.nodes = stack.nodes; - - // - - lightingModel.start(context, stack, builder); - - // lights - - this.setupLights(builder, _lightNodes); - - // - - lightingModel.indirect(context, stack, builder); - - // - - const { backdrop, backdropAlpha } = context; - const { directDiffuse, directSpecular, indirectDiffuse, indirectSpecular } = context.reflectedLight; - - let totalDiffuse = directDiffuse.add(indirectDiffuse); - - if (backdrop !== null) { - if (backdropAlpha !== null) { - totalDiffuse = vec3(backdropAlpha.mix(totalDiffuse, backdrop)); - } else { - totalDiffuse = vec3(backdrop); - } - - context.material.transparent = true; - } - - totalDiffuseNode.assign(totalDiffuse); - totalSpecularNode.assign(directSpecular.add(indirectSpecular)); - - outgoingLightNode.assign(totalDiffuseNode.add(totalSpecularNode)); - - // - - lightingModel.finish(context, stack, builder); - - // - - outgoingLightNode = outgoingLightNode.bypass(builder.removeStack()); - } - - return outgoingLightNode; - } - - setLights(lights) { - this._lights = lights; - - this._lightNodes = null; - this._lightNodesHash = null; - - return this; - } - - getLights() { - return this._lights; - } - - get hasLights() { - return this._lights.length > 0; - } -} - -export default LightsNode; - -export const lights = (lights = []) => nodeObject(new LightsNode()).setLights(lights); diff --git a/src-testing/src/nodes/lighting/PointLightNode.d.ts b/src-testing/src/nodes/lighting/PointLightNode.d.ts deleted file mode 100644 index 6ae10bc08..000000000 --- a/src-testing/src/nodes/lighting/PointLightNode.d.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { PointLight } from "../../lights/PointLight.js"; -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; -import AnalyticLightNode from "./AnalyticLightNode.js"; - -export const directPointLight: ( - color: NodeRepresentation, - lightViewPosition: NodeRepresentation, - cutoffDistance: NodeRepresentation, - decayExponent: NodeRepresentation, -) => ShaderNodeObject; - -declare class PointLightNode extends AnalyticLightNode { - cutoffDistanceNode: Node; - decayExponentNode: Node; - - constructor(light?: PointLight | null); -} - -export default PointLightNode; diff --git a/src-testing/src/nodes/lighting/RectAreaLightNode.d.ts b/src-testing/src/nodes/lighting/RectAreaLightNode.d.ts deleted file mode 100644 index db4d18b82..000000000 --- a/src-testing/src/nodes/lighting/RectAreaLightNode.d.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { RectAreaLight } from "../../lights/RectAreaLight.js"; -import { DataTexture } from "../../textures/DataTexture.js"; -import Node from "../core/Node.js"; -import AnalyticLightNode from "./AnalyticLightNode.js"; - -export interface RectAreaLightTexturesLib { - LTC_HALF_1: DataTexture; - LTC_HALF_2: DataTexture; - - LTC_FLOAT_1: DataTexture; - LTC_FLOAT_2: DataTexture; -} - -export default class RectAreaLightNode extends AnalyticLightNode { - halfHeight: Node; - halfWidth: Node; - - constructor(light?: RectAreaLight | null); - - static setLTC(ltc: RectAreaLightTexturesLib): void; -} diff --git a/src-testing/src/nodes/lighting/ShadowNode.d.ts b/src-testing/src/nodes/lighting/ShadowNode.d.ts deleted file mode 100644 index 1b8d4fa9f..000000000 --- a/src-testing/src/nodes/lighting/ShadowNode.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Light } from "../../lights/Light.js"; -import { LightShadow } from "../../lights/LightShadow.js"; -import Node from "../core/Node.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -declare class ShadowNode extends Node { - constructor(light: Light, shadow: LightShadow); -} - -export default ShadowNode; - -export const shadow: (light: Light, shadow: LightShadow) => ShaderNodeObject; diff --git a/src-testing/src/nodes/lighting/SpotLightNode.d.ts b/src-testing/src/nodes/lighting/SpotLightNode.d.ts deleted file mode 100644 index 0b1ae4b13..000000000 --- a/src-testing/src/nodes/lighting/SpotLightNode.d.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { SpotLight } from "../../lights/SpotLight.js"; -import Node from "../core/Node.js"; -import AnalyticLightNode from "./AnalyticLightNode.js"; - -export default class PointLightNode extends AnalyticLightNode { - directionNode: Node; - - coneCosNode: Node; - penumbraCosNode: Node; - - cutoffDistanceNode: Node; - decayExponentNode: Node; - - constructor(light?: SpotLight | null); -} diff --git a/src-testing/src/nodes/materialx/MaterialXNodes.d.ts b/src-testing/src/nodes/materialx/MaterialXNodes.d.ts deleted file mode 100644 index 8007125a7..000000000 --- a/src-testing/src/nodes/materialx/MaterialXNodes.d.ts +++ /dev/null @@ -1,107 +0,0 @@ -import Node from "../core/Node.js"; -import MathNode from "../math/MathNode.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; -import { mx_hsvtorgb, mx_rgbtohsv } from "./lib/mx_hsv.js"; -import { mx_srgb_texture_to_lin_rec709 } from "./lib/mx_transform_color.js"; - -export function mx_aastep(threshold: NodeRepresentation, value: NodeRepresentation): ShaderNodeObject; - -export function mx_ramplr( - valuel: NodeRepresentation, - valuer: NodeRepresentation, - texcoord?: NodeRepresentation, -): ShaderNodeObject; -export function mx_ramptb( - valuet: NodeRepresentation, - valueb: NodeRepresentation, - texcoord?: NodeRepresentation, -): ShaderNodeObject; - -export function mx_splitlr( - valuel: NodeRepresentation, - valuer: NodeRepresentation, - center: NodeRepresentation, - texcoord?: NodeRepresentation, -): ShaderNodeObject; -export function mx_splittb( - valuet: NodeRepresentation, - valueb: NodeRepresentation, - center: NodeRepresentation, - texcoord?: NodeRepresentation, -): ShaderNodeObject; - -export function mx_transform_uv( - uv_scale?: NodeRepresentation, - uv_offset?: NodeRepresentation, - uv_geo?: NodeRepresentation, -): ShaderNodeObject; - -export function mx_safepower(in1: NodeRepresentation, in2?: NodeRepresentation): ShaderNodeObject; - -export function mx_contrast( - input: NodeRepresentation, - amount?: NodeRepresentation, - pivot?: NodeRepresentation, -): ShaderNodeObject; - -export function mx_noise_float( - texcoord?: NodeRepresentation, - amplitude?: NodeRepresentation, - pivot?: NodeRepresentation, -): ShaderNodeObject; -export function mx_noise_vec3( - texcoord?: NodeRepresentation, - amplitude?: NodeRepresentation, - pivot?: NodeRepresentation, -): ShaderNodeObject; -export function mx_noise_vec4( - texcoord?: NodeRepresentation, - amplitude?: NodeRepresentation, - pivot?: NodeRepresentation, -): ShaderNodeObject; - -export function mx_worley_noise_float( - texcoord?: NodeRepresentation, - jitter?: NodeRepresentation, -): ShaderNodeObject; -export function mx_worley_noise_vec2( - texcoord?: NodeRepresentation, - jitter?: NodeRepresentation, -): ShaderNodeObject; -export function mx_worley_noise_vec3( - texcoord?: NodeRepresentation, - jitter?: NodeRepresentation, -): ShaderNodeObject; - -export function mx_cell_noise_float(texcoord?: NodeRepresentation): ShaderNodeObject; - -export function mx_fractal_noise_float( - position?: NodeRepresentation, - octaves?: NodeRepresentation, - lacunarity?: NodeRepresentation, - diminish?: NodeRepresentation, - amplitude?: NodeRepresentation, -): ShaderNodeObject; -export function mx_fractal_noise_vec2( - position?: NodeRepresentation, - octaves?: NodeRepresentation, - lacunarity?: NodeRepresentation, - diminish?: NodeRepresentation, - amplitude?: NodeRepresentation, -): ShaderNodeObject; -export function mx_fractal_noise_vec3( - position?: NodeRepresentation, - octaves?: NodeRepresentation, - lacunarity?: NodeRepresentation, - diminish?: NodeRepresentation, - amplitude?: NodeRepresentation, -): ShaderNodeObject; -export function mx_fractal_noise_vec4( - position?: NodeRepresentation, - octaves?: NodeRepresentation, - lacunarity?: NodeRepresentation, - diminish?: NodeRepresentation, - amplitude?: NodeRepresentation, -): ShaderNodeObject; - -export { mx_hsvtorgb, mx_rgbtohsv, mx_srgb_texture_to_lin_rec709 }; diff --git a/src-testing/src/nodes/materialx/lib/mx_hsv.d.ts b/src-testing/src/nodes/materialx/lib/mx_hsv.d.ts deleted file mode 100644 index ce11882e9..000000000 --- a/src-testing/src/nodes/materialx/lib/mx_hsv.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -import Node from "../../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../../tsl/TSLCore.js"; - -export const mx_hsvtorgb: (hsv: NodeRepresentation) => ShaderNodeObject; - -export const mx_rgbtohsv: (c_immutable: NodeRepresentation) => ShaderNodeObject; diff --git a/src-testing/src/nodes/materialx/lib/mx_noise.d.ts b/src-testing/src/nodes/materialx/lib/mx_noise.d.ts deleted file mode 100644 index 2e5405f75..000000000 --- a/src-testing/src/nodes/materialx/lib/mx_noise.d.ts +++ /dev/null @@ -1,359 +0,0 @@ -import Node from "../../core/Node.js"; -import VarNode from "../../core/VarNode.js"; -import { NodeRepresentation, ShaderNodeObject } from "../../tsl/TSLCore.js"; - -export const mx_select: ( - b_immutable: NodeRepresentation, - t_immutable: NodeRepresentation, - f_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_negate_if: ( - val_immutable: NodeRepresentation, - b_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_floor: (x_immutable: NodeRepresentation) => ShaderNodeObject; - -export const mx_floorfrac: (x_immutable: NodeRepresentation, i: ShaderNodeObject) => ShaderNodeObject; - -export const mx_bilerp_0: ( - v0_immutable: NodeRepresentation, - v1_immutable: NodeRepresentation, - v2_immutable: NodeRepresentation, - v3_immutable: NodeRepresentation, - s_immutable: NodeRepresentation, - t_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_bilerp_1: ( - v0_immutable: NodeRepresentation, - v1_immutable: NodeRepresentation, - v2_immutable: NodeRepresentation, - v3_immutable: NodeRepresentation, - s_immutable: NodeRepresentation, - t_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_bilerp: ( - v0_immutable: NodeRepresentation, - v1_immutable: NodeRepresentation, - v2_immutable: NodeRepresentation, - v3_immutable: NodeRepresentation, - s_immutable: NodeRepresentation, - t_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_trilerp_0: ( - v0_immutable: NodeRepresentation, - v1_immutable: NodeRepresentation, - v2_immutable: NodeRepresentation, - v3_immutable: NodeRepresentation, - v4_immutable: NodeRepresentation, - v5_immutable: NodeRepresentation, - v6_immutable: NodeRepresentation, - v7_immutable: NodeRepresentation, - s_immutable: NodeRepresentation, - t_immutable: NodeRepresentation, - r_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_trilerp_1: ( - v0_immutable: NodeRepresentation, - v1_immutable: NodeRepresentation, - v2_immutable: NodeRepresentation, - v3_immutable: NodeRepresentation, - v4_immutable: NodeRepresentation, - v5_immutable: NodeRepresentation, - v6_immutable: NodeRepresentation, - v7_immutable: NodeRepresentation, - s_immutable: NodeRepresentation, - t_immutable: NodeRepresentation, - r_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_trilerp: ( - v0_immutable: NodeRepresentation, - v1_immutable: NodeRepresentation, - v2_immutable: NodeRepresentation, - v3_immutable: NodeRepresentation, - v4_immutable: NodeRepresentation, - v5_immutable: NodeRepresentation, - v6_immutable: NodeRepresentation, - v7_immutable: NodeRepresentation, - s_immutable: NodeRepresentation, - t_immutable: NodeRepresentation, - r_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_gradient_float_0: ( - hash_immutable: NodeRepresentation, - x_immutable: NodeRepresentation, - y_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_gradient_float_1: ( - hash_immutable: NodeRepresentation, - x_immutable: NodeRepresentation, - y_immutable: NodeRepresentation, - z_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_gradient_float: ( - hash_immutable: NodeRepresentation, - x_immutable: NodeRepresentation, - y_immutable: NodeRepresentation, - z_immutable?: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_gradient_vec3_0: ( - hash_immutable: NodeRepresentation, - x_immutable: NodeRepresentation, - y_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_gradient_vec3_1: ( - hash_immutable: NodeRepresentation, - x_immutable: NodeRepresentation, - y_immutable: NodeRepresentation, - z_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_gradient_vec3: ( - hash_immutable: NodeRepresentation, - x_immutable: NodeRepresentation, - y_immutable: NodeRepresentation, - z_immutable?: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_gradient_scale2d_0: (v_immutable: NodeRepresentation) => ShaderNodeObject; - -export const mx_gradient_scale3d_0: (v_immutable: NodeRepresentation) => ShaderNodeObject; - -export const mx_gradient_scale2d_1: (v_immutable: NodeRepresentation) => ShaderNodeObject; - -export const mx_gradient_scale2d: (v_immutable: NodeRepresentation) => ShaderNodeObject; - -export const mx_gradient_scale3d_1: (v_immutable: NodeRepresentation) => ShaderNodeObject; - -export const mx_gradient_scale3d: (v_immutable: NodeRepresentation) => ShaderNodeObject; - -export const mx_rotl32: (x_immutable: NodeRepresentation, k_immutable: NodeRepresentation) => ShaderNodeObject; - -export const mx_bjmix: ( - a: ShaderNodeObject, - b: ShaderNodeObject, - c: ShaderNodeObject, -) => ShaderNodeObject; - -export const mx_bjfinal: ( - a_immutable: NodeRepresentation, - b_immutable: NodeRepresentation, - c_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_bits_to_01: (bits_immutable: NodeRepresentation) => ShaderNodeObject; - -export const mx_fade: (t_immutable: NodeRepresentation) => ShaderNodeObject; - -export const mx_hash_int_0: (x_immutable: NodeRepresentation) => ShaderNodeObject; - -export const mx_hash_int_1: ( - x_immutable: NodeRepresentation, - y_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_hash_int_2: ( - x_immutable: NodeRepresentation, - y_immutable: NodeRepresentation, - z_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_hash_int_3: ( - x_immutable: NodeRepresentation, - y_immutable: NodeRepresentation, - z_immutable: NodeRepresentation, - xx_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_hash_int_4: ( - x_immutable: NodeRepresentation, - y_immutable: NodeRepresentation, - z_immutable: NodeRepresentation, - xx_immutable: NodeRepresentation, - yy_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_hash_int: ( - x_immutable: NodeRepresentation, - y_immutable?: NodeRepresentation, - z_immutable?: NodeRepresentation, - xx_immutable?: NodeRepresentation, - yy_immutable?: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_hash_vec3_0: ( - x_immutable: NodeRepresentation, - y_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_hash_vec3_1: ( - x_immutable: NodeRepresentation, - y_immutable: NodeRepresentation, - z_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_hash_vec3: ( - x_immutable: NodeRepresentation, - y_immutable: NodeRepresentation, - z_immutable?: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_perlin_noise_float_0: (p_immutable: NodeRepresentation) => ShaderNodeObject; - -export const mx_perlin_noise_float_1: (p_immutable: NodeRepresentation) => ShaderNodeObject; - -export const mx_perlin_noise_float: (p_immutable: NodeRepresentation) => ShaderNodeObject; - -export const mx_perlin_noise_vec3_0: (p_immutable: NodeRepresentation) => ShaderNodeObject; - -export const mx_perlin_noise_vec3_1: (p_immutable: NodeRepresentation) => ShaderNodeObject; - -export const mx_perlin_noise_vec3: (p_immutable: NodeRepresentation) => ShaderNodeObject; - -export const mx_cell_noise_float_0: (p_immutable: NodeRepresentation) => ShaderNodeObject; - -export const mx_cell_noise_float_1: (p_immutable: NodeRepresentation) => ShaderNodeObject; - -export const mx_cell_noise_float_2: (p_immutable: NodeRepresentation) => ShaderNodeObject; - -export const mx_cell_noise_float_3: (p_immutable: NodeRepresentation) => ShaderNodeObject; - -export const mx_cell_noise_float: (p_immutable: NodeRepresentation) => ShaderNodeObject; - -export const mx_cell_noise_vec3_0: (p_immutable: NodeRepresentation) => ShaderNodeObject; - -export const mx_cell_noise_vec3_1: (p_immutable: NodeRepresentation) => ShaderNodeObject; - -export const mx_cell_noise_vec3_2: (p_immutable: NodeRepresentation) => ShaderNodeObject; - -export const mx_cell_noise_vec3_3: (p_immutable: NodeRepresentation) => ShaderNodeObject; - -export const mx_cell_noise_vec3: (p_immutable: NodeRepresentation) => ShaderNodeObject; - -export const mx_fractal_noise_float: ( - p_immutable: NodeRepresentation, - octaves_immutable: NodeRepresentation, - lacunarity_immutable: NodeRepresentation, - diminish_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_fractal_noise_vec3: ( - p_immutable: NodeRepresentation, - octaves_immutable: NodeRepresentation, - lacunarity_immutable: NodeRepresentation, - diminish_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_fractal_noise_vec2: ( - p_immutable: NodeRepresentation, - octaves_immutable: NodeRepresentation, - lacunarity_immutable: NodeRepresentation, - diminish_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_fractal_noise_vec4: ( - p_immutable: NodeRepresentation, - octaves_immutable: NodeRepresentation, - lacunarity_immutable: NodeRepresentation, - diminish_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_worley_distance_0: ( - p_immutable: NodeRepresentation, - x_immutable: NodeRepresentation, - y_immutable: NodeRepresentation, - z_immutable: NodeRepresentation, - xoff_immutable: NodeRepresentation, - yoff_immutable: NodeRepresentation, - jitter_immutable: NodeRepresentation, - metric_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_worley_distance_1: ( - p_immutable: NodeRepresentation, - x_immutable: NodeRepresentation, - y_immutable: NodeRepresentation, - z_immutable: NodeRepresentation, - xoff_immutable: NodeRepresentation, - yoff_immutable: NodeRepresentation, - zoff_immutable: NodeRepresentation, - jitter_immutable: NodeRepresentation, - metric_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_worley_distance: ( - p_immutable: NodeRepresentation, - x_immutable: NodeRepresentation, - y_immutable: NodeRepresentation, - z_immutable: NodeRepresentation, - xoff_immutable: NodeRepresentation, - yoff_immutable: NodeRepresentation, - zoff_immutable: NodeRepresentation, - jitter_immutable: NodeRepresentation, - metric_immutable?: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_worley_noise_float_0: ( - p_immutable: NodeRepresentation, - jitter_immutable: NodeRepresentation, - metric_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_worley_noise_vec2_0: ( - p_immutable: NodeRepresentation, - jitter_immutable: NodeRepresentation, - metric_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_worley_noise_vec3_0: ( - p_immutable: NodeRepresentation, - jitter_immutable: NodeRepresentation, - metric_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_worley_noise_float_1: ( - p_immutable: NodeRepresentation, - jitter_immutable: NodeRepresentation, - metric_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_worley_noise_float: ( - p_immutable: NodeRepresentation, - jitter_immutable: NodeRepresentation, - metric_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_worley_noise_vec2_1: ( - p_immutable: NodeRepresentation, - jitter_immutable: NodeRepresentation, - metric_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_worley_noise_vec2: ( - p_immutable: NodeRepresentation, - jitter_immutable: NodeRepresentation, - metric_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_worley_noise_vec3_1: ( - p_immutable: NodeRepresentation, - jitter_immutable: NodeRepresentation, - metric_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_worley_noise_vec3: ( - p_immutable: NodeRepresentation, - jitter_immutable: NodeRepresentation, - metric_immutable: NodeRepresentation, -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/materialx/lib/mx_transform_color.d.ts b/src-testing/src/nodes/materialx/lib/mx_transform_color.d.ts deleted file mode 100644 index 418818d0e..000000000 --- a/src-testing/src/nodes/materialx/lib/mx_transform_color.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -import Node from "../../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../../tsl/TSLCore.js"; - -export const mx_srgb_texture_to_lin_rec709: (color_immutable: NodeRepresentation) => ShaderNodeObject; diff --git a/src-testing/src/nodes/math/ConditionalNode.d.ts b/src-testing/src/nodes/math/ConditionalNode.d.ts deleted file mode 100644 index 5313a9836..000000000 --- a/src-testing/src/nodes/math/ConditionalNode.d.ts +++ /dev/null @@ -1,39 +0,0 @@ -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -declare class ConditionalNode extends Node { - condNode: Node; - ifNode: Node; - elseNode: Node; - - constructor(condNode: Node, ifNode: Node, elseNode: Node); -} - -export default ConditionalNode; - -export const select: ( - condNode: NodeRepresentation, - ifNode: NodeRepresentation, - elseNode: NodeRepresentation, -) => ShaderNodeObject; - -declare module "../tsl/TSLCore.js" { - interface NodeElements { - select: typeof select; - } -} - -/** - * @deprecated cond() has been renamed to select() - */ -export const cond: ( - condNode: NodeRepresentation, - ifNode: NodeRepresentation, - elseNode: NodeRepresentation, -) => ShaderNodeObject; - -declare module "../tsl/TSLCore.js" { - interface NodeElements { - cond: typeof cond; - } -} diff --git a/src-testing/src/nodes/math/Hash.d.ts b/src-testing/src/nodes/math/Hash.d.ts deleted file mode 100644 index df9e81997..000000000 --- a/src-testing/src/nodes/math/Hash.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -export const hash: (seed: NodeRepresentation) => ShaderNodeObject; diff --git a/src-testing/src/nodes/math/MathNode.d.ts b/src-testing/src/nodes/math/MathNode.d.ts deleted file mode 100644 index f65546d75..000000000 --- a/src-testing/src/nodes/math/MathNode.d.ts +++ /dev/null @@ -1,273 +0,0 @@ -import Node from "../core/Node.js"; -import TempNode from "../core/TempNode.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; -import OperatorNode from "./OperatorNode.js"; - -export type MathNodeMethod1 = - | typeof MathNode.RADIANS - | typeof MathNode.DEGREES - | typeof MathNode.EXP - | typeof MathNode.EXP2 - | typeof MathNode.LOG - | typeof MathNode.LOG2 - | typeof MathNode.SQRT - | typeof MathNode.INVERSE_SQRT - | typeof MathNode.FLOOR - | typeof MathNode.CEIL - | typeof MathNode.NORMALIZE - | typeof MathNode.FRACT - | typeof MathNode.SIN - | typeof MathNode.COS - | typeof MathNode.TAN - | typeof MathNode.ASIN - | typeof MathNode.ACOS - | typeof MathNode.ATAN - | typeof MathNode.ABS - | typeof MathNode.SIGN - | typeof MathNode.LENGTH - | typeof MathNode.NEGATE - | typeof MathNode.ONE_MINUS - | typeof MathNode.DFDX - | typeof MathNode.DFDY - | typeof MathNode.ROUND - | typeof MathNode.RECIPROCAL - | typeof MathNode.TRUNC - | typeof MathNode.FWIDTH - | typeof MathNode.BITCAST - | typeof MathNode.TRANSPOSE; - -export type MathNodeMethod2 = - | typeof MathNode.ATAN2 - | typeof MathNode.MIN - | typeof MathNode.MAX - | typeof MathNode.MOD - | typeof MathNode.STEP - | typeof MathNode.REFLECT - | typeof MathNode.DISTANCE - | typeof MathNode.DOT - | typeof MathNode.CROSS - | typeof MathNode.POW - | typeof MathNode.TRANSFORM_DIRECTION; - -export type MathNodeMethod3 = - | typeof MathNode.MIX - | typeof MathNode.CLAMP - | typeof MathNode.REFRACT - | typeof MathNode.SMOOTHSTEP - | typeof MathNode.FACEFORWARD; - -export type MathNodeMethod = MathNodeMethod1 | MathNodeMethod2 | MathNodeMethod3; - -export default class MathNode extends TempNode { - // 1 input - - static ALL: "all"; - static ANY: "any"; - static EQUALS: "equals"; - - static RADIANS: "radians"; - static DEGREES: "degrees"; - static EXP: "exp"; - static EXP2: "exp2"; - static LOG: "log"; - static LOG2: "log2"; - static SQRT: "sqrt"; - static INVERSE_SQRT: "inversesqrt"; - static FLOOR: "floor"; - static CEIL: "ceil"; - static NORMALIZE: "normalize"; - static FRACT: "fract"; - static SIN: "sin"; - static COS: "cos"; - static TAN: "tan"; - static ASIN: "asin"; - static ACOS: "acos"; - static ATAN: "atan"; - static ABS: "abs"; - static SIGN: "sign"; - static LENGTH: "length"; - static NEGATE: "negate"; - static ONE_MINUS: "oneMinus"; - static DFDX: "dFdx"; - static DFDY: "dFdy"; - static ROUND: "round"; - static RECIPROCAL: "reciprocal"; - static TRUNC: "trunc"; - static FWIDTH: "fwidth"; - static BITCAST: "bitcast"; - static TRANSPOSE: "transpose"; - - // 2 inputs - - static ATAN2: "atan2"; - static MIN: "min"; - static MAX: "max"; - static MOD: "mod"; - static STEP: "step"; - static REFLECT: "reflect"; - static DISTANCE: "distance"; - static DOT: "dot"; - static CROSS: "cross"; - static POW: "pow"; - static TRANSFORM_DIRECTION: "transformDirection"; - - // 3 inputs - - static MIX: "mix"; - static CLAMP: "clamp"; - static REFRACT: "refract"; - static SMOOTHSTEP: "smoothstep"; - static FACEFORWARD: "faceforward"; - - method: MathNodeMethod; - aNode: Node; - bNode: Node | null; - cNode: Node | null; - - constructor(method: MathNodeMethod1, aNode: Node); - constructor(method: MathNodeMethod2, aNode: Node, bNode: Node); - constructor(method: MathNodeMethod3, aNode: Node, bNode: Node, cNode: Node); -} - -export const EPSILON: ShaderNodeObject; -export const INFINITY: ShaderNodeObject; -export const PI: ShaderNodeObject; -export const PI2: ShaderNodeObject; - -type Unary = (a: NodeRepresentation) => ShaderNodeObject; - -export const all: Unary; -export const any: Unary; -export const equals: Unary; - -export const radians: Unary; -export const degrees: Unary; -export const exp: Unary; -export const exp2: Unary; -export const log: Unary; -export const log2: Unary; -export const sqrt: Unary; -export const inverseSqrt: Unary; -export const floor: Unary; -export const ceil: Unary; -export const normalize: Unary; -export const fract: Unary; -export const sin: Unary; -export const cos: Unary; -export const tan: Unary; -export const asin: Unary; -export const acos: Unary; -export const atan: Unary; -export const abs: Unary; -export const sign: Unary; -export const length: Unary; -export const negate: Unary; -export const oneMinus: Unary; -export const dFdx: Unary; -export const dFdy: Unary; -export const round: Unary; -export const reciprocal: Unary; -export const trunc: Unary; -export const fwidth: Unary; -export const bitcast: Unary; -export const transpose: Unary; - -type Binary = (a: NodeRepresentation, b: NodeRepresentation) => ShaderNodeObject; - -export const atan2: Binary; -export const min: Binary; -export const max: Binary; -export const mod: Binary; -export const step: Binary; -export const reflect: Binary; -export const distance: Binary; -export const difference: Binary; -export const dot: Binary; -export const cross: Binary; -export const pow: Binary; -export const pow2: Binary; -export const pow3: Binary; -export const pow4: Binary; -export const transformDirection: Binary; - -type Ternary = (a: NodeRepresentation, b: NodeRepresentation, c: NodeRepresentation) => ShaderNodeObject; - -export const cbrt: Unary; -export const lengthSq: Unary; -export const mix: Ternary; -export const clamp: ( - a: NodeRepresentation, - b?: NodeRepresentation, - c?: NodeRepresentation, -) => ShaderNodeObject; -export const saturate: Unary; -export const refract: Ternary; -export const smoothstep: Ternary; -export const faceForward: Ternary; - -export const rand: (uv: NodeRepresentation) => ShaderNodeObject; - -export const mixElement: Ternary; -export const smoothstepElement: Ternary; - -declare module "../tsl/TSLCore.js" { - interface NodeElements { - all: typeof all; - any: typeof any; - equals: typeof equals; - radians: typeof radians; - degrees: typeof degrees; - exp: typeof exp; - exp2: typeof exp2; - log: typeof log; - log2: typeof log2; - sqrt: typeof sqrt; - inverseSqrt: typeof inverseSqrt; - floor: typeof floor; - ceil: typeof ceil; - normalize: typeof normalize; - fract: typeof fract; - sin: typeof sin; - cos: typeof cos; - tan: typeof tan; - asin: typeof asin; - acos: typeof acos; - atan: typeof atan; - abs: typeof abs; - sign: typeof sign; - length: typeof length; - lengthSq: typeof lengthSq; - negate: typeof negate; - oneMinus: typeof oneMinus; - dFdx: typeof dFdx; - dFdy: typeof dFdy; - round: typeof round; - reciprocal: typeof reciprocal; - trunc: typeof trunc; - fwidth: typeof fwidth; - atan2: typeof atan2; - min: typeof min; - max: typeof max; - mod: typeof mod; - step: typeof step; - reflect: typeof reflect; - distance: typeof distance; - dot: typeof dot; - cross: typeof cross; - pow: typeof pow; - pow2: typeof pow2; - pow3: typeof pow3; - pow4: typeof pow4; - transformDirection: typeof transformDirection; - mix: typeof mixElement; - clamp: typeof clamp; - refract: typeof refract; - smoothstep: typeof smoothstepElement; - faceForward: typeof faceForward; - difference: typeof difference; - saturate: typeof saturate; - cbrt: typeof cbrt; - transpose: typeof transpose; - rand: typeof rand; - } -} diff --git a/src-testing/src/nodes/math/MathUtils.d.ts b/src-testing/src/nodes/math/MathUtils.d.ts deleted file mode 100644 index 572d9eef5..000000000 --- a/src-testing/src/nodes/math/MathUtils.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { Binary, Ternary } from "./MathNode.js"; - -export const parabola: Binary; -export const gain: Binary; -export const pcurve: Ternary; -export const sinc: Binary; diff --git a/src-testing/src/nodes/math/OperatorNode.d.ts b/src-testing/src/nodes/math/OperatorNode.d.ts deleted file mode 100644 index 77157ea73..000000000 --- a/src-testing/src/nodes/math/OperatorNode.d.ts +++ /dev/null @@ -1,97 +0,0 @@ -import Node from "../core/Node.js"; -import TempNode from "../core/TempNode.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -export type OperatorNodeOp = - | "%" - | "&" - | "|" - | "^" - | ">>" - | "<<" - | "==" - | "&&" - | "||" - | "^^" - | "<" - | ">" - | "<=" - | ">=" - | "+" - | "-" - | "*" - | "/"; - -export default class OperatorNode extends TempNode { - aNode: Node; - bNode: Node; - op: OperatorNodeOp; - - constructor(op: OperatorNodeOp, ...params: [Node, Node, ...Node[]]); -} - -type Operator = ( - a: NodeRepresentation, - b: NodeRepresentation, - ...others: NodeRepresentation[] -) => ShaderNodeObject; - -export const add: Operator; -export const sub: Operator; -export const mul: Operator; -export const div: Operator; -export const modInt: Operator; -export const equal: Operator; -export const lessThan: Operator; -export const greaterThan: Operator; -export const lessThanEqual: Operator; -export const greaterThanEqual: Operator; -export const and: Operator; -export const or: Operator; -export const not: (a: NodeRepresentation) => ShaderNodeObject; -export const xor: Operator; -export const bitAnd: Operator; -export const bitNot: (a: NodeRepresentation) => ShaderNodeObject; -export const bitOr: Operator; -export const bitXor: Operator; -export const shiftLeft: Operator; -export const shiftRight: Operator; - -declare module "../tsl/TSLCore.js" { - interface NodeElements { - add: typeof add; - sub: typeof sub; - mul: typeof mul; - div: typeof div; - modInt: typeof modInt; - equal: typeof equal; - lessThan: typeof lessThan; - greaterThan: typeof greaterThan; - lessThanEqual: typeof lessThanEqual; - greaterThanEqual: typeof greaterThanEqual; - and: typeof and; - or: typeof or; - not: typeof not; - xor: typeof xor; - bitAnd: typeof bitAnd; - bitNot: typeof bitNot; - bitOr: typeof bitOr; - bitXor: typeof bitXor; - shiftLeft: typeof shiftLeft; - shiftRight: typeof shiftRight; - } -} - -/** - * @deprecated .remainder() has been renamed to .modInt(). - */ -export const remainder: Operator; - -declare module "../tsl/TSLCore.js" { - interface NodeElements { - /** - * @deprecated .remainder() has been renamed to .modInt(). - */ - remainder: typeof remainder; - } -} diff --git a/src-testing/src/nodes/math/TriNoise3D.d.ts b/src-testing/src/nodes/math/TriNoise3D.d.ts deleted file mode 100644 index f5220dbe6..000000000 --- a/src-testing/src/nodes/math/TriNoise3D.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -export const tri: (x: NodeRepresentation) => ShaderNodeObject; - -export const tri3: (p: NodeRepresentation) => ShaderNodeObject; - -export const triNoise3D: ( - p_immutable: NodeRepresentation, - spd: NodeRepresentation, - time: NodeRepresentation, -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/parsers/GLSLNodeFunction.d.ts b/src-testing/src/nodes/parsers/GLSLNodeFunction.d.ts deleted file mode 100644 index ec2396423..000000000 --- a/src-testing/src/nodes/parsers/GLSLNodeFunction.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import NodeFunction from "../core/NodeFunction.js"; - -declare class GLSLNodeFunction extends NodeFunction { - constructor(source: string); - - getCode(name?: string): string; -} - -export default GLSLNodeFunction; diff --git a/src-testing/src/nodes/parsers/GLSLNodeParser.d.ts b/src-testing/src/nodes/parsers/GLSLNodeParser.d.ts deleted file mode 100644 index f6b663d4b..000000000 --- a/src-testing/src/nodes/parsers/GLSLNodeParser.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import NodeParser from "../core/NodeParser.js"; -import GLSLNodeFunction from "./GLSLNodeFunction.js"; - -declare class GLSLNodeParser extends NodeParser { - parseFunction(source: string): GLSLNodeFunction; -} - -export default GLSLNodeParser; diff --git a/src-testing/src/nodes/pmrem/PMREMNode.d.ts b/src-testing/src/nodes/pmrem/PMREMNode.d.ts deleted file mode 100644 index 2a957c8e6..000000000 --- a/src-testing/src/nodes/pmrem/PMREMNode.d.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Texture } from "../../textures/Texture.js"; -import Node from "../core/Node.js"; -import TempNode from "../core/TempNode.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -declare class PMREMNode extends TempNode { - uvNode: Node | null; - levelNode: Node | null; - - constructor(value: Texture, uvNode?: Node | null, levelNode?: Node | null); - - set value(value: Texture); - get value(): Texture; -} - -export default PMREMNode; - -export const pmremTexture: ( - value: Texture, - uvNode?: NodeRepresentation, - levelNode?: NodeRepresentation, -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/pmrem/PMREMUtils.d.ts b/src-testing/src/nodes/pmrem/PMREMUtils.d.ts deleted file mode 100644 index 947e7fe25..000000000 --- a/src-testing/src/nodes/pmrem/PMREMUtils.d.ts +++ /dev/null @@ -1,28 +0,0 @@ -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -export const getDirection: (uv_immutable: NodeRepresentation, face: NodeRepresentation) => ShaderNodeObject; - -export const textureCubeUV: ( - envMap: NodeRepresentation, - sampleDir_immutable: NodeRepresentation, - roughness_immutable: NodeRepresentation, - CUBEUV_TEXEL_WIDTH: NodeRepresentation, - CUBEUV_TEXEL_HEIGHT: NodeRepresentation, - CUBEUV_MAX_MIP: NodeRepresentation, -) => ShaderNodeObject; - -export const blur: ( - n: NodeRepresentation, - latitudinal: NodeRepresentation, - poleAxis: NodeRepresentation, - outputDirection: NodeRepresentation, - weights: NodeRepresentation, - samples: NodeRepresentation, - dTheta: NodeRepresentation, - mipInt: NodeRepresentation, - envMap: NodeRepresentation, - CUBEUV_TEXEL_WIDTH: NodeRepresentation, - CUBEUV_TEXEL_HEIGHT: NodeRepresentation, - CUBEUV_MAX_MIP: NodeRepresentation, -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/procedural/Checker.d.ts b/src-testing/src/nodes/procedural/Checker.d.ts deleted file mode 100644 index af7cce3a7..000000000 --- a/src-testing/src/nodes/procedural/Checker.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -export const checker: (coord?: NodeRepresentation) => ShaderNodeObject; diff --git a/src-testing/src/nodes/tsl/TSLBase.d.ts b/src-testing/src/nodes/tsl/TSLBase.d.ts deleted file mode 100644 index 297b9a483..000000000 --- a/src-testing/src/nodes/tsl/TSLBase.d.ts +++ /dev/null @@ -1,21 +0,0 @@ -export * from "../accessors/BufferAttributeNode.js"; -export * from "../code/ExpressionNode.js"; -export * from "../code/FunctionCallNode.js"; -export * from "../core/AssignNode.js"; -export * from "../core/BypassNode.js"; -export * from "../core/CacheNode.js"; -export * from "../core/ContextNode.js"; -export * from "../core/PropertyNode.js"; -export * from "../core/UniformNode.js"; -export * from "../core/VarNode.js"; -export * from "../core/VaryingNode.js"; -export * from "../display/ColorSpaceNode.js"; -export * from "../display/RenderOutputNode.js"; -export * from "../display/ToneMappingNode.js"; -export * from "../gpgpu/ComputeNode.js"; -export * from "../math/ConditionalNode.js"; -export * from "../math/MathNode.js"; -export * from "../math/OperatorNode.js"; -export * from "../utils/Discard.js"; -export * from "../utils/RemapNode.js"; -export * from "./TSLCore.js"; diff --git a/src-testing/src/nodes/tsl/TSLCore.ts b/src-testing/src/nodes/tsl/TSLCore.ts deleted file mode 100644 index 4ac059f08..000000000 --- a/src-testing/src/nodes/tsl/TSLCore.ts +++ /dev/null @@ -1,533 +0,0 @@ -import Node from '../core/Node.js'; -import ArrayElementNode from '../utils/ArrayElementNode.js'; -import ConvertNode from '../utils/ConvertNode.js'; -import JoinNode from '../utils/JoinNode.js'; -import SplitNode from '../utils/SplitNode.js'; -import SetNode from '../utils/SetNode.js'; -import FlipNode from '../utils/FlipNode.js'; -import ConstNode from '../core/ConstNode.js'; -import { getValueFromType, getValueType } from '../core/NodeUtils.js'; - -// - -let currentStack = null; - -const NodeElements = new Map(); - -export function addMethodChaining(name, nodeElement) { - if (NodeElements.has(name)) { - console.warn(`Redefinition of method chaining ${name}`); - return; - } - - if (typeof nodeElement !== 'function') throw new Error(`Node element ${name} is not a function`); - - NodeElements.set(name, nodeElement); -} - -const parseSwizzle = props => props.replace(/r|s/g, 'x').replace(/g|t/g, 'y').replace(/b|p/g, 'z').replace(/a|q/g, 'w'); -const parseSwizzleAndSort = props => parseSwizzle(props).split('').sort().join(''); - -const shaderNodeHandler = { - setup(NodeClosure, params) { - const inputs = params.shift(); - - return NodeClosure(nodeObjects(inputs), ...params); - }, - - get(node, prop, nodeObj) { - if (typeof prop === 'string' && node[prop] === undefined) { - if (node.isStackNode !== true && prop === 'assign') { - return (...params) => { - currentStack.assign(nodeObj, ...params); - - return nodeObj; - }; - } else if (NodeElements.has(prop)) { - const nodeElement = NodeElements.get(prop); - - return node.isStackNode - ? (...params) => nodeObj.add(nodeElement(...params)) - : (...params) => nodeElement(nodeObj, ...params); - } else if (prop === 'self') { - return node; - } else if (prop.endsWith('Assign') && NodeElements.has(prop.slice(0, prop.length - 'Assign'.length))) { - const nodeElement = NodeElements.get(prop.slice(0, prop.length - 'Assign'.length)); - - return node.isStackNode - ? (...params) => nodeObj.assign(params[0], nodeElement(...params)) - : (...params) => nodeObj.assign(nodeElement(nodeObj, ...params)); - } else if (/^[xyzwrgbastpq]{1,4}$/.test(prop) === true) { - // accessing properties ( swizzle ) - - prop = parseSwizzle(prop); - - return nodeObject(new SplitNode(nodeObj, prop)); - } else if (/^set[XYZWRGBASTPQ]{1,4}$/.test(prop) === true) { - // set properties ( swizzle ) and sort to xyzw sequence - - prop = parseSwizzleAndSort(prop.slice(3).toLowerCase()); - - return value => nodeObject(new SetNode(node, prop, value)); - } else if (/^flip[XYZWRGBASTPQ]{1,4}$/.test(prop) === true) { - // set properties ( swizzle ) and sort to xyzw sequence - - prop = parseSwizzleAndSort(prop.slice(4).toLowerCase()); - - return () => nodeObject(new FlipNode(nodeObject(node), prop)); - } else if (prop === 'width' || prop === 'height' || prop === 'depth') { - // accessing property - - if (prop === 'width') prop = 'x'; - else if (prop === 'height') prop = 'y'; - else if (prop === 'depth') prop = 'z'; - - return nodeObject(new SplitNode(node, prop)); - } else if (/^\d+$/.test(prop) === true) { - // accessing array - - return nodeObject(new ArrayElementNode(nodeObj, new ConstNode(Number(prop), 'uint'))); - } - } - - return Reflect.get(node, prop, nodeObj); - }, - - set(node, prop, value, nodeObj) { - if (typeof prop === 'string' && node[prop] === undefined) { - // setting properties - - if ( - /^[xyzwrgbastpq]{1,4}$/.test(prop) === true || - prop === 'width' || - prop === 'height' || - prop === 'depth' || - /^\d+$/.test(prop) === true - ) { - nodeObj[prop].assign(value); - - return true; - } - } - - return Reflect.set(node, prop, value, nodeObj); - }, -}; - -const nodeObjectsCacheMap = new WeakMap(); -const nodeBuilderFunctionsCacheMap = new WeakMap(); - -const ShaderNodeObject = function (obj, altType = null) { - const type = getValueType(obj); - - if (type === 'node') { - let nodeObject = nodeObjectsCacheMap.get(obj); - - if (nodeObject === undefined) { - nodeObject = new Proxy(obj, shaderNodeHandler); - - nodeObjectsCacheMap.set(obj, nodeObject); - nodeObjectsCacheMap.set(nodeObject, nodeObject); - } - - return nodeObject; - } else if ( - (altType === null && (type === 'float' || type === 'boolean')) || - (type && type !== 'shader' && type !== 'string') - ) { - return nodeObject(getConstNode(obj, altType)); - } else if (type === 'shader') { - return Fn(obj); - } - - return obj; -}; - -const ShaderNodeObjects = function (objects, altType = null) { - for (const name in objects) { - objects[name] = nodeObject(objects[name], altType); - } - - return objects; -}; - -const ShaderNodeArray = function (array, altType = null) { - const len = array.length; - - for (let i = 0; i < len; i++) { - array[i] = nodeObject(array[i], altType); - } - - return array; -}; - -const ShaderNodeProxy = function (NodeClass, scope = null, factor = null, settings = null) { - const assignNode = node => nodeObject(settings !== null ? Object.assign(node, settings) : node); - - if (scope === null) { - return (...params) => { - return assignNode(new NodeClass(...nodeArray(params))); - }; - } else if (factor !== null) { - factor = nodeObject(factor); - - return (...params) => { - return assignNode(new NodeClass(scope, ...nodeArray(params), factor)); - }; - } else { - return (...params) => { - return assignNode(new NodeClass(scope, ...nodeArray(params))); - }; - } -}; - -const ShaderNodeImmutable = function (NodeClass, ...params) { - return nodeObject(new NodeClass(...nodeArray(params))); -}; - -class ShaderCallNodeInternal extends Node { - constructor(shaderNode, inputNodes) { - super(); - - this.shaderNode = shaderNode; - this.inputNodes = inputNodes; - } - - getNodeType(builder) { - return this.shaderNode.nodeType || this.getOutputNode(builder).getNodeType(builder); - } - - call(builder) { - const { shaderNode, inputNodes } = this; - - const properties = builder.getNodeProperties(shaderNode); - if (properties.onceOutput) return properties.onceOutput; - - // - - let result = null; - - if (shaderNode.layout) { - let functionNodesCacheMap = nodeBuilderFunctionsCacheMap.get(builder.constructor); - - if (functionNodesCacheMap === undefined) { - functionNodesCacheMap = new WeakMap(); - - nodeBuilderFunctionsCacheMap.set(builder.constructor, functionNodesCacheMap); - } - - let functionNode = functionNodesCacheMap.get(shaderNode); - - if (functionNode === undefined) { - functionNode = nodeObject(builder.buildFunctionNode(shaderNode)); - - functionNodesCacheMap.set(shaderNode, functionNode); - } - - if (builder.currentFunctionNode !== null) { - builder.currentFunctionNode.includes.push(functionNode); - } - - result = nodeObject(functionNode.call(inputNodes)); - } else { - const jsFunc = shaderNode.jsFunc; - const outputNode = inputNodes !== null ? jsFunc(inputNodes, builder) : jsFunc(builder); - - result = nodeObject(outputNode); - } - - if (shaderNode.once) { - properties.onceOutput = result; - } - - return result; - } - - getOutputNode(builder) { - const properties = builder.getNodeProperties(this); - - if (properties.outputNode === null) { - properties.outputNode = this.setupOutput(builder); - } - - return properties.outputNode; - } - - setup(builder) { - return this.getOutputNode(builder); - } - - setupOutput(builder) { - builder.addStack(); - - builder.stack.outputNode = this.call(builder); - - return builder.removeStack(); - } - - generate(builder, output) { - const outputNode = this.getOutputNode(builder); - - return outputNode.build(builder, output); - } -} - -class ShaderNodeInternal extends Node { - constructor(jsFunc, nodeType) { - super(nodeType); - - this.jsFunc = jsFunc; - this.layout = null; - - this.global = true; - - this.once = false; - } - - setLayout(layout) { - this.layout = layout; - - return this; - } - - call(inputs = null) { - nodeObjects(inputs); - - return nodeObject(new ShaderCallNodeInternal(this, inputs)); - } - - setup() { - return this.call(); - } -} - -const bools = [false, true]; -const uints = [0, 1, 2, 3]; -const ints = [-1, -2]; -const floats = [ - 0.5, - 1.5, - 1 / 3, - 1e-6, - 1e6, - Math.PI, - Math.PI * 2, - 1 / Math.PI, - 2 / Math.PI, - 1 / (Math.PI * 2), - Math.PI / 2, -]; - -const boolsCacheMap = new Map(); -for (const bool of bools) boolsCacheMap.set(bool, new ConstNode(bool)); - -const uintsCacheMap = new Map(); -for (const uint of uints) uintsCacheMap.set(uint, new ConstNode(uint, 'uint')); - -const intsCacheMap = new Map([...uintsCacheMap].map(el => new ConstNode(el.value, 'int'))); -for (const int of ints) intsCacheMap.set(int, new ConstNode(int, 'int')); - -const floatsCacheMap = new Map([...intsCacheMap].map(el => new ConstNode(el.value))); -for (const float of floats) floatsCacheMap.set(float, new ConstNode(float)); -for (const float of floats) floatsCacheMap.set(-float, new ConstNode(-float)); - -const cacheMaps = { bool: boolsCacheMap, uint: uintsCacheMap, ints: intsCacheMap, float: floatsCacheMap }; - -const constNodesCacheMap = new Map([...boolsCacheMap, ...floatsCacheMap]); - -const getConstNode = (value, type) => { - if (constNodesCacheMap.has(value)) { - return constNodesCacheMap.get(value); - } else if (value.isNode === true) { - return value; - } else { - return new ConstNode(value, type); - } -}; - -const safeGetNodeType = node => { - try { - return node.getNodeType(); - } catch (_) { - return undefined; - } -}; - -const ConvertType = function (type, cacheMap = null) { - return (...params) => { - if ( - params.length === 0 || - (!['bool', 'float', 'int', 'uint'].includes(type) && params.every(param => typeof param !== 'object')) - ) { - params = [getValueFromType(type, ...params)]; - } - - if (params.length === 1 && cacheMap !== null && cacheMap.has(params[0])) { - return nodeObject(cacheMap.get(params[0])); - } - - if (params.length === 1) { - const node = getConstNode(params[0], type); - if (safeGetNodeType(node) === type) return nodeObject(node); - return nodeObject(new ConvertNode(node, type)); - } - - const nodes = params.map(param => getConstNode(param)); - return nodeObject(new JoinNode(nodes, type)); - }; -}; - -// exports - -export const defined = v => (typeof v === 'object' && v !== null ? v.value : v); // TODO: remove boolean conversion and defined function - -// utils - -export const getConstNodeType = value => - value !== undefined && value !== null - ? value.nodeType || value.convertTo || (typeof value === 'string' ? value : null) - : null; - -// shader node base - -export function ShaderNode(jsFunc, nodeType) { - return new Proxy(new ShaderNodeInternal(jsFunc, nodeType), shaderNodeHandler); -} - -export const nodeObject = (val, altType = null) => /* new */ ShaderNodeObject(val, altType); -export const nodeObjects = (val, altType = null) => new ShaderNodeObjects(val, altType); -export const nodeArray = (val, altType = null) => new ShaderNodeArray(val, altType); -export const nodeProxy = (...params) => new ShaderNodeProxy(...params); -export const nodeImmutable = (...params) => new ShaderNodeImmutable(...params); - -export const Fn = (jsFunc, nodeType) => { - const shaderNode = new ShaderNode(jsFunc, nodeType); - - const fn = (...params) => { - let inputs; - - nodeObjects(params); - - if (params[0] && params[0].isNode) { - inputs = [...params]; - } else { - inputs = params[0]; - } - - return shaderNode.call(inputs); - }; - - fn.shaderNode = shaderNode; - - fn.setLayout = layout => { - shaderNode.setLayout(layout); - - return fn; - }; - - fn.once = () => { - shaderNode.once = true; - - return fn; - }; - - return fn; -}; - -export const tslFn = (...params) => { - // @deprecated, r168 - - console.warn('TSL.ShaderNode: tslFn() has been renamed to Fn().'); - return Fn(...params); -}; - -// - -addMethodChaining('toGlobal', node => { - node.global = true; - - return node; -}); - -// - -export const setCurrentStack = stack => { - if (currentStack === stack) { - //throw new Error( 'Stack already defined.' ); - } - - currentStack = stack; -}; - -export const getCurrentStack = () => currentStack; - -export const If = (...params) => currentStack.If(...params); - -export function append(node) { - if (currentStack) currentStack.add(node); - - return node; -} - -addMethodChaining('append', append); - -// types - -export const color = new ConvertType('color'); - -export const float = new ConvertType('float', cacheMaps.float); -export const int = new ConvertType('int', cacheMaps.ints); -export const uint = new ConvertType('uint', cacheMaps.uint); -export const bool = new ConvertType('bool', cacheMaps.bool); - -export const vec2 = new ConvertType('vec2'); -export const ivec2 = new ConvertType('ivec2'); -export const uvec2 = new ConvertType('uvec2'); -export const bvec2 = new ConvertType('bvec2'); - -export const vec3 = new ConvertType('vec3'); -export const ivec3 = new ConvertType('ivec3'); -export const uvec3 = new ConvertType('uvec3'); -export const bvec3 = new ConvertType('bvec3'); - -export const vec4 = new ConvertType('vec4'); -export const ivec4 = new ConvertType('ivec4'); -export const uvec4 = new ConvertType('uvec4'); -export const bvec4 = new ConvertType('bvec4'); - -export const mat2 = new ConvertType('mat2'); -export const mat3 = new ConvertType('mat3'); -export const mat4 = new ConvertType('mat4'); - -export const string = (value = '') => nodeObject(new ConstNode(value, 'string')); -export const arrayBuffer = value => nodeObject(new ConstNode(value, 'ArrayBuffer')); - -addMethodChaining('toColor', color); -addMethodChaining('toFloat', float); -addMethodChaining('toInt', int); -addMethodChaining('toUint', uint); -addMethodChaining('toBool', bool); -addMethodChaining('toVec2', vec2); -addMethodChaining('toIVec2', ivec2); -addMethodChaining('toUVec2', uvec2); -addMethodChaining('toBVec2', bvec2); -addMethodChaining('toVec3', vec3); -addMethodChaining('toIVec3', ivec3); -addMethodChaining('toUVec3', uvec3); -addMethodChaining('toBVec3', bvec3); -addMethodChaining('toVec4', vec4); -addMethodChaining('toIVec4', ivec4); -addMethodChaining('toUVec4', uvec4); -addMethodChaining('toBVec4', bvec4); -addMethodChaining('toMat2', mat2); -addMethodChaining('toMat3', mat3); -addMethodChaining('toMat4', mat4); - -// basic nodes - -export const element = /*@__PURE__*/ nodeProxy(ArrayElementNode); -export const convert = (node, types) => nodeObject(new ConvertNode(nodeObject(node), types)); -export const split = (node, channels) => nodeObject(new SplitNode(nodeObject(node), channels)); - -addMethodChaining('element', element); -addMethodChaining('convert', convert); diff --git a/src-testing/src/nodes/utils/ArrayElementNode.d.ts b/src-testing/src/nodes/utils/ArrayElementNode.d.ts deleted file mode 100644 index 650f04047..000000000 --- a/src-testing/src/nodes/utils/ArrayElementNode.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import Node from "../core/Node.js"; -import { TempNode } from "../Nodes.js"; - -export default class ArrayElementNode extends TempNode { - node: Node; - indexNode: Node; - - constructor(node: Node, indexNode: Node); -} diff --git a/src-testing/src/nodes/utils/ConvertNode.d.ts b/src-testing/src/nodes/utils/ConvertNode.d.ts deleted file mode 100644 index 7972df608..000000000 --- a/src-testing/src/nodes/utils/ConvertNode.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -import Node from "../core/Node.js"; - -export default class ConvertNode extends Node { - node: Node; - convertTo: string; - constructor(node: Node, convertTo: string); -} diff --git a/src-testing/src/nodes/utils/CubeMapNode.d.ts b/src-testing/src/nodes/utils/CubeMapNode.d.ts deleted file mode 100644 index 6a5c47371..000000000 --- a/src-testing/src/nodes/utils/CubeMapNode.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -import Node from "../core/Node.js"; -import TempNode from "../core/TempNode.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -declare class CubeMapNode extends TempNode { - envNode: Node; - - constructor(envNode: Node); -} - -export default CubeMapNode; - -export const cubeMapNode: (envNode: NodeRepresentation) => ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/Discard.d.ts b/src-testing/src/nodes/utils/Discard.d.ts deleted file mode 100644 index 819c009b1..000000000 --- a/src-testing/src/nodes/utils/Discard.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -export const Discard: (conditional?: NodeRepresentation) => ShaderNodeObject; -export const Return: () => ShaderNodeObject; - -declare module "../tsl/TSLCore.js" { - interface NodeElements { - discard: typeof Discard; - } -} diff --git a/src-testing/src/nodes/utils/EquirectUVNode.d.ts b/src-testing/src/nodes/utils/EquirectUVNode.d.ts deleted file mode 100644 index 4e85dc40e..000000000 --- a/src-testing/src/nodes/utils/EquirectUVNode.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Node, TempNode } from "../Nodes.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -export default class EquirectUVNode extends TempNode { - constructor(dirNode?: ShaderNodeObject); -} - -export const equirectUV: ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/FunctionOverloadingNode.d.ts b/src-testing/src/nodes/utils/FunctionOverloadingNode.d.ts deleted file mode 100644 index d7c3febb4..000000000 --- a/src-testing/src/nodes/utils/FunctionOverloadingNode.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -import Node from "../core/Node.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -declare class FunctionOverloadingNode extends Node { - functionNodes: Node[]; - parameterNodes: Node[]; - - constructor(functionNodes?: Node[], ...parameterNodes: Node[]); -} - -export default FunctionOverloadingNode; - -export const overloadingFn: (functionNodes: Node[]) => (...params: Node[]) => ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/JoinNode.d.ts b/src-testing/src/nodes/utils/JoinNode.d.ts deleted file mode 100644 index 7f456bafa..000000000 --- a/src-testing/src/nodes/utils/JoinNode.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import Node from "../core/Node.js"; -import { TempNode } from "../Nodes.js"; - -/** - * This node constructs given type from elements, like vec3(a,b,c) - */ -export default class JoinNode extends TempNode { - nodes: Node[]; - constructor(nodes: Node[]); -} diff --git a/src-testing/src/nodes/utils/LoopNode.d.ts b/src-testing/src/nodes/utils/LoopNode.d.ts deleted file mode 100644 index d59518588..000000000 --- a/src-testing/src/nodes/utils/LoopNode.d.ts +++ /dev/null @@ -1,22 +0,0 @@ -import Node from "../core/Node.js"; -import NodeBuilder from "../core/NodeBuilder.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -declare class LoopNode extends Node { - params: unknown[]; - - constructor(params?: unknown[]); - - getProperties(builder: NodeBuilder): unknown; -} - -export default LoopNode; - -export const Loop: (...params: unknown[]) => ShaderNodeObject; -export const Continue: () => ShaderNodeObject; -export const Break: () => ShaderNodeObject; - -/** - * @deprecated loop() has been renamed to Loop() - */ -export const loop: (...params: unknown[]) => ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/MatcapUVNode.d.ts b/src-testing/src/nodes/utils/MatcapUVNode.d.ts deleted file mode 100644 index 7f56667b3..000000000 --- a/src-testing/src/nodes/utils/MatcapUVNode.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import TempNode from "../core/TempNode.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -export default class MatcapUVNode extends TempNode { - constructor(); -} - -export const matcapUV: ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/MaxMipLevelNode.d.ts b/src-testing/src/nodes/utils/MaxMipLevelNode.d.ts deleted file mode 100644 index 455cb77a5..000000000 --- a/src-testing/src/nodes/utils/MaxMipLevelNode.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Texture } from "../../textures/Texture.js"; -import TextureNode from "../accessors/TextureNode.js"; -import UniformNode from "../core/UniformNode.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -export default class MaxMipLevelNode extends UniformNode<0> { - constructor(textureNode: TextureNode); - - get textureNode(): TextureNode; - - get texture(): Texture; -} - -export const maxMipLevel: (texture: Texture) => ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/Oscillators.d.ts b/src-testing/src/nodes/utils/Oscillators.d.ts deleted file mode 100644 index b1a196d43..000000000 --- a/src-testing/src/nodes/utils/Oscillators.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -export const oscSine: (timeNode?: NodeRepresentation) => ShaderNodeObject; -export const oscSquare: (timeNode?: NodeRepresentation) => ShaderNodeObject; -export const oscTriangle: (timeNode?: NodeRepresentation) => ShaderNodeObject; -export const oscSawtooth: (timeNode?: NodeRepresentation) => ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/Packing.d.ts b/src-testing/src/nodes/utils/Packing.d.ts deleted file mode 100644 index 61d0d039e..000000000 --- a/src-testing/src/nodes/utils/Packing.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -export const directionToColor: (node: NodeRepresentation) => ShaderNodeObject; -export const colorToDirection: (node: NodeRepresentation) => ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/PostProcessingUtils.d.ts b/src-testing/src/nodes/utils/PostProcessingUtils.d.ts deleted file mode 100644 index 0406e4d77..000000000 --- a/src-testing/src/nodes/utils/PostProcessingUtils.d.ts +++ /dev/null @@ -1,45 +0,0 @@ -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -/** - * Computes a position in view space based on a fragment's screen position expressed as uv coordinates, the fragments - * depth value and the camera's inverse projection matrix. - * - * @param {vec2} screenPosition - The fragment's screen position expressed as uv coordinates. - * @param {float} depth - The fragment's depth value. - * @param {mat4} projectionMatrixInverse - The camera's inverse projection matrix. - * @return {vec3} The fragments position in view space. - */ -export const getViewPosition: ( - screenPosition: NodeRepresentation, - depth: NodeRepresentation, - projectionMatrixInverse: NodeRepresentation, -) => ShaderNodeObject; - -/** - * Computes a screen position expressed as uv coordinates based on a fragment's position in view space and the camera's - * projection matrix - * - * @param {vec3} viewPosition - The fragments position in view space. - * @param {mat4} projectionMatrix - The camera's projection matrix. - * @return {vec2} The fragment's screen position expressed as uv coordinates. - */ -export const getScreenPosition: ( - viewPosition: NodeRepresentation, - projectionMatrix: NodeRepresentation, -) => ShaderNodeObject; - -/** - * Computes a normal vector based on depth data. Can be used as a fallback when no normal render target is available or - * if flat surface normals are required. - * - * @param {vec2} uv - The texture coordinate. - * @param {DepthTexture} depthTexture - The depth texture. - * @param {mat4} projectionMatrixInverse - The camera's inverse projection matrix. - * @return {vec3} The computed normal vector. - */ -export const getNormalFromDepth: ( - uv: NodeRepresentation, - depthTexture: NodeRepresentation, - projectionMatrixInverse: NodeRepresentation, -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/RTTNode.d.ts b/src-testing/src/nodes/utils/RTTNode.d.ts deleted file mode 100644 index 9f0d3e46e..000000000 --- a/src-testing/src/nodes/utils/RTTNode.d.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { TextureDataType } from "../../constants.js"; -import { RenderTarget } from "../../core/RenderTarget.js"; -import TextureNode from "../accessors/TextureNode.js"; -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -export interface RTTNodeOptions { - type: TextureDataType; -} - -declare class RTTNode extends TextureNode { - node: Node; - width: number | null; - height: number | null; - - renderTarget: RenderTarget | null; - - textureNeedsUpdate: boolean; - autoUpdate: boolean; - - pixelRatio?: number; - - constructor(node: Node, width?: number | null, height?: number | null, options?: RTTNodeOptions); - - get autoSize(): boolean; - - setSize(width: number | null, height: number | null): void; - - setPixelRatio(pixelRatio: number): void; -} - -export default RTTNode; - -export const rtt: ( - node: NodeRepresentation, - width?: number | null, - height?: number | null, - options?: RTTNodeOptions, -) => ShaderNodeObject; -export const convertToTexture: ( - node: Node, - width?: number | null, - height?: number | null, - options?: RTTNodeOptions, -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/ReflectorNode.d.ts b/src-testing/src/nodes/utils/ReflectorNode.d.ts deleted file mode 100644 index 54cd9abfc..000000000 --- a/src-testing/src/nodes/utils/ReflectorNode.d.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { Camera } from "../../cameras/Camera.js"; -import { Object3D } from "../../core/Object3D.js"; -import { RenderTarget } from "../../core/RenderTarget.js"; -import TextureNode from "../accessors/TextureNode.js"; -import Node from "../core/Node.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -export interface ReflectorNodeParameters { - target?: Object3D | undefined; - resolution?: number | undefined; - generateMipmaps?: boolean | undefined; - bounces?: boolean | undefined; -} - -declare class ReflectorNode extends TextureNode { - constructor(parameters?: ReflectorNodeParameters); - - get reflector(): ReflectorBaseNode; - - get target(): Object3D; - - getDepthNode(): ShaderNodeObject; -} - -declare class ReflectorBaseNode extends Node { - textureNode: TextureNode; - - target: Object3D; - resolution: number; - generateMipmaps: boolean; - bounces: boolean; - - virtualCameras: WeakMap; - renderTargets: WeakMap; - - constructor(textureNode: TextureNode, parameters?: ReflectorNodeParameters); - - getVirtualCamera(camera: Camera): Camera; - - getRenderTarget(camera: Camera): RenderTarget; -} - -export const reflector: (parameters?: ReflectorNodeParameters) => ShaderNodeObject; - -export default ReflectorNode; diff --git a/src-testing/src/nodes/utils/RemapNode.d.ts b/src-testing/src/nodes/utils/RemapNode.d.ts deleted file mode 100644 index e50456d0a..000000000 --- a/src-testing/src/nodes/utils/RemapNode.d.ts +++ /dev/null @@ -1,36 +0,0 @@ -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -export default class RemapNode extends Node { - node: Node; - inLowNode: Node; - inHighNode: Node; - outLowNode: Node; - outHighNode: Node; - - doClamp: boolean; - - constructor(node: Node, inLowNode: Node, inHighNode: Node, outLowNode?: Node, outHighNode?: Node); -} - -export const remap: ( - node: Node, - inLowNode: NodeRepresentation, - inHighNode: NodeRepresentation, - outLowNode?: NodeRepresentation, - outHighNode?: NodeRepresentation, -) => ShaderNodeObject; -export const remapClamp: ( - node: Node, - inLowNode: NodeRepresentation, - inHighNode: NodeRepresentation, - outLowNode?: NodeRepresentation, - outHighNode?: NodeRepresentation, -) => ShaderNodeObject; - -declare module "../tsl/TSLCore.js" { - interface NodeElements { - remap: typeof remap; - remapClamp: typeof remapClamp; - } -} diff --git a/src-testing/src/nodes/utils/RotateNode.d.ts b/src-testing/src/nodes/utils/RotateNode.d.ts deleted file mode 100644 index 8f6df796a..000000000 --- a/src-testing/src/nodes/utils/RotateNode.d.ts +++ /dev/null @@ -1,15 +0,0 @@ -import Node from "../core/Node.js"; -import TempNode from "../core/TempNode.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -export default class RotateNode extends TempNode { - positionNode: Node; - rotationNode: Node; - - constructor(positionNode: Node, rotationNode: Node); -} - -export const rotate: ( - positionNode: NodeRepresentation, - rotationNode: NodeRepresentation, -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/SetNode.d.ts b/src-testing/src/nodes/utils/SetNode.d.ts deleted file mode 100644 index 7124d46c3..000000000 --- a/src-testing/src/nodes/utils/SetNode.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -import TempNode from "../core/TempNode.js"; - -declare class SetNode extends TempNode { - sourceNode: Node; - components: string[]; - targetNode: Node; - - constructor(sourceNode: Node, components: string[], targetNode: Node); -} - -export default SetNode; diff --git a/src-testing/src/nodes/utils/SplitNode.d.ts b/src-testing/src/nodes/utils/SplitNode.d.ts deleted file mode 100644 index f3aa50f41..000000000 --- a/src-testing/src/nodes/utils/SplitNode.d.ts +++ /dev/null @@ -1,15 +0,0 @@ -import Node from "../core/Node.js"; -import { SwizzleOption } from "../tsl/TSLCore.js"; - -/** swizzle node */ -export default class SplitNode extends Node { - node: Node; - components: string; - - /** - * @param node the input node - * @param components swizzle like string, default = "x" - */ - constructor(node: Node, components?: SwizzleOption); - getVectorLength(): number; -} diff --git a/src-testing/src/nodes/utils/SpriteSheetUVNode.d.ts b/src-testing/src/nodes/utils/SpriteSheetUVNode.d.ts deleted file mode 100644 index 9e191a390..000000000 --- a/src-testing/src/nodes/utils/SpriteSheetUVNode.d.ts +++ /dev/null @@ -1,16 +0,0 @@ -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -export default class SpriteSheetUVNode extends Node { - countNode: Node; - uvNode: Node; - frameNode: Node; - - constructor(countNode: Node, uvNode?: Node, frameNode?: Node); -} - -export const spritesheetUV: ( - countNode: NodeRepresentation, - uvNode?: NodeRepresentation, - frameNode?: NodeRepresentation, -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/SpriteUtils.d.ts b/src-testing/src/nodes/utils/SpriteUtils.d.ts deleted file mode 100644 index 85884df7b..000000000 --- a/src-testing/src/nodes/utils/SpriteUtils.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -export const billboarding: ( - args?: { position?: NodeRepresentation | null; horizontal?: boolean; vertical?: boolean }, -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/StorageArrayElementNode.d.ts b/src-testing/src/nodes/utils/StorageArrayElementNode.d.ts deleted file mode 100644 index 53ff9a79a..000000000 --- a/src-testing/src/nodes/utils/StorageArrayElementNode.d.ts +++ /dev/null @@ -1,19 +0,0 @@ -import StorageBufferNode from "../accessors/StorageBufferNode.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; -import ArrayElementNode from "./ArrayElementNode.js"; - -export default class StorageArrayElementNode extends ArrayElementNode { - node: StorageBufferNode; - - readonly isStorageArrayElementNode: true; - - constructor(storageBufferNode: StorageBufferNode, indexNode: Node); - - get storageBufferNode(): StorageBufferNode; - set storageBufferNode(value: StorageBufferNode); -} - -export const storageElement: ( - storageBufferNode: NodeRepresentation, - indexNode: NodeRepresentation, -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/Timer.d.ts b/src-testing/src/nodes/utils/Timer.d.ts deleted file mode 100644 index ffad3ed7f..000000000 --- a/src-testing/src/nodes/utils/Timer.d.ts +++ /dev/null @@ -1,21 +0,0 @@ -import Node from "../core/Node.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -export const time: ShaderNodeObject; -export const deltaTime: ShaderNodeObject; -export const frameId: ShaderNodeObject; - -/** - * @deprecated Use "time" instead. - */ -export const timerLocal: (timeScale?: number) => ShaderNodeObject; - -/** - * @deprecated Use "time" instead. - */ -export const timerGlobal: (timeScale?: number) => ShaderNodeObject; - -/** - * @deprecated Use "deltaTime" instead. - */ -export const timerDelta: (timeScale?: number) => ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/TriplanarTexturesNode.d.ts b/src-testing/src/nodes/utils/TriplanarTexturesNode.d.ts deleted file mode 100644 index 1f2875c26..000000000 --- a/src-testing/src/nodes/utils/TriplanarTexturesNode.d.ts +++ /dev/null @@ -1,36 +0,0 @@ -import TextureNode from "../accessors/TextureNode.js"; -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -export default class TriplanarTexturesNode extends Node { - textureXNode: TextureNode; - textureYNode: TextureNode | null; - textureZNode: TextureNode | null; - - scaleNode: ShaderNodeObject; - - positionNode: ShaderNodeObject; - normalNode: ShaderNodeObject; - - constructor( - textureXNode: Node, - textureYNode?: TextureNode | null, - textureZNode?: TextureNode | null, - scaleNode?: ShaderNodeObject, - positionNode?: ShaderNodeObject, - normalNode?: ShaderNodeObject, - ); -} - -export const triplanarTextures: ( - textureXNode: NodeRepresentation, - textureYNode?: NodeRepresentation, - textureZNode?: NodeRepresentation, - scaleNode?: NodeRepresentation, - positionNode?: NodeRepresentation, - normalNode?: NodeRepresentation, -) => ShaderNodeObject; -export const triplanarTexture: ( - texture: NodeRepresentation, - ...params: NodeRepresentation[] -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/UVUtils.d.ts b/src-testing/src/nodes/utils/UVUtils.d.ts deleted file mode 100644 index d375e1e11..000000000 --- a/src-testing/src/nodes/utils/UVUtils.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -import OperatorNode from "../math/OperatorNode.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -export const rotateUV: ( - uv: NodeRepresentation, - rotation: NodeRepresentation, - center?: NodeRepresentation, -) => ShaderNodeObject; - -export const spherizeUV: ( - uv: NodeRepresentation, - strength: NodeRepresentation, - center?: NodeRepresentation, -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/ViewportUtils.d.ts b/src-testing/src/nodes/utils/ViewportUtils.d.ts deleted file mode 100644 index e77e7f350..000000000 --- a/src-testing/src/nodes/utils/ViewportUtils.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -export const viewportSafeUV: (uv?: NodeRepresentation | null) => ShaderNodeObject; diff --git a/src-testing/src/objects/BatchedMesh.d.ts b/src-testing/src/objects/BatchedMesh.d.ts deleted file mode 100644 index 84044f00b..000000000 --- a/src-testing/src/objects/BatchedMesh.d.ts +++ /dev/null @@ -1,275 +0,0 @@ -import { Camera } from "../cameras/Camera.js"; -import { BufferGeometry } from "../core/BufferGeometry.js"; -import { Material } from "../materials/Material.js"; -import { Box3 } from "../math/Box3.js"; -import { Color } from "../math/Color.js"; -import { Matrix4 } from "../math/Matrix4.js"; -import { Sphere } from "../math/Sphere.js"; -import { Mesh } from "./Mesh.js"; - -export interface BatchedMeshGeometryRange { - vertexStart: number; - vertexCount: number; - reservedVertexCount: number; - indexStart: number; - indexCount: number; - reservedIndexCount: number; - start: number; - count: number; -} - -/** - * A special version of {@link Mesh} with multi draw batch rendering support. Use {@link BatchedMesh} if you have to - * render a large number of objects with the same material but with different world transformations. The usage of - * {@link BatchedMesh} will help you to reduce the number of draw calls and thus improve the overall rendering - * performance in your application. - * - * If the {@link https://developer.mozilla.org/en-US/docs/Web/API/WEBGL_multi_draw WEBGL_multi_draw extension} is not - * supported then a less performant fallback is used. - * - * @example - * const box = new THREE.BoxGeometry( 1, 1, 1 ); - * const sphere = new THREE.SphereGeometry( 1, 12, 12 ); - * const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } ); - * - * // initialize and add geometries into the batched mesh - * const batchedMesh = new BatchedMesh( 10, 5000, 10000, material ); - * const boxGeometryId = batchedMesh.addGeometry( box ); - * const sphereGeometryId = batchedMesh.addGeometry( sphere ); - * - * // create instances of those geometries - * const boxInstancedId1 = batchedMesh.addInstance( boxGeometryId ); - * const boxInstancedId2 = batchedMesh.addInstance( boxGeometryId ); - * - * const sphereInstancedId1 = batchedMesh.addInstance( sphereGeometryId ); - * const sphereInstancedId2 = batchedMesh.addInstance( sphereGeometryId ); - * - * // position the geometries - * batchedMesh.setMatrixAt( boxInstancedId1, boxMatrix1 ); - * batchedMesh.setMatrixAt( boxInstancedId2, boxMatrix2 ); - * - * batchedMesh.setMatrixAt( sphereInstancedId1, sphereMatrix1 ); - * batchedMesh.setMatrixAt( sphereInstancedId2, sphereMatrix2 ); - * - * scene.add( batchedMesh ); - * - * @also Example: {@link https://threejs.org/examples/#webgl_mesh_batch WebGL / mesh / batch} - */ -declare class BatchedMesh extends Mesh { - /** - * This bounding box encloses all instances of the {@link BatchedMesh}. Can be calculated with - * {@link .computeBoundingBox()}. - * @default null - */ - boundingBox: Box3 | null; - - /** - * This bounding sphere encloses all instances of the {@link BatchedMesh}. Can be calculated with - * {@link .computeBoundingSphere()}. - * @default null - */ - boundingSphere: Sphere | null; - - customSort: ((this: this, list: Array<{ start: number; count: number; z: number }>, camera: Camera) => void) | null; - - /** - * If true then the individual objects within the {@link BatchedMesh} are frustum culled. - * @default true - */ - perObjectFrustumCulled: boolean; - - /** - * If true then the individual objects within the {@link BatchedMesh} are sorted to improve overdraw-related - * artifacts. If the material is marked as "transparent" objects are rendered back to front and if not then they are - * rendered front to back. - * @default true - */ - sortObjects: boolean; - - /** - * The maximum number of individual geometries that can be stored in the {@link BatchedMesh}. Read only. - */ - get maxInstanceCount(): number; - - get instanceCount(): number; - - get unusedVertexCount(): number; - - get unusedIndexCount(): number; - - /** - * Read-only flag to check if a given object is of type {@link BatchedMesh}. - */ - readonly isBatchedMesh: true; - - /** - * @param maxInstanceCount the max number of individual geometries planned to be added. - * @param maxVertexCount the max number of vertices to be used by all geometries. - * @param maxIndexCount the max number of indices to be used by all geometries. - * @param material an instance of {@link Material}. Default is a new {@link MeshBasicMaterial}. - */ - constructor(maxInstanceCount: number, maxVertexCount: number, maxIndexCount?: number, material?: Material); - - /** - * Computes the bounding box, updating {@link .boundingBox} attribute. - * Bounding boxes aren't computed by default. They need to be explicitly computed, otherwise they are `null`. - */ - computeBoundingBox(): void; - - /** - * Computes the bounding sphere, updating {@link .boundingSphere} attribute. - * Bounding spheres aren't computed by default. They need to be explicitly computed, otherwise they are `null`. - */ - computeBoundingSphere(): void; - - /** - * Frees the GPU-related resources allocated by this instance. Call this method whenever this instance is no longer - * used in your app. - */ - dispose(): this; - - /** - * Takes a sort a function that is run before render. The function takes a list of instances to sort and a camera. - * The objects in the list include a "z" field to perform a depth-ordered sort with. - */ - setCustomSort( - sortFunction: - | ((this: this, list: Array<{ start: number; count: number; z: number }>, camera: Camera) => void) - | null, - ): this; - - /** - * Get the color of the defined geometry. - * @param instanceId The id of an instance to get the color of. - * @param target The target object to copy the color in to. - */ - getColorAt(instanceId: number, target: Color): void; - - /** - * Get the local transformation matrix of the defined instance. - * @param instanceId The id of an instance to get the matrix of. - * @param target This 4x4 matrix will be set to the local transformation matrix of the defined instance. - */ - getMatrixAt(instanceId: number, target: Matrix4): Matrix4; - - /** - * Get whether the given instance is marked as "visible" or not. - * @param instanceId The id of an instance to get the visibility state of. - */ - getVisibleAt(instanceId: number): boolean; - - /** - * Get the range representing the subset of triangles related to the attached geometry, indicating the starting - * offset and count, or `null` if invalid. - * - * Return an object of the form: { start: Integer, count: Integer } - * @param geometryId The id of the geometry to get the range of. - * @param target Optional target object to copy the range in to. - */ - getGeometryRangeAt( - geometryId: number, - target?: BatchedMeshGeometryRange, - ): BatchedMeshGeometryRange | null; - - /** - * Get the geometryIndex of the defined instance. - * @param instanceId The id of an instance to get the geometryIndex of. - */ - getGeometryIdAt(instanceId: number): number; - - /** - * Sets the given color to the defined geometry instance. - * @param instanceId The id of the instance to set the color of. - * @param color The color to set the instance to. - */ - setColorAt(instanceId: number, color: Color): void; - - /** - * Sets the given local transformation matrix to the defined instance. - * @param instanceId The id of an instance to set the matrix of. - * @param matrix A 4x4 matrix representing the local transformation of a single instance. - */ - setMatrixAt(instanceId: number, matrix: Matrix4): this; - - /** - * Sets the visibility of the instance at the given index. - * @param instanceId The id of the instance to set the visibility of. - * @param visible A boolean value indicating the visibility state. - */ - setVisibleAt(instanceId: number, visible: boolean): this; - - /** - * Sets the geometryIndex of the instance at the given index. - * @param instanceId The id of the instance to set the geometryIndex of. - * @param geometryId The geometryIndex to be use by the instance. - */ - setGeometryIdAt(instanceId: number, geometryId: number): this; - - /** - * Adds the given geometry to the {@link BatchedMesh} and returns the associated index referring to it. - * @param geometry The geometry to add into the {@link BatchedMesh}. - * @param reservedVertexRange Optional parameter specifying the amount of vertex buffer space to reserve for the - * added geometry. This is necessary if it is planned to set a new geometry at this index at a later time that is - * larger than the original geometry. Defaults to the length of the given geometry vertex buffer. - * @param reservedIndexRange Optional parameter specifying the amount of index buffer space to reserve for the added - * geometry. This is necessary if it is planned to set a new geometry at this index at a later time that is larger - * than the original geometry. Defaults to the length of the given geometry index buffer. - */ - addGeometry(geometry: BufferGeometry, reservedVertexRange?: number, reservedIndexRange?: number): number; - - /** - * Adds a new instance to the {@link BatchedMesh} using the geometry of the given geometryId and returns a new id - * referring to the new instance to be used by other functions. - * @param geometryId The id of a previously added geometry via "addGeometry" to add into the {@link BatchedMesh} to - * render. - */ - addInstance(geometryId: number): number; - - /** - * @param geometryId The id of a geometry to remove from the [name] that was previously added via "addGeometry". Any - * instances referencing this geometry will also be removed as a side effect. - */ - deleteGeometry(geometryId: number): this; - - /** - * Removes an existing instance from the BatchedMesh using the given instanceId. - * @param instanceId The id of an instance to remove from the BatchedMesh that was previously added via - * "addInstance". - */ - deleteInstance(instanceId: number): this; - - /** - * Replaces the geometry at `geometryId` with the provided geometry. Throws an error if there is not enough space - * reserved for geometry. Calling this will change all instances that are rendering that geometry. - * @param geometryId Which geometry id to replace with this geometry. - * @param geometry The geometry to substitute at the given geometry id. - */ - setGeometryAt(geometryId: number, geometry: BufferGeometry): number; - - /** - * Repacks the sub geometries in [name] to remove any unused space remaining from previously deleted geometry, - * freeing up space to add new geometry. - */ - optimize(): this; - - /** - * Resizes the available space in BatchedMesh's vertex and index buffer attributes to the provided sizes. If the - * provided arguments shrink the geometry buffers but there is not enough unused space at the end of the geometry - * attributes then an error is thrown. - * @param maxVertexCount the max number of vertices to be used by all unique geometries to resize to. - * @param maxIndexCount the max number of indices to be used by all unique geometries to resize to. - */ - setGeometrySize(maxVertexCount: number, maxIndexCount: number): void; - - /** - * Resizes the necessary buffers to support the provided number of instances. If the provided arguments shrink the - * number of instances but there are not enough unused ids at the end of the list then an error is thrown. - * @param maxInstanceCount the max number of individual instances that can be added and rendered by the BatchedMesh. - */ - setInstanceCount(maxInstanceCount: number): void; - - getBoundingBoxAt(geometryId: number, target: Box3): Box3 | null; - getBoundingSphereAt(geometryId: number, target: Sphere): Sphere | null; -} - -export { BatchedMesh }; diff --git a/src-testing/src/objects/Bone.d.ts b/src-testing/src/objects/Bone.d.ts deleted file mode 100644 index 3400ea1b6..000000000 --- a/src-testing/src/objects/Bone.d.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { Object3D, Object3DEventMap } from "../core/Object3D.js"; - -/** - * A {@link Bone} which is part of a {@link THREE.Skeleton | Skeleton} - * @remarks - * The skeleton in turn is used by the {@link THREE.SkinnedMesh | SkinnedMesh} - * Bones are almost identical to a blank {@link THREE.Object3D | Object3D}. - * @example - * ```typescript - * const root = new THREE.Bone(); - * const child = new THREE.Bone(); - * root.add(child); - * child.position.y = 5; - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/objects/Bone | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/objects/Bone.js | Source} - */ -export class Bone extends Object3D { - /** - * Creates a new {@link Bone}. - */ - constructor(); - - /** - * Read-only flag to check if a given object is of type {@link Bone}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isBone: true; - - /** - * @override - * @defaultValue `Bone` - */ - override readonly type: string | "Bone"; -} diff --git a/src-testing/src/objects/Group.d.ts b/src-testing/src/objects/Group.d.ts deleted file mode 100644 index 4b882d2e9..000000000 --- a/src-testing/src/objects/Group.d.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { Object3D, Object3DEventMap } from "../core/Object3D.js"; - -/** - * Its purpose is to make working with groups of objects syntactically clearer. - * @remarks This is almost identical to an {@link Object3D | Object3D} - * @example - * ```typescript - * const geometry = new THREE.BoxGeometry(1, 1, 1); - * const material = new THREE.MeshBasicMaterial({ - * color: 0x00ff00 - * }); - * const cubeA = new THREE.Mesh(geometry, material); - * cubeA.position.set(100, 100, 0); - * const cubeB = new THREE.Mesh(geometry, material); - * cubeB.position.set(-100, -100, 0); - * //create a {@link Group} and add the two cubes - * //These cubes can now be rotated / scaled etc as a {@link Group} * const {@link Group} = new THREE.Group(); - * group.add(cubeA); - * group.add(cubeB); - * scene.add(group); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/objects/Group | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/objects/Group.js | Source} - */ -export class Group extends Object3D { - /** - * Creates a new {@link Group}. - */ - constructor(); - - /** - * Read-only flag to check if a given object is of type {@link Group}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isGroup: true; -} diff --git a/src-testing/src/objects/InstancedMesh.d.ts b/src-testing/src/objects/InstancedMesh.d.ts deleted file mode 100644 index b239afb7a..000000000 --- a/src-testing/src/objects/InstancedMesh.d.ts +++ /dev/null @@ -1,179 +0,0 @@ -import { BufferAttributeJSON } from "./../core/BufferAttribute.js"; -import { BufferGeometry } from "../core/BufferGeometry.js"; -import { InstancedBufferAttribute } from "../core/InstancedBufferAttribute.js"; -import { JSONMeta, Object3DEventMap } from "../core/Object3D.js"; -import { Material } from "../materials/Material.js"; -import { Box3 } from "../math/Box3.js"; -import { Color } from "../math/Color.js"; -import { Matrix4 } from "../math/Matrix4.js"; -import { Sphere } from "../math/Sphere.js"; -import { DataTexture } from "../textures/DataTexture.js"; -import { Mesh, MeshJSONObject } from "./Mesh.js"; - -export interface InstancedMeshJSONObject extends MeshJSONObject { - count: number; - instanceMatrix: BufferAttributeJSON; - instanceColor?: BufferAttributeJSON; -} - -export interface InstancedMeshJSON extends MeshJSONObject { - object: InstancedMeshJSONObject; -} - -export interface InstancedMeshEventMap extends Object3DEventMap { - dispose: {}; -} - -/** - * A special version of {@link THREE.Mesh | Mesh} with instanced rendering support - * @remarks - * Use {@link InstancedMesh} if you have to render a large number of objects with the same geometry and material(s) but with different world transformations - * @remarks - * The usage of {@link InstancedMesh} will help you to reduce the number of draw calls and thus improve the overall rendering performance in your application. - * @see Example: {@link https://threejs.org/examples/#webgl_instancing_dynamic | WebGL / instancing / dynamic} - * @see Example: {@link https://threejs.org/examples/#webgl_instancing_performance | WebGL / instancing / performance} - * @see Example: {@link https://threejs.org/examples/#webgl_instancing_scatter | WebGL / instancing / scatter} - * @see Example: {@link https://threejs.org/examples/#webgl_instancing_raycast | WebGL / instancing / raycast} - * @see {@link https://threejs.org/docs/index.html#api/en/objects/InstancedMesh | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/objects/InstancedMesh.js | Source} - */ -export class InstancedMesh< - TGeometry extends BufferGeometry = BufferGeometry, - TMaterial extends Material | Material[] = Material | Material[], - TEventMap extends InstancedMeshEventMap = InstancedMeshEventMap, -> extends Mesh { - /** - * Create a new instance of {@link InstancedMesh} - * @param geometry An instance of {@link BufferGeometry}. - * @param material A single or an array of {@link Material}. Default is a new {@link MeshBasicMaterial}. - * @param count The **maximum** number of instances of this Mesh. Expects a `Integer` - */ - constructor(geometry: TGeometry | undefined, material: TMaterial | undefined, count: number); - - /** - * Read-only flag to check if a given object is of type {@link InstancedMesh}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isInstancedMesh: true; - - /** - * This bounding box encloses all instances of the {@link InstancedMesh},, which can be calculated with {@link computeBoundingBox | .computeBoundingBox()}. - * @remarks Bounding boxes aren't computed by default. They need to be explicitly computed, otherwise they are `null`. - * @defaultValue `null` - */ - boundingBox: Box3 | null; - - /** - * This bounding sphere encloses all instances of the {@link InstancedMesh}, which can be calculated with {@link computeBoundingSphere | .computeBoundingSphere()}. - * @remarks bounding spheres aren't computed by default. They need to be explicitly computed, otherwise they are `null`. - * @defaultValue `null` - */ - boundingSphere: Sphere | null; - - /** - * The number of instances. - * @remarks - * The `count` value passed into the {@link InstancedMesh | constructor} represents the **maximum** number of instances of this mesh. - * You can change the number of instances at runtime to an integer value in the range `[0, count]`. - * @remarks If you need more instances than the original `count` value, you have to create a new InstancedMesh. - * @remarks Expects a `Integer` - */ - count: number; - - /** - * Represents the colors of all instances. - * You have to set {@link InstancedBufferAttribute.needsUpdate | .instanceColor.needsUpdate()} flag to `true` if you modify instanced data via {@link setColorAt | .setColorAt()}. - * @defaultValue `null` - */ - instanceColor: InstancedBufferAttribute | null; - - /** - * Represents the local transformation of all instances. - * You have to set {@link InstancedBufferAttribute.needsUpdate | .instanceMatrix.needsUpdate()} flag to `true` if you modify instanced data via {@link setMatrixAt | .setMatrixAt()}. - */ - instanceMatrix: InstancedBufferAttribute; - - /** - * Represents the morph target weights of all instances. You have to set its {@link .needsUpdate} flag to true if - * you modify instanced data via {@link .setMorphAt}. - */ - morphTexture: DataTexture | null; - - /** - * Computes the bounding box of the instanced mesh, and updates the {@link .boundingBox} attribute. The bounding box - * is not computed by the engine; it must be computed by your app. You may need to recompute the bounding box if an - * instance is transformed via {@link .setMatrixAt()}. - */ - computeBoundingBox(): void; - - /** - * Computes the bounding sphere of the instanced mesh, and updates the {@link .boundingSphere} attribute. The engine - * automatically computes the bounding sphere when it is needed, e.g., for ray casting or view frustum culling. You - * may need to recompute the bounding sphere if an instance is transformed via [page:.setMatrixAt](). - */ - computeBoundingSphere(): void; - - /** - * Get the color of the defined instance. - * @param index The index of an instance. Values have to be in the range `[0, count]`. Expects a `Integer` - * @param color This color object will be set to the color of the defined instance. - */ - getColorAt(index: number, color: Color): void; - - /** - * Sets the given color to the defined instance - * @remarks - * Make sure you set {@link InstancedBufferAttribute.needsUpdate | .instanceColor.needsUpdate()} to `true` after updating all the colors. - * @param index The index of an instance. Values have to be in the range `[0, count]`. Expects a `Integer` - * @param color The color of a single instance. - */ - setColorAt(index: number, color: Color): void; - - /** - * Get the local transformation matrix of the defined instance. - * @param index The index of an instance Values have to be in the range `[0, count]`. Expects a `Integer` - * @param matrix This 4x4 matrix will be set to the local transformation matrix of the defined instance. - */ - getMatrixAt(index: number, matrix: Matrix4): void; - - /** - * Get the morph target weights of the defined instance. - * @param index The index of an instance. Values have to be in the range [0, count]. - * @param mesh The {@link .morphTargetInfluences} property of this mesh will be filled with the morph target weights of the defined instance. - */ - getMorphAt(index: number, mesh: Mesh): void; - - /** - * Sets the given local transformation matrix to the defined instance. - * @remarks - * Make sure you set {@link InstancedBufferAttribute.needsUpdate | .instanceMatrix.needsUpdate()} flag to `true` after updating all the matrices. - * @param index The index of an instance. Values have to be in the range `[0, count]`. Expects a `Integer` - * @param matrix A 4x4 matrix representing the local transformation of a single instance. - */ - setMatrixAt(index: number, matrix: Matrix4): void; - - /** - * Sets the morph target weights to the defined instance. Make sure you set {@link .morphTexture}{@link .needsUpdate} - * to true after updating all the influences. - * @param index The index of an instance. Values have to be in the range [0, count]. - * @param mesh A mesh with {@link .morphTargetInfluences} property containing the morph target weights of a single instance. - */ - setMorphAt(index: number, mesh: Mesh): void; - - /** - * No effect in {@link InstancedMesh}. - * @ignore - * @hidden - */ - override updateMorphTargets(): void; - - /** - * Frees the GPU-related resources allocated by this instance - * @remarks - * Call this method whenever this instance is no longer used in your app. - */ - dispose(): this; - - toJSON(meta?: JSONMeta): InstancedMeshJSON; -} diff --git a/src-testing/src/objects/LOD.d.ts b/src-testing/src/objects/LOD.d.ts deleted file mode 100644 index 2440b8503..000000000 --- a/src-testing/src/objects/LOD.d.ts +++ /dev/null @@ -1,111 +0,0 @@ -import { Camera } from "../cameras/Camera.js"; -import { JSONMeta, Object3D, Object3DEventMap, Object3DJSON, Object3DJSONObject } from "../core/Object3D.js"; - -export interface LODJSONObject extends Object3DJSONObject { - autoUpdate?: boolean; - - levels: Array<{ - object: string; - distance: number; - hysteresis: number; - }>; -} - -export interface LODJSON extends Object3DJSON { - object: LODJSONObject; -} - -/** - * Every level is associated with an object, and rendering can be switched between them at the distances specified - * @remarks - * Typically you would create, say, three meshes, one for far away (low detail), one for mid range (medium detail) and one for close up (high detail). - * @example - * ```typescript - * const {@link LOD} = new THREE.LOD(); - * //Create spheres with 3 levels of detail and create new {@link LOD} levels for them - * for (let i = 0; i & lt; 3; i++) { - * const geometry = new THREE.IcosahedronGeometry(10, 3 - i) - * const mesh = new THREE.Mesh(geometry, material); - * lod.addLevel(mesh, i * 75); - * } - * scene.add(lod); - * ``` - * @see Example: {@link https://threejs.org/examples/#webgl_lod | webgl / {@link LOD} } - * @see {@link https://threejs.org/docs/index.html#api/en/objects/LOD | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/objects/LOD.js | Source} - */ -export class LOD extends Object3D { - /** - * Creates a new {@link LOD}. - */ - constructor(); - - /** - * Read-only flag to check if a given object is of type {@link LOD}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isLOD: true; - - /** - * @override - * @defaultValue `LOD` - */ - override readonly type: string | "LOD"; - - /** - * An array of level objects - */ - levels: Array<{ - /** The Object3D to display at this level. */ - object: Object3D; - /** The distance at which to display this level of detail. Expects a `Float`. */ - distance: number; - /** Threshold used to avoid flickering at LOD boundaries, as a fraction of distance. Expects a `Float`. */ - hysteresis: number; - }>; - - /** - * Whether the {@link LOD} object is updated automatically by the renderer per frame or not. - * If set to `false`, you have to call {@link update | .update()} in the render loop by yourself. - * @defaultValue `true` - */ - autoUpdate: boolean; - - /** - * Adds a mesh that will display at a certain distance and greater. Typically the further away the distance, the lower the detail on the mesh. - * - * @param object The Object3D to display at this level. - * @param distance The distance at which to display this level of detail. Expects a `Float`. Default `0.0`. - * @param hysteresis Threshold used to avoid flickering at LOD boundaries, as a fraction of distance. Expects a `Float`. Default `0.0`. - */ - addLevel(object: Object3D, distance?: number, hysteresis?: number): this; - - /** - * Removes an existing level, based on the distance from the camera. Returns `true` when the level has been removed. - * Otherwise `false`. - * @param distance Distance of the level to delete. - */ - removeLabel(distance: number): boolean; - - /** - * Get the currently active {@link LOD} level - * @remarks - * As index of the levels array. - */ - getCurrentLevel(): number; - - /** - * Get a reference to the first {@link THREE.Object3D | Object3D} (mesh) that is greater than {@link distance}. - * @param distance Expects a `Float` - */ - getObjectForDistance(distance: number): Object3D | null; - - /** - * Set the visibility of each {@link levels | level}'s {@link THREE.Object3D | object} based on distance from the {@link THREE.Camera | camera}. - * @param camera - */ - update(camera: Camera): void; - - toJSON(meta?: JSONMeta): LODJSON; -} diff --git a/src-testing/src/objects/Line.d.ts b/src-testing/src/objects/Line.d.ts deleted file mode 100644 index 2d76dec69..000000000 --- a/src-testing/src/objects/Line.d.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { BufferGeometry } from "../core/BufferGeometry.js"; -import { Object3D, Object3DEventMap } from "../core/Object3D.js"; -import { Material } from "../materials/Material.js"; - -/** - * A continuous line. - * @remarks - * This is nearly the same as {@link THREE.LineSegments | LineSegments}, - * the only difference is that it is rendered using {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/drawElements | gl.LINE_STRIP} - * instead of {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/drawElements | gl.LINES} - * @example - * ```typescript - * const material = new THREE.LineBasicMaterial({ - * color: 0x0000ff - * }); - * const points = []; - * points.push(new THREE.Vector3(-10, 0, 0)); - * points.push(new THREE.Vector3(0, 10, 0)); - * points.push(new THREE.Vector3(10, 0, 0)); - * const geometry = new THREE.BufferGeometry().setFromPoints(points); - * const {@link Line} = new THREE.Line(geometry, material); - * scene.add(line); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/objects/Line | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/objects/Line.js | Source} - */ -export class Line< - TGeometry extends BufferGeometry = BufferGeometry, - TMaterial extends Material | Material[] = Material | Material[], - TEventMap extends Object3DEventMap = Object3DEventMap, -> extends Object3D { - /** - * Create a new instance of {@link Line} - * @param geometry Vertices representing the {@link Line} segment(s). Default {@link THREE.BufferGeometry | `new THREE.BufferGeometry()`}. - * @param material Material for the line. Default {@link THREE.LineBasicMaterial | `new THREE.LineBasicMaterial()`}. - */ - constructor(geometry?: TGeometry, material?: TMaterial); - - /** - * Read-only flag to check if a given object is of type {@link Line}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isLine: true; - - /** - * @override - * @defaultValue `Line` - */ - override readonly type: string | "Line"; - - /** - * Vertices representing the {@link Line} segment(s). - */ - geometry: TGeometry; - - /** - * Material for the line. - */ - material: TMaterial; - - /** - * An array of weights typically from `0-1` that specify how much of the morph is applied. - * @defaultValue `undefined`, but reset to a blank array by {@link updateMorphTargets | .updateMorphTargets()}. - */ - morphTargetInfluences?: number[] | undefined; - - /** - * A dictionary of morphTargets based on the `morphTarget.name` property. - * @defaultValue `undefined`, but reset to a blank array by {@link updateMorphTargets | .updateMorphTargets()}. - */ - morphTargetDictionary?: { [key: string]: number } | undefined; - - /** - * Computes an array of distance values which are necessary for {@link THREE.LineDashedMaterial | LineDashedMaterial} - * @remarks - * For each vertex in the geometry, the method calculates the cumulative length from the current point to the very beginning of the line. - */ - computeLineDistances(): this; - - /** - * Updates the morphTargets to have no influence on the object - * @remarks - * Resets the {@link morphTargetInfluences | .morphTargetInfluences} and {@link morphTargetDictionary | .morphTargetDictionary} properties. - */ - updateMorphTargets(): void; -} diff --git a/src-testing/src/objects/LineLoop.d.ts b/src-testing/src/objects/LineLoop.d.ts deleted file mode 100644 index 0a070a838..000000000 --- a/src-testing/src/objects/LineLoop.d.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { BufferGeometry } from "../core/BufferGeometry.js"; -import { Object3DEventMap } from "../core/Object3D.js"; -import { Material } from "../materials/Material.js"; -import { Line } from "./Line.js"; - -/** - * A continuous line that connects back to the start. - * @remarks - * This is nearly the same as {@link THREE.Line | Line}, - * the only difference is that it is rendered using {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/drawElements | gl.LINE_LOOP} - * instead of {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/drawElements | gl.LINE_STRIP}, - * which draws a straight line to the next vertex, and connects the last vertex back to the first. - * @see {@link https://threejs.org/docs/index.html#api/en/objects/LineLoop | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/objects/LineLoop.js | Source} - */ -export class LineLoop< - TGeometry extends BufferGeometry = BufferGeometry, - TMaterial extends Material | Material[] = Material | Material[], - TEventMap extends Object3DEventMap = Object3DEventMap, -> extends Line { - /** - * Create a new instance of {@link LineLoop} - * @param geometry List of vertices representing points on the line loop. Default {@link THREE.BufferGeometry | `new THREE.BufferGeometry()`}. - * @param material Material for the line. Default {@link THREE.LineBasicMaterial | `new THREE.LineBasicMaterial()`}. - */ - constructor(geometry?: TGeometry, material?: TMaterial); - - /** - * Read-only flag to check if a given object is of type {@link LineLoop}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isLineLoop: true; - - /** - * @override - * @defaultValue `LineLoop` - */ - override readonly type: string | "LineLoop"; -} diff --git a/src-testing/src/objects/LineSegments.d.ts b/src-testing/src/objects/LineSegments.d.ts deleted file mode 100644 index 9a8199bdc..000000000 --- a/src-testing/src/objects/LineSegments.d.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { BufferGeometry } from "../core/BufferGeometry.js"; -import { Object3DEventMap } from "../core/Object3D.js"; -import { Material } from "../materials/Material.js"; -import { Line } from "./Line.js"; - -/** - * A series of lines drawn between pairs of vertices. - * @remarks - * This is nearly the same as {@link THREE.Line | Line}, - * the only difference is that it is rendered using {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/drawElements | gl.LINES} - * instead of {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/drawElements | gl.LINE_STRIP}. - * @see {@link https://threejs.org/docs/index.html#api/en/objects/LineSegments | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/objects/LineSegments.js | Source} - */ -export class LineSegments< - TGeometry extends BufferGeometry = BufferGeometry, - TMaterial extends Material | Material[] = Material | Material[], - TEventMap extends Object3DEventMap = Object3DEventMap, -> extends Line { - /** - * Create a new instance of {@link LineSegments} - * @param geometry Pair(s) of vertices representing each line segment(s). Default {@link THREE.BufferGeometry | `new THREE.BufferGeometry()`}. - * @param material Material for the line. Default {@link THREE.LineBasicMaterial | `new THREE.LineBasicMaterial()`}. - */ - constructor(geometry?: TGeometry, material?: TMaterial); - - /** - * Read-only flag to check if a given object is of type {@link LineSegments}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isLineSegments: true; - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @override - * @defaultValue `LineSegments` - */ - override readonly type: string | "LineSegments"; -} diff --git a/src-testing/src/objects/Mesh.d.ts b/src-testing/src/objects/Mesh.d.ts deleted file mode 100644 index 38dad1c73..000000000 --- a/src-testing/src/objects/Mesh.d.ts +++ /dev/null @@ -1,94 +0,0 @@ -import { BufferGeometry } from "../core/BufferGeometry.js"; -import { JSONMeta, Object3D, Object3DEventMap, Object3DJSON, Object3DJSONObject } from "../core/Object3D.js"; -import { Material } from "../materials/Material.js"; -import { Vector3 } from "../math/Vector3.js"; - -export interface MeshJSONObject extends Object3DJSONObject { - geometry: string; -} - -export interface MeshJSON extends Object3DJSON { - object: MeshJSONObject; -} - -/** - * Class representing triangular {@link https://en.wikipedia.org/wiki/Polygon_mesh | polygon mesh} based objects. - * @remarks - * Also serves as a base for other classes such as {@link THREE.SkinnedMesh | SkinnedMesh}, {@link THREE.InstancedMesh | InstancedMesh}. - * @example - * ```typescript - * const geometry = new THREE.BoxGeometry(1, 1, 1); - * const material = new THREE.MeshBasicMaterial({ - * color: 0xffff00 - * }); - * const {@link Mesh} = new THREE.Mesh(geometry, material); - * scene.add(mesh); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/objects/Mesh | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/objects/Mesh.js | Source} - */ -export class Mesh< - TGeometry extends BufferGeometry = BufferGeometry, - TMaterial extends Material | Material[] = Material | Material[], - TEventMap extends Object3DEventMap = Object3DEventMap, -> extends Object3D { - /** - * Create a new instance of {@link Mesh} - * @param geometry An instance of {@link THREE.BufferGeometry | BufferGeometry}. Default {@link THREE.BufferGeometry | `new THREE.BufferGeometry()`}. - * @param material A single or an array of {@link THREE.Material | Material}. Default {@link THREE.MeshBasicMaterial | `new THREE.MeshBasicMaterial()`}. - */ - constructor(geometry?: TGeometry, material?: TMaterial); - - /** - * Read-only flag to check if a given object is of type {@link Mesh}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isMesh: true; - - /** - * @override - * @defaultValue `Mesh` - */ - override readonly type: string | "Mesh"; - - /** - * An instance of {@link THREE.BufferGeometry | BufferGeometry} (or derived classes), defining the object's structure. - * @defaultValue {@link THREE.BufferGeometry | `new THREE.BufferGeometry()`}. - */ - geometry: TGeometry; - - /** - * An instance of material derived from the {@link THREE.Material | Material} base class or an array of materials, defining the object's appearance. - * @defaultValue {@link THREE.MeshBasicMaterial | `new THREE.MeshBasicMaterial()`}. - */ - material: TMaterial; - - /** - * An array of weights typically from `0-1` that specify how much of the morph is applied. - * @defaultValue `undefined`, _but reset to a blank array by {@link updateMorphTargets | .updateMorphTargets()}._ - */ - morphTargetInfluences?: number[] | undefined; - - /** - * A dictionary of morphTargets based on the `morphTarget.name` property. - * @defaultValue `undefined`, _but rebuilt by {@link updateMorphTargets | .updateMorphTargets()}._ - */ - morphTargetDictionary?: { [key: string]: number } | undefined; - - /** - * Updates the morphTargets to have no influence on the object - * @remarks Resets the {@link morphTargetInfluences} and {@link morphTargetDictionary} properties. - */ - updateMorphTargets(): void; - - /** - * Get the local-space position of the vertex at the given index, - * taking into account the current animation state of both morph targets and skinning. - * @param index Expects a `Integer` - * @param target - */ - getVertexPosition(index: number, target: Vector3): Vector3; - - toJSON(meta?: JSONMeta): MeshJSON; -} diff --git a/src-testing/src/objects/Points.d.ts b/src-testing/src/objects/Points.d.ts deleted file mode 100644 index 3cba2c74b..000000000 --- a/src-testing/src/objects/Points.d.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { BufferGeometry, NormalOrGLBufferAttributes } from "../core/BufferGeometry.js"; -import { Object3D, Object3DEventMap } from "../core/Object3D.js"; -import { Material } from "../materials/Material.js"; - -/** - * A class for displaying {@link Points} - * @remarks - * The {@link Points} are rendered by the {@link THREE.WebGLRenderer | WebGLRenderer} using {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/drawElements | gl.POINTS}. - * @see {@link https://threejs.org/docs/index.html#api/en/objects/Points | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/objects/Points.js | Source} - */ -export class Points< - TGeometry extends BufferGeometry = BufferGeometry, - TMaterial extends Material | Material[] = Material | Material[], - TEventMap extends Object3DEventMap = Object3DEventMap, -> extends Object3D { - /** - * Create a new instance of {@link Points} - * @param geometry An instance of {@link THREE.BufferGeometry | BufferGeometry}. Default {@link THREE.BufferGeometry | `new THREE.BufferGeometry()`}. - * @param material A single or an array of {@link THREE.Material | Material}. Default {@link THREE.PointsMaterial | `new THREE.PointsMaterial()`}. - */ - constructor(geometry?: TGeometry, material?: TMaterial); - - /** - * Read-only flag to check if a given object is of type {@link Points}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isPoints: true; - - /** - * @override - * @defaultValue `Points` - */ - override readonly type: string | "Points"; - - /** - * An array of weights typically from `0-1` that specify how much of the morph is applied. - * @defaultValue `undefined`, _but reset to a blank array by {@link updateMorphTargets | .updateMorphTargets()}._ - */ - morphTargetInfluences?: number[] | undefined; - - /** - * A dictionary of morphTargets based on the `morphTarget.name` property. - * @defaultValue `undefined`, _but rebuilt by {@link updateMorphTargets | .updateMorphTargets()}._ - */ - morphTargetDictionary?: { [key: string]: number } | undefined; - - /** - * An instance of {@link THREE.BufferGeometry | BufferGeometry} (or derived classes), defining the object's structure. - * @remarks each vertex designates the position of a particle in the system. - */ - geometry: TGeometry; - - /** - * An instance of {@link THREE.Material | Material}, defining the object's appearance. - * @defaultValue {@link THREE.PointsMaterial | `new THREE.PointsMaterial()`}, _with randomised colour_. - */ - material: TMaterial; - - /** - * Updates the morphTargets to have no influence on the object - * @remarks Resets the {@link morphTargetInfluences} and {@link morphTargetDictionary} properties. - */ - updateMorphTargets(): void; -} diff --git a/src-testing/src/objects/Skeleton.d.ts b/src-testing/src/objects/Skeleton.d.ts deleted file mode 100644 index aaeb3198b..000000000 --- a/src-testing/src/objects/Skeleton.d.ts +++ /dev/null @@ -1,120 +0,0 @@ -import { Matrix4, Matrix4Tuple } from "../math/Matrix4.js"; -import { DataTexture } from "../textures/DataTexture.js"; -import { Bone } from "./Bone.js"; - -export interface SkeletonJSON { - metadata: { version: number; type: string; generator: string }; - bones: string[]; - boneInverses: Matrix4Tuple[]; - uuid: string; -} - -/** - * Use an array of {@link Bone | bones} to create a {@link Skeleton} that can be used by a {@link THREE.SkinnedMesh | SkinnedMesh}. - * @example - * ```typescript - * // Create a simple "arm" - * const bones = []; - * const shoulder = new THREE.Bone(); - * const elbow = new THREE.Bone(); - * const hand = new THREE.Bone(); - * shoulder.add(elbow); - * elbow.add(hand); - * bones.push(shoulder); - * bones.push(elbow); - * bones.push(hand); - * shoulder.position.y = -5; - * elbow.position.y = 0; - * hand.position.y = 5; - * const armSkeleton = new THREE.Skeleton(bones); - * See the[page: SkinnedMesh] page - * for an example of usage with standard[page: BufferGeometry]. - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/objects/Skeleton | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/objects/Skeleton.js | Source} - */ -export class Skeleton { - /** - * Creates a new Skeleton. - * @param bones The array of {@link THREE.Bone | bones}. Default `[]`. - * @param boneInverses An array of {@link THREE.Matrix4 | Matrix4s}. Default `[]`. - */ - constructor(bones?: Bone[], boneInverses?: Matrix4[]); - - /** - * {@link http://en.wikipedia.org/wiki/Universally_unique_identifier | UUID} of this object instance. - * @remarks This gets automatically assigned and shouldn't be edited. - */ - uuid: string; - - /** - * The array of {@link THREE.Bone | Bones}. - * @remarks Note this is a copy of the original array, not a reference, so you can modify the original array without effecting this one. - */ - bones: Bone[]; - - /** - * An array of {@link Matrix4 | Matrix4s} that represent the inverse of the {@link THREE.Matrix4 | matrixWorld} of the individual bones. - */ - boneInverses: Matrix4[]; - - /** - * The array buffer holding the bone data when using a vertex texture. - */ - boneMatrices: Float32Array; - - /** - * The {@link THREE.DataTexture | DataTexture} holding the bone data when using a vertex texture. - */ - boneTexture: null | DataTexture; - - frame: number; - - init(): void; - - /** - * Generates the {@link boneInverses} array if not provided in the constructor. - */ - calculateInverses(): void; - - /** - * Computes an instance of {@link THREE.DataTexture | DataTexture} in order to pass the bone data more efficiently to the shader - * @remarks - * The texture is assigned to {@link boneTexture}. - */ - computeBoneTexture(): this; - - /** - * Returns the skeleton to the base pose. - */ - pose(): void; - - /** - * Updates the {@link boneMatrices} and {@link boneTexture} after changing the bones - * @remarks - * This is called automatically by the {@link THREE.WebGLRenderer | WebGLRenderer} if the {@link Skeleton} is used with a {@link THREE.SkinnedMesh | SkinnedMesh}. - */ - update(): void; - - /** - * Returns a clone of this {@link Skeleton} object. - */ - clone(): Skeleton; - - /** - * Searches through the skeleton's bone array and returns the first with a matching name. - * @param name String to match to the Bone's {@link THREE.Bone.name | .name} property. - */ - getBoneByName(name: string): undefined | Bone; - - /** - * Frees the GPU-related resources allocated by this instance - * @remarks - * Call this method whenever this instance is no longer used in your app. - */ - dispose(): void; - - toJSON(): SkeletonJSON; - - fromJSON(json: SkeletonJSON, bones: Record): void; -} diff --git a/src-testing/src/objects/SkinnedMesh.d.ts b/src-testing/src/objects/SkinnedMesh.d.ts deleted file mode 100644 index 35149c5d1..000000000 --- a/src-testing/src/objects/SkinnedMesh.d.ts +++ /dev/null @@ -1,160 +0,0 @@ -import { BindMode } from "../constants.js"; -import { BufferGeometry } from "../core/BufferGeometry.js"; -import { JSONMeta, Object3DEventMap } from "../core/Object3D.js"; -import { Material } from "../materials/Material.js"; -import { Box3 } from "../math/Box3.js"; -import { Matrix4, Matrix4Tuple } from "../math/Matrix4.js"; -import { Sphere } from "../math/Sphere.js"; -import { Vector3 } from "../math/Vector3.js"; -import { Mesh, MeshJSON, MeshJSONObject } from "./Mesh.js"; -import { Skeleton } from "./Skeleton.js"; - -export interface SkinnedMeshJSONObject extends MeshJSONObject { - bindMode: BindMode; - bindMatrix: Matrix4Tuple; - skeleton?: string; -} - -export interface SkinnedMeshJSON extends MeshJSON { - object: SkinnedMeshJSONObject; -} - -/** - * A mesh that has a {@link THREE.Skeleton | Skeleton} with {@link Bone | bones} that can then be used to animate the vertices of the geometry. - * @example - * ```typescript - * const geometry = new THREE.CylinderGeometry(5, 5, 5, 5, 15, 5, 30); - * // create the skin indices and skin weights manually - * // (typically a loader would read this data from a 3D model for you) - * const position = geometry.attributes.position; - * const vertex = new THREE.Vector3(); - * const skinIndices = []; - * const skinWeights = []; - * for (let i = 0; i & lt; position.count; i++) { - * vertex.fromBufferAttribute(position, i); - * // compute skinIndex and skinWeight based on some configuration data - * const y = (vertex.y + sizing.halfHeight); - * const skinIndex = Math.floor(y / sizing.segmentHeight); - * const skinWeight = (y % sizing.segmentHeight) / sizing.segmentHeight; - * skinIndices.push(skinIndex, skinIndex + 1, 0, 0); - * skinWeights.push(1 - skinWeight, skinWeight, 0, 0); - * } - * geometry.setAttribute('skinIndex', new THREE.Uint16BufferAttribute(skinIndices, 4)); - * geometry.setAttribute('skinWeight', new THREE.Float32BufferAttribute(skinWeights, 4)); - * // create skinned mesh and skeleton - * const mesh = new THREE.SkinnedMesh(geometry, material); - * const skeleton = new THREE.Skeleton(bones); - * // see example from THREE.Skeleton - * const rootBone = skeleton.bones[0]; - * mesh.add(rootBone); - * // bind the skeleton to the mesh - * mesh.bind(skeleton); - * // move the bones and manipulate the model - * skeleton.bones[0].rotation.x = -0.1; - * skeleton.bones[1].rotation.x = 0.2; - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/objects/SkinnedMesh | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/objects/SkinnedMesh.js | Source} - */ -export class SkinnedMesh< - TGeometry extends BufferGeometry = BufferGeometry, - TMaterial extends Material | Material[] = Material | Material[], - TEventMap extends Object3DEventMap = Object3DEventMap, -> extends Mesh { - /** - * Create a new instance of {@link SkinnedMesh} - * @param geometry An instance of {@link THREE.BufferGeometry | BufferGeometry}. Default {@link THREE.BufferGeometry | `new THREE.BufferGeometry()`}. - * @param material A single or an array of {@link THREE.Material | Material}. Default {@link THREE.MeshBasicMaterial | `new THREE.MeshBasicMaterial()`}. - */ - constructor(geometry?: TGeometry, material?: TMaterial, useVertexTexture?: boolean); - - /** - * Read-only flag to check if a given object is of type {@link SkinnedMesh}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isSkinnedMesh: true; - - /** - * @override - * @defaultValue `SkinnedMesh` - */ - override readonly type: string | "SkinnedMesh"; - - /** - * Either {@link AttachedBindMode} or {@link DetachedBindMode}. {@link AttachedBindMode} means the skinned mesh - * shares the same world space as the skeleton. This is not true when using {@link DetachedBindMode} which is useful - * when sharing a skeleton across multiple skinned meshes. - * @defaultValue `AttachedBindMode` - */ - bindMode: BindMode; - - /** - * The base matrix that is used for the bound bone transforms. - */ - bindMatrix: Matrix4; - /** - * The base matrix that is used for resetting the bound bone transforms. - */ - bindMatrixInverse: Matrix4; - - /** - * The bounding box of the SkinnedMesh. Can be calculated with {@link computeBoundingBox | .computeBoundingBox()}. - * @default `null` - */ - boundingBox: Box3; - - /** - * The bounding box of the SkinnedMesh. Can be calculated with {@link computeBoundingSphere | .computeBoundingSphere()}. - * @default `null` - */ - boundingSphere: Sphere; - - /** - * {@link THREE.Skeleton | Skeleton} representing the bone hierarchy of the skinned mesh. - */ - skeleton: Skeleton; - - /** - * Bind a skeleton to the skinned mesh - * @remarks - * The bindMatrix gets saved to .bindMatrix property and the .bindMatrixInverse gets calculated. - * @param skeleton {@link THREE.Skeleton | Skeleton} created from a {@link Bone | Bones} tree. - * @param bindMatrix {@link THREE.Matrix4 | Matrix4} that represents the base transform of the skeleton. - */ - bind(skeleton: Skeleton, bindMatrix?: Matrix4): void; - - /** - * Computes the bounding box of the skinned mesh, and updates the {@link .boundingBox} attribute. The bounding box - * is not computed by the engine; it must be computed by your app. If the skinned mesh is animated, the bounding box - * should be recomputed per frame. - */ - computeBoundingBox(): void; - - /** - * Computes the bounding sphere of the skinned mesh, and updates the {@link .boundingSphere} attribute. The bounding - * sphere is automatically computed by the engine when it is needed, e.g., for ray casting and view frustum culling. - * If the skinned mesh is animated, the bounding sphere should be recomputed per frame. - */ - computeBoundingSphere(): void; - - /** - * This method sets the skinned mesh in the rest pose (resets the pose). - */ - pose(): void; - - /** - * Normalizes the skin weights. - */ - normalizeSkinWeights(): void; - - /** - * Applies the bone transform associated with the given index to the given position vector - * @remarks Returns the updated vector. - * @param index Expects a `Integer` - * @param vector - */ - applyBoneTransform(index: number, vector: Vector3): Vector3; - - toJSON(meta?: JSONMeta): SkinnedMeshJSON; -} diff --git a/src-testing/src/objects/Sprite.d.ts b/src-testing/src/objects/Sprite.d.ts deleted file mode 100644 index 427b8b414..000000000 --- a/src-testing/src/objects/Sprite.d.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { BufferGeometry } from "../core/BufferGeometry.js"; -import { Object3D, Object3DEventMap } from "../core/Object3D.js"; -import { SpriteMaterial } from "../materials/Materials.js"; -import { Vector2 } from "../math/Vector2.js"; - -/** - * A {@link Sprite} is a plane that always faces towards the camera, generally with a partially transparent texture applied. - * @remarks Sprites do not cast shadows, setting `castShadow = true` will have no effect. - * @example - * ```typescript - * const map = new THREE.TextureLoader().load('sprite.png'); - * const material = new THREE.SpriteMaterial({ - * map: map - * }); - * const {@link Sprite} = new THREE.Sprite(material); - * scene.add(sprite); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/objects/Sprite | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/objects/Sprite.js | Source} - */ -export class Sprite extends Object3D { - /** - * Creates a new Sprite. - * @param material An instance of {@link THREE.SpriteMaterial | SpriteMaterial}. Default {@link THREE.SpriteMaterial | `new SpriteMaterial()`}, _with white color_. - */ - constructor(material?: SpriteMaterial); - - /** - * Read-only flag to check if a given object is of type {@link Sprite}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isSprite: true; - - /** - * @override - * @defaultValue `Sprite` - */ - override readonly type: string | "Sprite"; - - /** - * Whether the object gets rendered into shadow map. - * No effect in {@link Sprite}. - * @ignore - * @hidden - * @defaultValue `false` - */ - override castShadow: false; - - geometry: BufferGeometry; - - /** - * An instance of {@link THREE.SpriteMaterial | SpriteMaterial}, defining the object's appearance. - * @defaultValue {@link THREE.SpriteMaterial | `new SpriteMaterial()`}, _with white color_. - */ - material: SpriteMaterial; - - /** - * The sprite's anchor point, and the point around which the {@link Sprite} rotates. - * A value of (0.5, 0.5) corresponds to the midpoint of the sprite. - * A value of (0, 0) corresponds to the lower left corner of the sprite. - * @defaultValue {@link THREE.Vector2 | `new Vector2(0.5, 0.5)`}. - */ - center: Vector2; -} diff --git a/src-testing/src/renderers/WebGL3DRenderTarget.d.ts b/src-testing/src/renderers/WebGL3DRenderTarget.d.ts deleted file mode 100644 index 420caa97e..000000000 --- a/src-testing/src/renderers/WebGL3DRenderTarget.d.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { RenderTargetOptions } from "../core/RenderTarget.js"; -import { Data3DTexture } from "../textures/Data3DTexture.js"; -import { WebGLRenderTarget } from "./WebGLRenderTarget.js"; - -/** - * Represents a three-dimensional render target. - */ -export class WebGL3DRenderTarget extends WebGLRenderTarget { - /** - * Creates a new WebGL3DRenderTarget. - * - * @param width the width of the render target, in pixels. Default is `1`. - * @param height the height of the render target, in pixels. Default is `1`. - * @param depth the depth of the render target. Default is `1`. - * @param options optional object that holds texture parameters for an auto-generated target texture and - * depthBuffer/stencilBuffer booleans. See {@link WebGLRenderTarget} for details. - */ - constructor(width?: number, height?: number, depth?: number, options?: RenderTargetOptions); - - textures: Data3DTexture[]; - - /** - * The texture property is overwritten with an instance of {@link Data3DTexture}. - */ - get texture(): Data3DTexture; - set texture(value: Data3DTexture); - - readonly isWebGL3DRenderTarget: true; -} diff --git a/src-testing/src/renderers/WebGLArrayRenderTarget.d.ts b/src-testing/src/renderers/WebGLArrayRenderTarget.d.ts deleted file mode 100644 index 1ac617889..000000000 --- a/src-testing/src/renderers/WebGLArrayRenderTarget.d.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { RenderTargetOptions } from "../core/RenderTarget.js"; -import { DataArrayTexture } from "../textures/DataArrayTexture.js"; -import { WebGLRenderTarget } from "./WebGLRenderTarget.js"; - -/** - * This type of render target represents an array of textures. - */ -export class WebGLArrayRenderTarget extends WebGLRenderTarget { - /** - * Creates a new WebGLArrayRenderTarget. - * - * @param width the width of the render target, in pixels. Default is `1`. - * @param height the height of the render target, in pixels. Default is `1`. - * @param depth the depth/layer count of the render target. Default is `1`. - * @param options optional object that holds texture parameters for an auto-generated target texture and - * depthBuffer/stencilBuffer booleans. See {@link WebGLRenderTarget} for details. - */ - constructor(width?: number, height?: number, depth?: number, options?: RenderTargetOptions); - - textures: DataArrayTexture[]; - - /** - * The texture property is overwritten with an instance of {@link DataArrayTexture}. - */ - get texture(): DataArrayTexture; - set texture(value: DataArrayTexture); - - readonly isWebGLArrayRenderTarget: true; -} diff --git a/src-testing/src/renderers/WebGLCubeRenderTarget.d.ts b/src-testing/src/renderers/WebGLCubeRenderTarget.d.ts deleted file mode 100644 index c390adb67..000000000 --- a/src-testing/src/renderers/WebGLCubeRenderTarget.d.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { RenderTargetOptions } from "../core/RenderTarget.js"; -import { CubeTexture } from "../textures/CubeTexture.js"; -import { Texture } from "../textures/Texture.js"; -import { WebGLRenderer } from "./WebGLRenderer.js"; -import { WebGLRenderTarget } from "./WebGLRenderTarget.js"; - -export class WebGLCubeRenderTarget extends WebGLRenderTarget { - constructor(size?: number, options?: RenderTargetOptions); - - textures: CubeTexture[]; - - get texture(): CubeTexture; - set texture(value: CubeTexture); - - fromEquirectangularTexture(renderer: WebGLRenderer, texture: Texture): this; - - clear(renderer: WebGLRenderer, color: boolean, depth: boolean, stencil: boolean): void; -} diff --git a/src-testing/src/renderers/WebGLRenderTarget.d.ts b/src-testing/src/renderers/WebGLRenderTarget.d.ts deleted file mode 100644 index fdff12e78..000000000 --- a/src-testing/src/renderers/WebGLRenderTarget.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { RenderTarget, RenderTargetOptions } from "../core/RenderTarget.js"; -import { Texture } from "../textures/Texture.js"; - -export class WebGLRenderTarget extends RenderTarget { - constructor(width?: number, height?: number, options?: RenderTargetOptions); - - readonly isWebGLRenderTarget: true; -} diff --git a/src-testing/src/renderers/WebGLRenderer.d.ts b/src-testing/src/renderers/WebGLRenderer.d.ts deleted file mode 100644 index 963fd850a..000000000 --- a/src-testing/src/renderers/WebGLRenderer.d.ts +++ /dev/null @@ -1,558 +0,0 @@ -import { Camera } from "../cameras/Camera.js"; -import { CullFace, ShadowMapType, ToneMapping, WebGLCoordinateSystem } from "../constants.js"; -import { TypedArray } from "../core/BufferAttribute.js"; -import { BufferGeometry } from "../core/BufferGeometry.js"; -import { Object3D } from "../core/Object3D.js"; -import { Material } from "../materials/Material.js"; -import { Box2 } from "../math/Box2.js"; -import { Box3 } from "../math/Box3.js"; -import { Color, ColorRepresentation } from "../math/Color.js"; -import { Plane } from "../math/Plane.js"; -import { Vector2 } from "../math/Vector2.js"; -import { Vector3 } from "../math/Vector3.js"; -import { Vector4 } from "../math/Vector4.js"; -import { Scene } from "../scenes/Scene.js"; -import { Data3DTexture } from "../textures/Data3DTexture.js"; -import { DataArrayTexture } from "../textures/DataArrayTexture.js"; -import { OffscreenCanvas, Texture } from "../textures/Texture.js"; -import { WebGLCapabilities, WebGLCapabilitiesParameters } from "./webgl/WebGLCapabilities.js"; -import { WebGLExtensions } from "./webgl/WebGLExtensions.js"; -import { WebGLInfo } from "./webgl/WebGLInfo.js"; -import { WebGLProgram } from "./webgl/WebGLProgram.js"; -import { WebGLProperties } from "./webgl/WebGLProperties.js"; -import { WebGLRenderLists } from "./webgl/WebGLRenderLists.js"; -import { WebGLShadowMap } from "./webgl/WebGLShadowMap.js"; -import { WebGLState } from "./webgl/WebGLState.js"; -import { WebGLRenderTarget } from "./WebGLRenderTarget.js"; -import { WebXRManager } from "./webxr/WebXRManager.js"; - -export interface Renderer { - domElement: HTMLCanvasElement; - - render(scene: Object3D, camera: Camera): void; - setSize(width: number, height: number, updateStyle?: boolean): void; -} - -export interface WebGLRendererParameters extends WebGLCapabilitiesParameters { - /** - * A Canvas where the renderer draws its output. - */ - canvas?: HTMLCanvasElement | OffscreenCanvas | undefined; - - /** - * A WebGL Rendering Context. - * (https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext) - * Default is null - */ - context?: WebGLRenderingContext | undefined; - - /** - * default is false. - */ - alpha?: boolean | undefined; - - /** - * default is true. - */ - premultipliedAlpha?: boolean | undefined; - - /** - * default is false. - */ - antialias?: boolean | undefined; - - /** - * default is false. - */ - stencil?: boolean | undefined; - - /** - * default is false. - */ - preserveDrawingBuffer?: boolean | undefined; - - /** - * Can be "high-performance", "low-power" or "default" - */ - powerPreference?: WebGLPowerPreference | undefined; - - /** - * default is true. - */ - depth?: boolean | undefined; - - /** - * default is false. - */ - failIfMajorPerformanceCaveat?: boolean | undefined; -} - -export interface WebGLDebug { - /** - * Enables error checking and reporting when shader programs are being compiled. - */ - checkShaderErrors: boolean; - - /** - * A callback function that can be used for custom error reporting. The callback receives the WebGL context, an - * instance of WebGLProgram as well two instances of WebGLShader representing the vertex and fragment shader. - * Assigning a custom function disables the default error reporting. - * @default `null` - */ - onShaderError: - | (( - gl: WebGLRenderingContext, - program: WebGLProgram, - glVertexShader: WebGLShader, - glFragmentShader: WebGLShader, - ) => void) - | null; -} - -/** - * The WebGL renderer displays your beautifully crafted scenes using WebGL, if your device supports it. - * This renderer has way better performance than CanvasRenderer. - * - * see {@link https://github.com/mrdoob/three.js/blob/master/src/renderers/WebGLRenderer.js|src/renderers/WebGLRenderer.js} - */ -export class WebGLRenderer implements Renderer { - /** - * parameters is an optional object with properties defining the renderer's behavior. - * The constructor also accepts no parameters at all. - * In all cases, it will assume sane defaults when parameters are missing. - */ - constructor(parameters?: WebGLRendererParameters); - - /** - * A Canvas where the renderer draws its output. - * This is automatically created by the renderer in the constructor (if not provided already); you just need to add it to your page. - * @default document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' ) - */ - domElement: HTMLCanvasElement; - - /** - * Defines whether the renderer should automatically clear its output before rendering. - * @default true - */ - autoClear: boolean; - - /** - * If autoClear is true, defines whether the renderer should clear the color buffer. Default is true. - * @default true - */ - autoClearColor: boolean; - - /** - * If autoClear is true, defines whether the renderer should clear the depth buffer. Default is true. - * @default true - */ - autoClearDepth: boolean; - - /** - * If autoClear is true, defines whether the renderer should clear the stencil buffer. Default is true. - * @default true - */ - autoClearStencil: boolean; - - /** - * Debug configurations. - * @default { checkShaderErrors: true } - */ - debug: WebGLDebug; - - /** - * Defines whether the renderer should sort objects. Default is true. - * @default true - */ - sortObjects: boolean; - - /** - * @default [] - */ - clippingPlanes: Plane[]; - - /** - * @default false - */ - localClippingEnabled: boolean; - - extensions: WebGLExtensions; - - /** - * Color space used for output to HTMLCanvasElement. Supported values are - * {@link SRGBColorSpace} and {@link LinearSRGBColorSpace}. - * @default THREE.SRGBColorSpace. - */ - get outputColorSpace(): string; - set outputColorSpace(colorSpace: string); - - get coordinateSystem(): typeof WebGLCoordinateSystem; - - /** - * @default THREE.NoToneMapping - */ - toneMapping: ToneMapping; - - /** - * @default 1 - */ - toneMappingExposure: number; - - info: WebGLInfo; - - shadowMap: WebGLShadowMap; - - pixelRatio: number; - - capabilities: WebGLCapabilities; - properties: WebGLProperties; - renderLists: WebGLRenderLists; - state: WebGLState; - - xr: WebXRManager; - - /** - * Return the WebGL context. - */ - getContext(): WebGLRenderingContext | WebGL2RenderingContext; - getContextAttributes(): any; - forceContextLoss(): void; - forceContextRestore(): void; - - /** - * @deprecated Use {@link WebGLCapabilities#getMaxAnisotropy .capabilities.getMaxAnisotropy()} instead. - */ - getMaxAnisotropy(): number; - - /** - * @deprecated Use {@link WebGLCapabilities#precision .capabilities.precision} instead. - */ - getPrecision(): string; - - getPixelRatio(): number; - setPixelRatio(value: number): void; - - getDrawingBufferSize(target: Vector2): Vector2; - setDrawingBufferSize(width: number, height: number, pixelRatio: number): void; - - getSize(target: Vector2): Vector2; - - /** - * Resizes the output canvas to (width, height), and also sets the viewport to fit that size, starting in (0, 0). - */ - setSize(width: number, height: number, updateStyle?: boolean): void; - - getCurrentViewport(target: Vector4): Vector4; - - /** - * Copies the viewport into target. - */ - getViewport(target: Vector4): Vector4; - - /** - * Sets the viewport to render from (x, y) to (x + width, y + height). - * (x, y) is the lower-left corner of the region. - */ - setViewport(x: Vector4 | number, y?: number, width?: number, height?: number): void; - - /** - * Copies the scissor area into target. - */ - getScissor(target: Vector4): Vector4; - - /** - * Sets the scissor area from (x, y) to (x + width, y + height). - */ - setScissor(x: Vector4 | number, y?: number, width?: number, height?: number): void; - - /** - * Returns true if scissor test is enabled; returns false otherwise. - */ - getScissorTest(): boolean; - - /** - * Enable the scissor test. When this is enabled, only the pixels within the defined scissor area will be affected by further renderer actions. - */ - setScissorTest(enable: boolean): void; - - /** - * Sets the custom opaque sort function for the WebGLRenderLists. Pass null to use the default painterSortStable function. - */ - setOpaqueSort(method: (a: any, b: any) => number): void; - - /** - * Sets the custom transparent sort function for the WebGLRenderLists. Pass null to use the default reversePainterSortStable function. - */ - setTransparentSort(method: (a: any, b: any) => number): void; - - /** - * Returns a THREE.Color instance with the current clear color. - */ - getClearColor(target: Color): Color; - - /** - * Sets the clear color, using color for the color and alpha for the opacity. - */ - setClearColor(color: ColorRepresentation, alpha?: number): void; - - /** - * Returns a float with the current clear alpha. Ranges from 0 to 1. - */ - getClearAlpha(): number; - - setClearAlpha(alpha: number): void; - - /** - * Tells the renderer to clear its color, depth or stencil drawing buffer(s). - * Arguments default to true - */ - clear(color?: boolean, depth?: boolean, stencil?: boolean): void; - - clearColor(): void; - clearDepth(): void; - clearStencil(): void; - clearTarget(renderTarget: WebGLRenderTarget, color: boolean, depth: boolean, stencil: boolean): void; - - /** - * @deprecated Use {@link WebGLState#reset .state.reset()} instead. - */ - resetGLState(): void; - dispose(): void; - - renderBufferDirect( - camera: Camera, - scene: Scene, - geometry: BufferGeometry, - material: Material, - object: Object3D, - geometryGroup: any, - ): void; - - /** - * A build in function that can be used instead of requestAnimationFrame. For WebXR projects this function must be used. - * @param callback The function will be called every available frame. If `null` is passed it will stop any already ongoing animation. - */ - setAnimationLoop(callback: XRFrameRequestCallback | null): void; - - /** - * @deprecated Use {@link WebGLRenderer#setAnimationLoop .setAnimationLoop()} instead. - */ - animate(callback: () => void): void; - - /** - * Compiles all materials in the scene with the camera. This is useful to precompile shaders before the first - * rendering. If you want to add a 3D object to an existing scene, use the third optional parameter for applying the - * target scene. - * Note that the (target) scene's lighting should be configured before calling this method. - */ - compile: (scene: Object3D, camera: Camera, targetScene?: Scene | null) => Set; - - /** - * Asynchronous version of {@link compile}(). The method returns a Promise that resolves when the given scene can be - * rendered without unnecessary stalling due to shader compilation. - * This method makes use of the KHR_parallel_shader_compile WebGL extension. - */ - compileAsync: (scene: Object3D, camera: Camera, targetScene?: Scene | null) => Promise; - - /** - * Render a scene or an object using a camera. - * The render is done to a previously specified {@link WebGLRenderTarget#renderTarget .renderTarget} set by calling - * {@link WebGLRenderer#setRenderTarget .setRenderTarget} or to the canvas as usual. - * - * By default render buffers are cleared before rendering but you can prevent this by setting the property - * {@link WebGLRenderer#autoClear autoClear} to false. If you want to prevent only certain buffers being cleared - * you can set either the {@link WebGLRenderer#autoClearColor autoClearColor}, - * {@link WebGLRenderer#autoClearStencil autoClearStencil} or {@link WebGLRenderer#autoClearDepth autoClearDepth} - * properties to false. To forcibly clear one ore more buffers call {@link WebGLRenderer#clear .clear}. - */ - render(scene: Object3D, camera: Camera): void; - - /** - * Returns the current active cube face. - */ - getActiveCubeFace(): number; - - /** - * Returns the current active mipmap level. - */ - getActiveMipmapLevel(): number; - - /** - * Returns the current render target. If no render target is set, null is returned. - */ - getRenderTarget(): WebGLRenderTarget | null; - - /** - * @deprecated Use {@link WebGLRenderer#getRenderTarget .getRenderTarget()} instead. - */ - getCurrentRenderTarget(): WebGLRenderTarget | null; - - /** - * Sets the active render target. - * - * @param renderTarget The {@link WebGLRenderTarget renderTarget} that needs to be activated. When `null` is given, the canvas is set as the active render target instead. - * @param activeCubeFace Specifies the active cube side (PX 0, NX 1, PY 2, NY 3, PZ 4, NZ 5) of {@link WebGLCubeRenderTarget}. - * @param activeMipmapLevel Specifies the active mipmap level. - */ - setRenderTarget( - renderTarget: WebGLRenderTarget | WebGLRenderTarget | null, - activeCubeFace?: number, - activeMipmapLevel?: number, - ): void; - - readRenderTargetPixels( - renderTarget: WebGLRenderTarget | WebGLRenderTarget, - x: number, - y: number, - width: number, - height: number, - buffer: TypedArray, - activeCubeFaceIndex?: number, - ): void; - - readRenderTargetPixelsAsync( - renderTarget: WebGLRenderTarget | WebGLRenderTarget, - x: number, - y: number, - width: number, - height: number, - buffer: TypedArray, - activeCubeFaceIndex?: number, - ): Promise; - - /** - * Copies a region of the currently bound framebuffer into the selected mipmap level of the selected texture. - * This region is defined by the size of the destination texture's mip level, offset by the input position. - * - * @param texture Specifies the destination texture. - * @param position Specifies the pixel offset from which to copy out of the framebuffer. - * @param level Specifies the destination mipmap level of the texture. - */ - copyFramebufferToTexture(texture: Texture, position?: Vector2 | null, level?: number): void; - - /** - * Copies the pixels of a texture in the bounds `srcRegion` in the destination texture starting from the given - * position. The `depthTexture` and `texture` property of render targets are supported as well. - * - * When using render target textures as `srcTexture` and `dstTexture`, you must make sure both render targets are - * intitialized e.g. via {@link .initRenderTarget}(). - * - * @param srcTexture Specifies the source texture. - * @param dstTexture Specifies the destination texture. - * @param srcRegion Specifies the bounds - * @param dstPosition Specifies the pixel offset into the dstTexture where the copy will occur. - * @param level Specifies the destination mipmap level of the texture. - */ - copyTextureToTexture( - srcTexture: Texture, - dstTexture: Texture, - srcRegion?: Box2 | null, - dstPosition?: Vector2 | null, - level?: number, - ): void; - - /** - * Copies the pixels of a texture in the bounds `srcRegion` in the destination texture starting from the given - * position. The `depthTexture` and `texture` property of 3D render targets are supported as well. - * - * When using render target textures as `srcTexture` and `dstTexture`, you must make sure both render targets are - * intitialized e.g. via {@link .initRenderTarget}(). - * - * @param srcTexture Specifies the source texture. - * @param dstTexture Specifies the destination texture. - * @param srcRegion Specifies the bounds - * @param dstPosition Specifies the pixel offset into the dstTexture where the copy will occur. - * @param level Specifies the destination mipmap level of the texture. - */ - copyTextureToTexture3D( - srcTexture: Texture, - dstTexture: Data3DTexture | DataArrayTexture, - srcRegion?: Box3 | null, - dstPosition?: Vector3 | null, - level?: number, - ): void; - - /** - * Initializes the given WebGLRenderTarget memory. Useful for initializing a render target so data can be copied - * into it using {@link WebGLRenderer.copyTextureToTexture} before it has been rendered to. - * @param target - */ - initRenderTarget(target: WebGLRenderTarget): void; - - /** - * Initializes the given texture. Can be used to preload a texture rather than waiting until first render (which can cause noticeable lags due to decode and GPU upload overhead). - * - * @param texture The texture to Initialize. - */ - initTexture(texture: Texture): void; - - /** - * Can be used to reset the internal WebGL state. - */ - resetState(): void; - - /** - * @deprecated Use {@link WebGLRenderer#xr .xr} instead. - */ - vr: boolean; - - /** - * @deprecated Use {@link WebGLShadowMap#enabled .shadowMap.enabled} instead. - */ - shadowMapEnabled: boolean; - - /** - * @deprecated Use {@link WebGLShadowMap#type .shadowMap.type} instead. - */ - shadowMapType: ShadowMapType; - - /** - * @deprecated Use {@link WebGLShadowMap#cullFace .shadowMap.cullFace} instead. - */ - shadowMapCullFace: CullFace; - - /** - * @deprecated Use {@link WebGLExtensions#get .extensions.get( 'OES_texture_float' )} instead. - */ - supportsFloatTextures(): any; - - /** - * @deprecated Use {@link WebGLExtensions#get .extensions.get( 'OES_texture_half_float' )} instead. - */ - supportsHalfFloatTextures(): any; - - /** - * @deprecated Use {@link WebGLExtensions#get .extensions.get( 'OES_standard_derivatives' )} instead. - */ - supportsStandardDerivatives(): any; - - /** - * @deprecated Use {@link WebGLExtensions#get .extensions.get( 'WEBGL_compressed_texture_s3tc' )} instead. - */ - supportsCompressedTextureS3TC(): any; - - /** - * @deprecated Use {@link WebGLExtensions#get .extensions.get( 'WEBGL_compressed_texture_pvrtc' )} instead. - */ - supportsCompressedTexturePVRTC(): any; - - /** - * @deprecated Use {@link WebGLExtensions#get .extensions.get( 'EXT_blend_minmax' )} instead. - */ - supportsBlendMinMax(): any; - - /** - * @deprecated Use {@link WebGLCapabilities#vertexTextures .capabilities.vertexTextures} instead. - */ - supportsVertexTextures(): any; - - /** - * @deprecated Use {@link WebGLExtensions#get .extensions.get( 'ANGLE_instanced_arrays' )} instead. - */ - supportsInstancedArrays(): any; - - /** - * @deprecated Use {@link WebGLRenderer#setScissorTest .setScissorTest()} instead. - */ - enableScissorTest(boolean: any): any; -} diff --git a/src-testing/src/renderers/common/Animation.ts b/src-testing/src/renderers/common/Animation.ts deleted file mode 100644 index 0b00319a1..000000000 --- a/src-testing/src/renderers/common/Animation.ts +++ /dev/null @@ -1,38 +0,0 @@ -class Animation { - constructor(nodes, info) { - this.nodes = nodes; - this.info = info; - - this.animationLoop = null; - this.requestId = null; - - this._init(); - } - - _init() { - const update = (time, frame) => { - this.requestId = self.requestAnimationFrame(update); - - if (this.info.autoReset === true) this.info.reset(); - - this.nodes.nodeFrame.update(); - - this.info.frame = this.nodes.nodeFrame.frameId; - - if (this.animationLoop !== null) this.animationLoop(time, frame); - }; - - update(); - } - - dispose() { - self.cancelAnimationFrame(this.requestId); - this.requestId = null; - } - - setAnimationLoop(callback) { - this.animationLoop = callback; - } -} - -export default Animation; diff --git a/src-testing/src/renderers/common/Attributes.ts b/src-testing/src/renderers/common/Attributes.ts deleted file mode 100644 index 4631d528b..000000000 --- a/src-testing/src/renderers/common/Attributes.ts +++ /dev/null @@ -1,56 +0,0 @@ -import DataMap from './DataMap.js'; -import { AttributeType } from './Constants.js'; - -import { DynamicDrawUsage } from '../../constants.js'; - -class Attributes extends DataMap { - constructor(backend) { - super(); - - this.backend = backend; - } - - delete(attribute) { - const attributeData = super.delete(attribute); - - if (attributeData !== undefined) { - this.backend.destroyAttribute(attribute); - } - - return attributeData; - } - - update(attribute, type) { - const data = this.get(attribute); - - if (data.version === undefined) { - if (type === AttributeType.VERTEX) { - this.backend.createAttribute(attribute); - } else if (type === AttributeType.INDEX) { - this.backend.createIndexAttribute(attribute); - } else if (type === AttributeType.STORAGE) { - this.backend.createStorageAttribute(attribute); - } else if (type === AttributeType.INDIRECT) { - this.backend.createIndirectStorageAttribute(attribute); - } - - data.version = this._getBufferAttribute(attribute).version; - } else { - const bufferAttribute = this._getBufferAttribute(attribute); - - if (data.version < bufferAttribute.version || bufferAttribute.usage === DynamicDrawUsage) { - this.backend.updateAttribute(attribute); - - data.version = bufferAttribute.version; - } - } - } - - _getBufferAttribute(attribute) { - if (attribute.isInterleavedBufferAttribute) attribute = attribute.data; - - return attribute; - } -} - -export default Attributes; diff --git a/src-testing/src/renderers/common/Backend.ts b/src-testing/src/renderers/common/Backend.ts deleted file mode 100644 index edd4fcf9c..000000000 --- a/src-testing/src/renderers/common/Backend.ts +++ /dev/null @@ -1,170 +0,0 @@ -let vector2 = null; -let vector4 = null; -let color4 = null; - -import Color4 from './Color4.js'; -import { Vector2 } from '../../math/Vector2.js'; -import { Vector4 } from '../../math/Vector4.js'; -import { createCanvasElement } from '../../utils.js'; -import { REVISION } from '../../constants.js'; - -class Backend { - constructor(parameters = {}) { - this.parameters = Object.assign({}, parameters); - this.data = new WeakMap(); - this.renderer = null; - this.domElement = null; - } - - async init(renderer) { - this.renderer = renderer; - } - - // render context - - begin(/*renderContext*/) {} - - finish(/*renderContext*/) {} - - // render object - - draw(/*renderObject, info*/) {} - - // program - - createProgram(/*program*/) {} - - destroyProgram(/*program*/) {} - - // bindings - - createBindings(/*bingGroup, bindings*/) {} - - updateBindings(/*bingGroup, bindings*/) {} - - // pipeline - - createRenderPipeline(/*renderObject*/) {} - - createComputePipeline(/*computeNode, pipeline*/) {} - - destroyPipeline(/*pipeline*/) {} - - // cache key - - needsRenderUpdate(/*renderObject*/) {} // return Boolean ( fast test ) - - getRenderCacheKey(/*renderObject*/) {} // return String - - // node builder - - createNodeBuilder(/*renderObject*/) {} // return NodeBuilder (ADD IT) - - // textures - - createSampler(/*texture*/) {} - - createDefaultTexture(/*texture*/) {} - - createTexture(/*texture*/) {} - - copyTextureToBuffer(/*texture, x, y, width, height*/) {} - - // attributes - - createAttribute(/*attribute*/) {} - - createIndexAttribute(/*attribute*/) {} - - updateAttribute(/*attribute*/) {} - - destroyAttribute(/*attribute*/) {} - - // canvas - - getContext() {} - - updateSize() {} - - // utils - - resolveTimestampAsync(/*renderContext, type*/) {} - - hasFeatureAsync(/*name*/) {} // return Boolean - - hasFeature(/*name*/) {} // return Boolean - - getInstanceCount(renderObject) { - const { object, geometry } = renderObject; - - return geometry.isInstancedBufferGeometry ? geometry.instanceCount : object.count > 1 ? object.count : 1; - } - - getDrawingBufferSize() { - vector2 = vector2 || new Vector2(); - - return this.renderer.getDrawingBufferSize(vector2); - } - - getScissor() { - vector4 = vector4 || new Vector4(); - - return this.renderer.getScissor(vector4); - } - - setScissorTest(/*boolean*/) {} - - getClearColor() { - const renderer = this.renderer; - - color4 = color4 || new Color4(); - - renderer.getClearColor(color4); - - color4.getRGB(color4, this.renderer.currentColorSpace); - - return color4; - } - - getDomElement() { - let domElement = this.domElement; - - if (domElement === null) { - domElement = this.parameters.canvas !== undefined ? this.parameters.canvas : createCanvasElement(); - - // OffscreenCanvas does not have setAttribute, see #22811 - if ('setAttribute' in domElement) domElement.setAttribute('data-engine', `three.js r${REVISION} webgpu`); - - this.domElement = domElement; - } - - return domElement; - } - - // resource properties - - set(object, value) { - this.data.set(object, value); - } - - get(object) { - let map = this.data.get(object); - - if (map === undefined) { - map = {}; - this.data.set(object, map); - } - - return map; - } - - has(object) { - return this.data.has(object); - } - - delete(object) { - this.data.delete(object); - } -} - -export default Backend; diff --git a/src-testing/src/renderers/common/Background.ts b/src-testing/src/renderers/common/Background.ts deleted file mode 100644 index b56dd3724..000000000 --- a/src-testing/src/renderers/common/Background.ts +++ /dev/null @@ -1,133 +0,0 @@ -import DataMap from './DataMap.js'; -import Color4 from './Color4.js'; -import { - vec4, - context, - normalWorld, - backgroundBlurriness, - backgroundIntensity, - modelViewProjection, -} from '../../nodes/TSL.js'; -import NodeMaterial from '../../materials/nodes/NodeMaterial.js'; - -import { Mesh } from '../../objects/Mesh.js'; -import { SphereGeometry } from '../../geometries/SphereGeometry.js'; -import { BackSide, LinearSRGBColorSpace } from '../../constants.js'; - -const _clearColor = /*@__PURE__*/ new Color4(); - -class Background extends DataMap { - constructor(renderer, nodes) { - super(); - - this.renderer = renderer; - this.nodes = nodes; - } - - update(scene, renderList, renderContext) { - const renderer = this.renderer; - const background = this.nodes.getBackgroundNode(scene) || scene.background; - - let forceClear = false; - - if (background === null) { - // no background settings, use clear color configuration from the renderer - - renderer._clearColor.getRGB(_clearColor, LinearSRGBColorSpace); - _clearColor.a = renderer._clearColor.a; - } else if (background.isColor === true) { - // background is an opaque color - - background.getRGB(_clearColor, LinearSRGBColorSpace); - _clearColor.a = 1; - - forceClear = true; - } else if (background.isNode === true) { - const sceneData = this.get(scene); - const backgroundNode = background; - - _clearColor.copy(renderer._clearColor); - - let backgroundMesh = sceneData.backgroundMesh; - - if (backgroundMesh === undefined) { - const backgroundMeshNode = context(vec4(backgroundNode).mul(backgroundIntensity), { - // @TODO: Add Texture2D support using node context - getUV: () => normalWorld, - getTextureLevel: () => backgroundBlurriness, - }); - - let viewProj = modelViewProjection(); - viewProj = viewProj.setZ(viewProj.w); - - const nodeMaterial = new NodeMaterial(); - nodeMaterial.name = 'Background.material'; - nodeMaterial.side = BackSide; - nodeMaterial.depthTest = false; - nodeMaterial.depthWrite = false; - nodeMaterial.fog = false; - nodeMaterial.lights = false; - nodeMaterial.vertexNode = viewProj; - nodeMaterial.colorNode = backgroundMeshNode; - - sceneData.backgroundMeshNode = backgroundMeshNode; - sceneData.backgroundMesh = backgroundMesh = new Mesh(new SphereGeometry(1, 32, 32), nodeMaterial); - backgroundMesh.frustumCulled = false; - backgroundMesh.name = 'Background.mesh'; - - backgroundMesh.onBeforeRender = function (renderer, scene, camera) { - this.matrixWorld.copyPosition(camera.matrixWorld); - }; - } - - const backgroundCacheKey = backgroundNode.getCacheKey(); - - if (sceneData.backgroundCacheKey !== backgroundCacheKey) { - sceneData.backgroundMeshNode.node = vec4(backgroundNode).mul(backgroundIntensity); - sceneData.backgroundMeshNode.needsUpdate = true; - - backgroundMesh.material.needsUpdate = true; - - sceneData.backgroundCacheKey = backgroundCacheKey; - } - - renderList.unshift(backgroundMesh, backgroundMesh.geometry, backgroundMesh.material, 0, 0, null); - } else { - console.error('THREE.Renderer: Unsupported background configuration.', background); - } - - // - - if (renderer.autoClear === true || forceClear === true) { - const clearColorValue = renderContext.clearColorValue; - - clearColorValue.r = _clearColor.r; - clearColorValue.g = _clearColor.g; - clearColorValue.b = _clearColor.b; - clearColorValue.a = _clearColor.a; - - // premultiply alpha - - if (renderer.backend.isWebGLBackend === true || renderer.alpha === true) { - clearColorValue.r *= clearColorValue.a; - clearColorValue.g *= clearColorValue.a; - clearColorValue.b *= clearColorValue.a; - } - - // - - renderContext.depthClearValue = renderer._clearDepth; - renderContext.stencilClearValue = renderer._clearStencil; - - renderContext.clearColor = renderer.autoClearColor === true; - renderContext.clearDepth = renderer.autoClearDepth === true; - renderContext.clearStencil = renderer.autoClearStencil === true; - } else { - renderContext.clearColor = false; - renderContext.clearDepth = false; - renderContext.clearStencil = false; - } - } -} - -export default Background; diff --git a/src-testing/src/renderers/common/BindGroup.ts b/src-testing/src/renderers/common/BindGroup.ts deleted file mode 100644 index ae78d4787..000000000 --- a/src-testing/src/renderers/common/BindGroup.ts +++ /dev/null @@ -1,14 +0,0 @@ -let _id = 0; - -class BindGroup { - constructor(name = '', bindings = [], index = 0, bindingsReference = []) { - this.name = name; - this.bindings = bindings; - this.index = index; - this.bindingsReference = bindingsReference; - - this.id = _id++; - } -} - -export default BindGroup; diff --git a/src-testing/src/renderers/common/Binding.ts b/src-testing/src/renderers/common/Binding.ts deleted file mode 100644 index a12f3563b..000000000 --- a/src-testing/src/renderers/common/Binding.ts +++ /dev/null @@ -1,17 +0,0 @@ -class Binding { - constructor(name = '') { - this.name = name; - - this.visibility = 0; - } - - setVisibility(visibility) { - this.visibility |= visibility; - } - - clone() { - return Object.assign(new this.constructor(), this); - } -} - -export default Binding; diff --git a/src-testing/src/renderers/common/Bindings.ts b/src-testing/src/renderers/common/Bindings.ts deleted file mode 100644 index 1414c94fb..000000000 --- a/src-testing/src/renderers/common/Bindings.ts +++ /dev/null @@ -1,160 +0,0 @@ -import DataMap from './DataMap.js'; -import { AttributeType } from './Constants.js'; - -class Bindings extends DataMap { - constructor(backend, nodes, textures, attributes, pipelines, info) { - super(); - - this.backend = backend; - this.textures = textures; - this.pipelines = pipelines; - this.attributes = attributes; - this.nodes = nodes; - this.info = info; - - this.pipelines.bindings = this; // assign bindings to pipelines - } - - getForRender(renderObject) { - const bindings = renderObject.getBindings(); - - for (const bindGroup of bindings) { - const groupData = this.get(bindGroup); - - if (groupData.bindGroup === undefined) { - // each object defines an array of bindings (ubos, textures, samplers etc.) - - this._init(bindGroup); - - this.backend.createBindings(bindGroup, bindings); - - groupData.bindGroup = bindGroup; - } - } - - return bindings; - } - - getForCompute(computeNode) { - const bindings = this.nodes.getForCompute(computeNode).bindings; - - for (const bindGroup of bindings) { - const groupData = this.get(bindGroup); - - if (groupData.bindGroup === undefined) { - this._init(bindGroup); - - this.backend.createBindings(bindGroup, bindings); - - groupData.bindGroup = bindGroup; - } - } - - return bindings; - } - - updateForCompute(computeNode) { - this._updateBindings(this.getForCompute(computeNode)); - } - - updateForRender(renderObject) { - this._updateBindings(this.getForRender(renderObject)); - } - - _updateBindings(bindings) { - for (const bindGroup of bindings) { - this._update(bindGroup, bindings); - } - } - - _init(bindGroup) { - for (const binding of bindGroup.bindings) { - if (binding.isSampledTexture) { - this.textures.updateTexture(binding.texture); - } else if (binding.isStorageBuffer) { - const attribute = binding.attribute; - const attributeType = attribute.isIndirectStorageBufferAttribute - ? AttributeType.INDIRECT - : AttributeType.STORAGE; - - this.attributes.update(attribute, attributeType); - } - } - } - - _update(bindGroup, bindings) { - const { backend } = this; - - let needsBindingsUpdate = false; - - // iterate over all bindings and check if buffer updates or a new binding group is required - - for (const binding of bindGroup.bindings) { - if (binding.isNodeUniformsGroup) { - const updated = this.nodes.updateGroup(binding); - - if (!updated) continue; - } - - if (binding.isUniformBuffer) { - const updated = binding.update(); - - if (updated) { - backend.updateBinding(binding); - } - } else if (binding.isSampler) { - binding.update(); - } else if (binding.isSampledTexture) { - if (binding.needsBindingsUpdate(this.textures.get(binding.texture).generation)) - needsBindingsUpdate = true; - - const updated = binding.update(); - - const texture = binding.texture; - - if (updated) { - this.textures.updateTexture(texture); - } - - const textureData = backend.get(texture); - - if ( - backend.isWebGPUBackend === true && - textureData.texture === undefined && - textureData.externalTexture === undefined - ) { - // TODO: Remove this once we found why updated === false isn't bound to a texture in the WebGPU backend - console.error( - 'Bindings._update: binding should be available:', - binding, - updated, - texture, - binding.textureNode.value, - needsBindingsUpdate, - ); - - this.textures.updateTexture(texture); - needsBindingsUpdate = true; - } - - if (texture.isStorageTexture === true) { - const textureData = this.get(texture); - - if (binding.store === true) { - textureData.needsMipmap = true; - } else if (this.textures.needsMipmaps(texture) && textureData.needsMipmap === true) { - this.backend.generateMipmaps(texture); - - textureData.needsMipmap = false; - } - } - } - } - - if (needsBindingsUpdate === true) { - this.backend.updateBindings(bindGroup, bindings); - } - } -} - -export default Bindings; diff --git a/src-testing/src/renderers/common/Buffer.ts b/src-testing/src/renderers/common/Buffer.ts deleted file mode 100644 index 17013c6dc..000000000 --- a/src-testing/src/renderers/common/Buffer.ts +++ /dev/null @@ -1,28 +0,0 @@ -import Binding from './Binding.js'; -import { getFloatLength } from './BufferUtils.js'; - -class Buffer extends Binding { - constructor(name, buffer = null) { - super(name); - - this.isBuffer = true; - - this.bytesPerElement = Float32Array.BYTES_PER_ELEMENT; - - this._buffer = buffer; - } - - get byteLength() { - return getFloatLength(this._buffer.byteLength); - } - - get buffer() { - return this._buffer; - } - - update() { - return true; - } -} - -export default Buffer; diff --git a/src-testing/src/renderers/common/BufferUtils.ts b/src-testing/src/renderers/common/BufferUtils.ts deleted file mode 100644 index 99ddcb48b..000000000 --- a/src-testing/src/renderers/common/BufferUtils.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { GPU_CHUNK_BYTES } from './Constants.js'; - -function getFloatLength(floatLength) { - // ensure chunk size alignment (STD140 layout) - - return floatLength + ((GPU_CHUNK_BYTES - (floatLength % GPU_CHUNK_BYTES)) % GPU_CHUNK_BYTES); -} - -function getVectorLength(count, vectorLength = 4) { - const strideLength = getStrideLength(vectorLength); - - const floatLength = strideLength * count; - - return getFloatLength(floatLength); -} - -function getStrideLength(vectorLength) { - const strideLength = 4; - - return vectorLength + ((strideLength - (vectorLength % strideLength)) % strideLength); -} - -export { getFloatLength, getVectorLength, getStrideLength }; diff --git a/src-testing/src/renderers/common/BundleGroup.ts b/src-testing/src/renderers/common/BundleGroup.ts deleted file mode 100644 index 1dd8e0a2c..000000000 --- a/src-testing/src/renderers/common/BundleGroup.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Group } from '../../objects/Group.js'; - -class BundleGroup extends Group { - constructor() { - super(); - - this.isBundleGroup = true; - - this.type = 'BundleGroup'; - - this.static = true; - this.version = 0; - } - - set needsUpdate(value) { - if (value === true) this.version++; - } -} - -export default BundleGroup; diff --git a/src-testing/src/renderers/common/ChainMap.ts b/src-testing/src/renderers/common/ChainMap.ts deleted file mode 100644 index b17e7080f..000000000 --- a/src-testing/src/renderers/common/ChainMap.ts +++ /dev/null @@ -1,43 +0,0 @@ -export default class ChainMap { - constructor() { - this.weakMap = new WeakMap(); - } - - get(keys) { - let map = this.weakMap; - - for (let i = 0; i < keys.length; i++) { - map = map.get(keys[i]); - - if (map === undefined) return undefined; - } - - return map.get(keys[keys.length - 1]); - } - - set(keys, value) { - let map = this.weakMap; - - for (let i = 0; i < keys.length; i++) { - const key = keys[i]; - - if (map.has(key) === false) map.set(key, new WeakMap()); - - map = map.get(key); - } - - return map.set(keys[keys.length - 1], value); - } - - delete(keys) { - let map = this.weakMap; - - for (let i = 0; i < keys.length; i++) { - map = map.get(keys[i]); - - if (map === undefined) return false; - } - - return map.delete(keys[keys.length - 1]); - } -} diff --git a/src-testing/src/renderers/common/ClippingContext.ts b/src-testing/src/renderers/common/ClippingContext.ts deleted file mode 100644 index c5659721a..000000000 --- a/src-testing/src/renderers/common/ClippingContext.ts +++ /dev/null @@ -1,136 +0,0 @@ -import { Matrix3 } from '../../math/Matrix3.js'; -import { Plane } from '../../math/Plane.js'; -import { Vector4 } from '../../math/Vector4.js'; -import { hash } from '../../nodes/core/NodeUtils.js'; - -const _plane = /*@__PURE__*/ new Plane(); - -class ClippingContext { - constructor() { - this.version = 0; - - this.globalClippingCount = 0; - - this.localClippingCount = 0; - this.localClippingEnabled = false; - this.localClipIntersection = false; - - this.planes = []; - - this.parentVersion = 0; - this.viewNormalMatrix = new Matrix3(); - this.cacheKey = 0; - } - - projectPlanes(source, offset) { - const l = source.length; - const planes = this.planes; - - for (let i = 0; i < l; i++) { - _plane.copy(source[i]).applyMatrix4(this.viewMatrix, this.viewNormalMatrix); - - const v = planes[offset + i]; - const normal = _plane.normal; - - v.x = -normal.x; - v.y = -normal.y; - v.z = -normal.z; - v.w = _plane.constant; - } - } - - updateGlobal(renderer, camera) { - const rendererClippingPlanes = renderer.clippingPlanes; - this.viewMatrix = camera.matrixWorldInverse; - - this.viewNormalMatrix.getNormalMatrix(this.viewMatrix); - - let update = false; - - if (Array.isArray(rendererClippingPlanes) && rendererClippingPlanes.length !== 0) { - const l = rendererClippingPlanes.length; - - if (l !== this.globalClippingCount) { - const planes = []; - - for (let i = 0; i < l; i++) { - planes.push(new Vector4()); - } - - this.globalClippingCount = l; - this.planes = planes; - - update = true; - } - - this.projectPlanes(rendererClippingPlanes, 0); - } else if (this.globalClippingCount !== 0) { - this.globalClippingCount = 0; - this.planes = []; - update = true; - } - - if (renderer.localClippingEnabled !== this.localClippingEnabled) { - this.localClippingEnabled = renderer.localClippingEnabled; - update = true; - } - - if (update) { - this.version++; - this.cacheKey = hash(this.globalClippingCount, this.localClippingEnabled === true ? 1 : 0); - } - } - - update(parent, material) { - let update = false; - - if (this !== parent && parent.version !== this.parentVersion) { - this.globalClippingCount = material.isShadowNodeMaterial ? 0 : parent.globalClippingCount; - this.localClippingEnabled = parent.localClippingEnabled; - this.planes = Array.from(parent.planes); - this.parentVersion = parent.version; - this.viewMatrix = parent.viewMatrix; - this.viewNormalMatrix = parent.viewNormalMatrix; - - update = true; - } - - if (this.localClippingEnabled) { - const localClippingPlanes = material.clippingPlanes; - - if (Array.isArray(localClippingPlanes) && localClippingPlanes.length !== 0) { - const l = localClippingPlanes.length; - const planes = this.planes; - const offset = this.globalClippingCount; - - if (update || l !== this.localClippingCount) { - planes.length = offset + l; - - for (let i = 0; i < l; i++) { - planes[offset + i] = new Vector4(); - } - - this.localClippingCount = l; - update = true; - } - - this.projectPlanes(localClippingPlanes, offset); - } else if (this.localClippingCount !== 0) { - this.localClippingCount = 0; - update = true; - } - - if (this.localClipIntersection !== material.clipIntersection) { - this.localClipIntersection = material.clipIntersection; - update = true; - } - } - - if (update) { - this.version += parent.version; - this.cacheKey = hash(parent.cacheKey, this.localClippingCount, this.localClipIntersection === true ? 1 : 0); - } - } -} - -export default ClippingContext; diff --git a/src-testing/src/renderers/common/Color4.ts b/src-testing/src/renderers/common/Color4.ts deleted file mode 100644 index 77caa31e0..000000000 --- a/src-testing/src/renderers/common/Color4.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { Color } from '../../math/Color.js'; - -class Color4 extends Color { - constructor(r, g, b, a = 1) { - super(r, g, b); - - this.a = a; - } - - set(r, g, b, a = 1) { - this.a = a; - - return super.set(r, g, b); - } - - copy(color) { - if (color.a !== undefined) this.a = color.a; - - return super.copy(color); - } - - clone() { - return new this.constructor(this.r, this.g, this.b, this.a); - } -} - -export default Color4; diff --git a/src-testing/src/renderers/common/ComputePipeline.ts b/src-testing/src/renderers/common/ComputePipeline.ts deleted file mode 100644 index 0fd3ca531..000000000 --- a/src-testing/src/renderers/common/ComputePipeline.ts +++ /dev/null @@ -1,13 +0,0 @@ -import Pipeline from './Pipeline.js'; - -class ComputePipeline extends Pipeline { - constructor(cacheKey, computeProgram) { - super(cacheKey); - - this.computeProgram = computeProgram; - - this.isComputePipeline = true; - } -} - -export default ComputePipeline; diff --git a/src-testing/src/renderers/common/Constants.ts b/src-testing/src/renderers/common/Constants.ts deleted file mode 100644 index c2dfad4c4..000000000 --- a/src-testing/src/renderers/common/Constants.ts +++ /dev/null @@ -1,15 +0,0 @@ -export const AttributeType = { - VERTEX: 1, - INDEX: 2, - STORAGE: 3, - INDIRECT: 4, -}; - -// size of a chunk in bytes (STD140 layout) - -export const GPU_CHUNK_BYTES = 16; - -// @TODO: Move to src/constants.js - -export const BlendColorFactor = 211; -export const OneMinusBlendColorFactor = 212; diff --git a/src-testing/src/renderers/common/CubeRenderTarget.ts b/src-testing/src/renderers/common/CubeRenderTarget.ts deleted file mode 100644 index 00c0fd8c4..000000000 --- a/src-testing/src/renderers/common/CubeRenderTarget.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { equirectUV } from '../../nodes/utils/EquirectUVNode.js'; -import { texture as TSL_Texture } from '../../nodes/accessors/TextureNode.js'; -import { positionWorldDirection } from '../../nodes/accessors/Position.js'; -import NodeMaterial from '../../materials/nodes/NodeMaterial.js'; - -import { WebGLCubeRenderTarget } from '../../renderers/WebGLCubeRenderTarget.js'; -import { Scene } from '../../scenes/Scene.js'; -import { CubeCamera } from '../../cameras/CubeCamera.js'; -import { BoxGeometry } from '../../geometries/BoxGeometry.js'; -import { Mesh } from '../../objects/Mesh.js'; -import { BackSide, NoBlending, LinearFilter, LinearMipmapLinearFilter } from '../../constants.js'; - -// @TODO: Consider rename WebGLCubeRenderTarget to just CubeRenderTarget - -class CubeRenderTarget extends WebGLCubeRenderTarget { - constructor(size = 1, options = {}) { - super(size, options); - - this.isCubeRenderTarget = true; - } - - fromEquirectangularTexture(renderer, texture) { - const currentMinFilter = texture.minFilter; - const currentGenerateMipmaps = texture.generateMipmaps; - - texture.generateMipmaps = true; - - this.texture.type = texture.type; - this.texture.colorSpace = texture.colorSpace; - - this.texture.generateMipmaps = texture.generateMipmaps; - this.texture.minFilter = texture.minFilter; - this.texture.magFilter = texture.magFilter; - - const geometry = new BoxGeometry(5, 5, 5); - - const uvNode = equirectUV(positionWorldDirection); - - const material = new NodeMaterial(); - material.colorNode = TSL_Texture(texture, uvNode, 0); - material.side = BackSide; - material.blending = NoBlending; - - const mesh = new Mesh(geometry, material); - - const scene = new Scene(); - scene.add(mesh); - - // Avoid blurred poles - if (texture.minFilter === LinearMipmapLinearFilter) texture.minFilter = LinearFilter; - - const camera = new CubeCamera(1, 10, this); - - const currentMRT = renderer.getMRT(); - renderer.setMRT(null); - - camera.update(renderer, scene); - - renderer.setMRT(currentMRT); - - texture.minFilter = currentMinFilter; - texture.currentGenerateMipmaps = currentGenerateMipmaps; - - mesh.geometry.dispose(); - mesh.material.dispose(); - - return this; - } -} - -export default CubeRenderTarget; diff --git a/src-testing/src/renderers/common/DataMap.ts b/src-testing/src/renderers/common/DataMap.ts deleted file mode 100644 index 006bc2950..000000000 --- a/src-testing/src/renderers/common/DataMap.ts +++ /dev/null @@ -1,38 +0,0 @@ -class DataMap { - constructor() { - this.data = new WeakMap(); - } - - get(object) { - let map = this.data.get(object); - - if (map === undefined) { - map = {}; - this.data.set(object, map); - } - - return map; - } - - delete(object) { - let map; - - if (this.data.has(object)) { - map = this.data.get(object); - - this.data.delete(object); - } - - return map; - } - - has(object) { - return this.data.has(object); - } - - dispose() { - this.data = new WeakMap(); - } -} - -export default DataMap; diff --git a/src-testing/src/renderers/common/Geometries.ts b/src-testing/src/renderers/common/Geometries.ts deleted file mode 100644 index 14c52f6f6..000000000 --- a/src-testing/src/renderers/common/Geometries.ts +++ /dev/null @@ -1,199 +0,0 @@ -import DataMap from './DataMap.js'; -import { AttributeType } from './Constants.js'; - -import { Uint16BufferAttribute, Uint32BufferAttribute } from '../../core/BufferAttribute.js'; - -function arrayNeedsUint32(array) { - // assumes larger values usually on last - - for (let i = array.length - 1; i >= 0; --i) { - if (array[i] >= 65535) return true; // account for PRIMITIVE_RESTART_FIXED_INDEX, #24565 - } - - return false; -} - -function getWireframeVersion(geometry) { - return geometry.index !== null ? geometry.index.version : geometry.attributes.position.version; -} - -function getWireframeIndex(geometry) { - const indices = []; - - const geometryIndex = geometry.index; - const geometryPosition = geometry.attributes.position; - - if (geometryIndex !== null) { - const array = geometryIndex.array; - - for (let i = 0, l = array.length; i < l; i += 3) { - const a = array[i + 0]; - const b = array[i + 1]; - const c = array[i + 2]; - - indices.push(a, b, b, c, c, a); - } - } else { - const array = geometryPosition.array; - - for (let i = 0, l = array.length / 3 - 1; i < l; i += 3) { - const a = i + 0; - const b = i + 1; - const c = i + 2; - - indices.push(a, b, b, c, c, a); - } - } - - const attribute = new (arrayNeedsUint32(indices) ? Uint32BufferAttribute : Uint16BufferAttribute)(indices, 1); - attribute.version = getWireframeVersion(geometry); - - return attribute; -} - -class Geometries extends DataMap { - constructor(attributes, info) { - super(); - - this.attributes = attributes; - this.info = info; - - this.wireframes = new WeakMap(); - - this.attributeCall = new WeakMap(); - } - - has(renderObject) { - const geometry = renderObject.geometry; - - return super.has(geometry) && this.get(geometry).initialized === true; - } - - updateForRender(renderObject) { - if (this.has(renderObject) === false) this.initGeometry(renderObject); - - this.updateAttributes(renderObject); - } - - initGeometry(renderObject) { - const geometry = renderObject.geometry; - const geometryData = this.get(geometry); - - geometryData.initialized = true; - - this.info.memory.geometries++; - - const onDispose = () => { - this.info.memory.geometries--; - - const index = geometry.index; - const geometryAttributes = renderObject.getAttributes(); - - if (index !== null) { - this.attributes.delete(index); - } - - for (const geometryAttribute of geometryAttributes) { - this.attributes.delete(geometryAttribute); - } - - const wireframeAttribute = this.wireframes.get(geometry); - - if (wireframeAttribute !== undefined) { - this.attributes.delete(wireframeAttribute); - } - - geometry.removeEventListener('dispose', onDispose); - }; - - geometry.addEventListener('dispose', onDispose); - } - - updateAttributes(renderObject) { - // attributes - - const attributes = renderObject.getAttributes(); - - for (const attribute of attributes) { - if (attribute.isStorageBufferAttribute || attribute.isStorageInstancedBufferAttribute) { - this.updateAttribute(attribute, AttributeType.STORAGE); - } else { - this.updateAttribute(attribute, AttributeType.VERTEX); - } - } - - // indexes - - const index = this.getIndex(renderObject); - - if (index !== null) { - this.updateAttribute(index, AttributeType.INDEX); - } - - // indirect - - const indirect = renderObject.geometry.indirect; - - if (indirect !== null) { - this.updateAttribute(indirect, AttributeType.INDIRECT); - } - } - - updateAttribute(attribute, type) { - const callId = this.info.render.calls; - - if (!attribute.isInterleavedBufferAttribute) { - if (this.attributeCall.get(attribute) !== callId) { - this.attributes.update(attribute, type); - - this.attributeCall.set(attribute, callId); - } - } else { - if (this.attributeCall.get(attribute) === undefined) { - this.attributes.update(attribute, type); - - this.attributeCall.set(attribute, callId); - } else if (this.attributeCall.get(attribute.data) !== callId) { - this.attributes.update(attribute, type); - - this.attributeCall.set(attribute.data, callId); - - this.attributeCall.set(attribute, callId); - } - } - } - - getIndirect(renderObject) { - return renderObject.geometry.indirect; - } - - getIndex(renderObject) { - const { geometry, material } = renderObject; - - let index = geometry.index; - - if (material.wireframe === true) { - const wireframes = this.wireframes; - - let wireframeAttribute = wireframes.get(geometry); - - if (wireframeAttribute === undefined) { - wireframeAttribute = getWireframeIndex(geometry); - - wireframes.set(geometry, wireframeAttribute); - } else if (wireframeAttribute.version !== getWireframeVersion(geometry)) { - this.attributes.delete(wireframeAttribute); - - wireframeAttribute = getWireframeIndex(geometry); - - wireframes.set(geometry, wireframeAttribute); - } - - index = wireframeAttribute; - } - - return index; - } -} - -export default Geometries; diff --git a/src-testing/src/renderers/common/IndirectStorageBufferAttribute.d.ts b/src-testing/src/renderers/common/IndirectStorageBufferAttribute.d.ts deleted file mode 100644 index 925294395..000000000 --- a/src-testing/src/renderers/common/IndirectStorageBufferAttribute.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { TypedArray } from "../../core/BufferAttribute.js"; -import StorageBufferAttribute from "./StorageBufferAttribute.js"; - -declare class IndirectStorageBufferAttribute extends StorageBufferAttribute { - readonly isIndirectStorageBufferAttribute: true; - - constructor(array: TypedArray, itemSize: number); -} - -export default IndirectStorageBufferAttribute; diff --git a/src-testing/src/renderers/common/Info.ts b/src-testing/src/renderers/common/Info.ts deleted file mode 100644 index 4ede75de7..000000000 --- a/src-testing/src/renderers/common/Info.ts +++ /dev/null @@ -1,95 +0,0 @@ -class Info { - constructor() { - this.autoReset = true; - - this.frame = 0; - this.calls = 0; - - this.render = { - calls: 0, - frameCalls: 0, - drawCalls: 0, - triangles: 0, - points: 0, - lines: 0, - timestamp: 0, - previousFrameCalls: 0, - timestampCalls: 0, - }; - - this.compute = { - calls: 0, - frameCalls: 0, - timestamp: 0, - previousFrameCalls: 0, - timestampCalls: 0, - }; - - this.memory = { - geometries: 0, - textures: 0, - }; - } - - update(object, count, instanceCount) { - this.render.drawCalls++; - - if (object.isMesh || object.isSprite) { - this.render.triangles += instanceCount * (count / 3); - } else if (object.isPoints) { - this.render.points += instanceCount * count; - } else if (object.isLineSegments) { - this.render.lines += instanceCount * (count / 2); - } else if (object.isLine) { - this.render.lines += instanceCount * (count - 1); - } else { - console.error('THREE.WebGPUInfo: Unknown object type.'); - } - } - - updateTimestamp(type, time) { - if (this[type].timestampCalls === 0) { - this[type].timestamp = 0; - } - - this[type].timestamp += time; - - this[type].timestampCalls++; - - if (this[type].timestampCalls >= this[type].previousFrameCalls) { - this[type].timestampCalls = 0; - } - } - - reset() { - const previousRenderFrameCalls = this.render.frameCalls; - this.render.previousFrameCalls = previousRenderFrameCalls; - - const previousComputeFrameCalls = this.compute.frameCalls; - this.compute.previousFrameCalls = previousComputeFrameCalls; - - this.render.drawCalls = 0; - this.render.frameCalls = 0; - this.compute.frameCalls = 0; - - this.render.triangles = 0; - this.render.points = 0; - this.render.lines = 0; - } - - dispose() { - this.reset(); - - this.calls = 0; - - this.render.calls = 0; - this.compute.calls = 0; - - this.render.timestamp = 0; - this.compute.timestamp = 0; - this.memory.geometries = 0; - this.memory.textures = 0; - } -} - -export default Info; diff --git a/src-testing/src/renderers/common/Lighting.d.ts b/src-testing/src/renderers/common/Lighting.d.ts deleted file mode 100644 index 72842e6e7..000000000 --- a/src-testing/src/renderers/common/Lighting.d.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Camera } from "../../cameras/Camera.js"; -import { Object3D } from "../../core/Object3D.js"; -import { Light } from "../../lights/Light.js"; -import LightsNode from "../../nodes/lighting/LightsNode.js"; -import ChainMap from "./ChainMap.js"; - -declare class Lighting extends ChainMap<[Object3D, Camera], LightsNode> { - constructor(); - - createNode(lights?: Light[]): LightsNode; - - getNode(scene: Object3D, camera: Camera): LightsNode; -} - -export default Lighting; diff --git a/src-testing/src/renderers/common/Pipeline.ts b/src-testing/src/renderers/common/Pipeline.ts deleted file mode 100644 index 16017455a..000000000 --- a/src-testing/src/renderers/common/Pipeline.ts +++ /dev/null @@ -1,9 +0,0 @@ -class Pipeline { - constructor(cacheKey) { - this.cacheKey = cacheKey; - - this.usedTimes = 0; - } -} - -export default Pipeline; diff --git a/src-testing/src/renderers/common/Pipelines.ts b/src-testing/src/renderers/common/Pipelines.ts deleted file mode 100644 index 68c8f223c..000000000 --- a/src-testing/src/renderers/common/Pipelines.ts +++ /dev/null @@ -1,270 +0,0 @@ -import DataMap from './DataMap.js'; -import RenderPipeline from './RenderPipeline.js'; -import ComputePipeline from './ComputePipeline.js'; -import ProgrammableStage from './ProgrammableStage.js'; - -class Pipelines extends DataMap { - constructor(backend, nodes) { - super(); - - this.backend = backend; - this.nodes = nodes; - - this.bindings = null; // set by the bindings - - this.caches = new Map(); - this.programs = { - vertex: new Map(), - fragment: new Map(), - compute: new Map(), - }; - } - - getForCompute(computeNode, bindings) { - const { backend } = this; - - const data = this.get(computeNode); - - if (this._needsComputeUpdate(computeNode)) { - const previousPipeline = data.pipeline; - - if (previousPipeline) { - previousPipeline.usedTimes--; - previousPipeline.computeProgram.usedTimes--; - } - - // get shader - - const nodeBuilderState = this.nodes.getForCompute(computeNode); - - // programmable stage - - let stageCompute = this.programs.compute.get(nodeBuilderState.computeShader); - - if (stageCompute === undefined) { - if (previousPipeline && previousPipeline.computeProgram.usedTimes === 0) - this._releaseProgram(previousPipeline.computeProgram); - - stageCompute = new ProgrammableStage( - nodeBuilderState.computeShader, - 'compute', - nodeBuilderState.transforms, - nodeBuilderState.nodeAttributes, - ); - this.programs.compute.set(nodeBuilderState.computeShader, stageCompute); - - backend.createProgram(stageCompute); - } - - // determine compute pipeline - - const cacheKey = this._getComputeCacheKey(computeNode, stageCompute); - - let pipeline = this.caches.get(cacheKey); - - if (pipeline === undefined) { - if (previousPipeline && previousPipeline.usedTimes === 0) this._releasePipeline(previousPipeline); - - pipeline = this._getComputePipeline(computeNode, stageCompute, cacheKey, bindings); - } - - // keep track of all used times - - pipeline.usedTimes++; - stageCompute.usedTimes++; - - // - - data.version = computeNode.version; - data.pipeline = pipeline; - } - - return data.pipeline; - } - - getForRender(renderObject, promises = null) { - const { backend } = this; - - const data = this.get(renderObject); - - if (this._needsRenderUpdate(renderObject)) { - const previousPipeline = data.pipeline; - - if (previousPipeline) { - previousPipeline.usedTimes--; - previousPipeline.vertexProgram.usedTimes--; - previousPipeline.fragmentProgram.usedTimes--; - } - - // get shader - - const nodeBuilderState = renderObject.getNodeBuilderState(); - - // programmable stages - - let stageVertex = this.programs.vertex.get(nodeBuilderState.vertexShader); - - if (stageVertex === undefined) { - if (previousPipeline && previousPipeline.vertexProgram.usedTimes === 0) - this._releaseProgram(previousPipeline.vertexProgram); - - stageVertex = new ProgrammableStage(nodeBuilderState.vertexShader, 'vertex'); - this.programs.vertex.set(nodeBuilderState.vertexShader, stageVertex); - - backend.createProgram(stageVertex); - } - - let stageFragment = this.programs.fragment.get(nodeBuilderState.fragmentShader); - - if (stageFragment === undefined) { - if (previousPipeline && previousPipeline.fragmentProgram.usedTimes === 0) - this._releaseProgram(previousPipeline.fragmentProgram); - - stageFragment = new ProgrammableStage(nodeBuilderState.fragmentShader, 'fragment'); - this.programs.fragment.set(nodeBuilderState.fragmentShader, stageFragment); - - backend.createProgram(stageFragment); - } - - // determine render pipeline - - const cacheKey = this._getRenderCacheKey(renderObject, stageVertex, stageFragment); - - let pipeline = this.caches.get(cacheKey); - - if (pipeline === undefined) { - if (previousPipeline && previousPipeline.usedTimes === 0) this._releasePipeline(previousPipeline); - - pipeline = this._getRenderPipeline(renderObject, stageVertex, stageFragment, cacheKey, promises); - } else { - renderObject.pipeline = pipeline; - } - - // keep track of all used times - - pipeline.usedTimes++; - stageVertex.usedTimes++; - stageFragment.usedTimes++; - - // - - data.pipeline = pipeline; - } - - return data.pipeline; - } - - delete(object) { - const pipeline = this.get(object).pipeline; - - if (pipeline) { - // pipeline - - pipeline.usedTimes--; - - if (pipeline.usedTimes === 0) this._releasePipeline(pipeline); - - // programs - - if (pipeline.isComputePipeline) { - pipeline.computeProgram.usedTimes--; - - if (pipeline.computeProgram.usedTimes === 0) this._releaseProgram(pipeline.computeProgram); - } else { - pipeline.fragmentProgram.usedTimes--; - pipeline.vertexProgram.usedTimes--; - - if (pipeline.vertexProgram.usedTimes === 0) this._releaseProgram(pipeline.vertexProgram); - if (pipeline.fragmentProgram.usedTimes === 0) this._releaseProgram(pipeline.fragmentProgram); - } - } - - return super.delete(object); - } - - dispose() { - super.dispose(); - - this.caches = new Map(); - this.programs = { - vertex: new Map(), - fragment: new Map(), - compute: new Map(), - }; - } - - updateForRender(renderObject) { - this.getForRender(renderObject); - } - - _getComputePipeline(computeNode, stageCompute, cacheKey, bindings) { - // check for existing pipeline - - cacheKey = cacheKey || this._getComputeCacheKey(computeNode, stageCompute); - - let pipeline = this.caches.get(cacheKey); - - if (pipeline === undefined) { - pipeline = new ComputePipeline(cacheKey, stageCompute); - - this.caches.set(cacheKey, pipeline); - - this.backend.createComputePipeline(pipeline, bindings); - } - - return pipeline; - } - - _getRenderPipeline(renderObject, stageVertex, stageFragment, cacheKey, promises) { - // check for existing pipeline - - cacheKey = cacheKey || this._getRenderCacheKey(renderObject, stageVertex, stageFragment); - - let pipeline = this.caches.get(cacheKey); - - if (pipeline === undefined) { - pipeline = new RenderPipeline(cacheKey, stageVertex, stageFragment); - - this.caches.set(cacheKey, pipeline); - - renderObject.pipeline = pipeline; - - this.backend.createRenderPipeline(renderObject, promises); - } - - return pipeline; - } - - _getComputeCacheKey(computeNode, stageCompute) { - return computeNode.id + ',' + stageCompute.id; - } - - _getRenderCacheKey(renderObject, stageVertex, stageFragment) { - return stageVertex.id + ',' + stageFragment.id + ',' + this.backend.getRenderCacheKey(renderObject); - } - - _releasePipeline(pipeline) { - this.caches.delete(pipeline.cacheKey); - } - - _releaseProgram(program) { - const code = program.code; - const stage = program.stage; - - this.programs[stage].delete(code); - } - - _needsComputeUpdate(computeNode) { - const data = this.get(computeNode); - - return data.pipeline === undefined || data.version !== computeNode.version; - } - - _needsRenderUpdate(renderObject) { - const data = this.get(renderObject); - - return data.pipeline === undefined || this.backend.needsRenderUpdate(renderObject); - } -} - -export default Pipelines; diff --git a/src-testing/src/renderers/common/PostProcessing.d.ts b/src-testing/src/renderers/common/PostProcessing.d.ts deleted file mode 100644 index fdd4e5bdc..000000000 --- a/src-testing/src/renderers/common/PostProcessing.d.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { Node } from "../../nodes/Nodes.js"; -import Renderer from "./Renderer.js"; - -declare class PostProcessing { - renderer: Renderer; - outputNode: Node; - - outputColorTransform: boolean; - - needsUpdate: boolean; - - constructor(renderer: Renderer, outputNode?: Node); - - render(): void; - - update(): void; - - renderAsync(): Promise; -} - -export default PostProcessing; diff --git a/src-testing/src/renderers/common/PostProcessingUtils.d.ts b/src-testing/src/renderers/common/PostProcessingUtils.d.ts deleted file mode 100644 index 2ef80556c..000000000 --- a/src-testing/src/renderers/common/PostProcessingUtils.d.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { Camera } from "../../cameras/Camera.js"; -import { ToneMapping } from "../../constants.js"; -import { BufferGeometry, GeometryGroup } from "../../core/BufferGeometry.js"; -import { Object3D } from "../../core/Object3D.js"; -import { RenderTarget } from "../../core/RenderTarget.js"; -import { Material } from "../../materials/Material.js"; -import { Color } from "../../math/Color.js"; -import MRTNode from "../../nodes/core/MRTNode.js"; -import LightsNode from "../../nodes/lighting/LightsNode.js"; -import { Scene } from "../../scenes/Scene.js"; -import { CubeTexture } from "../../textures/CubeTexture.js"; -import { Texture } from "../../textures/Texture.js"; -import Color4 from "./Color4.js"; -import Renderer from "./Renderer.js"; - -// renderer state - -export interface RendererState { - toneMapping: ToneMapping; - toneMappingExposure: number; - outputColorSpace: string; - renderTarget: RenderTarget | null; - activeCubeFace: number; - activeMipmapLevel: number; - renderObjectFunction: - | (( - object: Object3D, - scene: Scene, - camera: Camera, - geometry: BufferGeometry, - material: Material, - group: GeometryGroup, - lightsNode: LightsNode, - ) => void) - | null; - pixelRatio: number; - mrt: MRTNode | null; - clearColor: Color4; - clearAlpha: number; - autoClear: boolean; - scissorTest: boolean; -} - -export function saveRendererState(renderer: Renderer, state?: RendererState): RendererState; - -export function resetRendererState(renderer: Renderer, state?: RendererState): RendererState; - -export function restoreRendererState(renderer: Renderer, state: RendererState): void; - -// renderer and scene state - -export interface RendererAndSceneState extends RendererState { - background: Color | Texture | CubeTexture | null; - backgroundNode: Node | null | undefined; - overrideMaterial: Material | null; -} - -export function saveRendererAndSceneState( - renderer: RendererState, - scene: Scene, - state?: RendererAndSceneState, -): RendererAndSceneState; - -export function resetRendererAndSceneState(renderer: Renderer, state?: RendererAndSceneState): RendererAndSceneState; - -export function restoreRendererAndSceneState(renderer: Renderer, state: RendererAndSceneState): void; diff --git a/src-testing/src/renderers/common/ProgrammableStage.ts b/src-testing/src/renderers/common/ProgrammableStage.ts deleted file mode 100644 index a684e4443..000000000 --- a/src-testing/src/renderers/common/ProgrammableStage.ts +++ /dev/null @@ -1,16 +0,0 @@ -let _id = 0; - -class ProgrammableStage { - constructor(code, type, transforms = null, attributes = null) { - this.id = _id++; - - this.code = code; - this.stage = type; - this.transforms = transforms; - this.attributes = attributes; - - this.usedTimes = 0; - } -} - -export default ProgrammableStage; diff --git a/src-testing/src/renderers/common/QuadMesh.d.ts b/src-testing/src/renderers/common/QuadMesh.d.ts deleted file mode 100644 index ee2bb93ba..000000000 --- a/src-testing/src/renderers/common/QuadMesh.d.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { OrthographicCamera } from "../../cameras/OrthographicCamera.js"; -import { Material } from "../../materials/Material.js"; -import { Mesh } from "../../objects/Mesh.js"; -import Renderer from "./Renderer.js"; - -export default class QuadMesh extends Mesh { - camera: OrthographicCamera; - - readonly isQuadMesh: true; - - constructor(material?: Material | null); - - renderAsync(renderer: Renderer): Promise; - - render(renderer: Renderer): void; -} diff --git a/src-testing/src/renderers/common/RenderBundle.ts b/src-testing/src/renderers/common/RenderBundle.ts deleted file mode 100644 index e59e49378..000000000 --- a/src-testing/src/renderers/common/RenderBundle.ts +++ /dev/null @@ -1,12 +0,0 @@ -class RenderBundle { - constructor(scene, camera) { - this.scene = scene; - this.camera = camera; - } - - clone() { - return Object.assign(new this.constructor(), this); - } -} - -export default RenderBundle; diff --git a/src-testing/src/renderers/common/RenderBundles.ts b/src-testing/src/renderers/common/RenderBundles.ts deleted file mode 100644 index 291403652..000000000 --- a/src-testing/src/renderers/common/RenderBundles.ts +++ /dev/null @@ -1,28 +0,0 @@ -import ChainMap from './ChainMap.js'; -import RenderBundle from './RenderBundle.js'; - -class RenderBundles { - constructor() { - this.lists = new ChainMap(); - } - - get(scene, camera) { - const lists = this.lists; - const keys = [scene, camera]; - - let list = lists.get(keys); - - if (list === undefined) { - list = new RenderBundle(scene, camera); - lists.set(keys, list); - } - - return list; - } - - dispose() { - this.lists = new ChainMap(); - } -} - -export default RenderBundles; diff --git a/src-testing/src/renderers/common/RenderContext.ts b/src-testing/src/renderers/common/RenderContext.ts deleted file mode 100644 index 9b5ee3a28..000000000 --- a/src-testing/src/renderers/common/RenderContext.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { Vector4 } from '../../math/Vector4.js'; -import { hashArray } from '../../nodes/core/NodeUtils.js'; - -let id = 0; - -class RenderContext { - constructor() { - this.id = id++; - - this.color = true; - this.clearColor = true; - this.clearColorValue = { r: 0, g: 0, b: 0, a: 1 }; - - this.depth = true; - this.clearDepth = true; - this.clearDepthValue = 1; - - this.stencil = false; - this.clearStencil = true; - this.clearStencilValue = 1; - - this.viewport = false; - this.viewportValue = new Vector4(); - - this.scissor = false; - this.scissorValue = new Vector4(); - - this.textures = null; - this.depthTexture = null; - this.activeCubeFace = 0; - this.sampleCount = 1; - - this.width = 0; - this.height = 0; - - this.isRenderContext = true; - } - - getCacheKey() { - return getCacheKey(this); - } -} - -export function getCacheKey(renderContext) { - const { textures, activeCubeFace } = renderContext; - - const values = [activeCubeFace]; - - for (const texture of textures) { - values.push(texture.id); - } - - return hashArray(values); -} - -export default RenderContext; diff --git a/src-testing/src/renderers/common/RenderContexts.ts b/src-testing/src/renderers/common/RenderContexts.ts deleted file mode 100644 index e77308c1d..000000000 --- a/src-testing/src/renderers/common/RenderContexts.ts +++ /dev/null @@ -1,47 +0,0 @@ -import ChainMap from './ChainMap.js'; -import RenderContext from './RenderContext.js'; - -class RenderContexts { - constructor() { - this.chainMaps = {}; - } - - get(scene, camera, renderTarget = null) { - const chainKey = [scene, camera]; - - let attachmentState; - - if (renderTarget === null) { - attachmentState = 'default'; - } else { - const format = renderTarget.texture.format; - const count = renderTarget.textures.length; - - attachmentState = `${count}:${format}:${renderTarget.samples}:${renderTarget.depthBuffer}:${renderTarget.stencilBuffer}`; - } - - const chainMap = this.getChainMap(attachmentState); - - let renderState = chainMap.get(chainKey); - - if (renderState === undefined) { - renderState = new RenderContext(); - - chainMap.set(chainKey, renderState); - } - - if (renderTarget !== null) renderState.sampleCount = renderTarget.samples === 0 ? 1 : renderTarget.samples; - - return renderState; - } - - getChainMap(attachmentState) { - return this.chainMaps[attachmentState] || (this.chainMaps[attachmentState] = new ChainMap()); - } - - dispose() { - this.chainMaps = {}; - } -} - -export default RenderContexts; diff --git a/src-testing/src/renderers/common/RenderList.ts b/src-testing/src/renderers/common/RenderList.ts deleted file mode 100644 index 63d236dd0..000000000 --- a/src-testing/src/renderers/common/RenderList.ts +++ /dev/null @@ -1,142 +0,0 @@ -function painterSortStable(a, b) { - if (a.groupOrder !== b.groupOrder) { - return a.groupOrder - b.groupOrder; - } else if (a.renderOrder !== b.renderOrder) { - return a.renderOrder - b.renderOrder; - } else if (a.material.id !== b.material.id) { - return a.material.id - b.material.id; - } else if (a.z !== b.z) { - return a.z - b.z; - } else { - return a.id - b.id; - } -} - -function reversePainterSortStable(a, b) { - if (a.groupOrder !== b.groupOrder) { - return a.groupOrder - b.groupOrder; - } else if (a.renderOrder !== b.renderOrder) { - return a.renderOrder - b.renderOrder; - } else if (a.z !== b.z) { - return b.z - a.z; - } else { - return a.id - b.id; - } -} - -class RenderList { - constructor(lighting, scene, camera) { - this.renderItems = []; - this.renderItemsIndex = 0; - - this.opaque = []; - this.transparent = []; - this.bundles = []; - - this.lightsNode = lighting.getNode(scene, camera); - this.lightsArray = []; - - this.scene = scene; - this.camera = camera; - - this.occlusionQueryCount = 0; - } - - begin() { - this.renderItemsIndex = 0; - - this.opaque.length = 0; - this.transparent.length = 0; - this.bundles.length = 0; - - this.lightsArray.length = 0; - - this.occlusionQueryCount = 0; - - return this; - } - - getNextRenderItem(object, geometry, material, groupOrder, z, group) { - let renderItem = this.renderItems[this.renderItemsIndex]; - - if (renderItem === undefined) { - renderItem = { - id: object.id, - object: object, - geometry: geometry, - material: material, - groupOrder: groupOrder, - renderOrder: object.renderOrder, - z: z, - group: group, - }; - - this.renderItems[this.renderItemsIndex] = renderItem; - } else { - renderItem.id = object.id; - renderItem.object = object; - renderItem.geometry = geometry; - renderItem.material = material; - renderItem.groupOrder = groupOrder; - renderItem.renderOrder = object.renderOrder; - renderItem.z = z; - renderItem.group = group; - } - - this.renderItemsIndex++; - - return renderItem; - } - - push(object, geometry, material, groupOrder, z, group) { - const renderItem = this.getNextRenderItem(object, geometry, material, groupOrder, z, group); - - if (object.occlusionTest === true) this.occlusionQueryCount++; - - (material.transparent === true || material.transmission > 0 ? this.transparent : this.opaque).push(renderItem); - } - - unshift(object, geometry, material, groupOrder, z, group) { - const renderItem = this.getNextRenderItem(object, geometry, material, groupOrder, z, group); - - (material.transparent === true ? this.transparent : this.opaque).unshift(renderItem); - } - - pushBundle(group) { - this.bundles.push(group); - } - - pushLight(light) { - this.lightsArray.push(light); - } - - sort(customOpaqueSort, customTransparentSort) { - if (this.opaque.length > 1) this.opaque.sort(customOpaqueSort || painterSortStable); - if (this.transparent.length > 1) this.transparent.sort(customTransparentSort || reversePainterSortStable); - } - - finish() { - // update lights - - this.lightsNode.setLights(this.lightsArray); - - // Clear references from inactive renderItems in the list - - for (let i = this.renderItemsIndex, il = this.renderItems.length; i < il; i++) { - const renderItem = this.renderItems[i]; - - if (renderItem.id === null) break; - - renderItem.id = null; - renderItem.object = null; - renderItem.geometry = null; - renderItem.material = null; - renderItem.groupOrder = null; - renderItem.renderOrder = null; - renderItem.z = null; - renderItem.group = null; - } - } -} - -export default RenderList; diff --git a/src-testing/src/renderers/common/RenderLists.ts b/src-testing/src/renderers/common/RenderLists.ts deleted file mode 100644 index 0486f7933..000000000 --- a/src-testing/src/renderers/common/RenderLists.ts +++ /dev/null @@ -1,30 +0,0 @@ -import ChainMap from './ChainMap.js'; -import RenderList from './RenderList.js'; - -class RenderLists { - constructor(lighting) { - this.lighting = lighting; - - this.lists = new ChainMap(); - } - - get(scene, camera) { - const lists = this.lists; - const keys = [scene, camera]; - - let list = lists.get(keys); - - if (list === undefined) { - list = new RenderList(this.lighting, scene, camera); - lists.set(keys, list); - } - - return list; - } - - dispose() { - this.lists = new ChainMap(); - } -} - -export default RenderLists; diff --git a/src-testing/src/renderers/common/RenderObject.ts b/src-testing/src/renderers/common/RenderObject.ts deleted file mode 100644 index e46d3871f..000000000 --- a/src-testing/src/renderers/common/RenderObject.ts +++ /dev/null @@ -1,350 +0,0 @@ -import { hashString } from '../../nodes/core/NodeUtils.js'; -import ClippingContext from './ClippingContext.js'; - -let _id = 0; - -function getKeys(obj) { - const keys = Object.keys(obj); - - let proto = Object.getPrototypeOf(obj); - - while (proto) { - const descriptors = Object.getOwnPropertyDescriptors(proto); - - for (const key in descriptors) { - if (descriptors[key] !== undefined) { - const descriptor = descriptors[key]; - - if (descriptor && typeof descriptor.get === 'function') { - keys.push(key); - } - } - } - - proto = Object.getPrototypeOf(proto); - } - - return keys; -} - -export default class RenderObject { - constructor(nodes, geometries, renderer, object, material, scene, camera, lightsNode, renderContext) { - this._nodes = nodes; - this._geometries = geometries; - - this.id = _id++; - - this.renderer = renderer; - this.object = object; - this.material = material; - this.scene = scene; - this.camera = camera; - this.lightsNode = lightsNode; - this.context = renderContext; - - this.geometry = object.geometry; - this.version = material.version; - - this.drawRange = null; - - this.attributes = null; - this.pipeline = null; - this.vertexBuffers = null; - this.drawParams = null; - - this.bundle = null; - - this.updateClipping(renderContext.clippingContext); - - this.clippingContextVersion = this.clippingContext.version; - - this.initialNodesCacheKey = this.getDynamicCacheKey(); - this.initialCacheKey = this.getCacheKey(); - - this._nodeBuilderState = null; - this._bindings = null; - this._monitor = null; - - this.onDispose = null; - - this.isRenderObject = true; - - this.onMaterialDispose = () => { - this.dispose(); - }; - - this.material.addEventListener('dispose', this.onMaterialDispose); - } - - updateClipping(parent) { - const material = this.material; - - let clippingContext = this.clippingContext; - - if (Array.isArray(material.clippingPlanes)) { - if (clippingContext === parent || !clippingContext) { - clippingContext = new ClippingContext(); - this.clippingContext = clippingContext; - } - - clippingContext.update(parent, material); - } else if (this.clippingContext !== parent) { - this.clippingContext = parent; - } - } - - get clippingNeedsUpdate() { - if (this.clippingContext.version === this.clippingContextVersion) return false; - - this.clippingContextVersion = this.clippingContext.version; - - return true; - } - - getNodeBuilderState() { - return this._nodeBuilderState || (this._nodeBuilderState = this._nodes.getForRender(this)); - } - - getMonitor() { - return this._monitor || (this._monitor = this.getNodeBuilderState().monitor); - } - - getBindings() { - return this._bindings || (this._bindings = this.getNodeBuilderState().createBindings()); - } - - getIndex() { - return this._geometries.getIndex(this); - } - - getIndirect() { - return this._geometries.getIndirect(this); - } - - getChainArray() { - return [this.object, this.material, this.context, this.lightsNode]; - } - - getAttributes() { - if (this.attributes !== null) return this.attributes; - - const nodeAttributes = this.getNodeBuilderState().nodeAttributes; - const geometry = this.geometry; - - const attributes = []; - const vertexBuffers = new Set(); - - for (const nodeAttribute of nodeAttributes) { - const attribute = - nodeAttribute.node && nodeAttribute.node.attribute - ? nodeAttribute.node.attribute - : geometry.getAttribute(nodeAttribute.name); - - if (attribute === undefined) continue; - - attributes.push(attribute); - - const bufferAttribute = attribute.isInterleavedBufferAttribute ? attribute.data : attribute; - vertexBuffers.add(bufferAttribute); - } - - this.attributes = attributes; - this.vertexBuffers = Array.from(vertexBuffers.values()); - - return attributes; - } - - getVertexBuffers() { - if (this.vertexBuffers === null) this.getAttributes(); - - return this.vertexBuffers; - } - - getDrawParameters() { - const { object, material, geometry, group, drawRange } = this; - - const drawParams = - this.drawParams || - (this.drawParams = { - vertexCount: 0, - firstVertex: 0, - instanceCount: 0, - firstInstance: 0, - }); - - const index = this.getIndex(); - const hasIndex = index !== null; - const instanceCount = geometry.isInstancedBufferGeometry - ? geometry.instanceCount - : object.count > 1 - ? object.count - : 1; - - if (instanceCount === 0) return null; - - drawParams.instanceCount = instanceCount; - - if (object.isBatchedMesh === true) return drawParams; - - let rangeFactor = 1; - - if ( - material.wireframe === true && - !object.isPoints && - !object.isLineSegments && - !object.isLine && - !object.isLineLoop - ) { - rangeFactor = 2; - } - - let firstVertex = drawRange.start * rangeFactor; - let lastVertex = (drawRange.start + drawRange.count) * rangeFactor; - - if (group !== null) { - firstVertex = Math.max(firstVertex, group.start * rangeFactor); - lastVertex = Math.min(lastVertex, (group.start + group.count) * rangeFactor); - } - - const position = geometry.attributes.position; - let itemCount = Infinity; - - if (hasIndex) { - itemCount = index.count; - } else if (position !== undefined && position !== null) { - itemCount = position.count; - } - - firstVertex = Math.max(firstVertex, 0); - lastVertex = Math.min(lastVertex, itemCount); - - const count = lastVertex - firstVertex; - - if (count < 0 || count === Infinity) return null; - - drawParams.vertexCount = count; - drawParams.firstVertex = firstVertex; - - return drawParams; - } - - getGeometryCacheKey() { - const { geometry } = this; - - let cacheKey = ''; - - for (const name of Object.keys(geometry.attributes).sort()) { - const attribute = geometry.attributes[name]; - - cacheKey += name + ','; - - if (attribute.data) cacheKey += attribute.data.stride + ','; - if (attribute.offset) cacheKey += attribute.offset + ','; - if (attribute.itemSize) cacheKey += attribute.itemSize + ','; - if (attribute.normalized) cacheKey += 'n,'; - } - - if (geometry.index) { - cacheKey += 'index,'; - } - - return cacheKey; - } - - getMaterialCacheKey() { - const { object, material } = this; - - let cacheKey = material.customProgramCacheKey(); - - for (const property of getKeys(material)) { - if (/^(is[A-Z]|_)|^(visible|version|uuid|name|opacity|userData)$/.test(property)) continue; - - const value = material[property]; - - let valueKey; - - if (value !== null) { - // some material values require a formatting - - const type = typeof value; - - if (type === 'number') { - valueKey = value !== 0 ? '1' : '0'; // Convert to on/off, important for clearcoat, transmission, etc - } else if (type === 'object') { - valueKey = '{'; - - if (value.isTexture) { - valueKey += value.mapping; - } - - valueKey += '}'; - } else { - valueKey = String(value); - } - } else { - valueKey = String(value); - } - - cacheKey += /*property + ':' +*/ valueKey + ','; - } - - cacheKey += this.clippingContext.cacheKey + ','; - - if (object.geometry) { - cacheKey += this.getGeometryCacheKey(); - } - - if (object.skeleton) { - cacheKey += object.skeleton.bones.length + ','; - } - - if (object.morphTargetInfluences) { - cacheKey += object.morphTargetInfluences.length + ','; - } - - if (object.isBatchedMesh) { - cacheKey += object._matricesTexture.uuid + ','; - - if (object._colorsTexture !== null) { - cacheKey += object._colorsTexture.uuid + ','; - } - } - - if (object.count > 1) { - // TODO: https://github.com/mrdoob/three.js/pull/29066#issuecomment-2269400850 - - cacheKey += object.uuid + ','; - } - - return hashString(cacheKey); - } - - get needsUpdate() { - return ( - /*this.object.static !== true &&*/ this.initialNodesCacheKey !== this.getDynamicCacheKey() || - this.clippingNeedsUpdate - ); - } - - getDynamicCacheKey() { - // Environment Nodes Cache Key - - let cacheKey = this._nodes.getCacheKey(this.scene, this.lightsNode); - - if (this.object.receiveShadow) { - cacheKey += 1; - } - - return cacheKey; - } - - getCacheKey() { - return this.getMaterialCacheKey() + this.getDynamicCacheKey(); - } - - dispose() { - this.material.removeEventListener('dispose', this.onMaterialDispose); - - this.onDispose(); - } -} diff --git a/src-testing/src/renderers/common/RenderObjects.ts b/src-testing/src/renderers/common/RenderObjects.ts deleted file mode 100644 index 6bd06dd5e..000000000 --- a/src-testing/src/renderers/common/RenderObjects.ts +++ /dev/null @@ -1,107 +0,0 @@ -import ChainMap from './ChainMap.js'; -import RenderObject from './RenderObject.js'; - -const chainArray = []; - -class RenderObjects { - constructor(renderer, nodes, geometries, pipelines, bindings, info) { - this.renderer = renderer; - this.nodes = nodes; - this.geometries = geometries; - this.pipelines = pipelines; - this.bindings = bindings; - this.info = info; - - this.chainMaps = {}; - } - - get(object, material, scene, camera, lightsNode, renderContext, passId) { - const chainMap = this.getChainMap(passId); - - // reuse chainArray - chainArray[0] = object; - chainArray[1] = material; - chainArray[2] = renderContext; - chainArray[3] = lightsNode; - - let renderObject = chainMap.get(chainArray); - - if (renderObject === undefined) { - renderObject = this.createRenderObject( - this.nodes, - this.geometries, - this.renderer, - object, - material, - scene, - camera, - lightsNode, - renderContext, - passId, - ); - - chainMap.set(chainArray, renderObject); - } else { - renderObject.updateClipping(renderContext.clippingContext); - - if (renderObject.version !== material.version || renderObject.needsUpdate) { - if (renderObject.initialCacheKey !== renderObject.getCacheKey()) { - renderObject.dispose(); - - renderObject = this.get(object, material, scene, camera, lightsNode, renderContext, passId); - } else { - renderObject.version = material.version; - } - } - } - - return renderObject; - } - - getChainMap(passId = 'default') { - return this.chainMaps[passId] || (this.chainMaps[passId] = new ChainMap()); - } - - dispose() { - this.chainMaps = {}; - } - - createRenderObject( - nodes, - geometries, - renderer, - object, - material, - scene, - camera, - lightsNode, - renderContext, - passId, - ) { - const chainMap = this.getChainMap(passId); - - const renderObject = new RenderObject( - nodes, - geometries, - renderer, - object, - material, - scene, - camera, - lightsNode, - renderContext, - ); - - renderObject.onDispose = () => { - this.pipelines.delete(renderObject); - this.bindings.delete(renderObject); - this.nodes.delete(renderObject); - - chainMap.delete(renderObject.getChainArray()); - }; - - return renderObject; - } -} - -export default RenderObjects; diff --git a/src-testing/src/renderers/common/RenderPipeline.ts b/src-testing/src/renderers/common/RenderPipeline.ts deleted file mode 100644 index 0ec34b043..000000000 --- a/src-testing/src/renderers/common/RenderPipeline.ts +++ /dev/null @@ -1,12 +0,0 @@ -import Pipeline from './Pipeline.js'; - -class RenderPipeline extends Pipeline { - constructor(cacheKey, vertexProgram, fragmentProgram) { - super(cacheKey); - - this.vertexProgram = vertexProgram; - this.fragmentProgram = fragmentProgram; - } -} - -export default RenderPipeline; diff --git a/src-testing/src/renderers/common/Renderer.ts b/src-testing/src/renderers/common/Renderer.ts deleted file mode 100644 index 533684051..000000000 --- a/src-testing/src/renderers/common/Renderer.ts +++ /dev/null @@ -1,1425 +0,0 @@ -import Animation from './Animation.js'; -import RenderObjects from './RenderObjects.js'; -import Attributes from './Attributes.js'; -import Geometries from './Geometries.js'; -import Info from './Info.js'; -import Pipelines from './Pipelines.js'; -import Bindings from './Bindings.js'; -import RenderLists from './RenderLists.js'; -import RenderContexts from './RenderContexts.js'; -import Textures from './Textures.js'; -import Background from './Background.js'; -import Nodes from './nodes/Nodes.js'; -import Color4 from './Color4.js'; -import ClippingContext from './ClippingContext.js'; -import QuadMesh from './QuadMesh.js'; -import RenderBundles from './RenderBundles.js'; -import NodeLibrary from './nodes/NodeLibrary.js'; -import Lighting from './Lighting.js'; - -import NodeMaterial from '../../materials/nodes/NodeMaterial.js'; - -import { Scene } from '../../scenes/Scene.js'; -import { Frustum } from '../../math/Frustum.js'; -import { Matrix4 } from '../../math/Matrix4.js'; -import { Vector2 } from '../../math/Vector2.js'; -import { Vector4 } from '../../math/Vector4.js'; -import { RenderTarget } from '../../core/RenderTarget.js'; -import { - DoubleSide, - BackSide, - FrontSide, - SRGBColorSpace, - NoToneMapping, - LinearFilter, - LinearSRGBColorSpace, - HalfFloatType, - RGBAFormat, - PCFShadowMap, -} from '../../constants.js'; - -const _scene = /*@__PURE__*/ new Scene(); -const _drawingBufferSize = /*@__PURE__*/ new Vector2(); -const _screen = /*@__PURE__*/ new Vector4(); -const _frustum = /*@__PURE__*/ new Frustum(); -const _projScreenMatrix = /*@__PURE__*/ new Matrix4(); -const _vector4 = /*@__PURE__*/ new Vector4(); - -class Renderer { - constructor(backend, parameters = {}) { - this.isRenderer = true; - - // - - const { - logarithmicDepthBuffer = false, - alpha = true, - depth = true, - stencil = false, - antialias = false, - samples = 0, - getFallback = null, - } = parameters; - - // public - this.domElement = backend.getDomElement(); - - this.backend = backend; - - this.samples = samples || antialias === true ? 4 : 0; - - this.autoClear = true; - this.autoClearColor = true; - this.autoClearDepth = true; - this.autoClearStencil = true; - - this.alpha = alpha; - - this.logarithmicDepthBuffer = logarithmicDepthBuffer; - - this.outputColorSpace = SRGBColorSpace; - - this.toneMapping = NoToneMapping; - this.toneMappingExposure = 1.0; - - this.sortObjects = true; - - this.depth = depth; - this.stencil = stencil; - - this.clippingPlanes = []; - - this.info = new Info(); - - this.nodes = { - modelViewMatrix: null, - modelNormalViewMatrix: null, - }; - - this.library = new NodeLibrary(); - this.lighting = new Lighting(); - - // internals - - this._getFallback = getFallback; - - this._pixelRatio = 1; - this._width = this.domElement.width; - this._height = this.domElement.height; - - this._viewport = new Vector4(0, 0, this._width, this._height); - this._scissor = new Vector4(0, 0, this._width, this._height); - this._scissorTest = false; - - this._attributes = null; - this._geometries = null; - this._nodes = null; - this._animation = null; - this._bindings = null; - this._objects = null; - this._pipelines = null; - this._bundles = null; - this._renderLists = null; - this._renderContexts = null; - this._textures = null; - this._background = null; - - this._quad = new QuadMesh(new NodeMaterial()); - this._quad.material.type = 'Renderer_output'; - - this._currentRenderContext = null; - - this._opaqueSort = null; - this._transparentSort = null; - - this._frameBufferTarget = null; - - const alphaClear = this.alpha === true ? 0 : 1; - - this._clearColor = new Color4(0, 0, 0, alphaClear); - this._clearDepth = 1; - this._clearStencil = 0; - - this._renderTarget = null; - this._activeCubeFace = 0; - this._activeMipmapLevel = 0; - - this._mrt = null; - - this._renderObjectFunction = null; - this._currentRenderObjectFunction = null; - this._currentRenderBundle = null; - - this._handleObjectFunction = this._renderObjectDirect; - - this._initialized = false; - this._initPromise = null; - - this._compilationPromises = null; - - this.transparent = true; - this.opaque = true; - - this.shadowMap = { - enabled: false, - type: PCFShadowMap, - }; - - this.xr = { - enabled: false, - }; - - this.debug = { - checkShaderErrors: true, - onShaderError: null, - getShaderAsync: async (scene, camera, object) => { - await this.compileAsync(scene, camera); - - const renderList = this._renderLists.get(scene, camera); - const renderContext = this._renderContexts.get(scene, camera, this._renderTarget); - - const material = scene.overrideMaterial || object.material; - - const renderObject = this._objects.get( - object, - material, - scene, - camera, - renderList.lightsNode, - renderContext, - ); - - const { fragmentShader, vertexShader } = renderObject.getNodeBuilderState(); - - return { fragmentShader, vertexShader }; - }, - }; - } - - async init() { - if (this._initialized) { - throw new Error('Renderer: Backend has already been initialized.'); - } - - if (this._initPromise !== null) { - return this._initPromise; - } - - this._initPromise = new Promise(async (resolve, reject) => { - let backend = this.backend; - - try { - await backend.init(this); - } catch (error) { - if (this._getFallback !== null) { - // try the fallback - - try { - this.backend = backend = this._getFallback(error); - await backend.init(this); - } catch (error) { - reject(error); - return; - } - } else { - reject(error); - return; - } - } - - this._nodes = new Nodes(this, backend); - this._animation = new Animation(this._nodes, this.info); - this._attributes = new Attributes(backend); - this._background = new Background(this, this._nodes); - this._geometries = new Geometries(this._attributes, this.info); - this._textures = new Textures(this, backend, this.info); - this._pipelines = new Pipelines(backend, this._nodes); - this._bindings = new Bindings( - backend, - this._nodes, - this._textures, - this._attributes, - this._pipelines, - this.info, - ); - this._objects = new RenderObjects( - this, - this._nodes, - this._geometries, - this._pipelines, - this._bindings, - this.info, - ); - this._renderLists = new RenderLists(this.lighting); - this._bundles = new RenderBundles(); - this._renderContexts = new RenderContexts(); - - // - - this._initialized = true; - - resolve(); - }); - - return this._initPromise; - } - - get coordinateSystem() { - return this.backend.coordinateSystem; - } - - async compileAsync(scene, camera, targetScene = null) { - if (this._initialized === false) await this.init(); - - // preserve render tree - - const nodeFrame = this._nodes.nodeFrame; - - const previousRenderId = nodeFrame.renderId; - const previousRenderContext = this._currentRenderContext; - const previousRenderObjectFunction = this._currentRenderObjectFunction; - const previousCompilationPromises = this._compilationPromises; - - // - - const sceneRef = scene.isScene === true ? scene : _scene; - - if (targetScene === null) targetScene = scene; - - const renderTarget = this._renderTarget; - const renderContext = this._renderContexts.get(targetScene, camera, renderTarget); - const activeMipmapLevel = this._activeMipmapLevel; - - const compilationPromises = []; - - this._currentRenderContext = renderContext; - this._currentRenderObjectFunction = this.renderObject; - - this._handleObjectFunction = this._createObjectPipeline; - - this._compilationPromises = compilationPromises; - - nodeFrame.renderId++; - - // - - nodeFrame.update(); - - // - - renderContext.depth = this.depth; - renderContext.stencil = this.stencil; - - if (!renderContext.clippingContext) renderContext.clippingContext = new ClippingContext(); - renderContext.clippingContext.updateGlobal(this, camera); - - // - - sceneRef.onBeforeRender(this, scene, camera, renderTarget); - - // - - const renderList = this._renderLists.get(scene, camera); - renderList.begin(); - - this._projectObject(scene, camera, 0, renderList); - - // include lights from target scene - if (targetScene !== scene) { - targetScene.traverseVisible(function (object) { - if (object.isLight && object.layers.test(camera.layers)) { - renderList.pushLight(object); - } - }); - } - - renderList.finish(); - - // - - if (renderTarget !== null) { - this._textures.updateRenderTarget(renderTarget, activeMipmapLevel); - - const renderTargetData = this._textures.get(renderTarget); - - renderContext.textures = renderTargetData.textures; - renderContext.depthTexture = renderTargetData.depthTexture; - } else { - renderContext.textures = null; - renderContext.depthTexture = null; - } - - // - - this._nodes.updateScene(sceneRef); - - // - - this._background.update(sceneRef, renderList, renderContext); - - // process render lists - - const opaqueObjects = renderList.opaque; - const transparentObjects = renderList.transparent; - const lightsNode = renderList.lightsNode; - - if (this.opaque === true && opaqueObjects.length > 0) - this._renderObjects(opaqueObjects, camera, sceneRef, lightsNode); - if (this.transparent === true && transparentObjects.length > 0) - this._renderObjects(transparentObjects, camera, sceneRef, lightsNode); - - // restore render tree - - nodeFrame.renderId = previousRenderId; - - this._currentRenderContext = previousRenderContext; - this._currentRenderObjectFunction = previousRenderObjectFunction; - this._compilationPromises = previousCompilationPromises; - - this._handleObjectFunction = this._renderObjectDirect; - - // wait for all promises setup by backends awaiting compilation/linking/pipeline creation to complete - - await Promise.all(compilationPromises); - } - - async renderAsync(scene, camera) { - if (this._initialized === false) await this.init(); - - const renderContext = this._renderScene(scene, camera); - - await this.backend.resolveTimestampAsync(renderContext, 'render'); - } - - async waitForGPU() { - await this.backend.waitForGPU(); - } - - setMRT(mrt) { - this._mrt = mrt; - - return this; - } - - getMRT() { - return this._mrt; - } - - _renderBundle(bundle, sceneRef, lightsNode) { - const { bundleGroup, camera, renderList } = bundle; - - const renderContext = this._currentRenderContext; - - // - - const renderBundle = this._bundles.get(bundleGroup, camera); - const renderBundleData = this.backend.get(renderBundle); - - if (renderBundleData.renderContexts === undefined) renderBundleData.renderContexts = new Set(); - - // - - const needsUpdate = bundleGroup.version !== renderBundleData.version; - const renderBundleNeedsUpdate = renderBundleData.renderContexts.has(renderContext) === false || needsUpdate; - - renderBundleData.renderContexts.add(renderContext); - - if (renderBundleNeedsUpdate) { - this.backend.beginBundle(renderContext); - - if (renderBundleData.renderObjects === undefined || needsUpdate) { - renderBundleData.renderObjects = []; - } - - this._currentRenderBundle = renderBundle; - - const opaqueObjects = renderList.opaque; - - if (opaqueObjects.length > 0) this._renderObjects(opaqueObjects, camera, sceneRef, lightsNode); - - this._currentRenderBundle = null; - - // - - this.backend.finishBundle(renderContext, renderBundle); - - renderBundleData.version = bundleGroup.version; - } else { - const { renderObjects } = renderBundleData; - - for (let i = 0, l = renderObjects.length; i < l; i++) { - const renderObject = renderObjects[i]; - - if (this._nodes.needsRefresh(renderObject)) { - this._nodes.updateBefore(renderObject); - - this._nodes.updateForRender(renderObject); - this._bindings.updateForRender(renderObject); - - this._nodes.updateAfter(renderObject); - } - } - } - - this.backend.addBundle(renderContext, renderBundle); - } - - render(scene, camera) { - if (this._initialized === false) { - console.warn( - 'THREE.Renderer: .render() called before the backend is initialized. Try using .renderAsync() instead.', - ); - - return this.renderAsync(scene, camera); - } - - this._renderScene(scene, camera); - } - - _getFrameBufferTarget() { - const { currentToneMapping, currentColorSpace } = this; - - const useToneMapping = currentToneMapping !== NoToneMapping; - const useColorSpace = currentColorSpace !== LinearSRGBColorSpace; - - if (useToneMapping === false && useColorSpace === false) return null; - - const { width, height } = this.getDrawingBufferSize(_drawingBufferSize); - const { depth, stencil } = this; - - let frameBufferTarget = this._frameBufferTarget; - - if (frameBufferTarget === null) { - frameBufferTarget = new RenderTarget(width, height, { - depthBuffer: depth, - stencilBuffer: stencil, - type: HalfFloatType, // FloatType - format: RGBAFormat, - colorSpace: LinearSRGBColorSpace, - generateMipmaps: false, - minFilter: LinearFilter, - magFilter: LinearFilter, - samples: this.samples, - }); - - frameBufferTarget.isPostProcessingRenderTarget = true; - - this._frameBufferTarget = frameBufferTarget; - } - - frameBufferTarget.depthBuffer = depth; - frameBufferTarget.stencilBuffer = stencil; - frameBufferTarget.setSize(width, height); - frameBufferTarget.viewport.copy(this._viewport); - frameBufferTarget.scissor.copy(this._scissor); - frameBufferTarget.viewport.multiplyScalar(this._pixelRatio); - frameBufferTarget.scissor.multiplyScalar(this._pixelRatio); - frameBufferTarget.scissorTest = this._scissorTest; - - return frameBufferTarget; - } - - _renderScene(scene, camera, useFrameBufferTarget = true) { - const frameBufferTarget = useFrameBufferTarget ? this._getFrameBufferTarget() : null; - - // preserve render tree - - const nodeFrame = this._nodes.nodeFrame; - - const previousRenderId = nodeFrame.renderId; - const previousRenderContext = this._currentRenderContext; - const previousRenderObjectFunction = this._currentRenderObjectFunction; - - // - - const sceneRef = scene.isScene === true ? scene : _scene; - - const outputRenderTarget = this._renderTarget; - - const activeCubeFace = this._activeCubeFace; - const activeMipmapLevel = this._activeMipmapLevel; - - // - - let renderTarget; - - if (frameBufferTarget !== null) { - renderTarget = frameBufferTarget; - - this.setRenderTarget(renderTarget); - } else { - renderTarget = outputRenderTarget; - } - - // - - const renderContext = this._renderContexts.get(scene, camera, renderTarget); - - this._currentRenderContext = renderContext; - this._currentRenderObjectFunction = this._renderObjectFunction || this.renderObject; - - // - - this.info.calls++; - this.info.render.calls++; - this.info.render.frameCalls++; - - nodeFrame.renderId = this.info.calls; - - // - - const coordinateSystem = this.coordinateSystem; - - if (camera.coordinateSystem !== coordinateSystem) { - camera.coordinateSystem = coordinateSystem; - - camera.updateProjectionMatrix(); - } - - // - - if (scene.matrixWorldAutoUpdate === true) scene.updateMatrixWorld(); - - if (camera.parent === null && camera.matrixWorldAutoUpdate === true) camera.updateMatrixWorld(); - - // - - let viewport = this._viewport; - let scissor = this._scissor; - let pixelRatio = this._pixelRatio; - - if (renderTarget !== null) { - viewport = renderTarget.viewport; - scissor = renderTarget.scissor; - pixelRatio = 1; - } - - this.getDrawingBufferSize(_drawingBufferSize); - - _screen.set(0, 0, _drawingBufferSize.width, _drawingBufferSize.height); - - const minDepth = viewport.minDepth === undefined ? 0 : viewport.minDepth; - const maxDepth = viewport.maxDepth === undefined ? 1 : viewport.maxDepth; - - renderContext.viewportValue.copy(viewport).multiplyScalar(pixelRatio).floor(); - renderContext.viewportValue.width >>= activeMipmapLevel; - renderContext.viewportValue.height >>= activeMipmapLevel; - renderContext.viewportValue.minDepth = minDepth; - renderContext.viewportValue.maxDepth = maxDepth; - renderContext.viewport = renderContext.viewportValue.equals(_screen) === false; - - renderContext.scissorValue.copy(scissor).multiplyScalar(pixelRatio).floor(); - renderContext.scissor = this._scissorTest && renderContext.scissorValue.equals(_screen) === false; - renderContext.scissorValue.width >>= activeMipmapLevel; - renderContext.scissorValue.height >>= activeMipmapLevel; - - if (!renderContext.clippingContext) renderContext.clippingContext = new ClippingContext(); - renderContext.clippingContext.updateGlobal(this, camera); - - // - - sceneRef.onBeforeRender(this, scene, camera, renderTarget); - - // - - _projScreenMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse); - _frustum.setFromProjectionMatrix(_projScreenMatrix, coordinateSystem); - - const renderList = this._renderLists.get(scene, camera); - renderList.begin(); - - this._projectObject(scene, camera, 0, renderList); - - renderList.finish(); - - if (this.sortObjects === true) { - renderList.sort(this._opaqueSort, this._transparentSort); - } - - // - - if (renderTarget !== null) { - this._textures.updateRenderTarget(renderTarget, activeMipmapLevel); - - const renderTargetData = this._textures.get(renderTarget); - - renderContext.textures = renderTargetData.textures; - renderContext.depthTexture = renderTargetData.depthTexture; - renderContext.width = renderTargetData.width; - renderContext.height = renderTargetData.height; - renderContext.renderTarget = renderTarget; - renderContext.depth = renderTarget.depthBuffer; - renderContext.stencil = renderTarget.stencilBuffer; - } else { - renderContext.textures = null; - renderContext.depthTexture = null; - renderContext.width = this.domElement.width; - renderContext.height = this.domElement.height; - renderContext.depth = this.depth; - renderContext.stencil = this.stencil; - } - - renderContext.width >>= activeMipmapLevel; - renderContext.height >>= activeMipmapLevel; - renderContext.activeCubeFace = activeCubeFace; - renderContext.activeMipmapLevel = activeMipmapLevel; - renderContext.occlusionQueryCount = renderList.occlusionQueryCount; - - // - - this._nodes.updateScene(sceneRef); - - // - - this._background.update(sceneRef, renderList, renderContext); - - // - - this.backend.beginRender(renderContext); - - // process render lists - - const { bundles, lightsNode, transparent: transparentObjects, opaque: opaqueObjects } = renderList; - - if (bundles.length > 0) this._renderBundles(bundles, sceneRef, lightsNode); - if (this.opaque === true && opaqueObjects.length > 0) - this._renderObjects(opaqueObjects, camera, sceneRef, lightsNode); - if (this.transparent === true && transparentObjects.length > 0) - this._renderObjects(transparentObjects, camera, sceneRef, lightsNode); - - // finish render pass - - this.backend.finishRender(renderContext); - - // restore render tree - - nodeFrame.renderId = previousRenderId; - - this._currentRenderContext = previousRenderContext; - this._currentRenderObjectFunction = previousRenderObjectFunction; - - // - - if (frameBufferTarget !== null) { - this.setRenderTarget(outputRenderTarget, activeCubeFace, activeMipmapLevel); - - const quad = this._quad; - - if (this._nodes.hasOutputChange(renderTarget.texture)) { - quad.material.fragmentNode = this._nodes.getOutputNode(renderTarget.texture); - quad.material.needsUpdate = true; - } - - this._renderScene(quad, quad.camera, false); - } - - // - - sceneRef.onAfterRender(this, scene, camera, renderTarget); - - // - - return renderContext; - } - - getMaxAnisotropy() { - return this.backend.getMaxAnisotropy(); - } - - getActiveCubeFace() { - return this._activeCubeFace; - } - - getActiveMipmapLevel() { - return this._activeMipmapLevel; - } - - async setAnimationLoop(callback) { - if (this._initialized === false) await this.init(); - - this._animation.setAnimationLoop(callback); - } - - async getArrayBufferAsync(attribute) { - return await this.backend.getArrayBufferAsync(attribute); - } - - getContext() { - return this.backend.getContext(); - } - - getPixelRatio() { - return this._pixelRatio; - } - - getDrawingBufferSize(target) { - return target.set(this._width * this._pixelRatio, this._height * this._pixelRatio).floor(); - } - - getSize(target) { - return target.set(this._width, this._height); - } - - setPixelRatio(value = 1) { - if (this._pixelRatio === value) return; - - this._pixelRatio = value; - - this.setSize(this._width, this._height, false); - } - - setDrawingBufferSize(width, height, pixelRatio) { - this._width = width; - this._height = height; - - this._pixelRatio = pixelRatio; - - this.domElement.width = Math.floor(width * pixelRatio); - this.domElement.height = Math.floor(height * pixelRatio); - - this.setViewport(0, 0, width, height); - - if (this._initialized) this.backend.updateSize(); - } - - setSize(width, height, updateStyle = true) { - this._width = width; - this._height = height; - - this.domElement.width = Math.floor(width * this._pixelRatio); - this.domElement.height = Math.floor(height * this._pixelRatio); - - if (updateStyle === true) { - this.domElement.style.width = width + 'px'; - this.domElement.style.height = height + 'px'; - } - - this.setViewport(0, 0, width, height); - - if (this._initialized) this.backend.updateSize(); - } - - setOpaqueSort(method) { - this._opaqueSort = method; - } - - setTransparentSort(method) { - this._transparentSort = method; - } - - getScissor(target) { - const scissor = this._scissor; - - target.x = scissor.x; - target.y = scissor.y; - target.width = scissor.width; - target.height = scissor.height; - - return target; - } - - setScissor(x, y, width, height) { - const scissor = this._scissor; - - if (x.isVector4) { - scissor.copy(x); - } else { - scissor.set(x, y, width, height); - } - } - - getScissorTest() { - return this._scissorTest; - } - - setScissorTest(boolean) { - this._scissorTest = boolean; - - this.backend.setScissorTest(boolean); - } - - getViewport(target) { - return target.copy(this._viewport); - } - - setViewport(x, y, width, height, minDepth = 0, maxDepth = 1) { - const viewport = this._viewport; - - if (x.isVector4) { - viewport.copy(x); - } else { - viewport.set(x, y, width, height); - } - - viewport.minDepth = minDepth; - viewport.maxDepth = maxDepth; - } - - getClearColor(target) { - return target.copy(this._clearColor); - } - - setClearColor(color, alpha = 1) { - this._clearColor.set(color); - this._clearColor.a = alpha; - } - - getClearAlpha() { - return this._clearColor.a; - } - - setClearAlpha(alpha) { - this._clearColor.a = alpha; - } - - getClearDepth() { - return this._clearDepth; - } - - setClearDepth(depth) { - this._clearDepth = depth; - } - - getClearStencil() { - return this._clearStencil; - } - - setClearStencil(stencil) { - this._clearStencil = stencil; - } - - isOccluded(object) { - const renderContext = this._currentRenderContext; - - return renderContext && this.backend.isOccluded(renderContext, object); - } - - clear(color = true, depth = true, stencil = true) { - if (this._initialized === false) { - console.warn( - 'THREE.Renderer: .clear() called before the backend is initialized. Try using .clearAsync() instead.', - ); - - return this.clearAsync(color, depth, stencil); - } - - const renderTarget = this._renderTarget || this._getFrameBufferTarget(); - - let renderTargetData = null; - - if (renderTarget !== null) { - this._textures.updateRenderTarget(renderTarget); - - renderTargetData = this._textures.get(renderTarget); - } - - this.backend.clear(color, depth, stencil, renderTargetData); - - if (renderTarget !== null && this._renderTarget === null) { - // If a color space transform or tone mapping is required, - // the clear operation clears the intermediate renderTarget texture, but does not update the screen canvas. - - const quad = this._quad; - - if (this._nodes.hasOutputChange(renderTarget.texture)) { - quad.material.fragmentNode = this._nodes.getOutputNode(renderTarget.texture); - quad.material.needsUpdate = true; - } - - this._renderScene(quad, quad.camera, false); - } - } - - clearColor() { - return this.clear(true, false, false); - } - - clearDepth() { - return this.clear(false, true, false); - } - - clearStencil() { - return this.clear(false, false, true); - } - - async clearAsync(color = true, depth = true, stencil = true) { - if (this._initialized === false) await this.init(); - - this.clear(color, depth, stencil); - } - - clearColorAsync() { - return this.clearAsync(true, false, false); - } - - clearDepthAsync() { - return this.clearAsync(false, true, false); - } - - clearStencilAsync() { - return this.clearAsync(false, false, true); - } - - get currentToneMapping() { - return this._renderTarget !== null ? NoToneMapping : this.toneMapping; - } - - get currentColorSpace() { - return this._renderTarget !== null ? LinearSRGBColorSpace : this.outputColorSpace; - } - - dispose() { - this.info.dispose(); - - this._animation.dispose(); - this._objects.dispose(); - this._pipelines.dispose(); - this._nodes.dispose(); - this._bindings.dispose(); - this._renderLists.dispose(); - this._renderContexts.dispose(); - this._textures.dispose(); - - this.setRenderTarget(null); - this.setAnimationLoop(null); - } - - setRenderTarget(renderTarget, activeCubeFace = 0, activeMipmapLevel = 0) { - this._renderTarget = renderTarget; - this._activeCubeFace = activeCubeFace; - this._activeMipmapLevel = activeMipmapLevel; - } - - getRenderTarget() { - return this._renderTarget; - } - - setRenderObjectFunction(renderObjectFunction) { - this._renderObjectFunction = renderObjectFunction; - } - - getRenderObjectFunction() { - return this._renderObjectFunction; - } - - compute(computeNodes) { - if (this._initialized === false) { - console.warn( - 'THREE.Renderer: .compute() called before the backend is initialized. Try using .computeAsync() instead.', - ); - - return this.computeAsync(computeNodes); - } - - // - - const nodeFrame = this._nodes.nodeFrame; - - const previousRenderId = nodeFrame.renderId; - - // - - this.info.calls++; - this.info.compute.calls++; - this.info.compute.frameCalls++; - - nodeFrame.renderId = this.info.calls; - - // - - const backend = this.backend; - const pipelines = this._pipelines; - const bindings = this._bindings; - const nodes = this._nodes; - - const computeList = Array.isArray(computeNodes) ? computeNodes : [computeNodes]; - - if (computeList[0] === undefined || computeList[0].isComputeNode !== true) { - throw new Error('THREE.Renderer: .compute() expects a ComputeNode.'); - } - - backend.beginCompute(computeNodes); - - for (const computeNode of computeList) { - // onInit - - if (pipelines.has(computeNode) === false) { - const dispose = () => { - computeNode.removeEventListener('dispose', dispose); - - pipelines.delete(computeNode); - bindings.delete(computeNode); - nodes.delete(computeNode); - }; - - computeNode.addEventListener('dispose', dispose); - - // - - const onInitFn = computeNode.onInitFunction; - - if (onInitFn !== null) { - onInitFn.call(computeNode, { renderer: this }); - } - } - - nodes.updateForCompute(computeNode); - bindings.updateForCompute(computeNode); - - const computeBindings = bindings.getForCompute(computeNode); - const computePipeline = pipelines.getForCompute(computeNode, computeBindings); - - backend.compute(computeNodes, computeNode, computeBindings, computePipeline); - } - - backend.finishCompute(computeNodes); - - // - - nodeFrame.renderId = previousRenderId; - } - - async computeAsync(computeNodes) { - if (this._initialized === false) await this.init(); - - this.compute(computeNodes); - - await this.backend.resolveTimestampAsync(computeNodes, 'compute'); - } - - async hasFeatureAsync(name) { - if (this._initialized === false) await this.init(); - - return this.backend.hasFeature(name); - } - - hasFeature(name) { - if (this._initialized === false) { - console.warn( - 'THREE.Renderer: .hasFeature() called before the backend is initialized. Try using .hasFeatureAsync() instead.', - ); - - return false; - } - - return this.backend.hasFeature(name); - } - - copyFramebufferToTexture(framebufferTexture, rectangle = null) { - const renderContext = this._currentRenderContext; - - this._textures.updateTexture(framebufferTexture); - - rectangle = - rectangle === null - ? _vector4.set(0, 0, framebufferTexture.image.width, framebufferTexture.image.height) - : rectangle; - - this.backend.copyFramebufferToTexture(framebufferTexture, renderContext, rectangle); - } - - copyTextureToTexture(srcTexture, dstTexture, srcRegion = null, dstPosition = null, level = 0) { - this._textures.updateTexture(srcTexture); - this._textures.updateTexture(dstTexture); - - this.backend.copyTextureToTexture(srcTexture, dstTexture, srcRegion, dstPosition, level); - } - - readRenderTargetPixelsAsync(renderTarget, x, y, width, height, index = 0, faceIndex = 0) { - return this.backend.copyTextureToBuffer(renderTarget.textures[index], x, y, width, height, faceIndex); - } - - _projectObject(object, camera, groupOrder, renderList) { - if (object.visible === false) return; - - const visible = object.layers.test(camera.layers); - - if (visible) { - if (object.isGroup) { - groupOrder = object.renderOrder; - } else if (object.isLOD) { - if (object.autoUpdate === true) object.update(camera); - } else if (object.isLight) { - renderList.pushLight(object); - } else if (object.isSprite) { - if (!object.frustumCulled || _frustum.intersectsSprite(object)) { - if (this.sortObjects === true) { - _vector4.setFromMatrixPosition(object.matrixWorld).applyMatrix4(_projScreenMatrix); - } - - const { geometry, material } = object; - - if (material.visible) { - renderList.push(object, geometry, material, groupOrder, _vector4.z, null); - } - } - } else if (object.isLineLoop) { - console.error( - 'THREE.Renderer: Objects of type THREE.LineLoop are not supported. Please use THREE.Line or THREE.LineSegments.', - ); - } else if (object.isMesh || object.isLine || object.isPoints) { - if (!object.frustumCulled || _frustum.intersectsObject(object)) { - const { geometry, material } = object; - - if (this.sortObjects === true) { - if (geometry.boundingSphere === null) geometry.computeBoundingSphere(); - - _vector4 - .copy(geometry.boundingSphere.center) - .applyMatrix4(object.matrixWorld) - .applyMatrix4(_projScreenMatrix); - } - - if (Array.isArray(material)) { - const groups = geometry.groups; - - for (let i = 0, l = groups.length; i < l; i++) { - const group = groups[i]; - const groupMaterial = material[group.materialIndex]; - - if (groupMaterial && groupMaterial.visible) { - renderList.push(object, geometry, groupMaterial, groupOrder, _vector4.z, group); - } - } - } else if (material.visible) { - renderList.push(object, geometry, material, groupOrder, _vector4.z, null); - } - } - } - } - - if (object.isBundleGroup === true && this.backend.beginBundle !== undefined) { - const baseRenderList = renderList; - - // replace render list - renderList = this._renderLists.get(object, camera); - - renderList.begin(); - - baseRenderList.pushBundle({ - bundleGroup: object, - camera, - renderList, - }); - - renderList.finish(); - } - - const children = object.children; - - for (let i = 0, l = children.length; i < l; i++) { - this._projectObject(children[i], camera, groupOrder, renderList); - } - } - - _renderBundles(bundles, sceneRef, lightsNode) { - for (const bundle of bundles) { - this._renderBundle(bundle, sceneRef, lightsNode); - } - } - - _renderObjects(renderList, camera, scene, lightsNode) { - // process renderable objects - - for (let i = 0, il = renderList.length; i < il; i++) { - const renderItem = renderList[i]; - - // @TODO: Add support for multiple materials per object. This will require to extract - // the material from the renderItem object and pass it with its group data to renderObject(). - - const { object, geometry, material, group } = renderItem; - - if (camera.isArrayCamera) { - const cameras = camera.cameras; - - for (let j = 0, jl = cameras.length; j < jl; j++) { - const camera2 = cameras[j]; - - if (object.layers.test(camera2.layers)) { - const vp = camera2.viewport; - const minDepth = vp.minDepth === undefined ? 0 : vp.minDepth; - const maxDepth = vp.maxDepth === undefined ? 1 : vp.maxDepth; - - const viewportValue = this._currentRenderContext.viewportValue; - viewportValue.copy(vp).multiplyScalar(this._pixelRatio).floor(); - viewportValue.minDepth = minDepth; - viewportValue.maxDepth = maxDepth; - - this.backend.updateViewport(this._currentRenderContext); - - this._currentRenderObjectFunction( - object, - scene, - camera2, - geometry, - material, - group, - lightsNode, - ); - } - } - } else { - this._currentRenderObjectFunction(object, scene, camera, geometry, material, group, lightsNode); - } - } - } - - renderObject(object, scene, camera, geometry, material, group, lightsNode) { - let overridePositionNode; - let overrideFragmentNode; - let overrideDepthNode; - - // - - object.onBeforeRender(this, scene, camera, geometry, material, group); - - // - - if (scene.overrideMaterial !== null) { - const overrideMaterial = scene.overrideMaterial; - - if (material.positionNode && material.positionNode.isNode) { - overridePositionNode = overrideMaterial.positionNode; - overrideMaterial.positionNode = material.positionNode; - } - - if (overrideMaterial.isShadowNodeMaterial) { - overrideMaterial.side = material.shadowSide === null ? material.side : material.shadowSide; - - if (material.depthNode && material.depthNode.isNode) { - overrideDepthNode = overrideMaterial.depthNode; - overrideMaterial.depthNode = material.depthNode; - } - - if (material.shadowNode && material.shadowNode.isNode) { - overrideFragmentNode = overrideMaterial.fragmentNode; - overrideMaterial.fragmentNode = material.shadowNode; - } - - if (this.localClippingEnabled) { - if (material.clipShadows) { - if (overrideMaterial.clippingPlanes !== material.clippingPlanes) { - overrideMaterial.clippingPlanes = material.clippingPlanes; - overrideMaterial.needsUpdate = true; - } - - if (overrideMaterial.clipIntersection !== material.clipIntersection) { - overrideMaterial.clipIntersection = material.clipIntersection; - } - } else if (Array.isArray(overrideMaterial.clippingPlanes)) { - overrideMaterial.clippingPlanes = null; - overrideMaterial.needsUpdate = true; - } - } - } - - material = overrideMaterial; - } - - // - - if (material.transparent === true && material.side === DoubleSide && material.forceSinglePass === false) { - material.side = BackSide; - this._handleObjectFunction(object, material, scene, camera, lightsNode, group, 'backSide'); // create backSide pass id - - material.side = FrontSide; - this._handleObjectFunction(object, material, scene, camera, lightsNode, group); // use default pass id - - material.side = DoubleSide; - } else { - this._handleObjectFunction(object, material, scene, camera, lightsNode, group); - } - - // - - if (overridePositionNode !== undefined) { - scene.overrideMaterial.positionNode = overridePositionNode; - } - - if (overrideDepthNode !== undefined) { - scene.overrideMaterial.depthNode = overrideDepthNode; - } - - if (overrideFragmentNode !== undefined) { - scene.overrideMaterial.fragmentNode = overrideFragmentNode; - } - - // - - object.onAfterRender(this, scene, camera, geometry, material, group); - } - - _renderObjectDirect(object, material, scene, camera, lightsNode, group, passId) { - const renderObject = this._objects.get( - object, - material, - scene, - camera, - lightsNode, - this._currentRenderContext, - passId, - ); - renderObject.drawRange = object.geometry.drawRange; - renderObject.group = group; - - // - - const needsRefresh = this._nodes.needsRefresh(renderObject); - - if (needsRefresh) { - this._nodes.updateBefore(renderObject); - - this._geometries.updateForRender(renderObject); - - this._nodes.updateForRender(renderObject); - this._bindings.updateForRender(renderObject); - } - - this._pipelines.updateForRender(renderObject); - - // - - if (this._currentRenderBundle !== null) { - const renderBundleData = this.backend.get(this._currentRenderBundle); - - renderBundleData.renderObjects.push(renderObject); - - renderObject.bundle = this._currentRenderBundle.scene; - } - - this.backend.draw(renderObject, this.info); - - if (needsRefresh) this._nodes.updateAfter(renderObject); - } - - _createObjectPipeline(object, material, scene, camera, lightsNode, passId) { - const renderObject = this._objects.get( - object, - material, - scene, - camera, - lightsNode, - this._currentRenderContext, - passId, - ); - - // - - this._nodes.updateBefore(renderObject); - - this._geometries.updateForRender(renderObject); - - this._nodes.updateForRender(renderObject); - this._bindings.updateForRender(renderObject); - - this._pipelines.getForRender(renderObject, this._compilationPromises); - - this._nodes.updateAfter(renderObject); - } - - get compile() { - return this.compileAsync; - } -} - -export default Renderer; diff --git a/src-testing/src/renderers/common/SampledTexture.ts b/src-testing/src/renderers/common/SampledTexture.ts deleted file mode 100644 index 841e6a85b..000000000 --- a/src-testing/src/renderers/common/SampledTexture.ts +++ /dev/null @@ -1,68 +0,0 @@ -import Binding from './Binding.js'; - -let _id = 0; - -class SampledTexture extends Binding { - constructor(name, texture) { - super(name); - - this.id = _id++; - - this.texture = texture; - this.version = texture ? texture.version : 0; - this.store = false; - this.generation = null; - - this.isSampledTexture = true; - } - - needsBindingsUpdate(generation) { - const { texture } = this; - - if (generation !== this.generation) { - this.generation = generation; - - return true; - } - - return texture.isVideoTexture; - } - - update() { - const { texture, version } = this; - - if (version !== texture.version) { - this.version = texture.version; - - return true; - } - - return false; - } -} - -class SampledArrayTexture extends SampledTexture { - constructor(name, texture) { - super(name, texture); - - this.isSampledArrayTexture = true; - } -} - -class Sampled3DTexture extends SampledTexture { - constructor(name, texture) { - super(name, texture); - - this.isSampled3DTexture = true; - } -} - -class SampledCubeTexture extends SampledTexture { - constructor(name, texture) { - super(name, texture); - - this.isSampledCubeTexture = true; - } -} - -export { SampledTexture, SampledArrayTexture, Sampled3DTexture, SampledCubeTexture }; diff --git a/src-testing/src/renderers/common/Sampler.ts b/src-testing/src/renderers/common/Sampler.ts deleted file mode 100644 index 8cd20d04a..000000000 --- a/src-testing/src/renderers/common/Sampler.ts +++ /dev/null @@ -1,14 +0,0 @@ -import Binding from './Binding.js'; - -class Sampler extends Binding { - constructor(name, texture) { - super(name); - - this.texture = texture; - this.version = texture ? texture.version : 0; - - this.isSampler = true; - } -} - -export default Sampler; diff --git a/src-testing/src/renderers/common/StorageBuffer.ts b/src-testing/src/renderers/common/StorageBuffer.ts deleted file mode 100644 index ef5d3e464..000000000 --- a/src-testing/src/renderers/common/StorageBuffer.ts +++ /dev/null @@ -1,13 +0,0 @@ -import Buffer from './Buffer.js'; - -class StorageBuffer extends Buffer { - constructor(name, attribute) { - super(name, attribute ? attribute.array : null); - - this.attribute = attribute; - - this.isStorageBuffer = true; - } -} - -export default StorageBuffer; diff --git a/src-testing/src/renderers/common/StorageBufferAttribute.d.ts b/src-testing/src/renderers/common/StorageBufferAttribute.d.ts deleted file mode 100644 index 2a864f54a..000000000 --- a/src-testing/src/renderers/common/StorageBufferAttribute.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { BufferAttribute, TypedArray } from "../../core/BufferAttribute.js"; - -export default class StorageBufferAttribute extends BufferAttribute { - readonly isStorageBufferAttribute: true; - - constructor(array: TypedArray, itemSize: number); -} diff --git a/src-testing/src/renderers/common/StorageInstancedBufferAttribute.d.ts b/src-testing/src/renderers/common/StorageInstancedBufferAttribute.d.ts deleted file mode 100644 index 3f01891e8..000000000 --- a/src-testing/src/renderers/common/StorageInstancedBufferAttribute.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { TypedArray } from "../../core/BufferAttribute.js"; -import { InstancedBufferAttribute } from "../../core/InstancedBufferAttribute.js"; - -export default class StorageInstancedBufferAttribute extends InstancedBufferAttribute { - readonly isStorageInstancedBufferAttribute: true; - - constructor(array: TypedArray | number, itemSize: number); -} diff --git a/src-testing/src/renderers/common/StorageTexture.d.ts b/src-testing/src/renderers/common/StorageTexture.d.ts deleted file mode 100644 index 435ef9ba3..000000000 --- a/src-testing/src/renderers/common/StorageTexture.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { Texture } from "../../textures/Texture.js"; - -export default class StorageTexture extends Texture { - constructor(width?: number, height?: number); -} diff --git a/src-testing/src/renderers/common/Textures.ts b/src-testing/src/renderers/common/Textures.ts deleted file mode 100644 index 8d35f664f..000000000 --- a/src-testing/src/renderers/common/Textures.ts +++ /dev/null @@ -1,294 +0,0 @@ -import DataMap from './DataMap.js'; - -import { Vector3 } from '../../math/Vector3.js'; -import { DepthTexture } from '../../textures/DepthTexture.js'; -import { - DepthStencilFormat, - DepthFormat, - UnsignedIntType, - UnsignedInt248Type, - EquirectangularReflectionMapping, - EquirectangularRefractionMapping, - CubeReflectionMapping, - CubeRefractionMapping, - UnsignedByteType, -} from '../../constants.js'; - -const _size = /*@__PURE__*/ new Vector3(); - -class Textures extends DataMap { - constructor(renderer, backend, info) { - super(); - - this.renderer = renderer; - this.backend = backend; - this.info = info; - } - - updateRenderTarget(renderTarget, activeMipmapLevel = 0) { - const renderTargetData = this.get(renderTarget); - - const sampleCount = renderTarget.samples === 0 ? 1 : renderTarget.samples; - const depthTextureMips = renderTargetData.depthTextureMips || (renderTargetData.depthTextureMips = {}); - - const textures = renderTarget.textures; - - const size = this.getSize(textures[0]); - - const mipWidth = size.width >> activeMipmapLevel; - const mipHeight = size.height >> activeMipmapLevel; - - let depthTexture = renderTarget.depthTexture || depthTextureMips[activeMipmapLevel]; - const useDepthTexture = renderTarget.depthBuffer === true || renderTarget.stencilBuffer === true; - - let textureNeedsUpdate = false; - - if (depthTexture === undefined && useDepthTexture) { - depthTexture = new DepthTexture(); - depthTexture.format = renderTarget.stencilBuffer ? DepthStencilFormat : DepthFormat; - depthTexture.type = renderTarget.stencilBuffer ? UnsignedInt248Type : UnsignedIntType; // FloatType - depthTexture.image.width = mipWidth; - depthTexture.image.height = mipHeight; - - depthTextureMips[activeMipmapLevel] = depthTexture; - } - - if (renderTargetData.width !== size.width || size.height !== renderTargetData.height) { - textureNeedsUpdate = true; - - if (depthTexture) { - depthTexture.needsUpdate = true; - depthTexture.image.width = mipWidth; - depthTexture.image.height = mipHeight; - } - } - - renderTargetData.width = size.width; - renderTargetData.height = size.height; - renderTargetData.textures = textures; - renderTargetData.depthTexture = depthTexture || null; - renderTargetData.depth = renderTarget.depthBuffer; - renderTargetData.stencil = renderTarget.stencilBuffer; - renderTargetData.renderTarget = renderTarget; - - if (renderTargetData.sampleCount !== sampleCount) { - textureNeedsUpdate = true; - - if (depthTexture) { - depthTexture.needsUpdate = true; - } - - renderTargetData.sampleCount = sampleCount; - } - - // - - const options = { sampleCount }; - - for (let i = 0; i < textures.length; i++) { - const texture = textures[i]; - - if (textureNeedsUpdate) texture.needsUpdate = true; - - this.updateTexture(texture, options); - } - - if (depthTexture) { - this.updateTexture(depthTexture, options); - } - - // dispose handler - - if (renderTargetData.initialized !== true) { - renderTargetData.initialized = true; - - // dispose - - const onDispose = () => { - renderTarget.removeEventListener('dispose', onDispose); - - for (let i = 0; i < textures.length; i++) { - this._destroyTexture(textures[i]); - } - - if (depthTexture) { - this._destroyTexture(depthTexture); - } - - this.delete(renderTarget); - }; - - renderTarget.addEventListener('dispose', onDispose); - } - } - - updateTexture(texture, options = {}) { - const textureData = this.get(texture); - if (textureData.initialized === true && textureData.version === texture.version) return; - - const isRenderTarget = texture.isRenderTargetTexture || texture.isDepthTexture || texture.isFramebufferTexture; - const backend = this.backend; - - if (isRenderTarget && textureData.initialized === true) { - // it's an update - - backend.destroySampler(texture); - backend.destroyTexture(texture); - } - - // - - if (texture.isFramebufferTexture) { - const renderer = this.renderer; - const renderTarget = renderer.getRenderTarget(); - - if (renderTarget) { - texture.type = renderTarget.texture.type; - } else { - texture.type = UnsignedByteType; - } - } - - // - - const { width, height, depth } = this.getSize(texture); - - options.width = width; - options.height = height; - options.depth = depth; - options.needsMipmaps = this.needsMipmaps(texture); - options.levels = options.needsMipmaps ? this.getMipLevels(texture, width, height) : 1; - - // - - if (isRenderTarget || texture.isStorageTexture === true) { - backend.createSampler(texture); - backend.createTexture(texture, options); - - textureData.generation = texture.version; - } else { - const needsCreate = textureData.initialized !== true; - - if (needsCreate) backend.createSampler(texture); - - if (texture.version > 0) { - const image = texture.image; - - if (image === undefined) { - console.warn('THREE.Renderer: Texture marked for update but image is undefined.'); - } else if (image.complete === false) { - console.warn('THREE.Renderer: Texture marked for update but image is incomplete.'); - } else { - if (texture.images) { - const images = []; - - for (const image of texture.images) { - images.push(image); - } - - options.images = images; - } else { - options.image = image; - } - - if (textureData.isDefaultTexture === undefined || textureData.isDefaultTexture === true) { - backend.createTexture(texture, options); - - textureData.isDefaultTexture = false; - textureData.generation = texture.version; - } - - if (texture.source.dataReady === true) backend.updateTexture(texture, options); - - if (options.needsMipmaps && texture.mipmaps.length === 0) backend.generateMipmaps(texture); - } - } else { - // async update - - backend.createDefaultTexture(texture); - - textureData.isDefaultTexture = true; - textureData.generation = texture.version; - } - } - - // dispose handler - - if (textureData.initialized !== true) { - textureData.initialized = true; - textureData.generation = texture.version; - - // - - this.info.memory.textures++; - - // dispose - - const onDispose = () => { - texture.removeEventListener('dispose', onDispose); - - this._destroyTexture(texture); - - this.info.memory.textures--; - }; - - texture.addEventListener('dispose', onDispose); - } - - // - - textureData.version = texture.version; - } - - getSize(texture, target = _size) { - let image = texture.images ? texture.images[0] : texture.image; - - if (image) { - if (image.image !== undefined) image = image.image; - - target.width = image.width; - target.height = image.height; - target.depth = texture.isCubeTexture ? 6 : image.depth || 1; - } else { - target.width = target.height = target.depth = 1; - } - - return target; - } - - getMipLevels(texture, width, height) { - let mipLevelCount; - - if (texture.isCompressedTexture) { - mipLevelCount = texture.mipmaps.length; - } else { - mipLevelCount = Math.floor(Math.log2(Math.max(width, height))) + 1; - } - - return mipLevelCount; - } - - needsMipmaps(texture) { - return this.isEnvironmentTexture(texture) || texture.isCompressedTexture === true || texture.generateMipmaps; - } - - isEnvironmentTexture(texture) { - const mapping = texture.mapping; - - return ( - mapping === EquirectangularReflectionMapping || - mapping === EquirectangularRefractionMapping || - mapping === CubeReflectionMapping || - mapping === CubeRefractionMapping - ); - } - - _destroyTexture(texture) { - this.backend.destroySampler(texture); - this.backend.destroyTexture(texture); - - this.delete(texture); - } -} - -export default Textures; diff --git a/src-testing/src/renderers/common/Uniform.ts b/src-testing/src/renderers/common/Uniform.ts deleted file mode 100644 index 80c131494..000000000 --- a/src-testing/src/renderers/common/Uniform.ts +++ /dev/null @@ -1,105 +0,0 @@ -import { Color } from '../../math/Color.js'; -import { Matrix3 } from '../../math/Matrix3.js'; -import { Matrix4 } from '../../math/Matrix4.js'; -import { Vector2 } from '../../math/Vector2.js'; -import { Vector3 } from '../../math/Vector3.js'; -import { Vector4 } from '../../math/Vector4.js'; - -class Uniform { - constructor(name, value) { - this.name = name; - this.value = value; - - this.boundary = 0; // used to build the uniform buffer according to the STD140 layout - this.itemSize = 0; - - this.offset = 0; // this property is set by WebGPUUniformsGroup and marks the start position in the uniform buffer - } - - setValue(value) { - this.value = value; - } - - getValue() { - return this.value; - } -} - -class NumberUniform extends Uniform { - constructor(name, value = 0) { - super(name, value); - - this.isNumberUniform = true; - - this.boundary = 4; - this.itemSize = 1; - } -} - -class Vector2Uniform extends Uniform { - constructor(name, value = new Vector2()) { - super(name, value); - - this.isVector2Uniform = true; - - this.boundary = 8; - this.itemSize = 2; - } -} - -class Vector3Uniform extends Uniform { - constructor(name, value = new Vector3()) { - super(name, value); - - this.isVector3Uniform = true; - - this.boundary = 16; - this.itemSize = 3; - } -} - -class Vector4Uniform extends Uniform { - constructor(name, value = new Vector4()) { - super(name, value); - - this.isVector4Uniform = true; - - this.boundary = 16; - this.itemSize = 4; - } -} - -class ColorUniform extends Uniform { - constructor(name, value = new Color()) { - super(name, value); - - this.isColorUniform = true; - - this.boundary = 16; - this.itemSize = 3; - } -} - -class Matrix3Uniform extends Uniform { - constructor(name, value = new Matrix3()) { - super(name, value); - - this.isMatrix3Uniform = true; - - this.boundary = 48; - this.itemSize = 12; - } -} - -class Matrix4Uniform extends Uniform { - constructor(name, value = new Matrix4()) { - super(name, value); - - this.isMatrix4Uniform = true; - - this.boundary = 64; - this.itemSize = 16; - } -} - -export { NumberUniform, Vector2Uniform, Vector3Uniform, Vector4Uniform, ColorUniform, Matrix3Uniform, Matrix4Uniform }; diff --git a/src-testing/src/renderers/common/UniformBuffer.ts b/src-testing/src/renderers/common/UniformBuffer.ts deleted file mode 100644 index 28aac0d7e..000000000 --- a/src-testing/src/renderers/common/UniformBuffer.ts +++ /dev/null @@ -1,11 +0,0 @@ -import Buffer from './Buffer.js'; - -class UniformBuffer extends Buffer { - constructor(name, buffer = null) { - super(name, buffer); - - this.isUniformBuffer = true; - } -} - -export default UniformBuffer; diff --git a/src-testing/src/renderers/common/UniformsGroup.ts b/src-testing/src/renderers/common/UniformsGroup.ts deleted file mode 100644 index e2b62671a..000000000 --- a/src-testing/src/renderers/common/UniformsGroup.ts +++ /dev/null @@ -1,277 +0,0 @@ -import UniformBuffer from './UniformBuffer.js'; -import { GPU_CHUNK_BYTES } from './Constants.js'; - -class UniformsGroup extends UniformBuffer { - constructor(name) { - super(name); - - this.isUniformsGroup = true; - - this._values = null; - - // the order of uniforms in this array must match the order of uniforms in the shader - - this.uniforms = []; - } - - addUniform(uniform) { - this.uniforms.push(uniform); - - return this; - } - - removeUniform(uniform) { - const index = this.uniforms.indexOf(uniform); - - if (index !== -1) { - this.uniforms.splice(index, 1); - } - - return this; - } - - get values() { - if (this._values === null) { - this._values = Array.from(this.buffer); - } - - return this._values; - } - - get buffer() { - let buffer = this._buffer; - - if (buffer === null) { - const byteLength = this.byteLength; - - buffer = new Float32Array(new ArrayBuffer(byteLength)); - - this._buffer = buffer; - } - - return buffer; - } - - get byteLength() { - let offset = 0; // global buffer offset in bytes - - for (let i = 0, l = this.uniforms.length; i < l; i++) { - const uniform = this.uniforms[i]; - - const { boundary, itemSize } = uniform; - - // offset within a single chunk in bytes - - const chunkOffset = offset % GPU_CHUNK_BYTES; - const remainingSizeInChunk = GPU_CHUNK_BYTES - chunkOffset; - - // conformance tests - - if (chunkOffset !== 0 && remainingSizeInChunk - boundary < 0) { - // check for chunk overflow - - offset += GPU_CHUNK_BYTES - chunkOffset; - } else if (chunkOffset % boundary !== 0) { - // check for correct alignment - - offset += chunkOffset % boundary; - } - - uniform.offset = offset / this.bytesPerElement; - - offset += itemSize * this.bytesPerElement; - } - - return Math.ceil(offset / GPU_CHUNK_BYTES) * GPU_CHUNK_BYTES; - } - - update() { - let updated = false; - - for (const uniform of this.uniforms) { - if (this.updateByType(uniform) === true) { - updated = true; - } - } - - return updated; - } - - updateByType(uniform) { - if (uniform.isNumberUniform) return this.updateNumber(uniform); - if (uniform.isVector2Uniform) return this.updateVector2(uniform); - if (uniform.isVector3Uniform) return this.updateVector3(uniform); - if (uniform.isVector4Uniform) return this.updateVector4(uniform); - if (uniform.isColorUniform) return this.updateColor(uniform); - if (uniform.isMatrix3Uniform) return this.updateMatrix3(uniform); - if (uniform.isMatrix4Uniform) return this.updateMatrix4(uniform); - - console.error('THREE.WebGPUUniformsGroup: Unsupported uniform type.', uniform); - } - - updateNumber(uniform) { - let updated = false; - - const a = this.values; - const v = uniform.getValue(); - const offset = uniform.offset; - - if (a[offset] !== v) { - const b = this.buffer; - - b[offset] = a[offset] = v; - updated = true; - } - - return updated; - } - - updateVector2(uniform) { - let updated = false; - - const a = this.values; - const v = uniform.getValue(); - const offset = uniform.offset; - - if (a[offset + 0] !== v.x || a[offset + 1] !== v.y) { - const b = this.buffer; - - b[offset + 0] = a[offset + 0] = v.x; - b[offset + 1] = a[offset + 1] = v.y; - - updated = true; - } - - return updated; - } - - updateVector3(uniform) { - let updated = false; - - const a = this.values; - const v = uniform.getValue(); - const offset = uniform.offset; - - if (a[offset + 0] !== v.x || a[offset + 1] !== v.y || a[offset + 2] !== v.z) { - const b = this.buffer; - - b[offset + 0] = a[offset + 0] = v.x; - b[offset + 1] = a[offset + 1] = v.y; - b[offset + 2] = a[offset + 2] = v.z; - - updated = true; - } - - return updated; - } - - updateVector4(uniform) { - let updated = false; - - const a = this.values; - const v = uniform.getValue(); - const offset = uniform.offset; - - if (a[offset + 0] !== v.x || a[offset + 1] !== v.y || a[offset + 2] !== v.z || a[offset + 4] !== v.w) { - const b = this.buffer; - - b[offset + 0] = a[offset + 0] = v.x; - b[offset + 1] = a[offset + 1] = v.y; - b[offset + 2] = a[offset + 2] = v.z; - b[offset + 3] = a[offset + 3] = v.w; - - updated = true; - } - - return updated; - } - - updateColor(uniform) { - let updated = false; - - const a = this.values; - const c = uniform.getValue(); - const offset = uniform.offset; - - if (a[offset + 0] !== c.r || a[offset + 1] !== c.g || a[offset + 2] !== c.b) { - const b = this.buffer; - - b[offset + 0] = a[offset + 0] = c.r; - b[offset + 1] = a[offset + 1] = c.g; - b[offset + 2] = a[offset + 2] = c.b; - - updated = true; - } - - return updated; - } - - updateMatrix3(uniform) { - let updated = false; - - const a = this.values; - const e = uniform.getValue().elements; - const offset = uniform.offset; - - if ( - a[offset + 0] !== e[0] || - a[offset + 1] !== e[1] || - a[offset + 2] !== e[2] || - a[offset + 4] !== e[3] || - a[offset + 5] !== e[4] || - a[offset + 6] !== e[5] || - a[offset + 8] !== e[6] || - a[offset + 9] !== e[7] || - a[offset + 10] !== e[8] - ) { - const b = this.buffer; - - b[offset + 0] = a[offset + 0] = e[0]; - b[offset + 1] = a[offset + 1] = e[1]; - b[offset + 2] = a[offset + 2] = e[2]; - b[offset + 4] = a[offset + 4] = e[3]; - b[offset + 5] = a[offset + 5] = e[4]; - b[offset + 6] = a[offset + 6] = e[5]; - b[offset + 8] = a[offset + 8] = e[6]; - b[offset + 9] = a[offset + 9] = e[7]; - b[offset + 10] = a[offset + 10] = e[8]; - - updated = true; - } - - return updated; - } - - updateMatrix4(uniform) { - let updated = false; - - const a = this.values; - const e = uniform.getValue().elements; - const offset = uniform.offset; - - if (arraysEqual(a, e, offset) === false) { - const b = this.buffer; - b.set(e, offset); - setArray(a, e, offset); - updated = true; - } - - return updated; - } -} - -function setArray(a, b, offset) { - for (let i = 0, l = b.length; i < l; i++) { - a[offset + i] = b[i]; - } -} - -function arraysEqual(a, b, offset) { - for (let i = 0, l = b.length; i < l; i++) { - if (a[offset + i] !== b[i]) return false; - } - - return true; -} - -export default UniformsGroup; diff --git a/src-testing/src/renderers/common/extras/PMREMGenerator.ts b/src-testing/src/renderers/common/extras/PMREMGenerator.ts deleted file mode 100644 index b317f950c..000000000 --- a/src-testing/src/renderers/common/extras/PMREMGenerator.ts +++ /dev/null @@ -1,657 +0,0 @@ -import NodeMaterial from '../../../materials/nodes/NodeMaterial.js'; -import { getDirection, blur } from '../../../nodes/pmrem/PMREMUtils.js'; -import { equirectUV } from '../../../nodes/utils/EquirectUVNode.js'; -import { uniform } from '../../../nodes/core/UniformNode.js'; -import { uniformArray } from '../../../nodes/accessors/UniformArrayNode.js'; -import { texture } from '../../../nodes/accessors/TextureNode.js'; -import { cubeTexture } from '../../../nodes/accessors/CubeTextureNode.js'; -import { float, vec3 } from '../../../nodes/tsl/TSLBase.js'; -import { uv } from '../../../nodes/accessors/UV.js'; -import { attribute } from '../../../nodes/core/AttributeNode.js'; - -import { OrthographicCamera } from '../../../cameras/OrthographicCamera.js'; -import { Color } from '../../../math/Color.js'; -import { Vector3 } from '../../../math/Vector3.js'; -import { BufferGeometry } from '../../../core/BufferGeometry.js'; -import { BufferAttribute } from '../../../core/BufferAttribute.js'; -import { RenderTarget } from '../../../core/RenderTarget.js'; -import { Mesh } from '../../../objects/Mesh.js'; -import { PerspectiveCamera } from '../../../cameras/PerspectiveCamera.js'; -import { MeshBasicMaterial } from '../../../materials/MeshBasicMaterial.js'; -import { BoxGeometry } from '../../../geometries/BoxGeometry.js'; -import { - CubeReflectionMapping, - CubeRefractionMapping, - CubeUVReflectionMapping, - LinearFilter, - NoBlending, - RGBAFormat, - HalfFloatType, - BackSide, - LinearSRGBColorSpace, -} from '../../../constants.js'; - -const LOD_MIN = 4; - -// The standard deviations (radians) associated with the extra mips. These are -// chosen to approximate a Trowbridge-Reitz distribution function times the -// geometric shadowing function. These sigma values squared must match the -// variance #defines in cube_uv_reflection_fragment.glsl.js. -const EXTRA_LOD_SIGMA = [0.125, 0.215, 0.35, 0.446, 0.526, 0.582]; - -// The maximum length of the blur for loop. Smaller sigmas will use fewer -// samples and exit early, but not recompile the shader. -const MAX_SAMPLES = 20; - -const _flatCamera = /*@__PURE__*/ new OrthographicCamera(-1, 1, 1, -1, 0, 1); -const _cubeCamera = /*@__PURE__*/ new PerspectiveCamera(90, 1); -const _clearColor = /*@__PURE__*/ new Color(); -let _oldTarget = null; -let _oldActiveCubeFace = 0; -let _oldActiveMipmapLevel = 0; - -// Golden Ratio -const PHI = (1 + Math.sqrt(5)) / 2; -const INV_PHI = 1 / PHI; - -// Vertices of a dodecahedron (except the opposites, which represent the -// same axis), used as axis directions evenly spread on a sphere. -const _axisDirections = [ - /*@__PURE__*/ new Vector3(-PHI, INV_PHI, 0), - /*@__PURE__*/ new Vector3(PHI, INV_PHI, 0), - /*@__PURE__*/ new Vector3(-INV_PHI, 0, PHI), - /*@__PURE__*/ new Vector3(INV_PHI, 0, PHI), - /*@__PURE__*/ new Vector3(0, PHI, -INV_PHI), - /*@__PURE__*/ new Vector3(0, PHI, INV_PHI), - /*@__PURE__*/ new Vector3(-1, 1, -1), - /*@__PURE__*/ new Vector3(1, 1, -1), - /*@__PURE__*/ new Vector3(-1, 1, 1), - /*@__PURE__*/ new Vector3(1, 1, 1), -]; - -// - -// WebGPU Face indices -const _faceLib = [3, 1, 5, 0, 4, 2]; - -const direction = getDirection(uv(), attribute('faceIndex')).normalize(); -const outputDirection = vec3(direction.x, direction.y.negate(), direction.z); - -/** - * This class generates a Prefiltered, Mipmapped Radiance Environment Map - * (PMREM) from a cubeMap environment texture. This allows different levels of - * blur to be quickly accessed based on material roughness. It is packed into a - * special CubeUV format that allows us to perform custom interpolation so that - * we can support nonlinear formats such as RGBE. Unlike a traditional mipmap - * chain, it only goes down to the LOD_MIN level (above), and then creates extra - * even more filtered 'mips' at the same LOD_MIN resolution, associated with - * higher roughness levels. In this way we maintain resolution to smoothly - * interpolate diffuse lighting while limiting sampling computation. - * - * Paper: Fast, Accurate Image-Based Lighting - * https://drive.google.com/file/d/15y8r_UpKlU9SvV4ILb0C3qCPecS8pvLz/view - */ - -class PMREMGenerator { - constructor(renderer) { - this._renderer = renderer; - this._pingPongRenderTarget = null; - - this._lodMax = 0; - this._cubeSize = 0; - this._lodPlanes = []; - this._sizeLods = []; - this._sigmas = []; - this._lodMeshes = []; - - this._blurMaterial = null; - this._cubemapMaterial = null; - this._equirectMaterial = null; - this._backgroundBox = null; - } - - /** - * Generates a PMREM from a supplied Scene, which can be faster than using an - * image if networking bandwidth is low. Optional sigma specifies a blur radius - * in radians to be applied to the scene before PMREM generation. Optional near - * and far planes ensure the scene is rendered in its entirety (the cubeCamera - * is placed at the origin). - */ - fromScene(scene, sigma = 0, near = 0.1, far = 100) { - _oldTarget = this._renderer.getRenderTarget(); - _oldActiveCubeFace = this._renderer.getActiveCubeFace(); - _oldActiveMipmapLevel = this._renderer.getActiveMipmapLevel(); - - this._setSize(256); - - const cubeUVRenderTarget = this._allocateTargets(); - cubeUVRenderTarget.depthBuffer = true; - - this._sceneToCubeUV(scene, near, far, cubeUVRenderTarget); - - if (sigma > 0) { - this._blur(cubeUVRenderTarget, 0, 0, sigma); - } - - this._applyPMREM(cubeUVRenderTarget); - - this._cleanup(cubeUVRenderTarget); - - return cubeUVRenderTarget; - } - - /** - * Generates a PMREM from an equirectangular texture, which can be either LDR - * or HDR. The ideal input image size is 1k (1024 x 512), - * as this matches best with the 256 x 256 cubemap output. - */ - fromEquirectangular(equirectangular, renderTarget = null) { - return this._fromTexture(equirectangular, renderTarget); - } - - /** - * Generates a PMREM from an cubemap texture, which can be either LDR - * or HDR. The ideal input cube size is 256 x 256, - * as this matches best with the 256 x 256 cubemap output. - */ - fromCubemap(cubemap, renderTarget = null) { - return this._fromTexture(cubemap, renderTarget); - } - - /** - * Pre-compiles the cubemap shader. You can get faster start-up by invoking this method during - * your texture's network fetch for increased concurrency. - */ - async compileCubemapShader() { - if (this._cubemapMaterial === null) { - this._cubemapMaterial = _getCubemapMaterial(); - await this._compileMaterial(this._cubemapMaterial); - } - } - - /** - * Pre-compiles the equirectangular shader. You can get faster start-up by invoking this method during - * your texture's network fetch for increased concurrency. - */ - async compileEquirectangularShader() { - if (this._equirectMaterial === null) { - this._equirectMaterial = _getEquirectMaterial(); - await this._compileMaterial(this._equirectMaterial); - } - } - - /** - * Disposes of the PMREMGenerator's internal memory. Note that PMREMGenerator is a static class, - * so you should not need more than one PMREMGenerator object. If you do, calling dispose() on - * one of them will cause any others to also become unusable. - */ - dispose() { - this._dispose(); - - if (this._cubemapMaterial !== null) this._cubemapMaterial.dispose(); - if (this._equirectMaterial !== null) this._equirectMaterial.dispose(); - if (this._backgroundBox !== null) { - this._backgroundBox.geometry.dispose(); - this._backgroundBox.material.dispose(); - } - } - - // private interface - - _setSize(cubeSize) { - this._lodMax = Math.floor(Math.log2(cubeSize)); - this._cubeSize = Math.pow(2, this._lodMax); - } - - _dispose() { - if (this._blurMaterial !== null) this._blurMaterial.dispose(); - - if (this._pingPongRenderTarget !== null) this._pingPongRenderTarget.dispose(); - - for (let i = 0; i < this._lodPlanes.length; i++) { - this._lodPlanes[i].dispose(); - } - } - - _cleanup(outputTarget) { - this._renderer.setRenderTarget(_oldTarget, _oldActiveCubeFace, _oldActiveMipmapLevel); - outputTarget.scissorTest = false; - _setViewport(outputTarget, 0, 0, outputTarget.width, outputTarget.height); - } - - _fromTexture(texture, renderTarget) { - if (texture.mapping === CubeReflectionMapping || texture.mapping === CubeRefractionMapping) { - this._setSize(texture.image.length === 0 ? 16 : texture.image[0].width || texture.image[0].image.width); - } else { - // Equirectangular - - this._setSize(texture.image.width / 4); - } - - _oldTarget = this._renderer.getRenderTarget(); - _oldActiveCubeFace = this._renderer.getActiveCubeFace(); - _oldActiveMipmapLevel = this._renderer.getActiveMipmapLevel(); - - const cubeUVRenderTarget = renderTarget || this._allocateTargets(); - this._textureToCubeUV(texture, cubeUVRenderTarget); - this._applyPMREM(cubeUVRenderTarget); - this._cleanup(cubeUVRenderTarget); - - return cubeUVRenderTarget; - } - - _allocateTargets() { - const width = 3 * Math.max(this._cubeSize, 16 * 7); - const height = 4 * this._cubeSize; - - const params = { - magFilter: LinearFilter, - minFilter: LinearFilter, - generateMipmaps: false, - type: HalfFloatType, - format: RGBAFormat, - colorSpace: LinearSRGBColorSpace, - //depthBuffer: false - }; - - const cubeUVRenderTarget = _createRenderTarget(width, height, params); - - if ( - this._pingPongRenderTarget === null || - this._pingPongRenderTarget.width !== width || - this._pingPongRenderTarget.height !== height - ) { - if (this._pingPongRenderTarget !== null) { - this._dispose(); - } - - this._pingPongRenderTarget = _createRenderTarget(width, height, params); - - const { _lodMax } = this; - ({ - sizeLods: this._sizeLods, - lodPlanes: this._lodPlanes, - sigmas: this._sigmas, - lodMeshes: this._lodMeshes, - } = _createPlanes(_lodMax)); - - this._blurMaterial = _getBlurShader(_lodMax, width, height); - } - - return cubeUVRenderTarget; - } - - async _compileMaterial(material) { - const tmpMesh = new Mesh(this._lodPlanes[0], material); - await this._renderer.compile(tmpMesh, _flatCamera); - } - - _sceneToCubeUV(scene, near, far, cubeUVRenderTarget) { - const cubeCamera = _cubeCamera; - cubeCamera.near = near; - cubeCamera.far = far; - - // px, py, pz, nx, ny, nz - const upSign = [-1, 1, -1, -1, -1, -1]; - const forwardSign = [1, 1, 1, -1, -1, -1]; - - const renderer = this._renderer; - - const originalAutoClear = renderer.autoClear; - - renderer.getClearColor(_clearColor); - - renderer.autoClear = false; - - let backgroundBox = this._backgroundBox; - - if (backgroundBox === null) { - const backgroundMaterial = new MeshBasicMaterial({ - name: 'PMREM.Background', - side: BackSide, - depthWrite: false, - depthTest: false, - }); - - backgroundBox = new Mesh(new BoxGeometry(), backgroundMaterial); - } - - let useSolidColor = false; - const background = scene.background; - - if (background) { - if (background.isColor) { - backgroundBox.material.color.copy(background); - scene.background = null; - useSolidColor = true; - } - } else { - backgroundBox.material.color.copy(_clearColor); - useSolidColor = true; - } - - renderer.setRenderTarget(cubeUVRenderTarget); - - renderer.clear(); - - if (useSolidColor) { - renderer.render(backgroundBox, cubeCamera); - } - - for (let i = 0; i < 6; i++) { - const col = i % 3; - - if (col === 0) { - cubeCamera.up.set(0, upSign[i], 0); - cubeCamera.lookAt(forwardSign[i], 0, 0); - } else if (col === 1) { - cubeCamera.up.set(0, 0, upSign[i]); - cubeCamera.lookAt(0, forwardSign[i], 0); - } else { - cubeCamera.up.set(0, upSign[i], 0); - cubeCamera.lookAt(0, 0, forwardSign[i]); - } - - const size = this._cubeSize; - - _setViewport(cubeUVRenderTarget, col * size, i > 2 ? size : 0, size, size); - - renderer.render(scene, cubeCamera); - } - - renderer.autoClear = originalAutoClear; - scene.background = background; - } - - _textureToCubeUV(texture, cubeUVRenderTarget) { - const renderer = this._renderer; - - const isCubeTexture = texture.mapping === CubeReflectionMapping || texture.mapping === CubeRefractionMapping; - - if (isCubeTexture) { - if (this._cubemapMaterial === null) { - this._cubemapMaterial = _getCubemapMaterial(texture); - } - } else { - if (this._equirectMaterial === null) { - this._equirectMaterial = _getEquirectMaterial(texture); - } - } - - const material = isCubeTexture ? this._cubemapMaterial : this._equirectMaterial; - material.fragmentNode.value = texture; - - const mesh = this._lodMeshes[0]; - mesh.material = material; - - const size = this._cubeSize; - - _setViewport(cubeUVRenderTarget, 0, 0, 3 * size, 2 * size); - - renderer.setRenderTarget(cubeUVRenderTarget); - renderer.render(mesh, _flatCamera); - } - - _applyPMREM(cubeUVRenderTarget) { - const renderer = this._renderer; - const autoClear = renderer.autoClear; - renderer.autoClear = false; - const n = this._lodPlanes.length; - - for (let i = 1; i < n; i++) { - const sigma = Math.sqrt(this._sigmas[i] * this._sigmas[i] - this._sigmas[i - 1] * this._sigmas[i - 1]); - - const poleAxis = _axisDirections[(n - i - 1) % _axisDirections.length]; - - this._blur(cubeUVRenderTarget, i - 1, i, sigma, poleAxis); - } - - renderer.autoClear = autoClear; - } - - /** - * This is a two-pass Gaussian blur for a cubemap. Normally this is done - * vertically and horizontally, but this breaks down on a cube. Here we apply - * the blur latitudinally (around the poles), and then longitudinally (towards - * the poles) to approximate the orthogonally-separable blur. It is least - * accurate at the poles, but still does a decent job. - */ - _blur(cubeUVRenderTarget, lodIn, lodOut, sigma, poleAxis) { - const pingPongRenderTarget = this._pingPongRenderTarget; - - this._halfBlur(cubeUVRenderTarget, pingPongRenderTarget, lodIn, lodOut, sigma, 'latitudinal', poleAxis); - - this._halfBlur(pingPongRenderTarget, cubeUVRenderTarget, lodOut, lodOut, sigma, 'longitudinal', poleAxis); - } - - _halfBlur(targetIn, targetOut, lodIn, lodOut, sigmaRadians, direction, poleAxis) { - const renderer = this._renderer; - const blurMaterial = this._blurMaterial; - - if (direction !== 'latitudinal' && direction !== 'longitudinal') { - console.error('blur direction must be either latitudinal or longitudinal!'); - } - - // Number of standard deviations at which to cut off the discrete approximation. - const STANDARD_DEVIATIONS = 3; - - const blurMesh = this._lodMeshes[lodOut]; - blurMesh.material = blurMaterial; - - const blurUniforms = blurMaterial.uniforms; - - const pixels = this._sizeLods[lodIn] - 1; - const radiansPerPixel = isFinite(sigmaRadians) ? Math.PI / (2 * pixels) : (2 * Math.PI) / (2 * MAX_SAMPLES - 1); - const sigmaPixels = sigmaRadians / radiansPerPixel; - const samples = isFinite(sigmaRadians) ? 1 + Math.floor(STANDARD_DEVIATIONS * sigmaPixels) : MAX_SAMPLES; - - if (samples > MAX_SAMPLES) { - console.warn( - `sigmaRadians, ${sigmaRadians}, is too large and will clip, as it requested ${ - samples - } samples when the maximum is set to ${MAX_SAMPLES}`, - ); - } - - const weights = []; - let sum = 0; - - for (let i = 0; i < MAX_SAMPLES; ++i) { - const x = i / sigmaPixels; - const weight = Math.exp((-x * x) / 2); - weights.push(weight); - - if (i === 0) { - sum += weight; - } else if (i < samples) { - sum += 2 * weight; - } - } - - for (let i = 0; i < weights.length; i++) { - weights[i] = weights[i] / sum; - } - - targetIn.texture.frame = (targetIn.texture.frame || 0) + 1; - - blurUniforms.envMap.value = targetIn.texture; - blurUniforms.samples.value = samples; - blurUniforms.weights.array = weights; - blurUniforms.latitudinal.value = direction === 'latitudinal' ? 1 : 0; - - if (poleAxis) { - blurUniforms.poleAxis.value = poleAxis; - } - - const { _lodMax } = this; - blurUniforms.dTheta.value = radiansPerPixel; - blurUniforms.mipInt.value = _lodMax - lodIn; - - const outputSize = this._sizeLods[lodOut]; - const x = 3 * outputSize * (lodOut > _lodMax - LOD_MIN ? lodOut - _lodMax + LOD_MIN : 0); - const y = 4 * (this._cubeSize - outputSize); - - _setViewport(targetOut, x, y, 3 * outputSize, 2 * outputSize); - renderer.setRenderTarget(targetOut); - renderer.render(blurMesh, _flatCamera); - } -} - -function _createPlanes(lodMax) { - const lodPlanes = []; - const sizeLods = []; - const sigmas = []; - const lodMeshes = []; - - let lod = lodMax; - - const totalLods = lodMax - LOD_MIN + 1 + EXTRA_LOD_SIGMA.length; - - for (let i = 0; i < totalLods; i++) { - const sizeLod = Math.pow(2, lod); - sizeLods.push(sizeLod); - let sigma = 1.0 / sizeLod; - - if (i > lodMax - LOD_MIN) { - sigma = EXTRA_LOD_SIGMA[i - lodMax + LOD_MIN - 1]; - } else if (i === 0) { - sigma = 0; - } - - sigmas.push(sigma); - - const texelSize = 1.0 / (sizeLod - 2); - const min = -texelSize; - const max = 1 + texelSize; - const uv1 = [min, min, max, min, max, max, min, min, max, max, min, max]; - - const cubeFaces = 6; - const vertices = 6; - const positionSize = 3; - const uvSize = 2; - const faceIndexSize = 1; - - const position = new Float32Array(positionSize * vertices * cubeFaces); - const uv = new Float32Array(uvSize * vertices * cubeFaces); - const faceIndex = new Float32Array(faceIndexSize * vertices * cubeFaces); - - for (let face = 0; face < cubeFaces; face++) { - const x = ((face % 3) * 2) / 3 - 1; - const y = face > 2 ? 0 : -1; - const coordinates = [ - x, - y, - 0, - x + 2 / 3, - y, - 0, - x + 2 / 3, - y + 1, - 0, - x, - y, - 0, - x + 2 / 3, - y + 1, - 0, - x, - y + 1, - 0, - ]; - - const faceIdx = _faceLib[face]; - position.set(coordinates, positionSize * vertices * faceIdx); - uv.set(uv1, uvSize * vertices * faceIdx); - const fill = [faceIdx, faceIdx, faceIdx, faceIdx, faceIdx, faceIdx]; - faceIndex.set(fill, faceIndexSize * vertices * faceIdx); - } - - const planes = new BufferGeometry(); - planes.setAttribute('position', new BufferAttribute(position, positionSize)); - planes.setAttribute('uv', new BufferAttribute(uv, uvSize)); - planes.setAttribute('faceIndex', new BufferAttribute(faceIndex, faceIndexSize)); - lodPlanes.push(planes); - lodMeshes.push(new Mesh(planes, null)); - - if (lod > LOD_MIN) { - lod--; - } - } - - return { lodPlanes, sizeLods, sigmas, lodMeshes }; -} - -function _createRenderTarget(width, height, params) { - const cubeUVRenderTarget = new RenderTarget(width, height, params); - cubeUVRenderTarget.texture.mapping = CubeUVReflectionMapping; - cubeUVRenderTarget.texture.name = 'PMREM.cubeUv'; - cubeUVRenderTarget.texture.isPMREMTexture = true; - cubeUVRenderTarget.scissorTest = true; - return cubeUVRenderTarget; -} - -function _setViewport(target, x, y, width, height) { - target.viewport.set(x, y, width, height); - target.scissor.set(x, y, width, height); -} - -function _getMaterial(type) { - const material = new NodeMaterial(); - material.depthTest = false; - material.depthWrite = false; - material.blending = NoBlending; - material.name = `PMREM_${type}`; - - return material; -} - -function _getBlurShader(lodMax, width, height) { - const weights = uniformArray(new Array(MAX_SAMPLES).fill(0)); - const poleAxis = uniform(new Vector3(0, 1, 0)); - const dTheta = uniform(0); - const n = float(MAX_SAMPLES); - const latitudinal = uniform(0); // false, bool - const samples = uniform(1); // int - const envMap = texture(null); - const mipInt = uniform(0); // int - const CUBEUV_TEXEL_WIDTH = float(1 / width); - const CUBEUV_TEXEL_HEIGHT = float(1 / height); - const CUBEUV_MAX_MIP = float(lodMax); - - const materialUniforms = { - n, - latitudinal, - weights, - poleAxis, - outputDirection, - dTheta, - samples, - envMap, - mipInt, - CUBEUV_TEXEL_WIDTH, - CUBEUV_TEXEL_HEIGHT, - CUBEUV_MAX_MIP, - }; - - const material = _getMaterial('blur'); - material.uniforms = materialUniforms; // TODO: Move to outside of the material - material.fragmentNode = blur({ ...materialUniforms, latitudinal: latitudinal.equal(1) }); - - return material; -} - -function _getCubemapMaterial(envTexture) { - const material = _getMaterial('cubemap'); - material.fragmentNode = cubeTexture(envTexture, outputDirection); - - return material; -} - -function _getEquirectMaterial(envTexture) { - const material = _getMaterial('equirect'); - material.fragmentNode = texture(envTexture, equirectUV(outputDirection), 0); - - return material; -} - -export default PMREMGenerator; diff --git a/src-testing/src/renderers/common/nodes/NodeBuilderState.ts b/src-testing/src/renderers/common/nodes/NodeBuilderState.ts deleted file mode 100644 index 520a3c918..000000000 --- a/src-testing/src/renderers/common/nodes/NodeBuilderState.ts +++ /dev/null @@ -1,55 +0,0 @@ -import BindGroup from '../BindGroup.js'; - -class NodeBuilderState { - constructor( - vertexShader, - fragmentShader, - computeShader, - nodeAttributes, - bindings, - updateNodes, - updateBeforeNodes, - updateAfterNodes, - monitor, - transforms = [], - ) { - this.vertexShader = vertexShader; - this.fragmentShader = fragmentShader; - this.computeShader = computeShader; - this.transforms = transforms; - - this.nodeAttributes = nodeAttributes; - this.bindings = bindings; - - this.updateNodes = updateNodes; - this.updateBeforeNodes = updateBeforeNodes; - this.updateAfterNodes = updateAfterNodes; - - this.monitor = monitor; - - this.usedTimes = 0; - } - - createBindings() { - const bindings = []; - - for (const instanceGroup of this.bindings) { - const shared = instanceGroup.bindings[0].groupNode.shared; - - if (shared !== true) { - const bindingsGroup = new BindGroup(instanceGroup.name, [], instanceGroup.index, instanceGroup); - bindings.push(bindingsGroup); - - for (const instanceBinding of instanceGroup.bindings) { - bindingsGroup.bindings.push(instanceBinding.clone()); - } - } else { - bindings.push(instanceGroup); - } - } - - return bindings; - } -} - -export default NodeBuilderState; diff --git a/src-testing/src/renderers/common/nodes/NodeLibrary.ts b/src-testing/src/renderers/common/nodes/NodeLibrary.ts deleted file mode 100644 index b6738b95a..000000000 --- a/src-testing/src/renderers/common/nodes/NodeLibrary.ts +++ /dev/null @@ -1,76 +0,0 @@ -class NodeLibrary { - constructor() { - this.lightNodes = new WeakMap(); - this.materialNodes = new Map(); - this.toneMappingNodes = new Map(); - } - - fromMaterial(material) { - if (material.isNodeMaterial) return material; - - let nodeMaterial = null; - - const nodeMaterialClass = this.getMaterialNodeClass(material.type); - - if (nodeMaterialClass !== null) { - nodeMaterial = new nodeMaterialClass(); - - for (const key in material) { - nodeMaterial[key] = material[key]; - } - } - - return nodeMaterial; - } - - addToneMapping(toneMappingNode, toneMapping) { - this.addType(toneMappingNode, toneMapping, this.toneMappingNodes); - } - - getToneMappingFunction(toneMapping) { - return this.toneMappingNodes.get(toneMapping) || null; - } - - getMaterialNodeClass(materialType) { - return this.materialNodes.get(materialType) || null; - } - - addMaterial(materialNodeClass, materialClass) { - this.addType(materialNodeClass, materialClass.type, this.materialNodes); - } - - getLightNodeClass(light) { - return this.lightNodes.get(light) || null; - } - - addLight(lightNodeClass, lightClass) { - this.addClass(lightNodeClass, lightClass, this.lightNodes); - } - - addType(nodeClass, type, library) { - if (library.has(type)) { - console.warn(`Redefinition of node ${type}`); - return; - } - - if (typeof nodeClass !== 'function') throw new Error(`Node class ${nodeClass.name} is not a class.`); - if (typeof type === 'function' || typeof type === 'object') - throw new Error(`Base class ${type} is not a class.`); - - library.set(type, nodeClass); - } - - addClass(nodeClass, baseClass, library) { - if (library.has(baseClass)) { - console.warn(`Redefinition of node ${baseClass.name}`); - return; - } - - if (typeof nodeClass !== 'function') throw new Error(`Node class ${nodeClass.name} is not a class.`); - if (typeof baseClass !== 'function') throw new Error(`Base class ${baseClass.name} is not a class.`); - - library.set(baseClass, nodeClass); - } -} - -export default NodeLibrary; diff --git a/src-testing/src/renderers/common/nodes/NodeSampledTexture.d.ts b/src-testing/src/renderers/common/nodes/NodeSampledTexture.d.ts deleted file mode 100644 index 97c3c3adf..000000000 --- a/src-testing/src/renderers/common/nodes/NodeSampledTexture.d.ts +++ /dev/null @@ -1,29 +0,0 @@ -import TextureNode from "../../../nodes/accessors/TextureNode.js"; -import UniformGroupNode from "../../../nodes/core/UniformGroupNode.js"; -import { SampledTexture } from "../SampledTexture.js"; - -type GPUStorageTextureAccess = "read-only" | "read-write" | "write-only"; - -declare class NodeSampledTexture extends SampledTexture { - textureNode: TextureNode | undefined; - groupNode: UniformGroupNode; - - access: "read-write" | "read-only" | "write-only"; - - constructor( - name: string, - textureNode: TextureNode | undefined, - groupNode: UniformGroupNode, - access?: GPUStorageTextureAccess | null, - ); -} - -declare class NodeSampledCubeTexture extends NodeSampledTexture { - readonly isSampledCubeTexture: true; -} - -declare class NodeSampledTexture3D extends NodeSampledTexture { - readonly isSampledTexture3D = true; -} - -export { NodeSampledCubeTexture, NodeSampledTexture, NodeSampledTexture3D }; diff --git a/src-testing/src/renderers/common/nodes/NodeSampler.d.ts b/src-testing/src/renderers/common/nodes/NodeSampler.d.ts deleted file mode 100644 index 60db177d5..000000000 --- a/src-testing/src/renderers/common/nodes/NodeSampler.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -import TextureNode from "../../../nodes/accessors/TextureNode.js"; -import UniformGroupNode from "../../../nodes/core/UniformGroupNode.js"; -import Sampler from "../Sampler.js"; - -declare class NodeSampler extends Sampler { - textureNode: TextureNode | undefined; - groupNode: UniformGroupNode; - constructor(name: string, textureNode: TextureNode | undefined, groupNode: UniformGroupNode); - update(): void; -} - -export default NodeSampler; diff --git a/src-testing/src/renderers/common/nodes/NodeUniform.ts b/src-testing/src/renderers/common/nodes/NodeUniform.ts deleted file mode 100644 index 659f5a82f..000000000 --- a/src-testing/src/renderers/common/nodes/NodeUniform.ts +++ /dev/null @@ -1,103 +0,0 @@ -import { - NumberUniform, - Vector2Uniform, - Vector3Uniform, - Vector4Uniform, - ColorUniform, - Matrix3Uniform, - Matrix4Uniform, -} from '../Uniform.js'; - -class NumberNodeUniform extends NumberUniform { - constructor(nodeUniform) { - super(nodeUniform.name, nodeUniform.value); - - this.nodeUniform = nodeUniform; - } - - getValue() { - return this.nodeUniform.value; - } -} - -class Vector2NodeUniform extends Vector2Uniform { - constructor(nodeUniform) { - super(nodeUniform.name, nodeUniform.value); - - this.nodeUniform = nodeUniform; - } - - getValue() { - return this.nodeUniform.value; - } -} - -class Vector3NodeUniform extends Vector3Uniform { - constructor(nodeUniform) { - super(nodeUniform.name, nodeUniform.value); - - this.nodeUniform = nodeUniform; - } - - getValue() { - return this.nodeUniform.value; - } -} - -class Vector4NodeUniform extends Vector4Uniform { - constructor(nodeUniform) { - super(nodeUniform.name, nodeUniform.value); - - this.nodeUniform = nodeUniform; - } - - getValue() { - return this.nodeUniform.value; - } -} - -class ColorNodeUniform extends ColorUniform { - constructor(nodeUniform) { - super(nodeUniform.name, nodeUniform.value); - - this.nodeUniform = nodeUniform; - } - - getValue() { - return this.nodeUniform.value; - } -} - -class Matrix3NodeUniform extends Matrix3Uniform { - constructor(nodeUniform) { - super(nodeUniform.name, nodeUniform.value); - - this.nodeUniform = nodeUniform; - } - - getValue() { - return this.nodeUniform.value; - } -} - -class Matrix4NodeUniform extends Matrix4Uniform { - constructor(nodeUniform) { - super(nodeUniform.name, nodeUniform.value); - - this.nodeUniform = nodeUniform; - } - - getValue() { - return this.nodeUniform.value; - } -} - -export { - NumberNodeUniform, - Vector2NodeUniform, - Vector3NodeUniform, - Vector4NodeUniform, - ColorNodeUniform, - Matrix3NodeUniform, - Matrix4NodeUniform, -}; diff --git a/src-testing/src/renderers/common/nodes/NodeUniformsGroup.ts b/src-testing/src/renderers/common/nodes/NodeUniformsGroup.ts deleted file mode 100644 index d2d92cb20..000000000 --- a/src-testing/src/renderers/common/nodes/NodeUniformsGroup.ts +++ /dev/null @@ -1,30 +0,0 @@ -import UniformsGroup from '../UniformsGroup.js'; - -let _id = 0; - -class NodeUniformsGroup extends UniformsGroup { - constructor(name, groupNode) { - super(name); - - this.id = _id++; - this.groupNode = groupNode; - - this.isNodeUniformsGroup = true; - } - - getNodes() { - const nodes = []; - - for (const uniform of this.uniforms) { - const node = uniform.nodeUniform.node; - - if (!node) throw new Error('NodeUniformsGroup: Uniform has no node.'); - - nodes.push(node); - } - - return nodes; - } -} - -export default NodeUniformsGroup; diff --git a/src-testing/src/renderers/common/nodes/Nodes.ts b/src-testing/src/renderers/common/nodes/Nodes.ts deleted file mode 100644 index f409c2b15..000000000 --- a/src-testing/src/renderers/common/nodes/Nodes.ts +++ /dev/null @@ -1,433 +0,0 @@ -import DataMap from '../DataMap.js'; -import ChainMap from '../ChainMap.js'; -import NodeBuilderState from './NodeBuilderState.js'; -import { cubeMapNode } from '../../../nodes/utils/CubeMapNode.js'; -import { NodeFrame } from '../../../nodes/Nodes.js'; -import { - objectGroup, - renderGroup, - frameGroup, - cubeTexture, - texture, - rangeFog, - densityFog, - reference, - normalWorld, - pmremTexture, - screenUV, -} from '../../../nodes/TSL.js'; - -import { - CubeUVReflectionMapping, - EquirectangularReflectionMapping, - EquirectangularRefractionMapping, -} from '../../../constants.js'; -import { hashArray } from '../../../nodes/core/NodeUtils.js'; - -const outputNodeMap = new WeakMap(); - -class Nodes extends DataMap { - constructor(renderer, backend) { - super(); - - this.renderer = renderer; - this.backend = backend; - this.nodeFrame = new NodeFrame(); - this.nodeBuilderCache = new Map(); - this.callHashCache = new ChainMap(); - this.groupsData = new ChainMap(); - } - - updateGroup(nodeUniformsGroup) { - const groupNode = nodeUniformsGroup.groupNode; - const name = groupNode.name; - - // objectGroup is every updated - - if (name === objectGroup.name) return true; - - // renderGroup is updated once per render/compute call - - if (name === renderGroup.name) { - const uniformsGroupData = this.get(nodeUniformsGroup); - const renderId = this.nodeFrame.renderId; - - if (uniformsGroupData.renderId !== renderId) { - uniformsGroupData.renderId = renderId; - - return true; - } - - return false; - } - - // frameGroup is updated once per frame - - if (name === frameGroup.name) { - const uniformsGroupData = this.get(nodeUniformsGroup); - const frameId = this.nodeFrame.frameId; - - if (uniformsGroupData.frameId !== frameId) { - uniformsGroupData.frameId = frameId; - - return true; - } - - return false; - } - - // other groups are updated just when groupNode.needsUpdate is true - - const groupChain = [groupNode, nodeUniformsGroup]; - - let groupData = this.groupsData.get(groupChain); - if (groupData === undefined) this.groupsData.set(groupChain, (groupData = {})); - - if (groupData.version !== groupNode.version) { - groupData.version = groupNode.version; - - return true; - } - - return false; - } - - getForRenderCacheKey(renderObject) { - return renderObject.initialCacheKey; - } - - getForRender(renderObject) { - const renderObjectData = this.get(renderObject); - - let nodeBuilderState = renderObjectData.nodeBuilderState; - - if (nodeBuilderState === undefined) { - const { nodeBuilderCache } = this; - - const cacheKey = this.getForRenderCacheKey(renderObject); - - nodeBuilderState = nodeBuilderCache.get(cacheKey); - - if (nodeBuilderState === undefined) { - const nodeBuilder = this.backend.createNodeBuilder(renderObject.object, this.renderer); - nodeBuilder.scene = renderObject.scene; - nodeBuilder.material = renderObject.material; - nodeBuilder.camera = renderObject.camera; - nodeBuilder.context.material = renderObject.material; - nodeBuilder.lightsNode = renderObject.lightsNode; - nodeBuilder.environmentNode = this.getEnvironmentNode(renderObject.scene); - nodeBuilder.fogNode = this.getFogNode(renderObject.scene); - nodeBuilder.clippingContext = renderObject.clippingContext; - nodeBuilder.build(); - - nodeBuilderState = this._createNodeBuilderState(nodeBuilder); - - nodeBuilderCache.set(cacheKey, nodeBuilderState); - } - - nodeBuilderState.usedTimes++; - - renderObjectData.nodeBuilderState = nodeBuilderState; - } - - return nodeBuilderState; - } - - delete(object) { - if (object.isRenderObject) { - const nodeBuilderState = this.get(object).nodeBuilderState; - nodeBuilderState.usedTimes--; - - if (nodeBuilderState.usedTimes === 0) { - this.nodeBuilderCache.delete(this.getForRenderCacheKey(object)); - } - } - - return super.delete(object); - } - - getForCompute(computeNode) { - const computeData = this.get(computeNode); - - let nodeBuilderState = computeData.nodeBuilderState; - - if (nodeBuilderState === undefined) { - const nodeBuilder = this.backend.createNodeBuilder(computeNode, this.renderer); - nodeBuilder.build(); - - nodeBuilderState = this._createNodeBuilderState(nodeBuilder); - - computeData.nodeBuilderState = nodeBuilderState; - } - - return nodeBuilderState; - } - - _createNodeBuilderState(nodeBuilder) { - return new NodeBuilderState( - nodeBuilder.vertexShader, - nodeBuilder.fragmentShader, - nodeBuilder.computeShader, - nodeBuilder.getAttributesArray(), - nodeBuilder.getBindings(), - nodeBuilder.updateNodes, - nodeBuilder.updateBeforeNodes, - nodeBuilder.updateAfterNodes, - nodeBuilder.monitor, - nodeBuilder.transforms, - ); - } - - getEnvironmentNode(scene) { - return scene.environmentNode || this.get(scene).environmentNode || null; - } - - getBackgroundNode(scene) { - return scene.backgroundNode || this.get(scene).backgroundNode || null; - } - - getFogNode(scene) { - return scene.fogNode || this.get(scene).fogNode || null; - } - - getCacheKey(scene, lightsNode) { - const chain = [scene, lightsNode]; - const callId = this.renderer.info.calls; - - let cacheKeyData = this.callHashCache.get(chain); - - if (cacheKeyData === undefined || cacheKeyData.callId !== callId) { - const environmentNode = this.getEnvironmentNode(scene); - const fogNode = this.getFogNode(scene); - - const values = []; - - if (lightsNode) values.push(lightsNode.getCacheKey(true)); - if (environmentNode) values.push(environmentNode.getCacheKey()); - if (fogNode) values.push(fogNode.getCacheKey()); - - values.push(this.renderer.shadowMap.enabled ? 1 : 0); - - cacheKeyData = { - callId, - cacheKey: hashArray(values), - }; - - this.callHashCache.set(chain, cacheKeyData); - } - - return cacheKeyData.cacheKey; - } - - updateScene(scene) { - this.updateEnvironment(scene); - this.updateFog(scene); - this.updateBackground(scene); - } - - get isToneMappingState() { - return this.renderer.getRenderTarget() ? false : true; - } - - updateBackground(scene) { - const sceneData = this.get(scene); - const background = scene.background; - - if (background) { - const forceUpdate = - (scene.backgroundBlurriness === 0 && sceneData.backgroundBlurriness > 0) || - (scene.backgroundBlurriness > 0 && sceneData.backgroundBlurriness === 0); - - if (sceneData.background !== background || forceUpdate) { - let backgroundNode = null; - - if ( - background.isCubeTexture === true || - background.mapping === EquirectangularReflectionMapping || - background.mapping === EquirectangularRefractionMapping || - background.mapping === CubeUVReflectionMapping - ) { - if (scene.backgroundBlurriness > 0 || background.mapping === CubeUVReflectionMapping) { - backgroundNode = pmremTexture(background, normalWorld); - } else { - let envMap; - - if (background.isCubeTexture === true) { - envMap = cubeTexture(background); - } else { - envMap = texture(background); - } - - backgroundNode = cubeMapNode(envMap); - } - } else if (background.isTexture === true) { - backgroundNode = texture(background, screenUV.flipY()).setUpdateMatrix(true); - } else if (background.isColor !== true) { - console.error('WebGPUNodes: Unsupported background configuration.', background); - } - - sceneData.backgroundNode = backgroundNode; - sceneData.background = background; - sceneData.backgroundBlurriness = scene.backgroundBlurriness; - } - } else if (sceneData.backgroundNode) { - delete sceneData.backgroundNode; - delete sceneData.background; - } - } - - updateFog(scene) { - const sceneData = this.get(scene); - const fog = scene.fog; - - if (fog) { - if (sceneData.fog !== fog) { - let fogNode = null; - - if (fog.isFogExp2) { - const color = reference('color', 'color', fog).setGroup(renderGroup); - const density = reference('density', 'float', fog).setGroup(renderGroup); - - fogNode = densityFog(color, density); - } else if (fog.isFog) { - const color = reference('color', 'color', fog).setGroup(renderGroup); - const near = reference('near', 'float', fog).setGroup(renderGroup); - const far = reference('far', 'float', fog).setGroup(renderGroup); - - fogNode = rangeFog(color, near, far); - } else { - console.error('WebGPUNodes: Unsupported fog configuration.', fog); - } - - sceneData.fogNode = fogNode; - sceneData.fog = fog; - } - } else { - delete sceneData.fogNode; - delete sceneData.fog; - } - } - - updateEnvironment(scene) { - const sceneData = this.get(scene); - const environment = scene.environment; - - if (environment) { - if (sceneData.environment !== environment) { - let environmentNode = null; - - if (environment.isCubeTexture === true) { - environmentNode = cubeTexture(environment); - } else if (environment.isTexture === true) { - environmentNode = texture(environment); - } else { - console.error('Nodes: Unsupported environment configuration.', environment); - } - - sceneData.environmentNode = environmentNode; - sceneData.environment = environment; - } - } else if (sceneData.environmentNode) { - delete sceneData.environmentNode; - delete sceneData.environment; - } - } - - getNodeFrame(renderer = this.renderer, scene = null, object = null, camera = null, material = null) { - const nodeFrame = this.nodeFrame; - nodeFrame.renderer = renderer; - nodeFrame.scene = scene; - nodeFrame.object = object; - nodeFrame.camera = camera; - nodeFrame.material = material; - - return nodeFrame; - } - - getNodeFrameForRender(renderObject) { - return this.getNodeFrame( - renderObject.renderer, - renderObject.scene, - renderObject.object, - renderObject.camera, - renderObject.material, - ); - } - - getOutputCacheKey() { - const renderer = this.renderer; - - return renderer.toneMapping + ',' + renderer.currentColorSpace; - } - - hasOutputChange(outputTarget) { - const cacheKey = outputNodeMap.get(outputTarget); - - return cacheKey !== this.getOutputCacheKey(); - } - - getOutputNode(outputTexture) { - const renderer = this.renderer; - const cacheKey = this.getOutputCacheKey(); - - const output = texture(outputTexture, screenUV).renderOutput(renderer.toneMapping, renderer.currentColorSpace); - - outputNodeMap.set(outputTexture, cacheKey); - - return output; - } - - updateBefore(renderObject) { - const nodeBuilder = renderObject.getNodeBuilderState(); - - for (const node of nodeBuilder.updateBeforeNodes) { - // update frame state for each node - - this.getNodeFrameForRender(renderObject).updateBeforeNode(node); - } - } - - updateAfter(renderObject) { - const nodeBuilder = renderObject.getNodeBuilderState(); - - for (const node of nodeBuilder.updateAfterNodes) { - // update frame state for each node - - this.getNodeFrameForRender(renderObject).updateAfterNode(node); - } - } - - updateForCompute(computeNode) { - const nodeFrame = this.getNodeFrame(); - const nodeBuilder = this.getForCompute(computeNode); - - for (const node of nodeBuilder.updateNodes) { - nodeFrame.updateNode(node); - } - } - - updateForRender(renderObject) { - const nodeFrame = this.getNodeFrameForRender(renderObject); - const nodeBuilder = renderObject.getNodeBuilderState(); - - for (const node of nodeBuilder.updateNodes) { - nodeFrame.updateNode(node); - } - } - - needsRefresh(renderObject) { - const nodeFrame = this.getNodeFrameForRender(renderObject); - const monitor = renderObject.getMonitor(); - - return monitor.needsRefresh(renderObject, nodeFrame); - } - - dispose() { - super.dispose(); - - this.nodeFrame = new NodeFrame(); - this.nodeBuilderCache = new Map(); - } -} - -export default Nodes; diff --git a/src-testing/src/renderers/common/nodes/StandardNodeLibrary.d.ts b/src-testing/src/renderers/common/nodes/StandardNodeLibrary.d.ts deleted file mode 100644 index d7db44562..000000000 --- a/src-testing/src/renderers/common/nodes/StandardNodeLibrary.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -import NodeLibrary from "./NodeLibrary.js"; -declare class StandardNodeLibrary extends NodeLibrary { - constructor(); -} -export default StandardNodeLibrary; diff --git a/src-testing/src/renderers/shaders/ShaderChunk.d.ts b/src-testing/src/renderers/shaders/ShaderChunk.d.ts deleted file mode 100644 index caf4e39bb..000000000 --- a/src-testing/src/renderers/shaders/ShaderChunk.d.ts +++ /dev/null @@ -1,143 +0,0 @@ -// Renderers / Shaders ///////////////////////////////////////////////////////////////////// -export const ShaderChunk: { - alphahash_fragment: string; - alphahash_pars_fragment: string; - alphamap_fragment: string; - alphamap_pars_fragment: string; - alphatest_fragment: string; - alphatest_pars_fragment: string; - aomap_fragment: string; - aomap_pars_fragment: string; - batching_pars_vertex: string; - begin_vertex: string; - beginnormal_vertex: string; - bsdfs: string; - iridescence_fragment: string; - bumpmap_pars_fragment: string; - clipping_planes_fragment: string; - clipping_planes_pars_fragment: string; - clipping_planes_pars_vertex: string; - clipping_planes_vertex: string; - color_fragment: string; - color_pars_fragment: string; - color_pars_vertex: string; - color_vertex: string; - common: string; - cube_uv_reflection_fragment: string; - defaultnormal_vertex: string; - displacementmap_pars_vertex: string; - displacementmap_vertex: string; - emissivemap_fragment: string; - emissivemap_pars_fragment: string; - colorspace_fragment: string; - colorspace_pars_fragment: string; - envmap_fragment: string; - envmap_common_pars_fragment: string; - envmap_pars_fragment: string; - envmap_pars_vertex: string; - envmap_physical_pars_fragment: string; - envmap_vertex: string; - fog_vertex: string; - fog_pars_vertex: string; - fog_fragment: string; - fog_pars_fragment: string; - gradientmap_pars_fragment: string; - lightmap_pars_fragment: string; - lights_lambert_fragment: string; - lights_lambert_pars_fragment: string; - lights_pars_begin: string; - lights_toon_fragment: string; - lights_toon_pars_fragment: string; - lights_phong_fragment: string; - lights_phong_pars_fragment: string; - lights_physical_fragment: string; - lights_physical_pars_fragment: string; - lights_fragment_begin: string; - lights_fragment_maps: string; - lights_fragment_end: string; - logdepthbuf_fragment: string; - logdepthbuf_pars_fragment: string; - logdepthbuf_pars_vertex: string; - logdepthbuf_vertex: string; - map_fragment: string; - map_pars_fragment: string; - map_particle_fragment: string; - map_particle_pars_fragment: string; - metalnessmap_fragment: string; - metalnessmap_pars_fragment: string; - morphcolor_vertex: string; - morphnormal_vertex: string; - morphtarget_pars_vertex: string; - morphtarget_vertex: string; - normal_fragment_begin: string; - normal_fragment_maps: string; - normal_pars_fragment: string; - normal_pars_vertex: string; - normal_vertex: string; - normalmap_pars_fragment: string; - clearcoat_normal_fragment_begin: string; - clearcoat_normal_fragment_maps: string; - clearcoat_pars_fragment: string; - iridescence_pars_fragment: string; - opaque_fragment: string; - packing: string; - premultiplied_alpha_fragment: string; - project_vertex: string; - dithering_fragment: string; - dithering_pars_fragment: string; - roughnessmap_fragment: string; - roughnessmap_pars_fragment: string; - shadowmap_pars_fragment: string; - shadowmap_pars_vertex: string; - shadowmap_vertex: string; - shadowmask_pars_fragment: string; - skinbase_vertex: string; - skinning_pars_vertex: string; - skinning_vertex: string; - skinnormal_vertex: string; - specularmap_fragment: string; - specularmap_pars_fragment: string; - tonemapping_fragment: string; - tonemapping_pars_fragment: string; - transmission_fragment: string; - transmission_pars_fragment: string; - uv_pars_fragment: string; - uv_pars_vertex: string; - uv_vertex: string; - worldpos_vertex: string; - - background_vert: string; - background_frag: string; - backgroundCube_vert: string; - backgroundCube_frag: string; - cube_vert: string; - cube_frag: string; - depth_vert: string; - depth_frag: string; - distanceRGBA_vert: string; - distanceRGBA_frag: string; - equirect_vert: string; - equirect_frag: string; - linedashed_vert: string; - linedashed_frag: string; - meshbasic_vert: string; - meshbasic_frag: string; - meshlambert_vert: string; - meshlambert_frag: string; - meshmatcap_vert: string; - meshmatcap_frag: string; - meshnormal_vert: string; - meshnormal_frag: string; - meshphong_vert: string; - meshphong_frag: string; - meshphysical_vert: string; - meshphysical_frag: string; - meshtoon_vert: string; - meshtoon_frag: string; - points_vert: string; - points_frag: string; - shadow_vert: string; - shadow_frag: string; - sprite_vert: string; - sprite_frag: string; -}; diff --git a/src-testing/src/renderers/shaders/ShaderLib.d.ts b/src-testing/src/renderers/shaders/ShaderLib.d.ts deleted file mode 100644 index 9a52c4dcd..000000000 --- a/src-testing/src/renderers/shaders/ShaderLib.d.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { IUniform } from "./UniformsLib.js"; - -export interface ShaderLibShader { - uniforms: { [uniform: string]: IUniform }; - vertexShader: string; - fragmentShader: string; -} - -declare const ShaderLib: { - [name: string]: ShaderLibShader; - basic: ShaderLibShader; - lambert: ShaderLibShader; - phong: ShaderLibShader; - standard: ShaderLibShader; - matcap: ShaderLibShader; - points: ShaderLibShader; - dashed: ShaderLibShader; - depth: ShaderLibShader; - normal: ShaderLibShader; - sprite: ShaderLibShader; - background: ShaderLibShader; - cube: ShaderLibShader; - equirect: ShaderLibShader; - distanceRGBA: ShaderLibShader; - shadow: ShaderLibShader; - physical: ShaderLibShader; -}; - -export { ShaderLib }; diff --git a/src-testing/src/renderers/shaders/UniformsLib.d.ts b/src-testing/src/renderers/shaders/UniformsLib.d.ts deleted file mode 100644 index cb0d808bd..000000000 --- a/src-testing/src/renderers/shaders/UniformsLib.d.ts +++ /dev/null @@ -1,189 +0,0 @@ -import { Color } from "../../math/Color.js"; -import { Matrix3 } from "../../math/Matrix3.js"; -import { Vector2 } from "../../math/Vector2.js"; - -// eslint-disable-next-line @typescript-eslint/naming-convention -export interface IUniform { - value: TValue; -} - -export const UniformsLib: { - common: { - diffuse: IUniform; - opacity: IUniform; - map: IUniform; - mapTransform: IUniform; - alphaMap: IUniform; - alphaMapTransform: IUniform; - alphaTest: IUniform; - }; - specularmap: { - specularMap: IUniform; - specularMapTransform: IUniform; - }; - envmap: { - envMap: IUniform; - envMapRotation: IUniform; - flipEnvMap: IUniform; - reflectivity: IUniform; - ior: IUniform; - refractRatio: IUniform; - }; - aomap: { - aoMap: IUniform; - aoMapIntensity: IUniform; - aoMapTransform: IUniform; - }; - lightmap: { - lightMap: IUniform; - lightMapIntensity: IUniform; - lightMapTransform: IUniform; - }; - bumpmap: { - bumpMap: IUniform; - bumpMapTransform: IUniform; - bumpScale: IUniform; - }; - normalmap: { - normalMap: IUniform; - normalMapTransform: IUniform; - normalScale: IUniform; - }; - displacementmap: { - displacementMap: IUniform; - displacementMapTransform: IUniform; - displacementScale: IUniform; - displacementBias: IUniform; - }; - emissivemap: { - emissiveMap: IUniform; - emissiveMapTransform: IUniform; - }; - metalnessmap: { - metalnessMap: IUniform; - metalnessMapTransform: IUniform; - }; - roughnessmap: { - roughnessMap: IUniform; - roughnessMapTransform: IUniform; - }; - gradientmap: { - gradientMap: IUniform; - }; - fog: { - fogDensity: IUniform; - fogNear: IUniform; - fogFar: IUniform; - fogColor: IUniform; - }; - lights: { - ambientLightColor: IUniform; - lightProbe: IUniform; - directionalLights: { - value: unknown[]; - properties: { - direction: {}; - color: {}; - }; - }; - directionalLightShadows: { - value: unknown[]; - properties: { - shadowIntensity: number; - shadowBias: {}; - shadowNormalBias: {}; - shadowRadius: {}; - shadowMapSize: {}; - }; - }; - directionalShadowMap: IUniform; - directionalShadowMatrix: IUniform; - spotLights: { - value: unknown[]; - properties: { - color: {}; - position: {}; - direction: {}; - distance: {}; - coneCos: {}; - penumbraCos: {}; - decay: {}; - }; - }; - spotLightShadows: { - value: unknown[]; - properties: { - shadowIntensity: number; - shadowBias: {}; - shadowNormalBias: {}; - shadowRadius: {}; - shadowMapSize: {}; - }; - }; - spotLightMap: IUniform; - spotShadowMap: IUniform; - spotLightMatrix: IUniform; - pointLights: { - value: unknown[]; - properties: { - color: {}; - position: {}; - decay: {}; - distance: {}; - }; - }; - pointLightShadows: { - value: unknown[]; - properties: { - shadowIntensity: number; - shadowBias: {}; - shadowNormalBias: {}; - shadowRadius: {}; - shadowMapSize: {}; - shadowCameraNear: {}; - shadowCameraFar: {}; - }; - }; - pointShadowMap: IUniform; - pointShadowMatrix: IUniform; - hemisphereLights: { - value: unknown[]; - properties: { - direction: {}; - skycolor: {}; - groundColor: {}; - }; - }; - rectAreaLights: { - value: unknown[]; - properties: { - color: {}; - position: {}; - width: {}; - height: {}; - }; - }; - ltc_1: IUniform; - ltc_2: IUniform; - }; - points: { - diffuse: IUniform; - opacity: IUniform; - size: IUniform; - scale: IUniform; - map: IUniform; - alphaMap: IUniform; - alphaTest: IUniform; - uvTransform: IUniform; - }; - sprite: { - diffuse: IUniform; - opacity: IUniform; - center: IUniform; - rotation: IUniform; - map: IUniform; - mapTransform: IUniform; - alphaMap: IUniform; - alphaTest: IUniform; - }; -}; diff --git a/src-testing/src/renderers/shaders/UniformsUtils.d.ts b/src-testing/src/renderers/shaders/UniformsUtils.d.ts deleted file mode 100644 index fe5178d55..000000000 --- a/src-testing/src/renderers/shaders/UniformsUtils.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { UniformsGroup } from "../../core/UniformsGroup.js"; -import { IUniform } from "./UniformsLib.js"; - -export function cloneUniforms(uniformsSrc: T): T; -export function mergeUniforms(uniforms: Array<{ [uniform: string]: IUniform }>): { [uniform: string]: IUniform }; - -export function cloneUniformsGroups(src: UniformsGroup[]): UniformsGroup[]; - -declare const UniformsUtils: { - clone: typeof cloneUniforms; - merge: typeof mergeUniforms; -}; - -export { UniformsUtils }; diff --git a/src-testing/src/renderers/webgl-fallback/WebGLBackend.ts b/src-testing/src/renderers/webgl-fallback/WebGLBackend.ts deleted file mode 100644 index ccf00b986..000000000 --- a/src-testing/src/renderers/webgl-fallback/WebGLBackend.ts +++ /dev/null @@ -1,1349 +0,0 @@ -import GLSLNodeBuilder from './nodes/GLSLNodeBuilder.js'; -import Backend from '../common/Backend.js'; -import { getCacheKey } from '../common/RenderContext.js'; - -import WebGLAttributeUtils from './utils/WebGLAttributeUtils.js'; -import WebGLState from './utils/WebGLState.js'; -import WebGLUtils from './utils/WebGLUtils.js'; -import WebGLTextureUtils from './utils/WebGLTextureUtils.js'; -import WebGLExtensions from './utils/WebGLExtensions.js'; -import WebGLCapabilities from './utils/WebGLCapabilities.js'; -import { GLFeatureName } from './utils/WebGLConstants.js'; -import { WebGLBufferRenderer } from './WebGLBufferRenderer.js'; - -import { warnOnce } from '../../utils.js'; -import { WebGLCoordinateSystem } from '../../constants.js'; - -// - -class WebGLBackend extends Backend { - constructor(parameters = {}) { - super(parameters); - - this.isWebGLBackend = true; - } - - init(renderer) { - super.init(renderer); - - // - - const parameters = this.parameters; - - const glContext = - parameters.context !== undefined ? parameters.context : renderer.domElement.getContext('webgl2'); - - this.gl = glContext; - - this.extensions = new WebGLExtensions(this); - this.capabilities = new WebGLCapabilities(this); - this.attributeUtils = new WebGLAttributeUtils(this); - this.textureUtils = new WebGLTextureUtils(this); - this.bufferRenderer = new WebGLBufferRenderer(this); - - this.state = new WebGLState(this); - this.utils = new WebGLUtils(this); - - this.vaoCache = {}; - this.transformFeedbackCache = {}; - this.discard = false; - this.trackTimestamp = parameters.trackTimestamp === true; - - this.extensions.get('EXT_color_buffer_float'); - this.extensions.get('WEBGL_clip_cull_distance'); - this.extensions.get('OES_texture_float_linear'); - this.extensions.get('EXT_color_buffer_half_float'); - this.extensions.get('WEBGL_multisampled_render_to_texture'); - this.extensions.get('WEBGL_render_shared_exponent'); - this.extensions.get('WEBGL_multi_draw'); - - this.disjoint = this.extensions.get('EXT_disjoint_timer_query_webgl2'); - this.parallel = this.extensions.get('KHR_parallel_shader_compile'); - - this._knownBindings = new WeakSet(); - - this._currentContext = null; - } - - get coordinateSystem() { - return WebGLCoordinateSystem; - } - - async getArrayBufferAsync(attribute) { - return await this.attributeUtils.getArrayBufferAsync(attribute); - } - - async waitForGPU() { - await this.utils._clientWaitAsync(); - } - - initTimestampQuery(renderContext) { - if (!this.disjoint || !this.trackTimestamp) return; - - const renderContextData = this.get(renderContext); - - if (this.queryRunning) { - if (!renderContextData.queryQueue) renderContextData.queryQueue = []; - renderContextData.queryQueue.push(renderContext); - return; - } - - if (renderContextData.activeQuery) { - this.gl.endQuery(this.disjoint.TIME_ELAPSED_EXT); - renderContextData.activeQuery = null; - } - - renderContextData.activeQuery = this.gl.createQuery(); - - if (renderContextData.activeQuery !== null) { - this.gl.beginQuery(this.disjoint.TIME_ELAPSED_EXT, renderContextData.activeQuery); - this.queryRunning = true; - } - } - - // timestamp utils - - prepareTimestampBuffer(renderContext) { - if (!this.disjoint || !this.trackTimestamp) return; - - const renderContextData = this.get(renderContext); - - if (renderContextData.activeQuery) { - this.gl.endQuery(this.disjoint.TIME_ELAPSED_EXT); - - if (!renderContextData.gpuQueries) renderContextData.gpuQueries = []; - renderContextData.gpuQueries.push({ query: renderContextData.activeQuery }); - renderContextData.activeQuery = null; - this.queryRunning = false; - - if (renderContextData.queryQueue && renderContextData.queryQueue.length > 0) { - const nextRenderContext = renderContextData.queryQueue.shift(); - this.initTimestampQuery(nextRenderContext); - } - } - } - - async resolveTimestampAsync(renderContext, type = 'render') { - if (!this.disjoint || !this.trackTimestamp) return; - - const renderContextData = this.get(renderContext); - - if (!renderContextData.gpuQueries) renderContextData.gpuQueries = []; - - for (let i = 0; i < renderContextData.gpuQueries.length; i++) { - const queryInfo = renderContextData.gpuQueries[i]; - const available = this.gl.getQueryParameter(queryInfo.query, this.gl.QUERY_RESULT_AVAILABLE); - const disjoint = this.gl.getParameter(this.disjoint.GPU_DISJOINT_EXT); - - if (available && !disjoint) { - const elapsed = this.gl.getQueryParameter(queryInfo.query, this.gl.QUERY_RESULT); - const duration = Number(elapsed) / 1000000; // Convert nanoseconds to milliseconds - this.gl.deleteQuery(queryInfo.query); - renderContextData.gpuQueries.splice(i, 1); // Remove the processed query - i--; - this.renderer.info.updateTimestamp(type, duration); - } - } - } - - getContext() { - return this.gl; - } - - beginRender(renderContext) { - const { gl } = this; - const renderContextData = this.get(renderContext); - - // - - // - - this.initTimestampQuery(renderContext); - - renderContextData.previousContext = this._currentContext; - this._currentContext = renderContext; - - this._setFramebuffer(renderContext); - - this.clear( - renderContext.clearColor, - renderContext.clearDepth, - renderContext.clearStencil, - renderContext, - false, - ); - - // - if (renderContext.viewport) { - this.updateViewport(renderContext); - } else { - gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); - } - - if (renderContext.scissor) { - const { x, y, width, height } = renderContext.scissorValue; - - gl.scissor(x, renderContext.height - height - y, width, height); - } - - const occlusionQueryCount = renderContext.occlusionQueryCount; - - if (occlusionQueryCount > 0) { - // Get a reference to the array of objects with queries. The renderContextData property - // can be changed by another render pass before the async reading of all previous queries complete - renderContextData.currentOcclusionQueries = renderContextData.occlusionQueries; - renderContextData.currentOcclusionQueryObjects = renderContextData.occlusionQueryObjects; - - renderContextData.lastOcclusionObject = null; - renderContextData.occlusionQueries = new Array(occlusionQueryCount); - renderContextData.occlusionQueryObjects = new Array(occlusionQueryCount); - renderContextData.occlusionQueryIndex = 0; - } - } - - finishRender(renderContext) { - const { gl, state } = this; - const renderContextData = this.get(renderContext); - const previousContext = renderContextData.previousContext; - - const occlusionQueryCount = renderContext.occlusionQueryCount; - - if (occlusionQueryCount > 0) { - if (occlusionQueryCount > renderContextData.occlusionQueryIndex) { - gl.endQuery(gl.ANY_SAMPLES_PASSED); - } - - this.resolveOccludedAsync(renderContext); - } - - const textures = renderContext.textures; - - if (textures !== null) { - for (let i = 0; i < textures.length; i++) { - const texture = textures[i]; - - if (texture.generateMipmaps) { - this.generateMipmaps(texture); - } - } - } - - this._currentContext = previousContext; - - if (renderContext.textures !== null && renderContext.renderTarget) { - const renderTargetContextData = this.get(renderContext.renderTarget); - - const { samples } = renderContext.renderTarget; - - if (samples > 0) { - const fb = renderTargetContextData.framebuffers[renderContext.getCacheKey()]; - - const mask = gl.COLOR_BUFFER_BIT; - - const msaaFrameBuffer = renderTargetContextData.msaaFrameBuffer; - - const textures = renderContext.textures; - - state.bindFramebuffer(gl.READ_FRAMEBUFFER, msaaFrameBuffer); - state.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fb); - - for (let i = 0; i < textures.length; i++) { - // TODO Add support for MRT - - if (renderContext.scissor) { - const { x, y, width, height } = renderContext.scissorValue; - - const viewY = renderContext.height - height - y; - - gl.blitFramebuffer( - x, - viewY, - x + width, - viewY + height, - x, - viewY, - x + width, - viewY + height, - mask, - gl.NEAREST, - ); - gl.invalidateSubFramebuffer( - gl.READ_FRAMEBUFFER, - renderTargetContextData.invalidationArray, - x, - viewY, - width, - height, - ); - } else { - gl.blitFramebuffer( - 0, - 0, - renderContext.width, - renderContext.height, - 0, - 0, - renderContext.width, - renderContext.height, - mask, - gl.NEAREST, - ); - gl.invalidateFramebuffer(gl.READ_FRAMEBUFFER, renderTargetContextData.invalidationArray); - } - } - } - } - - if (previousContext !== null) { - this._setFramebuffer(previousContext); - - if (previousContext.viewport) { - this.updateViewport(previousContext); - } else { - gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); - } - } - - this.prepareTimestampBuffer(renderContext); - } - - resolveOccludedAsync(renderContext) { - const renderContextData = this.get(renderContext); - - // handle occlusion query results - - const { currentOcclusionQueries, currentOcclusionQueryObjects } = renderContextData; - - if (currentOcclusionQueries && currentOcclusionQueryObjects) { - const occluded = new WeakSet(); - const { gl } = this; - - renderContextData.currentOcclusionQueryObjects = null; - renderContextData.currentOcclusionQueries = null; - - const check = () => { - let completed = 0; - - // check all queries and requeue as appropriate - for (let i = 0; i < currentOcclusionQueries.length; i++) { - const query = currentOcclusionQueries[i]; - - if (query === null) continue; - - if (gl.getQueryParameter(query, gl.QUERY_RESULT_AVAILABLE)) { - if (gl.getQueryParameter(query, gl.QUERY_RESULT) > 0) - occluded.add(currentOcclusionQueryObjects[i]); - - currentOcclusionQueries[i] = null; - gl.deleteQuery(query); - - completed++; - } - } - - if (completed < currentOcclusionQueries.length) { - requestAnimationFrame(check); - } else { - renderContextData.occluded = occluded; - } - }; - - check(); - } - } - - isOccluded(renderContext, object) { - const renderContextData = this.get(renderContext); - - return renderContextData.occluded && renderContextData.occluded.has(object); - } - - updateViewport(renderContext) { - const gl = this.gl; - const { x, y, width, height } = renderContext.viewportValue; - - gl.viewport(x, renderContext.height - height - y, width, height); - } - - setScissorTest(boolean) { - const gl = this.gl; - - if (boolean) { - gl.enable(gl.SCISSOR_TEST); - } else { - gl.disable(gl.SCISSOR_TEST); - } - } - - clear(color, depth, stencil, descriptor = null, setFrameBuffer = true) { - const { gl } = this; - - if (descriptor === null) { - const clearColor = this.getClearColor(); - - // premultiply alpha - - clearColor.r *= clearColor.a; - clearColor.g *= clearColor.a; - clearColor.b *= clearColor.a; - - descriptor = { - textures: null, - clearColorValue: clearColor, - }; - } - - // - - let clear = 0; - - if (color) clear |= gl.COLOR_BUFFER_BIT; - if (depth) clear |= gl.DEPTH_BUFFER_BIT; - if (stencil) clear |= gl.STENCIL_BUFFER_BIT; - - if (clear !== 0) { - let clearColor; - - if (descriptor.clearColorValue) { - clearColor = descriptor.clearColorValue; - } else { - clearColor = this.getClearColor(); - - // premultiply alpha - - clearColor.r *= clearColor.a; - clearColor.g *= clearColor.a; - clearColor.b *= clearColor.a; - } - - if (depth) this.state.setDepthMask(true); - - if (descriptor.textures === null) { - gl.clearColor(clearColor.r, clearColor.g, clearColor.b, clearColor.a); - gl.clear(clear); - } else { - if (setFrameBuffer) this._setFramebuffer(descriptor); - - if (color) { - for (let i = 0; i < descriptor.textures.length; i++) { - gl.clearBufferfv(gl.COLOR, i, [clearColor.r, clearColor.g, clearColor.b, clearColor.a]); - } - } - - if (depth && stencil) { - gl.clearBufferfi(gl.DEPTH_STENCIL, 0, 1, 0); - } else if (depth) { - gl.clearBufferfv(gl.DEPTH, 0, [1.0]); - } else if (stencil) { - gl.clearBufferiv(gl.STENCIL, 0, [0]); - } - } - } - } - - beginCompute(computeGroup) { - const { state, gl } = this; - - state.bindFramebuffer(gl.FRAMEBUFFER, null); - this.initTimestampQuery(computeGroup); - } - - compute(computeGroup, computeNode, bindings, pipeline) { - const { state, gl } = this; - - if (!this.discard) { - // required here to handle async behaviour of render.compute() - gl.enable(gl.RASTERIZER_DISCARD); - this.discard = true; - } - - const { programGPU, transformBuffers, attributes } = this.get(pipeline); - - const vaoKey = this._getVaoKey(null, attributes); - - const vaoGPU = this.vaoCache[vaoKey]; - - if (vaoGPU === undefined) { - this._createVao(null, attributes); - } else { - gl.bindVertexArray(vaoGPU); - } - - state.useProgram(programGPU); - - this._bindUniforms(bindings); - - const transformFeedbackGPU = this._getTransformFeedback(transformBuffers); - - gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, transformFeedbackGPU); - gl.beginTransformFeedback(gl.POINTS); - - if (attributes[0].isStorageInstancedBufferAttribute) { - gl.drawArraysInstanced(gl.POINTS, 0, 1, computeNode.count); - } else { - gl.drawArrays(gl.POINTS, 0, computeNode.count); - } - - gl.endTransformFeedback(); - gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null); - - // switch active buffers - - for (let i = 0; i < transformBuffers.length; i++) { - const dualAttributeData = transformBuffers[i]; - - if (dualAttributeData.pbo) { - this.textureUtils.copyBufferToTexture(dualAttributeData.transformBuffer, dualAttributeData.pbo); - } - - dualAttributeData.switchBuffers(); - } - } - - finishCompute(computeGroup) { - const gl = this.gl; - - this.discard = false; - - gl.disable(gl.RASTERIZER_DISCARD); - - this.prepareTimestampBuffer(computeGroup); - - if (this._currentContext) { - this._setFramebuffer(this._currentContext); - } - } - - draw(renderObject /*, info*/) { - const { object, pipeline, material, context } = renderObject; - const { programGPU } = this.get(pipeline); - - const { gl, state } = this; - - const contextData = this.get(context); - - const drawParams = renderObject.getDrawParameters(); - - if (drawParams === null) return; - - // - - this._bindUniforms(renderObject.getBindings()); - - const frontFaceCW = object.isMesh && object.matrixWorld.determinant() < 0; - - state.setMaterial(material, frontFaceCW); - - state.useProgram(programGPU); - - // - - let vaoGPU = renderObject.staticVao; - - if (vaoGPU === undefined) { - const vaoKey = this._getVaoKey(renderObject.getIndex(), renderObject.getAttributes()); - - vaoGPU = this.vaoCache[vaoKey]; - - if (vaoGPU === undefined) { - let staticVao; - - ({ vaoGPU, staticVao } = this._createVao(renderObject.getIndex(), renderObject.getAttributes())); - - if (staticVao) renderObject.staticVao = vaoGPU; - } - } - - gl.bindVertexArray(vaoGPU); - - // - - const index = renderObject.getIndex(); - - // - - const lastObject = contextData.lastOcclusionObject; - - if (lastObject !== object && lastObject !== undefined) { - if (lastObject !== null && lastObject.occlusionTest === true) { - gl.endQuery(gl.ANY_SAMPLES_PASSED); - - contextData.occlusionQueryIndex++; - } - - if (object.occlusionTest === true) { - const query = gl.createQuery(); - - gl.beginQuery(gl.ANY_SAMPLES_PASSED, query); - - contextData.occlusionQueries[contextData.occlusionQueryIndex] = query; - contextData.occlusionQueryObjects[contextData.occlusionQueryIndex] = object; - } - - contextData.lastOcclusionObject = object; - } - - // - const renderer = this.bufferRenderer; - - if (object.isPoints) renderer.mode = gl.POINTS; - else if (object.isLineSegments) renderer.mode = gl.LINES; - else if (object.isLine) renderer.mode = gl.LINE_STRIP; - else if (object.isLineLoop) renderer.mode = gl.LINE_LOOP; - else { - if (material.wireframe === true) { - state.setLineWidth(material.wireframeLinewidth * this.renderer.getPixelRatio()); - renderer.mode = gl.LINES; - } else { - renderer.mode = gl.TRIANGLES; - } - } - - // - - const { vertexCount, instanceCount } = drawParams; - let { firstVertex } = drawParams; - - renderer.object = object; - - if (index !== null) { - firstVertex *= index.array.BYTES_PER_ELEMENT; - - const indexData = this.get(index); - - renderer.index = index.count; - renderer.type = indexData.type; - } else { - renderer.index = 0; - } - - if (object.isBatchedMesh) { - if (object._multiDrawInstances !== null) { - renderer.renderMultiDrawInstances( - object._multiDrawStarts, - object._multiDrawCounts, - object._multiDrawCount, - object._multiDrawInstances, - ); - } else if (!this.hasFeature('WEBGL_multi_draw')) { - warnOnce('THREE.WebGLRenderer: WEBGL_multi_draw not supported.'); - } else { - renderer.renderMultiDraw(object._multiDrawStarts, object._multiDrawCounts, object._multiDrawCount); - } - } else if (instanceCount > 1) { - renderer.renderInstances(firstVertex, vertexCount, instanceCount); - } else { - renderer.render(firstVertex, vertexCount); - } - // - - gl.bindVertexArray(null); - } - - needsRenderUpdate(/*renderObject*/) { - return false; - } - - getRenderCacheKey(/*renderObject*/) { - return ''; - } - - // textures - - createDefaultTexture(texture) { - this.textureUtils.createDefaultTexture(texture); - } - - createTexture(texture, options) { - this.textureUtils.createTexture(texture, options); - } - - updateTexture(texture, options) { - this.textureUtils.updateTexture(texture, options); - } - - generateMipmaps(texture) { - this.textureUtils.generateMipmaps(texture); - } - - destroyTexture(texture) { - this.textureUtils.destroyTexture(texture); - } - - copyTextureToBuffer(texture, x, y, width, height, faceIndex) { - return this.textureUtils.copyTextureToBuffer(texture, x, y, width, height, faceIndex); - } - - createSampler(/*texture*/) { - //console.warn( 'Abstract class.' ); - } - - destroySampler() {} - - // node builder - - createNodeBuilder(object, renderer) { - return new GLSLNodeBuilder(object, renderer); - } - - // program - - createProgram(program) { - const gl = this.gl; - const { stage, code } = program; - - const shader = stage === 'fragment' ? gl.createShader(gl.FRAGMENT_SHADER) : gl.createShader(gl.VERTEX_SHADER); - - gl.shaderSource(shader, code); - gl.compileShader(shader); - - this.set(program, { - shaderGPU: shader, - }); - } - - destroyProgram(/*program*/) { - console.warn('Abstract class.'); - } - - createRenderPipeline(renderObject, promises) { - const gl = this.gl; - const pipeline = renderObject.pipeline; - - // Program - - const { fragmentProgram, vertexProgram } = pipeline; - - const programGPU = gl.createProgram(); - - const fragmentShader = this.get(fragmentProgram).shaderGPU; - const vertexShader = this.get(vertexProgram).shaderGPU; - - gl.attachShader(programGPU, fragmentShader); - gl.attachShader(programGPU, vertexShader); - gl.linkProgram(programGPU); - - this.set(pipeline, { - programGPU, - fragmentShader, - vertexShader, - }); - - if (promises !== null && this.parallel) { - const p = new Promise((resolve /*, reject*/) => { - const parallel = this.parallel; - const checkStatus = () => { - if (gl.getProgramParameter(programGPU, parallel.COMPLETION_STATUS_KHR)) { - this._completeCompile(renderObject, pipeline); - resolve(); - } else { - requestAnimationFrame(checkStatus); - } - }; - - checkStatus(); - }); - - promises.push(p); - - return; - } - - this._completeCompile(renderObject, pipeline); - } - - _handleSource(string, errorLine) { - const lines = string.split('\n'); - const lines2 = []; - - const from = Math.max(errorLine - 6, 0); - const to = Math.min(errorLine + 6, lines.length); - - for (let i = from; i < to; i++) { - const line = i + 1; - lines2.push(`${line === errorLine ? '>' : ' '} ${line}: ${lines[i]}`); - } - - return lines2.join('\n'); - } - - _getShaderErrors(gl, shader, type) { - const status = gl.getShaderParameter(shader, gl.COMPILE_STATUS); - const errors = gl.getShaderInfoLog(shader).trim(); - - if (status && errors === '') return ''; - - const errorMatches = /ERROR: 0:(\d+)/.exec(errors); - if (errorMatches) { - const errorLine = parseInt(errorMatches[1]); - return ( - type.toUpperCase() + - '\n\n' + - errors + - '\n\n' + - this._handleSource(gl.getShaderSource(shader), errorLine) - ); - } else { - return errors; - } - } - - _logProgramError(programGPU, glFragmentShader, glVertexShader) { - if (this.renderer.debug.checkShaderErrors) { - const gl = this.gl; - - const programLog = gl.getProgramInfoLog(programGPU).trim(); - - if (gl.getProgramParameter(programGPU, gl.LINK_STATUS) === false) { - if (typeof this.renderer.debug.onShaderError === 'function') { - this.renderer.debug.onShaderError(gl, programGPU, glVertexShader, glFragmentShader); - } else { - // default error reporting - - const vertexErrors = this._getShaderErrors(gl, glVertexShader, 'vertex'); - const fragmentErrors = this._getShaderErrors(gl, glFragmentShader, 'fragment'); - - console.error( - 'THREE.WebGLProgram: Shader Error ' + - gl.getError() + - ' - ' + - 'VALIDATE_STATUS ' + - gl.getProgramParameter(programGPU, gl.VALIDATE_STATUS) + - '\n\n' + - 'Program Info Log: ' + - programLog + - '\n' + - vertexErrors + - '\n' + - fragmentErrors, - ); - } - } else if (programLog !== '') { - console.warn('THREE.WebGLProgram: Program Info Log:', programLog); - } - } - } - - _completeCompile(renderObject, pipeline) { - const { state, gl } = this; - const pipelineData = this.get(pipeline); - const { programGPU, fragmentShader, vertexShader } = pipelineData; - - if (gl.getProgramParameter(programGPU, gl.LINK_STATUS) === false) { - this._logProgramError(programGPU, fragmentShader, vertexShader); - } - - state.useProgram(programGPU); - - // Bindings - - const bindings = renderObject.getBindings(); - - this._setupBindings(bindings, programGPU); - - // - - this.set(pipeline, { - programGPU, - }); - } - - createComputePipeline(computePipeline, bindings) { - const { state, gl } = this; - - // Program - - const fragmentProgram = { - stage: 'fragment', - code: '#version 300 es\nprecision highp float;\nvoid main() {}', - }; - - this.createProgram(fragmentProgram); - - const { computeProgram } = computePipeline; - - const programGPU = gl.createProgram(); - - const fragmentShader = this.get(fragmentProgram).shaderGPU; - const vertexShader = this.get(computeProgram).shaderGPU; - - const transforms = computeProgram.transforms; - - const transformVaryingNames = []; - const transformAttributeNodes = []; - - for (let i = 0; i < transforms.length; i++) { - const transform = transforms[i]; - - transformVaryingNames.push(transform.varyingName); - transformAttributeNodes.push(transform.attributeNode); - } - - gl.attachShader(programGPU, fragmentShader); - gl.attachShader(programGPU, vertexShader); - - gl.transformFeedbackVaryings(programGPU, transformVaryingNames, gl.SEPARATE_ATTRIBS); - - gl.linkProgram(programGPU); - - if (gl.getProgramParameter(programGPU, gl.LINK_STATUS) === false) { - this._logProgramError(programGPU, fragmentShader, vertexShader); - } - - state.useProgram(programGPU); - - // Bindings - - this._setupBindings(bindings, programGPU); - - const attributeNodes = computeProgram.attributes; - const attributes = []; - const transformBuffers = []; - - for (let i = 0; i < attributeNodes.length; i++) { - const attribute = attributeNodes[i].node.attribute; - - attributes.push(attribute); - - if (!this.has(attribute)) this.attributeUtils.createAttribute(attribute, gl.ARRAY_BUFFER); - } - - for (let i = 0; i < transformAttributeNodes.length; i++) { - const attribute = transformAttributeNodes[i].attribute; - - if (!this.has(attribute)) this.attributeUtils.createAttribute(attribute, gl.ARRAY_BUFFER); - - const attributeData = this.get(attribute); - - transformBuffers.push(attributeData); - } - - // - - this.set(computePipeline, { - programGPU, - transformBuffers, - attributes, - }); - } - - createBindings(bindGroup, bindings) { - if (this._knownBindings.has(bindings) === false) { - this._knownBindings.add(bindings); - - let uniformBuffers = 0; - let textures = 0; - - for (const bindGroup of bindings) { - this.set(bindGroup, { - textures: textures, - uniformBuffers: uniformBuffers, - }); - - for (const binding of bindGroup.bindings) { - if (binding.isUniformBuffer) uniformBuffers++; - if (binding.isSampledTexture) textures++; - } - } - } - - this.updateBindings(bindGroup, bindings); - } - - updateBindings(bindGroup /*, bindings*/) { - const { gl } = this; - - const bindGroupData = this.get(bindGroup); - - let i = bindGroupData.uniformBuffers; - let t = bindGroupData.textures; - - for (const binding of bindGroup.bindings) { - if (binding.isUniformsGroup || binding.isUniformBuffer) { - const data = binding.buffer; - const bufferGPU = gl.createBuffer(); - - gl.bindBuffer(gl.UNIFORM_BUFFER, bufferGPU); - gl.bufferData(gl.UNIFORM_BUFFER, data, gl.DYNAMIC_DRAW); - - this.set(binding, { - index: i++, - bufferGPU, - }); - } else if (binding.isSampledTexture) { - const { textureGPU, glTextureType } = this.get(binding.texture); - - this.set(binding, { - index: t++, - textureGPU, - glTextureType, - }); - } - } - } - - updateBinding(binding) { - const gl = this.gl; - - if (binding.isUniformsGroup || binding.isUniformBuffer) { - const bindingData = this.get(binding); - const bufferGPU = bindingData.bufferGPU; - const data = binding.buffer; - - gl.bindBuffer(gl.UNIFORM_BUFFER, bufferGPU); - gl.bufferData(gl.UNIFORM_BUFFER, data, gl.DYNAMIC_DRAW); - } - } - - // attributes - - createIndexAttribute(attribute) { - const gl = this.gl; - - this.attributeUtils.createAttribute(attribute, gl.ELEMENT_ARRAY_BUFFER); - } - - createAttribute(attribute) { - if (this.has(attribute)) return; - - const gl = this.gl; - - this.attributeUtils.createAttribute(attribute, gl.ARRAY_BUFFER); - } - - createStorageAttribute(attribute) { - if (this.has(attribute)) return; - - const gl = this.gl; - - this.attributeUtils.createAttribute(attribute, gl.ARRAY_BUFFER); - } - - updateAttribute(attribute) { - this.attributeUtils.updateAttribute(attribute); - } - - destroyAttribute(attribute) { - this.attributeUtils.destroyAttribute(attribute); - } - - updateSize() { - //console.warn( 'Abstract class.' ); - } - - hasFeature(name) { - const keysMatching = Object.keys(GLFeatureName).filter(key => GLFeatureName[key] === name); - - const extensions = this.extensions; - - for (let i = 0; i < keysMatching.length; i++) { - if (extensions.has(keysMatching[i])) return true; - } - - return false; - } - - getMaxAnisotropy() { - return this.capabilities.getMaxAnisotropy(); - } - - copyTextureToTexture(srcTexture, dstTexture, srcRegion, dstPosition, level) { - this.textureUtils.copyTextureToTexture(srcTexture, dstTexture, srcRegion, dstPosition, level); - } - - copyFramebufferToTexture(texture, renderContext, rectangle) { - this.textureUtils.copyFramebufferToTexture(texture, renderContext, rectangle); - } - - _setFramebuffer(descriptor) { - const { gl, state } = this; - - let currentFrameBuffer = null; - - if (descriptor.textures !== null) { - const renderTarget = descriptor.renderTarget; - const renderTargetContextData = this.get(renderTarget); - const { samples, depthBuffer, stencilBuffer } = renderTarget; - - const isCube = renderTarget.isWebGLCubeRenderTarget === true; - - let msaaFb = renderTargetContextData.msaaFrameBuffer; - let depthRenderbuffer = renderTargetContextData.depthRenderbuffer; - - const cacheKey = getCacheKey(descriptor); - - let fb; - - if (isCube) { - renderTargetContextData.cubeFramebuffers || (renderTargetContextData.cubeFramebuffers = {}); - - fb = renderTargetContextData.cubeFramebuffers[cacheKey]; - } else { - renderTargetContextData.framebuffers || (renderTargetContextData.framebuffers = {}); - - fb = renderTargetContextData.framebuffers[cacheKey]; - } - - if (fb === undefined) { - fb = gl.createFramebuffer(); - - state.bindFramebuffer(gl.FRAMEBUFFER, fb); - - const textures = descriptor.textures; - - if (isCube) { - renderTargetContextData.cubeFramebuffers[cacheKey] = fb; - - const { textureGPU } = this.get(textures[0]); - - const cubeFace = this.renderer._activeCubeFace; - - gl.framebufferTexture2D( - gl.FRAMEBUFFER, - gl.COLOR_ATTACHMENT0, - gl.TEXTURE_CUBE_MAP_POSITIVE_X + cubeFace, - textureGPU, - 0, - ); - } else { - renderTargetContextData.framebuffers[cacheKey] = fb; - - for (let i = 0; i < textures.length; i++) { - const texture = textures[i]; - const textureData = this.get(texture); - textureData.renderTarget = descriptor.renderTarget; - textureData.cacheKey = cacheKey; // required for copyTextureToTexture() - - const attachment = gl.COLOR_ATTACHMENT0 + i; - - gl.framebufferTexture2D(gl.FRAMEBUFFER, attachment, gl.TEXTURE_2D, textureData.textureGPU, 0); - } - - state.drawBuffers(descriptor, fb); - } - - if (descriptor.depthTexture !== null) { - const textureData = this.get(descriptor.depthTexture); - const depthStyle = stencilBuffer ? gl.DEPTH_STENCIL_ATTACHMENT : gl.DEPTH_ATTACHMENT; - textureData.renderTarget = descriptor.renderTarget; - textureData.cacheKey = cacheKey; // required for copyTextureToTexture() - - gl.framebufferTexture2D(gl.FRAMEBUFFER, depthStyle, gl.TEXTURE_2D, textureData.textureGPU, 0); - } - } - - if (samples > 0) { - if (msaaFb === undefined) { - const invalidationArray = []; - - msaaFb = gl.createFramebuffer(); - - state.bindFramebuffer(gl.FRAMEBUFFER, msaaFb); - - const msaaRenderbuffers = []; - - const textures = descriptor.textures; - - for (let i = 0; i < textures.length; i++) { - msaaRenderbuffers[i] = gl.createRenderbuffer(); - - gl.bindRenderbuffer(gl.RENDERBUFFER, msaaRenderbuffers[i]); - - invalidationArray.push(gl.COLOR_ATTACHMENT0 + i); - - if (depthBuffer) { - const depthStyle = stencilBuffer ? gl.DEPTH_STENCIL_ATTACHMENT : gl.DEPTH_ATTACHMENT; - invalidationArray.push(depthStyle); - } - - const texture = descriptor.textures[i]; - const textureData = this.get(texture); - - gl.renderbufferStorageMultisample( - gl.RENDERBUFFER, - samples, - textureData.glInternalFormat, - descriptor.width, - descriptor.height, - ); - gl.framebufferRenderbuffer( - gl.FRAMEBUFFER, - gl.COLOR_ATTACHMENT0 + i, - gl.RENDERBUFFER, - msaaRenderbuffers[i], - ); - } - - renderTargetContextData.msaaFrameBuffer = msaaFb; - renderTargetContextData.msaaRenderbuffers = msaaRenderbuffers; - - if (depthRenderbuffer === undefined) { - depthRenderbuffer = gl.createRenderbuffer(); - this.textureUtils.setupRenderBufferStorage(depthRenderbuffer, descriptor); - - renderTargetContextData.depthRenderbuffer = depthRenderbuffer; - - const depthStyle = stencilBuffer ? gl.DEPTH_STENCIL_ATTACHMENT : gl.DEPTH_ATTACHMENT; - invalidationArray.push(depthStyle); - } - - renderTargetContextData.invalidationArray = invalidationArray; - } - - currentFrameBuffer = renderTargetContextData.msaaFrameBuffer; - } else { - currentFrameBuffer = fb; - } - } - - state.bindFramebuffer(gl.FRAMEBUFFER, currentFrameBuffer); - } - - _getVaoKey(index, attributes) { - let key = []; - - if (index !== null) { - const indexData = this.get(index); - - key += ':' + indexData.id; - } - - for (let i = 0; i < attributes.length; i++) { - const attributeData = this.get(attributes[i]); - - key += ':' + attributeData.id; - } - - return key; - } - - _createVao(index, attributes) { - const { gl } = this; - - const vaoGPU = gl.createVertexArray(); - let key = ''; - - let staticVao = true; - - gl.bindVertexArray(vaoGPU); - - if (index !== null) { - const indexData = this.get(index); - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexData.bufferGPU); - - key += ':' + indexData.id; - } - - for (let i = 0; i < attributes.length; i++) { - const attribute = attributes[i]; - const attributeData = this.get(attribute); - - key += ':' + attributeData.id; - - gl.bindBuffer(gl.ARRAY_BUFFER, attributeData.bufferGPU); - gl.enableVertexAttribArray(i); - - if (attribute.isStorageBufferAttribute || attribute.isStorageInstancedBufferAttribute) staticVao = false; - - let stride, offset; - - if (attribute.isInterleavedBufferAttribute === true) { - stride = attribute.data.stride * attributeData.bytesPerElement; - offset = attribute.offset * attributeData.bytesPerElement; - } else { - stride = 0; - offset = 0; - } - - if (attributeData.isInteger) { - gl.vertexAttribIPointer(i, attribute.itemSize, attributeData.type, stride, offset); - } else { - gl.vertexAttribPointer(i, attribute.itemSize, attributeData.type, attribute.normalized, stride, offset); - } - - if (attribute.isInstancedBufferAttribute && !attribute.isInterleavedBufferAttribute) { - gl.vertexAttribDivisor(i, attribute.meshPerAttribute); - } else if (attribute.isInterleavedBufferAttribute && attribute.data.isInstancedInterleavedBuffer) { - gl.vertexAttribDivisor(i, attribute.data.meshPerAttribute); - } - } - - gl.bindBuffer(gl.ARRAY_BUFFER, null); - - this.vaoCache[key] = vaoGPU; - - return { vaoGPU, staticVao }; - } - - _getTransformFeedback(transformBuffers) { - let key = ''; - - for (let i = 0; i < transformBuffers.length; i++) { - key += ':' + transformBuffers[i].id; - } - - let transformFeedbackGPU = this.transformFeedbackCache[key]; - - if (transformFeedbackGPU !== undefined) { - return transformFeedbackGPU; - } - - const { gl } = this; - - transformFeedbackGPU = gl.createTransformFeedback(); - - gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, transformFeedbackGPU); - - for (let i = 0; i < transformBuffers.length; i++) { - const attributeData = transformBuffers[i]; - - gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, i, attributeData.transformBuffer); - } - - gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null); - - this.transformFeedbackCache[key] = transformFeedbackGPU; - - return transformFeedbackGPU; - } - - _setupBindings(bindings, programGPU) { - const gl = this.gl; - - for (const bindGroup of bindings) { - for (const binding of bindGroup.bindings) { - const bindingData = this.get(binding); - const index = bindingData.index; - - if (binding.isUniformsGroup || binding.isUniformBuffer) { - const location = gl.getUniformBlockIndex(programGPU, binding.name); - gl.uniformBlockBinding(programGPU, location, index); - } else if (binding.isSampledTexture) { - const location = gl.getUniformLocation(programGPU, binding.name); - gl.uniform1i(location, index); - } - } - } - } - - _bindUniforms(bindings) { - const { gl, state } = this; - - for (const bindGroup of bindings) { - for (const binding of bindGroup.bindings) { - const bindingData = this.get(binding); - const index = bindingData.index; - - if (binding.isUniformsGroup || binding.isUniformBuffer) { - // TODO USE bindBufferRange to group multiple uniform buffers - state.bindBufferBase(gl.UNIFORM_BUFFER, index, bindingData.bufferGPU); - } else if (binding.isSampledTexture) { - state.bindTexture(bindingData.glTextureType, bindingData.textureGPU, gl.TEXTURE0 + index); - } - } - } - } -} - -export default WebGLBackend; diff --git a/src-testing/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.ts b/src-testing/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.ts deleted file mode 100644 index b1e720647..000000000 --- a/src-testing/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.ts +++ /dev/null @@ -1,812 +0,0 @@ -import { GLSLNodeParser, NodeBuilder, TextureNode, vectorComponents } from '../../../nodes/Nodes.js'; - -import NodeUniformBuffer from '../../common/nodes/NodeUniformBuffer.js'; -import NodeUniformsGroup from '../../common/nodes/NodeUniformsGroup.js'; - -import { - NodeSampledTexture, - NodeSampledCubeTexture, - NodeSampledTexture3D, -} from '../../common/nodes/NodeSampledTexture.js'; - -import { - NoColorSpace, - ByteType, - ShortType, - RGBAIntegerFormat, - RGBIntegerFormat, - RedIntegerFormat, - RGIntegerFormat, - UnsignedByteType, - UnsignedIntType, - UnsignedShortType, - RedFormat, - RGFormat, - IntType, - RGBFormat, - RGBAFormat, - FloatType, -} from '../../../constants.js'; -import { DataTexture } from '../../../textures/DataTexture.js'; - -const glslMethods = { - atan2: 'atan', - textureDimensions: 'textureSize', - equals: 'equal', -}; - -const precisionLib = { - low: 'lowp', - medium: 'mediump', - high: 'highp', -}; - -const supports = { - swizzleAssign: true, - storageBuffer: false, -}; - -const defaultPrecisions = ` -precision highp float; -precision highp int; -precision highp sampler2D; -precision highp sampler3D; -precision highp samplerCube; -precision highp sampler2DArray; - -precision highp usampler2D; -precision highp usampler3D; -precision highp usamplerCube; -precision highp usampler2DArray; - -precision highp isampler2D; -precision highp isampler3D; -precision highp isamplerCube; -precision highp isampler2DArray; - -precision lowp sampler2DShadow; -`; - -class GLSLNodeBuilder extends NodeBuilder { - constructor(object, renderer) { - super(object, renderer, new GLSLNodeParser()); - - this.uniformGroups = {}; - this.transforms = []; - this.extensions = {}; - - this.useComparisonMethod = true; - } - - needsColorSpaceToLinearSRGB(texture) { - return texture.isVideoTexture === true && texture.colorSpace !== NoColorSpace; - } - - getMethod(method) { - return glslMethods[method] || method; - } - - getOutputStructName() { - return ''; - } - - buildFunctionCode(shaderNode) { - const layout = shaderNode.layout; - const flowData = this.flowShaderNode(shaderNode); - - const parameters = []; - - for (const input of layout.inputs) { - parameters.push(this.getType(input.type) + ' ' + input.name); - } - - // - - const code = `${this.getType(layout.type)} ${layout.name}( ${parameters.join(', ')} ) { - - ${flowData.vars} - -${flowData.code} - return ${flowData.result}; - -}`; - - // - - return code; - } - - setupPBO(storageBufferNode) { - const attribute = storageBufferNode.value; - - if (attribute.pbo === undefined) { - const originalArray = attribute.array; - const numElements = attribute.count * attribute.itemSize; - - const { itemSize } = attribute; - - const isInteger = attribute.array.constructor.name.toLowerCase().includes('int'); - - let format = isInteger ? RedIntegerFormat : RedFormat; - - if (itemSize === 2) { - format = isInteger ? RGIntegerFormat : RGFormat; - } else if (itemSize === 3) { - format = isInteger ? RGBIntegerFormat : RGBFormat; - } else if (itemSize === 4) { - format = isInteger ? RGBAIntegerFormat : RGBAFormat; - } - - const typeMap = { - Float32Array: FloatType, - Uint8Array: UnsignedByteType, - Uint16Array: UnsignedShortType, - Uint32Array: UnsignedIntType, - Int8Array: ByteType, - Int16Array: ShortType, - Int32Array: IntType, - Uint8ClampedArray: UnsignedByteType, - }; - - const width = Math.pow(2, Math.ceil(Math.log2(Math.sqrt(numElements / itemSize)))); - let height = Math.ceil(numElements / itemSize / width); - if (width * height * itemSize < numElements) height++; // Ensure enough space - - const newSize = width * height * itemSize; - - const newArray = new originalArray.constructor(newSize); - - newArray.set(originalArray, 0); - - attribute.array = newArray; - - const pboTexture = new DataTexture( - attribute.array, - width, - height, - format, - typeMap[attribute.array.constructor.name] || FloatType, - ); - pboTexture.needsUpdate = true; - pboTexture.isPBOTexture = true; - - const pbo = new TextureNode(pboTexture, null, null); - pbo.setPrecision('high'); - - attribute.pboNode = pbo; - attribute.pbo = pbo.value; - - this.getUniformFromNode(attribute.pboNode, 'texture', this.shaderStage, this.context.label); - } - } - - getPropertyName(node, shaderStage = this.shaderStage) { - if (node.isNodeUniform && node.node.isTextureNode !== true && node.node.isBufferNode !== true) { - return shaderStage.charAt(0) + '_' + node.name; - } - - return super.getPropertyName(node, shaderStage); - } - - generatePBO(storageArrayElementNode) { - const { node, indexNode } = storageArrayElementNode; - const attribute = node.value; - - if (this.renderer.backend.has(attribute)) { - const attributeData = this.renderer.backend.get(attribute); - attributeData.pbo = attribute.pbo; - } - - const nodeUniform = this.getUniformFromNode(attribute.pboNode, 'texture', this.shaderStage, this.context.label); - const textureName = this.getPropertyName(nodeUniform); - - this.increaseUsage(indexNode); // force cache generate to be used as index in x,y - const indexSnippet = indexNode.build(this, 'uint'); - - const elementNodeData = this.getDataFromNode(storageArrayElementNode); - - let propertyName = elementNodeData.propertyName; - - if (propertyName === undefined) { - // property element - - const nodeVar = this.getVarFromNode(storageArrayElementNode); - - propertyName = this.getPropertyName(nodeVar); - - // property size - - const bufferNodeData = this.getDataFromNode(node); - - let propertySizeName = bufferNodeData.propertySizeName; - - if (propertySizeName === undefined) { - propertySizeName = propertyName + 'Size'; - - this.getVarFromNode(node, propertySizeName, 'uint'); - - this.addLineFlowCode( - `${propertySizeName} = uint( textureSize( ${textureName}, 0 ).x )`, - storageArrayElementNode, - ); - - bufferNodeData.propertySizeName = propertySizeName; - } - - // - - const { itemSize } = attribute; - - const channel = '.' + vectorComponents.join('').slice(0, itemSize); - const uvSnippet = `ivec2(${indexSnippet} % ${propertySizeName}, ${indexSnippet} / ${propertySizeName})`; - - const snippet = this.generateTextureLoad(null, textureName, uvSnippet, null, '0'); - - // - - let prefix = 'vec4'; - - if (attribute.pbo.type === UnsignedIntType) { - prefix = 'uvec4'; - } else if (attribute.pbo.type === IntType) { - prefix = 'ivec4'; - } - - this.addLineFlowCode(`${propertyName} = ${prefix}(${snippet})${channel}`, storageArrayElementNode); - - elementNodeData.propertyName = propertyName; - } - - return propertyName; - } - - generateTextureLoad(texture, textureProperty, uvIndexSnippet, depthSnippet, levelSnippet = '0') { - if (depthSnippet) { - return `texelFetch( ${textureProperty}, ivec3( ${uvIndexSnippet}, ${depthSnippet} ), ${levelSnippet} )`; - } else { - return `texelFetch( ${textureProperty}, ${uvIndexSnippet}, ${levelSnippet} )`; - } - } - - generateTexture(texture, textureProperty, uvSnippet, depthSnippet) { - if (texture.isDepthTexture) { - return `texture( ${textureProperty}, ${uvSnippet} ).x`; - } else { - if (depthSnippet) uvSnippet = `vec3( ${uvSnippet}, ${depthSnippet} )`; - - return `texture( ${textureProperty}, ${uvSnippet} )`; - } - } - - generateTextureLevel(texture, textureProperty, uvSnippet, levelSnippet) { - return `textureLod( ${textureProperty}, ${uvSnippet}, ${levelSnippet} )`; - } - - generateTextureBias(texture, textureProperty, uvSnippet, biasSnippet) { - return `texture( ${textureProperty}, ${uvSnippet}, ${biasSnippet} )`; - } - - generateTextureGrad(texture, textureProperty, uvSnippet, gradSnippet) { - return `textureGrad( ${textureProperty}, ${uvSnippet}, ${gradSnippet[0]}, ${gradSnippet[1]} )`; - } - - generateTextureCompare( - texture, - textureProperty, - uvSnippet, - compareSnippet, - depthSnippet, - shaderStage = this.shaderStage, - ) { - if (shaderStage === 'fragment') { - return `texture( ${textureProperty}, vec3( ${uvSnippet}, ${compareSnippet} ) )`; - } else { - console.error( - `WebGPURenderer: THREE.DepthTexture.compareFunction() does not support ${shaderStage} shader.`, - ); - } - } - - getVars(shaderStage) { - const snippets = []; - - const vars = this.vars[shaderStage]; - - if (vars !== undefined) { - for (const variable of vars) { - snippets.push(`${this.getVar(variable.type, variable.name)};`); - } - } - - return snippets.join('\n\t'); - } - - getUniforms(shaderStage) { - const uniforms = this.uniforms[shaderStage]; - - const bindingSnippets = []; - const uniformGroups = {}; - - for (const uniform of uniforms) { - let snippet = null; - let group = false; - - if (uniform.type === 'texture') { - const texture = uniform.node.value; - - let typePrefix = ''; - - if (texture.isDataTexture === true) { - if (texture.type === UnsignedIntType) { - typePrefix = 'u'; - } else if (texture.type === IntType) { - typePrefix = 'i'; - } - } - - if (texture.compareFunction) { - snippet = `sampler2DShadow ${uniform.name};`; - } else if (texture.isDataArrayTexture === true || texture.isCompressedArrayTexture === true) { - snippet = `${typePrefix}sampler2DArray ${uniform.name};`; - } else { - snippet = `${typePrefix}sampler2D ${uniform.name};`; - } - } else if (uniform.type === 'cubeTexture') { - snippet = `samplerCube ${uniform.name};`; - } else if (uniform.type === 'texture3D') { - snippet = `sampler3D ${uniform.name};`; - } else if (uniform.type === 'buffer') { - const bufferNode = uniform.node; - const bufferType = this.getType(bufferNode.bufferType); - const bufferCount = bufferNode.bufferCount; - - const bufferCountSnippet = bufferCount > 0 ? bufferCount : ''; - snippet = `${bufferNode.name} {\n\t${bufferType} ${uniform.name}[${bufferCountSnippet}];\n};\n`; - } else { - const vectorType = this.getVectorType(uniform.type); - - snippet = `${vectorType} ${this.getPropertyName(uniform, shaderStage)};`; - - group = true; - } - - const precision = uniform.node.precision; - - if (precision !== null) { - snippet = precisionLib[precision] + ' ' + snippet; - } - - if (group) { - snippet = '\t' + snippet; - - const groupName = uniform.groupNode.name; - const groupSnippets = uniformGroups[groupName] || (uniformGroups[groupName] = []); - - groupSnippets.push(snippet); - } else { - snippet = 'uniform ' + snippet; - - bindingSnippets.push(snippet); - } - } - - let output = ''; - - for (const name in uniformGroups) { - const groupSnippets = uniformGroups[name]; - - output += this._getGLSLUniformStruct(shaderStage + '_' + name, groupSnippets.join('\n')) + '\n'; - } - - output += bindingSnippets.join('\n'); - - return output; - } - - getTypeFromAttribute(attribute) { - let nodeType = super.getTypeFromAttribute(attribute); - - if (/^[iu]/.test(nodeType) && attribute.gpuType !== IntType) { - let dataAttribute = attribute; - - if (attribute.isInterleavedBufferAttribute) dataAttribute = attribute.data; - - const array = dataAttribute.array; - - if ((array instanceof Uint32Array || array instanceof Int32Array) === false) { - nodeType = nodeType.slice(1); - } - } - - return nodeType; - } - - getAttributes(shaderStage) { - let snippet = ''; - - if (shaderStage === 'vertex' || shaderStage === 'compute') { - const attributes = this.getAttributesArray(); - - let location = 0; - - for (const attribute of attributes) { - snippet += `layout( location = ${location++} ) in ${attribute.type} ${attribute.name};\n`; - } - } - - return snippet; - } - - getStructMembers(struct) { - const snippets = []; - const members = struct.getMemberTypes(); - - for (let i = 0; i < members.length; i++) { - const member = members[i]; - snippets.push(`layout( location = ${i} ) out ${member} m${i};`); - } - - return snippets.join('\n'); - } - - getStructs(shaderStage) { - const snippets = []; - const structs = this.structs[shaderStage]; - - if (structs.length === 0) { - return 'layout( location = 0 ) out vec4 fragColor;\n'; - } - - for (let index = 0, length = structs.length; index < length; index++) { - const struct = structs[index]; - - let snippet = '\n'; - snippet += this.getStructMembers(struct); - snippet += '\n'; - - snippets.push(snippet); - } - - return snippets.join('\n\n'); - } - - getVaryings(shaderStage) { - let snippet = ''; - - const varyings = this.varyings; - - if (shaderStage === 'vertex' || shaderStage === 'compute') { - for (const varying of varyings) { - if (shaderStage === 'compute') varying.needsInterpolation = true; - const type = varying.type; - const flat = type.includes('int') || type.includes('uv') || type.includes('iv') ? 'flat ' : ''; - - snippet += `${flat}${varying.needsInterpolation ? 'out' : '/*out*/'} ${type} ${varying.name};\n`; - } - } else if (shaderStage === 'fragment') { - for (const varying of varyings) { - if (varying.needsInterpolation) { - const type = varying.type; - const flat = type.includes('int') || type.includes('uv') || type.includes('iv') ? 'flat ' : ''; - - snippet += `${flat}in ${type} ${varying.name};\n`; - } - } - } - - return snippet; - } - - getVertexIndex() { - return 'uint( gl_VertexID )'; - } - - getInstanceIndex() { - return 'uint( gl_InstanceID )'; - } - - getInvocationLocalIndex() { - const workgroupSize = this.object.workgroupSize; - - const size = workgroupSize.reduce((acc, curr) => acc * curr, 1); - - return `uint( gl_InstanceID ) % ${size}u`; - } - - getDrawIndex() { - const extensions = this.renderer.backend.extensions; - - if (extensions.has('WEBGL_multi_draw')) { - return 'uint( gl_DrawID )'; - } - - return null; - } - - getFrontFacing() { - return 'gl_FrontFacing'; - } - - getFragCoord() { - return 'gl_FragCoord.xy'; - } - - getFragDepth() { - return 'gl_FragDepth'; - } - - enableExtension(name, behavior, shaderStage = this.shaderStage) { - const map = this.extensions[shaderStage] || (this.extensions[shaderStage] = new Map()); - - if (map.has(name) === false) { - map.set(name, { - name, - behavior, - }); - } - } - - getExtensions(shaderStage) { - const snippets = []; - - if (shaderStage === 'vertex') { - const ext = this.renderer.backend.extensions; - const isBatchedMesh = this.object.isBatchedMesh; - - if (isBatchedMesh && ext.has('WEBGL_multi_draw')) { - this.enableExtension('GL_ANGLE_multi_draw', 'require', shaderStage); - } - } - - const extensions = this.extensions[shaderStage]; - - if (extensions !== undefined) { - for (const { name, behavior } of extensions.values()) { - snippets.push(`#extension ${name} : ${behavior}`); - } - } - - return snippets.join('\n'); - } - - isAvailable(name) { - let result = supports[name]; - - if (result === undefined) { - if (name === 'float32Filterable') { - const extensions = this.renderer.backend.extensions; - - if (extensions.has('OES_texture_float_linear')) { - extensions.get('OES_texture_float_linear'); - result = true; - } else { - result = false; - } - } - - supports[name] = result; - } - - return result; - } - - isFlipY() { - return true; - } - - registerTransform(varyingName, attributeNode) { - this.transforms.push({ varyingName, attributeNode }); - } - - getTransforms(/* shaderStage */) { - const transforms = this.transforms; - - let snippet = ''; - - for (let i = 0; i < transforms.length; i++) { - const transform = transforms[i]; - - const attributeName = this.getPropertyName(transform.attributeNode); - - snippet += `${transform.varyingName} = ${attributeName};\n\t`; - } - - return snippet; - } - - _getGLSLUniformStruct(name, vars) { - return ` -layout( std140 ) uniform ${name} { -${vars} -};`; - } - - _getGLSLVertexCode(shaderData) { - return `#version 300 es - -${this.getSignature()} - -// extensions -${shaderData.extensions} - -// precision -${defaultPrecisions} - -// uniforms -${shaderData.uniforms} - -// varyings -${shaderData.varyings} - -// attributes -${shaderData.attributes} - -// codes -${shaderData.codes} - -void main() { - - // vars - ${shaderData.vars} - - // transforms - ${shaderData.transforms} - - // flow - ${shaderData.flow} - - gl_PointSize = 1.0; - -} -`; - } - - _getGLSLFragmentCode(shaderData) { - return `#version 300 es - -${this.getSignature()} - -// precision -${defaultPrecisions} - -// uniforms -${shaderData.uniforms} - -// varyings -${shaderData.varyings} - -// codes -${shaderData.codes} - -${shaderData.structs} - -void main() { - - // vars - ${shaderData.vars} - - // flow - ${shaderData.flow} - -} -`; - } - - buildCode() { - const shadersData = this.material !== null ? { fragment: {}, vertex: {} } : { compute: {} }; - - this.sortBindingGroups(); - - for (const shaderStage in shadersData) { - let flow = '// code\n\n'; - flow += this.flowCode[shaderStage]; - - const flowNodes = this.flowNodes[shaderStage]; - const mainNode = flowNodes[flowNodes.length - 1]; - - for (const node of flowNodes) { - const flowSlotData = this.getFlowData(node /*, shaderStage*/); - const slotName = node.name; - - if (slotName) { - if (flow.length > 0) flow += '\n'; - - flow += `\t// flow -> ${slotName}\n\t`; - } - - flow += `${flowSlotData.code}\n\t`; - - if (node === mainNode && shaderStage !== 'compute') { - flow += '// result\n\t'; - - if (shaderStage === 'vertex') { - flow += 'gl_Position = '; - flow += `${flowSlotData.result};`; - } else if (shaderStage === 'fragment') { - if (!node.outputNode.isOutputStructNode) { - flow += 'fragColor = '; - flow += `${flowSlotData.result};`; - } - } - } - } - - const stageData = shadersData[shaderStage]; - - stageData.extensions = this.getExtensions(shaderStage); - stageData.uniforms = this.getUniforms(shaderStage); - stageData.attributes = this.getAttributes(shaderStage); - stageData.varyings = this.getVaryings(shaderStage); - stageData.vars = this.getVars(shaderStage); - stageData.structs = this.getStructs(shaderStage); - stageData.codes = this.getCodes(shaderStage); - stageData.transforms = this.getTransforms(shaderStage); - stageData.flow = flow; - } - - if (this.material !== null) { - this.vertexShader = this._getGLSLVertexCode(shadersData.vertex); - this.fragmentShader = this._getGLSLFragmentCode(shadersData.fragment); - } else { - this.computeShader = this._getGLSLVertexCode(shadersData.compute); - } - } - - getUniformFromNode(node, type, shaderStage, name = null) { - const uniformNode = super.getUniformFromNode(node, type, shaderStage, name); - const nodeData = this.getDataFromNode(node, shaderStage, this.globalCache); - - let uniformGPU = nodeData.uniformGPU; - - if (uniformGPU === undefined) { - const group = node.groupNode; - const groupName = group.name; - - const bindings = this.getBindGroupArray(groupName, shaderStage); - - if (type === 'texture') { - uniformGPU = new NodeSampledTexture(uniformNode.name, uniformNode.node, group); - bindings.push(uniformGPU); - } else if (type === 'cubeTexture') { - uniformGPU = new NodeSampledCubeTexture(uniformNode.name, uniformNode.node, group); - bindings.push(uniformGPU); - } else if (type === 'texture3D') { - uniformGPU = new NodeSampledTexture3D(uniformNode.name, uniformNode.node, group); - bindings.push(uniformGPU); - } else if (type === 'buffer') { - node.name = `NodeBuffer_${node.id}`; - uniformNode.name = `buffer${node.id}`; - - const buffer = new NodeUniformBuffer(node, group); - buffer.name = node.name; - - bindings.push(buffer); - - uniformGPU = buffer; - } else { - const uniformsStage = this.uniformGroups[shaderStage] || (this.uniformGroups[shaderStage] = {}); - - let uniformsGroup = uniformsStage[groupName]; - - if (uniformsGroup === undefined) { - uniformsGroup = new NodeUniformsGroup(shaderStage + '_' + groupName, group); - //uniformsGroup.setVisibility( gpuShaderStageLib[ shaderStage ] ); - - uniformsStage[groupName] = uniformsGroup; - - bindings.push(uniformsGroup); - } - - uniformGPU = this.getNodeUniform(uniformNode, type); - - uniformsGroup.addUniform(uniformGPU); - } - - nodeData.uniformGPU = uniformGPU; - } - - return uniformNode; - } -} - -export default GLSLNodeBuilder; diff --git a/src-testing/src/renderers/webgl/WebGLAttributes.d.ts b/src-testing/src/renderers/webgl/WebGLAttributes.d.ts deleted file mode 100644 index 8f4a9757b..000000000 --- a/src-testing/src/renderers/webgl/WebGLAttributes.d.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { BufferAttribute } from "../../core/BufferAttribute.js"; -import { GLBufferAttribute } from "../../core/GLBufferAttribute.js"; -import { InterleavedBufferAttribute } from "../../core/InterleavedBufferAttribute.js"; - -export class WebGLAttributes { - constructor(gl: WebGLRenderingContext | WebGL2RenderingContext); - - get(attribute: BufferAttribute | InterleavedBufferAttribute | GLBufferAttribute): - | { - buffer: WebGLBuffer; - type: number; - bytesPerElement: number; - version: number; - size: number; - } - | undefined; - - remove(attribute: BufferAttribute | InterleavedBufferAttribute | GLBufferAttribute): void; - - update(attribute: BufferAttribute | InterleavedBufferAttribute | GLBufferAttribute, bufferType: number): void; -} diff --git a/src-testing/src/renderers/webgl/WebGLBindingStates.d.ts b/src-testing/src/renderers/webgl/WebGLBindingStates.d.ts deleted file mode 100644 index 0b96de770..000000000 --- a/src-testing/src/renderers/webgl/WebGLBindingStates.d.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { BufferAttribute } from "../../core/BufferAttribute.js"; -import { BufferGeometry } from "../../core/BufferGeometry.js"; -import { Object3D } from "../../core/Object3D.js"; -import { Material } from "../../materials/Material.js"; -import { WebGLAttributes } from "./WebGLAttributes.js"; -import { WebGLProgram } from "./WebGLProgram.js"; - -export class WebGLBindingStates { - constructor(gl: WebGLRenderingContext, attributes: WebGLAttributes); - - setup( - object: Object3D, - material: Material, - program: WebGLProgram, - geometry: BufferGeometry, - index: BufferAttribute, - ): void; - reset(): void; - resetDefaultState(): void; - dispose(): void; - releaseStatesOfGeometry(): void; - releaseStatesOfProgram(): void; - initAttributes(): void; - enableAttribute(attribute: number): void; - disableUnusedAttributes(): void; -} diff --git a/src-testing/src/renderers/webgl/WebGLBufferRenderer.d.ts b/src-testing/src/renderers/webgl/WebGLBufferRenderer.d.ts deleted file mode 100644 index c75f74745..000000000 --- a/src-testing/src/renderers/webgl/WebGLBufferRenderer.d.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { WebGLExtensions } from "./WebGLExtensions.js"; -import { WebGLInfo } from "./WebGLInfo.js"; - -export class WebGLBufferRenderer { - constructor( - gl: WebGLRenderingContext, - extensions: WebGLExtensions, - info: WebGLInfo, - ); - - setMode: (value: any) => void; - render: (start: any, count: number) => void; - renderInstances: (start: any, count: number, primcount: number) => void; - renderMultiDraw: (starts: Int32Array, counts: Int32Array, drawCount: number) => void; - renderMultiDrawInstances: ( - starts: Int32Array, - counts: Int32Array, - drawCount: number, - primcount: Int32Array, - ) => void; -} diff --git a/src-testing/src/renderers/webgl/WebGLCapabilities.d.ts b/src-testing/src/renderers/webgl/WebGLCapabilities.d.ts deleted file mode 100644 index c36a9b0f2..000000000 --- a/src-testing/src/renderers/webgl/WebGLCapabilities.d.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { PixelFormat, TextureDataType } from "../../constants.js"; - -export interface WebGLCapabilitiesParameters { - /** - * shader precision. Can be "highp", "mediump" or "lowp". - */ - precision?: string | undefined; - - /** - * default is false. - */ - logarithmicDepthBuffer?: boolean | undefined; - - /** - * default is false. - */ - reverseDepthBuffer?: boolean | undefined; -} - -export class WebGLCapabilities { - constructor(gl: WebGLRenderingContext, extensions: any, parameters: WebGLCapabilitiesParameters); - - readonly isWebGL2: boolean; - - getMaxAnisotropy: () => number; - getMaxPrecision: (precision: string) => string; - - textureFormatReadable: (textureFormat: PixelFormat) => boolean; - textureTypeReadable: (textureType: TextureDataType) => boolean; - - precision: string; - logarithmicDepthBuffer: boolean; - reverseDepthBuffer: boolean; - - maxTextures: number; - maxVertexTextures: number; - maxTextureSize: number; - maxCubemapSize: number; - - maxAttributes: number; - maxVertexUniforms: number; - maxVaryings: number; - maxFragmentUniforms: number; - - vertexTextures: boolean; - - maxSamples: number; -} diff --git a/src-testing/src/renderers/webgl/WebGLClipping.d.ts b/src-testing/src/renderers/webgl/WebGLClipping.d.ts deleted file mode 100644 index 167a16b35..000000000 --- a/src-testing/src/renderers/webgl/WebGLClipping.d.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Camera } from "../../cameras/Camera.js"; -import { Material } from "../../materials/Material.js"; -import { Plane } from "../../math/Plane.js"; -import { WebGLProperties } from "./WebGLProperties.js"; - -export class WebGLClipping { - constructor(properties: WebGLProperties); - - uniform: { value: any; needsUpdate: boolean }; - - /** - * @default 0 - */ - numPlanes: number; - - /** - * @default 0 - */ - numIntersection: number; - - init(planes: any[], enableLocalClipping: boolean): boolean; - beginShadows(): void; - endShadows(): void; - setGlobalState(planes: Plane[], camera: Camera): void; - setState(material: Material, camera: Camera, useCache: boolean): void; -} diff --git a/src-testing/src/renderers/webgl/WebGLCubeMaps.d.ts b/src-testing/src/renderers/webgl/WebGLCubeMaps.d.ts deleted file mode 100644 index 32cda3f61..000000000 --- a/src-testing/src/renderers/webgl/WebGLCubeMaps.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { WebGLRenderer } from "../WebGLRenderer.js"; - -export class WebGLCubeMaps { - constructor(renderer: WebGLRenderer); - - get(texture: any): any; - dispose(): void; -} diff --git a/src-testing/src/renderers/webgl/WebGLCubeUVMaps.d.ts b/src-testing/src/renderers/webgl/WebGLCubeUVMaps.d.ts deleted file mode 100644 index e94246325..000000000 --- a/src-testing/src/renderers/webgl/WebGLCubeUVMaps.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Texture } from "../../textures/Texture.js"; -import { WebGLRenderer } from "../WebGLRenderer.js"; - -export class WebGLCubeUVMaps { - constructor(renderer: WebGLRenderer); - - get(texture: T): T extends Texture ? Texture : T; - dispose(): void; -} diff --git a/src-testing/src/renderers/webgl/WebGLExtensions.d.ts b/src-testing/src/renderers/webgl/WebGLExtensions.d.ts deleted file mode 100644 index 0f0c0bf4b..000000000 --- a/src-testing/src/renderers/webgl/WebGLExtensions.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -export class WebGLExtensions { - constructor(gl: WebGLRenderingContext); - - has(name: string): boolean; - init(): void; - get(name: string): any; -} diff --git a/src-testing/src/renderers/webgl/WebGLGeometries.d.ts b/src-testing/src/renderers/webgl/WebGLGeometries.d.ts deleted file mode 100644 index 422249f37..000000000 --- a/src-testing/src/renderers/webgl/WebGLGeometries.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { BufferAttribute } from "../../core/BufferAttribute.js"; -import { BufferGeometry } from "../../core/BufferGeometry.js"; -import { Object3D } from "../../core/Object3D.js"; -import { WebGLAttributes } from "./WebGLAttributes.js"; -import { WebGLInfo } from "./WebGLInfo.js"; - -export class WebGLGeometries { - constructor(gl: WebGLRenderingContext, attributes: WebGLAttributes, info: WebGLInfo); - - get(object: Object3D, geometry: BufferGeometry): BufferGeometry; - update(geometry: BufferGeometry): void; - getWireframeAttribute(geometry: BufferGeometry): BufferAttribute; -} diff --git a/src-testing/src/renderers/webgl/WebGLIndexedBufferRenderer.d.ts b/src-testing/src/renderers/webgl/WebGLIndexedBufferRenderer.d.ts deleted file mode 100644 index 8e016e847..000000000 --- a/src-testing/src/renderers/webgl/WebGLIndexedBufferRenderer.d.ts +++ /dev/null @@ -1,15 +0,0 @@ -export class WebGLIndexedBufferRenderer { - constructor(gl: WebGLRenderingContext, extensions: any, info: any); - - setMode: (value: any) => void; - setIndex: (index: any) => void; - render: (start: any, count: number) => void; - renderInstances: (start: any, count: number, primcount: number) => void; - renderMultiDraw: (starts: Int32Array, counts: Int32Array, drawCount: number) => void; - renderMultiDrawInstances: ( - starts: Int32Array, - counts: Int32Array, - drawCount: number, - primcount: Int32Array, - ) => void; -} diff --git a/src-testing/src/renderers/webgl/WebGLInfo.d.ts b/src-testing/src/renderers/webgl/WebGLInfo.d.ts deleted file mode 100644 index 952ff6f9f..000000000 --- a/src-testing/src/renderers/webgl/WebGLInfo.d.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { WebGLProgram } from "./WebGLProgram.js"; - -/** - * An object with a series of statistical information about the graphics board memory and the rendering process. - */ -export class WebGLInfo { - constructor(gl: WebGLRenderingContext); - - /** - * @default true - */ - autoReset: boolean; - - /** - * @default { geometries: 0, textures: 0 } - */ - memory: { - geometries: number; - textures: number; - }; - - /** - * @default null - */ - programs: WebGLProgram[] | null; - - /** - * @default { frame: 0, calls: 0, triangles: 0, points: 0, lines: 0 } - */ - render: { - calls: number; - frame: number; - lines: number; - points: number; - triangles: number; - }; - update(count: number, mode: number, instanceCount: number): void; - reset(): void; -} diff --git a/src-testing/src/renderers/webgl/WebGLLights.d.ts b/src-testing/src/renderers/webgl/WebGLLights.d.ts deleted file mode 100644 index 4c01422e8..000000000 --- a/src-testing/src/renderers/webgl/WebGLLights.d.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { WebGLExtensions } from "./WebGLExtensions.js"; - -export interface WebGLLightsState { - version: number; - - hash: { - directionalLength: number; - pointLength: number; - spotLength: number; - rectAreaLength: number; - hemiLength: number; - - numDirectionalShadows: number; - numPointShadows: number; - numSpotShadows: number; - numSpotMaps: number; - - numLightProbes: number; - }; - - ambient: number[]; - probe: any[]; - directional: any[]; - directionalShadow: any[]; - directionalShadowMap: any[]; - directionalShadowMatrix: any[]; - spot: any[]; - spotShadow: any[]; - spotShadowMap: any[]; - spotShadowMatrix: any[]; - rectArea: any[]; - point: any[]; - pointShadow: any[]; - pointShadowMap: any[]; - pointShadowMatrix: any[]; - hemi: any[]; - numSpotLightShadowsWithMaps: number; - numLightProbes: number; -} - -export class WebGLLights { - constructor(extensions: WebGLExtensions); - - state: WebGLLightsState; - - get(light: any): any; - setup(lights: any): void; - setupView(lights: any, camera: any): void; -} diff --git a/src-testing/src/renderers/webgl/WebGLObjects.d.ts b/src-testing/src/renderers/webgl/WebGLObjects.d.ts deleted file mode 100644 index aeb0356f7..000000000 --- a/src-testing/src/renderers/webgl/WebGLObjects.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -export class WebGLObjects { - constructor(gl: WebGLRenderingContext, geometries: any, attributes: any, info: any); - - update(object: any): any; - dispose(): void; -} diff --git a/src-testing/src/renderers/webgl/WebGLProgram.d.ts b/src-testing/src/renderers/webgl/WebGLProgram.d.ts deleted file mode 100644 index b3e5d6fd8..000000000 --- a/src-testing/src/renderers/webgl/WebGLProgram.d.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { WebGLRenderer } from "../WebGLRenderer.js"; -import { WebGLUniforms } from "./WebGLUniforms.js"; - -export class WebGLProgram { - constructor(renderer: WebGLRenderer, cacheKey: string, parameters: object); - - name: string; - id: number; - cacheKey: string; // unique identifier for this program, used for looking up compiled programs from cache. - - /** - * @default 1 - */ - usedTimes: number; - program: any; - vertexShader: WebGLShader; - fragmentShader: WebGLShader; - /** - * @deprecated Use {@link WebGLProgram#getUniforms getUniforms()} instead. - */ - uniforms: any; - /** - * @deprecated Use {@link WebGLProgram#getAttributes getAttributes()} instead. - */ - attributes: any; - - getUniforms(): WebGLUniforms; - getAttributes(): any; - destroy(): void; -} diff --git a/src-testing/src/renderers/webgl/WebGLPrograms.d.ts b/src-testing/src/renderers/webgl/WebGLPrograms.d.ts deleted file mode 100644 index 8f5999f06..000000000 --- a/src-testing/src/renderers/webgl/WebGLPrograms.d.ts +++ /dev/null @@ -1,233 +0,0 @@ -import { Combine, DepthPackingStrategies, GLSLVersion, Mapping, ShadowMapType, ToneMapping } from "../../constants.js"; -import { Object3D } from "../../core/Object3D.js"; -import { Light } from "../../lights/Light.js"; -import { Material } from "../../materials/Material.js"; -import { Scene } from "../../scenes/Scene.js"; -import { IUniform } from "../shaders/UniformsLib.js"; -import { WebGLRenderer } from "../WebGLRenderer.js"; -import { WebGLBindingStates } from "./WebGLBindingStates.js"; -import { WebGLCapabilities } from "./WebGLCapabilities.js"; -import { WebGLClipping } from "./WebGLClipping.js"; -import { WebGLCubeMaps } from "./WebGLCubeMaps.js"; -import { WebGLExtensions } from "./WebGLExtensions.js"; -import { WebGLLightsState } from "./WebGLLights.js"; -import { WebGLProgram } from "./WebGLProgram.js"; - -export interface WebGLProgramParameters { - shaderID: string; - shaderType: string; - shaderName: string; - - vertexShader: string; - fragmentShader: string; - defines: { [define: string]: string | number | boolean } | undefined; - - customVertexShaderID: string | undefined; - customFragmentShaderID: string | undefined; - - isRawShaderMaterial: boolean; - glslVersion: GLSLVersion | null | undefined; - - precision: "lowp" | "mediump" | "highp"; - - batching: boolean; - batchingColor: boolean; - instancing: boolean; - instancingColor: boolean; - instancingMorph: boolean; - - supportsVertexTextures: boolean; - outputColorSpace: string; - alphaToCoverage: boolean; - - map: boolean; - matcap: boolean; - envMap: boolean; - envMapMode: Mapping | false; - envMapCubeUVHeight: number | null; - aoMap: boolean; - lightMap: boolean; - bumpMap: boolean; - normalMap: boolean; - displacementMap: boolean; - emissiveMap: boolean; - - normalMapObjectSpace: boolean; - normalMapTangentSpace: boolean; - - metalnessMap: boolean; - roughnessMap: boolean; - - anisotropy: boolean; - anisotropyMap: boolean; - - clearcoat: boolean; - clearcoatMap: boolean; - clearcoatNormalMap: boolean; - clearcoatRoughnessMap: boolean; - - dispersion: boolean; - - iridescence: boolean; - iridescenceMap: boolean; - iridescenceThicknessMap: boolean; - - sheen: boolean; - sheenColorMap: boolean; - sheenRoughnessMap: boolean; - - specularMap: boolean; - specularColorMap: boolean; - specularIntensityMap: boolean; - - transmission: boolean; - transmissionMap: boolean; - thicknessMap: boolean; - - gradientMap: boolean; - - opaque: boolean; - - alphaMap: boolean; - alphaTest: boolean; - alphaHash: boolean; - - combine: Combine | undefined; - - // - - mapUv: string | false; - aoMapUv: string | false; - lightMapUv: string | false; - bumpMapUv: string | false; - normalMapUv: string | false; - displacementMapUv: string | false; - emissiveMapUv: string | false; - - metalnessMapUv: string | false; - roughnessMapUv: string | false; - - anisotropyMapUv: string | false; - - clearcoatMapUv: string | false; - clearcoatNormalMapUv: string | false; - clearcoatRoughnessMapUv: string | false; - - iridescenceMapUv: string | false; - iridescenceThicknessMapUv: string | false; - - sheenColorMapUv: string | false; - sheenRoughnessMapUv: string | false; - - specularMapUv: string | false; - specularColorMapUv: string | false; - specularIntensityMapUv: string | false; - - transmissionMapUv: string | false; - thicknessMapUv: string | false; - - alphaMapUv: string | false; - - // - - vertexTangents: boolean; - vertexColors: boolean; - vertexAlphas: boolean; - vertexUv1s: boolean; - vertexUv2s: boolean; - vertexUv3s: boolean; - - pointsUvs: boolean; - - fog: boolean; - useFog: boolean; - fogExp2: boolean; - - flatShading: boolean; - - sizeAttenuation: boolean; - logarithmicDepthBuffer: boolean; - reverseDepthBuffer: boolean; - - skinning: boolean; - - morphTargets: boolean; - morphNormals: boolean; - morphColors: boolean; - morphTargetsCount: number; - morphTextureStride: number; - - numDirLights: number; - numPointLights: number; - numSpotLights: number; - numSpotLightMaps: number; - numRectAreaLights: number; - numHemiLights: number; - - numDirLightShadows: number; - numPointLightShadows: number; - numSpotLightShadows: number; - numSpotLightShadowsWithMaps: number; - - numLightProbes: number; - - numClippingPlanes: number; - numClipIntersection: number; - - dithering: boolean; - - shadowMapEnabled: boolean; - shadowMapType: ShadowMapType; - - toneMapping: ToneMapping; - - decodeVideoTexture: boolean; - decodeVideoTextureEmissive: boolean; - - premultipliedAlpha: boolean; - - doubleSided: boolean; - flipSided: boolean; - - useDepthPacking: boolean; - depthPacking: DepthPackingStrategies | 0; - - index0AttributeName: string | undefined; - - extensionClipCullDistance: boolean; - extensionMultiDraw: boolean; - - rendererExtensionParallelShaderCompile: boolean; - - customProgramCacheKey: string; -} - -export interface WebGLProgramParametersWithUniforms extends WebGLProgramParameters { - uniforms: { [uniform: string]: IUniform }; -} - -export class WebGLPrograms { - constructor( - renderer: WebGLRenderer, - cubemaps: WebGLCubeMaps, - extensions: WebGLExtensions, - capabilities: WebGLCapabilities, - bindingStates: WebGLBindingStates, - clipping: WebGLClipping, - ); - - programs: WebGLProgram[]; - - getParameters( - material: Material, - lights: WebGLLightsState, - shadows: Light[], - scene: Scene, - object: Object3D, - ): WebGLProgramParameters; - - getProgramCacheKey(parameters: WebGLProgramParameters): string; - getUniforms(material: Material): { [uniform: string]: IUniform }; - acquireProgram(parameters: WebGLProgramParametersWithUniforms, cacheKey: string): WebGLProgram; - releaseProgram(program: WebGLProgram): void; -} diff --git a/src-testing/src/renderers/webgl/WebGLProperties.d.ts b/src-testing/src/renderers/webgl/WebGLProperties.d.ts deleted file mode 100644 index adcf01ec9..000000000 --- a/src-testing/src/renderers/webgl/WebGLProperties.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -export class WebGLProperties { - constructor(); - - has: (object: unknown) => boolean; - get: (object: unknown) => unknown; - remove: (object: unknown) => void; - update: (object: unknown, key: unknown, value: unknown) => unknown; - dispose: () => void; -} diff --git a/src-testing/src/renderers/webgl/WebGLRenderLists.d.ts b/src-testing/src/renderers/webgl/WebGLRenderLists.d.ts deleted file mode 100644 index 0f16a4287..000000000 --- a/src-testing/src/renderers/webgl/WebGLRenderLists.d.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { Camera } from "../../cameras/Camera.js"; -import { BufferGeometry } from "../../core/BufferGeometry.js"; -import { Object3D } from "../../core/Object3D.js"; -import { Material } from "../../materials/Material.js"; -import { Group } from "../../objects/Group.js"; -import { Scene } from "../../scenes/Scene.js"; -import { WebGLProgram } from "./WebGLProgram.js"; -import { WebGLProperties } from "./WebGLProperties.js"; - -export interface RenderItem { - id: number; - object: Object3D; - geometry: BufferGeometry | null; - material: Material; - program: WebGLProgram; - groupOrder: number; - renderOrder: number; - z: number; - group: Group | null; -} - -export class WebGLRenderList { - constructor(properties: WebGLProperties); - - /** - * @default [] - */ - opaque: RenderItem[]; - - /** - * @default [] - */ - transparent: RenderItem[]; - - /** - * @default [] - */ - transmissive: RenderItem[]; - - init(): void; - push( - object: Object3D, - geometry: BufferGeometry | null, - material: Material, - groupOrder: number, - z: number, - group: Group | null, - ): void; - unshift( - object: Object3D, - geometry: BufferGeometry | null, - material: Material, - groupOrder: number, - z: number, - group: Group | null, - ): void; - sort(opaqueSort: (a: any, b: any) => number, transparentSort: (a: any, b: any) => number): void; - finish(): void; -} - -export class WebGLRenderLists { - constructor(properties: WebGLProperties); - - dispose(): void; - get(scene: Scene, renderCallDepth: number): WebGLRenderList; -} diff --git a/src-testing/src/renderers/webgl/WebGLShader.d.ts b/src-testing/src/renderers/webgl/WebGLShader.d.ts deleted file mode 100644 index 5704fb88e..000000000 --- a/src-testing/src/renderers/webgl/WebGLShader.d.ts +++ /dev/null @@ -1 +0,0 @@ -export function WebGLShader(gl: WebGLRenderingContext, type: string, string: string): WebGLShader; diff --git a/src-testing/src/renderers/webgl/WebGLShadowMap.d.ts b/src-testing/src/renderers/webgl/WebGLShadowMap.d.ts deleted file mode 100644 index 8368fdee7..000000000 --- a/src-testing/src/renderers/webgl/WebGLShadowMap.d.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { Camera } from "../../cameras/Camera.js"; -import { ShadowMapType } from "../../constants.js"; -import { Light } from "../../lights/Light.js"; -import { Scene } from "../../scenes/Scene.js"; -import { WebGLRenderer } from "../WebGLRenderer.js"; -import { WebGLCapabilities } from "./WebGLCapabilities.js"; -import { WebGLObjects } from "./WebGLObjects.js"; - -export class WebGLShadowMap { - constructor(_renderer: WebGLRenderer, _objects: WebGLObjects, _capabilities: WebGLCapabilities); - - /** - * @default false - */ - enabled: boolean; - - /** - * @default true - */ - autoUpdate: boolean; - - /** - * @default false - */ - needsUpdate: boolean; - - /** - * @default THREE.PCFShadowMap - */ - type: ShadowMapType; - - render(shadowsArray: Light[], scene: Scene, camera: Camera): void; - - /** - * @deprecated Use {@link Material#shadowSide} instead. - */ - cullFace: any; -} diff --git a/src-testing/src/renderers/webgl/WebGLState.d.ts b/src-testing/src/renderers/webgl/WebGLState.d.ts deleted file mode 100644 index 13d4850e9..000000000 --- a/src-testing/src/renderers/webgl/WebGLState.d.ts +++ /dev/null @@ -1,116 +0,0 @@ -import { - Blending, - BlendingDstFactor, - BlendingEquation, - BlendingSrcFactor, - CullFace, - DepthModes, -} from "../../constants.js"; -import { Material } from "../../materials/Material.js"; -import { Vector4 } from "../../math/Vector4.js"; -import { WebGLRenderTarget } from "../WebGLRenderTarget.js"; - -export class WebGLColorBuffer { - constructor(); - - setMask(colorMask: boolean): void; - setLocked(lock: boolean): void; - setClear(r: number, g: number, b: number, a: number, premultipliedAlpha: boolean): void; - reset(): void; -} - -export class WebGLDepthBuffer { - constructor(); - - setTest(depthTest: boolean): void; - setMask(depthMask: boolean): void; - setFunc(depthFunc: DepthModes): void; - setLocked(lock: boolean): void; - setClear(depth: number): void; - reset(): void; -} - -export class WebGLStencilBuffer { - constructor(); - - setTest(stencilTest: boolean): void; - setMask(stencilMask: number): void; - setFunc(stencilFunc: number, stencilRef: number, stencilMask: number): void; - setOp(stencilFail: number, stencilZFail: number, stencilZPass: number): void; - setLocked(lock: boolean): void; - setClear(stencil: number): void; - reset(): void; -} - -export class WebGLState { - constructor(gl: WebGLRenderingContext); - - buffers: { - color: WebGLColorBuffer; - depth: WebGLDepthBuffer; - stencil: WebGLStencilBuffer; - }; - - enable(id: number): void; - disable(id: number): void; - bindFramebuffer(target: number, framebuffer: WebGLFramebuffer | null): void; - drawBuffers(renderTarget: WebGLRenderTarget | null, framebuffer: WebGLFramebuffer | null): void; - useProgram(program: any): boolean; - setBlending( - blending: Blending, - blendEquation?: BlendingEquation, - blendSrc?: BlendingSrcFactor, - blendDst?: BlendingDstFactor, - blendEquationAlpha?: BlendingEquation, - blendSrcAlpha?: BlendingSrcFactor, - blendDstAlpha?: BlendingDstFactor, - premultiplyAlpha?: boolean, - ): void; - setMaterial(material: Material, frontFaceCW: boolean): void; - setFlipSided(flipSided: boolean): void; - setCullFace(cullFace: CullFace): void; - setLineWidth(width: number): void; - setPolygonOffset(polygonoffset: boolean, factor?: number, units?: number): void; - setScissorTest(scissorTest: boolean): void; - activeTexture(webglSlot: number): void; - bindTexture(webglType: number, webglTexture: any): void; - unbindTexture(): void; - // Same interface as https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/compressedTexImage2D - compressedTexImage2D( - target: number, - level: number, - internalformat: number, - width: number, - height: number, - border: number, - data: ArrayBufferView, - ): void; - // Same interface as https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/texImage2D - texImage2D( - target: number, - level: number, - internalformat: number, - width: number, - height: number, - border: number, - format: number, - type: number, - pixels: ArrayBufferView | null, - ): void; - texImage2D(target: number, level: number, internalformat: number, format: number, type: number, source: any): void; - texImage3D( - target: number, - level: number, - internalformat: number, - width: number, - height: number, - depth: number, - border: number, - format: number, - type: number, - pixels: any, - ): void; - scissor(scissor: Vector4): void; - viewport(viewport: Vector4): void; - reset(): void; -} diff --git a/src-testing/src/renderers/webgl/WebGLTextures.d.ts b/src-testing/src/renderers/webgl/WebGLTextures.d.ts deleted file mode 100644 index 031866dee..000000000 --- a/src-testing/src/renderers/webgl/WebGLTextures.d.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { WebGLCapabilities } from "./WebGLCapabilities.js"; -import { WebGLExtensions } from "./WebGLExtensions.js"; -import { WebGLInfo } from "./WebGLInfo.js"; -import { WebGLProperties } from "./WebGLProperties.js"; -import { WebGLState } from "./WebGLState.js"; -import { WebGLUtils } from "./WebGLUtils.js"; - -export class WebGLTextures { - constructor( - gl: WebGLRenderingContext, - extensions: WebGLExtensions, - state: WebGLState, - properties: WebGLProperties, - capabilities: WebGLCapabilities, - utils: WebGLUtils, - info: WebGLInfo, - ); - - allocateTextureUnit(): void; - resetTextureUnits(): void; - setTexture2D(texture: any, slot: number): void; - setTexture2DArray(texture: any, slot: number): void; - setTexture3D(texture: any, slot: number): void; - setTextureCube(texture: any, slot: number): void; - setupRenderTarget(renderTarget: any): void; - updateRenderTargetMipmap(renderTarget: any): void; - updateMultisampleRenderTarget(renderTarget: any): void; - safeSetTexture2D(texture: any, slot: number): void; - safeSetTextureCube(texture: any, slot: number): void; -} diff --git a/src-testing/src/renderers/webgl/WebGLUniforms.d.ts b/src-testing/src/renderers/webgl/WebGLUniforms.d.ts deleted file mode 100644 index 925b5e4bf..000000000 --- a/src-testing/src/renderers/webgl/WebGLUniforms.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { WebGLProgram } from "./WebGLProgram.js"; -import { WebGLTextures } from "./WebGLTextures.js"; - -export class WebGLUniforms { - constructor(gl: WebGLRenderingContext, program: WebGLProgram); - - setValue(gl: WebGLRenderingContext, name: string, value: any, textures: WebGLTextures): void; - setOptional(gl: WebGLRenderingContext, object: any, name: string): void; - - static upload(gl: WebGLRenderingContext, seq: any, values: any[], textures: WebGLTextures): void; - static seqWithValue(seq: any, values: any[]): any[]; -} diff --git a/src-testing/src/renderers/webgl/WebGLUniformsGroups.d.ts b/src-testing/src/renderers/webgl/WebGLUniformsGroups.d.ts deleted file mode 100644 index a5e052c1f..000000000 --- a/src-testing/src/renderers/webgl/WebGLUniformsGroups.d.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { UniformsGroup } from "../../core/UniformsGroup.js"; - -import { WebGLCapabilities } from "./WebGLCapabilities.js"; -import { WebGLInfo } from "./WebGLInfo.js"; -import { WebGLProgram } from "./WebGLProgram.js"; -import { WebGLState } from "./WebGLState.js"; - -export function WebGLUniformsGroups( - gl: WebGLRenderingContext, - info: WebGLInfo, - capabilities: WebGLCapabilities, - state: WebGLState, -): { - dispose: () => void; - update: (uniformsGroup: UniformsGroup, program: WebGLProgram) => void; - bind: (uniformsGroup: UniformsGroup, program: WebGLProgram) => void; -}; diff --git a/src-testing/src/renderers/webgl/WebGLUtils.d.ts b/src-testing/src/renderers/webgl/WebGLUtils.d.ts deleted file mode 100644 index 53011bfe6..000000000 --- a/src-testing/src/renderers/webgl/WebGLUtils.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { CompressedPixelFormat, PixelFormat, TextureDataType } from "../../constants.js"; -import { WebGLExtensions } from "./WebGLExtensions.js"; - -export class WebGLUtils { - constructor( - gl: WebGLRenderingContext | WebGL2RenderingContext, - extensions: WebGLExtensions, - ); - - convert(p: PixelFormat | CompressedPixelFormat | TextureDataType, colorSpace?: string): number | null; -} diff --git a/src-testing/src/renderers/webgpu/WebGPUBackend.ts b/src-testing/src/renderers/webgpu/WebGPUBackend.ts deleted file mode 100644 index 930197a02..000000000 --- a/src-testing/src/renderers/webgpu/WebGPUBackend.ts +++ /dev/null @@ -1,1297 +0,0 @@ -/*// debugger tools -import 'https://greggman.github.io/webgpu-avoid-redundant-state-setting/webgpu-check-redundant-state-setting.js'; -//*/ - -import { - GPUFeatureName, - GPULoadOp, - GPUStoreOp, - GPUIndexFormat, - GPUTextureViewDimension, -} from './utils/WebGPUConstants.js'; - -import WGSLNodeBuilder from './nodes/WGSLNodeBuilder.js'; -import Backend from '../common/Backend.js'; - -import WebGPUUtils from './utils/WebGPUUtils.js'; -import WebGPUAttributeUtils from './utils/WebGPUAttributeUtils.js'; -import WebGPUBindingUtils from './utils/WebGPUBindingUtils.js'; -import WebGPUPipelineUtils from './utils/WebGPUPipelineUtils.js'; -import WebGPUTextureUtils from './utils/WebGPUTextureUtils.js'; - -import { WebGPUCoordinateSystem } from '../../constants.js'; - -// - -class WebGPUBackend extends Backend { - constructor(parameters = {}) { - super(parameters); - - this.isWebGPUBackend = true; - - // some parameters require default values other than "undefined" - this.parameters.alpha = parameters.alpha === undefined ? true : parameters.alpha; - - this.parameters.requiredLimits = parameters.requiredLimits === undefined ? {} : parameters.requiredLimits; - - this.trackTimestamp = parameters.trackTimestamp === true; - - this.device = null; - this.context = null; - this.colorBuffer = null; - this.defaultRenderPassdescriptor = null; - - this.utils = new WebGPUUtils(this); - this.attributeUtils = new WebGPUAttributeUtils(this); - this.bindingUtils = new WebGPUBindingUtils(this); - this.pipelineUtils = new WebGPUPipelineUtils(this); - this.textureUtils = new WebGPUTextureUtils(this); - this.occludedResolveCache = new Map(); - } - - async init(renderer) { - await super.init(renderer); - - // - - const parameters = this.parameters; - - // create the device if it is not passed with parameters - - let device; - - if (parameters.device === undefined) { - const adapterOptions = { - powerPreference: parameters.powerPreference, - }; - - const adapter = await navigator.gpu.requestAdapter(adapterOptions); - - if (adapter === null) { - throw new Error('WebGPUBackend: Unable to create WebGPU adapter.'); - } - - // feature support - - const features = Object.values(GPUFeatureName); - - const supportedFeatures = []; - - for (const name of features) { - if (adapter.features.has(name)) { - supportedFeatures.push(name); - } - } - - const deviceDescriptor = { - requiredFeatures: supportedFeatures, - requiredLimits: parameters.requiredLimits, - }; - - device = await adapter.requestDevice(deviceDescriptor); - } else { - device = parameters.device; - } - - const context = - parameters.context !== undefined ? parameters.context : renderer.domElement.getContext('webgpu'); - - this.device = device; - this.context = context; - - const alphaMode = parameters.alpha ? 'premultiplied' : 'opaque'; - - this.trackTimestamp = this.trackTimestamp && this.hasFeature(GPUFeatureName.TimestampQuery); - - this.context.configure({ - device: this.device, - format: this.utils.getPreferredCanvasFormat(), - usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.COPY_SRC, - alphaMode: alphaMode, - }); - - this.updateSize(); - } - - get coordinateSystem() { - return WebGPUCoordinateSystem; - } - - async getArrayBufferAsync(attribute) { - return await this.attributeUtils.getArrayBufferAsync(attribute); - } - - getContext() { - return this.context; - } - - _getDefaultRenderPassDescriptor() { - let descriptor = this.defaultRenderPassdescriptor; - - if (descriptor === null) { - const renderer = this.renderer; - - descriptor = { - colorAttachments: [ - { - view: null, - }, - ], - }; - - if (this.renderer.depth === true || this.renderer.stencil === true) { - descriptor.depthStencilAttachment = { - view: this.textureUtils.getDepthBuffer(renderer.depth, renderer.stencil).createView(), - }; - } - - const colorAttachment = descriptor.colorAttachments[0]; - - if (this.renderer.samples > 0) { - colorAttachment.view = this.colorBuffer.createView(); - } else { - colorAttachment.resolveTarget = undefined; - } - - this.defaultRenderPassdescriptor = descriptor; - } - - const colorAttachment = descriptor.colorAttachments[0]; - - if (this.renderer.samples > 0) { - colorAttachment.resolveTarget = this.context.getCurrentTexture().createView(); - } else { - colorAttachment.view = this.context.getCurrentTexture().createView(); - } - - return descriptor; - } - - _getRenderPassDescriptor(renderContext) { - const renderTarget = renderContext.renderTarget; - const renderTargetData = this.get(renderTarget); - - let descriptors = renderTargetData.descriptors; - - if ( - descriptors === undefined || - renderTargetData.width !== renderTarget.width || - renderTargetData.height !== renderTarget.height || - renderTargetData.activeMipmapLevel !== renderTarget.activeMipmapLevel || - renderTargetData.samples !== renderTarget.samples - ) { - descriptors = {}; - - renderTargetData.descriptors = descriptors; - - // dispose - - const onDispose = () => { - renderTarget.removeEventListener('dispose', onDispose); - - this.delete(renderTarget); - }; - - renderTarget.addEventListener('dispose', onDispose); - } - - const cacheKey = renderContext.getCacheKey(); - - let descriptor = descriptors[cacheKey]; - - if (descriptor === undefined) { - const textures = renderContext.textures; - const colorAttachments = []; - - for (let i = 0; i < textures.length; i++) { - const textureData = this.get(textures[i]); - - const textureView = textureData.texture.createView({ - baseMipLevel: renderContext.activeMipmapLevel, - mipLevelCount: 1, - baseArrayLayer: renderContext.activeCubeFace, - dimension: GPUTextureViewDimension.TwoD, - }); - - let view, resolveTarget; - - if (textureData.msaaTexture !== undefined) { - view = textureData.msaaTexture.createView(); - resolveTarget = textureView; - } else { - view = textureView; - resolveTarget = undefined; - } - - colorAttachments.push({ - view, - resolveTarget, - loadOp: GPULoadOp.Load, - storeOp: GPUStoreOp.Store, - }); - } - - descriptor = { - colorAttachments, - }; - - if (renderContext.depth) { - const depthTextureData = this.get(renderContext.depthTexture); - - const depthStencilAttachment = { - view: depthTextureData.texture.createView(), - }; - descriptor.depthStencilAttachment = depthStencilAttachment; - } - - descriptors[cacheKey] = descriptor; - - renderTargetData.width = renderTarget.width; - renderTargetData.height = renderTarget.height; - renderTargetData.samples = renderTarget.samples; - renderTargetData.activeMipmapLevel = renderTarget.activeMipmapLevel; - } - - return descriptor; - } - - beginRender(renderContext) { - const renderContextData = this.get(renderContext); - - const device = this.device; - const occlusionQueryCount = renderContext.occlusionQueryCount; - - let occlusionQuerySet; - - if (occlusionQueryCount > 0) { - if (renderContextData.currentOcclusionQuerySet) renderContextData.currentOcclusionQuerySet.destroy(); - if (renderContextData.currentOcclusionQueryBuffer) renderContextData.currentOcclusionQueryBuffer.destroy(); - - // Get a reference to the array of objects with queries. The renderContextData property - // can be changed by another render pass before the buffer.mapAsyc() completes. - renderContextData.currentOcclusionQuerySet = renderContextData.occlusionQuerySet; - renderContextData.currentOcclusionQueryBuffer = renderContextData.occlusionQueryBuffer; - renderContextData.currentOcclusionQueryObjects = renderContextData.occlusionQueryObjects; - - // - - occlusionQuerySet = device.createQuerySet({ type: 'occlusion', count: occlusionQueryCount }); - - renderContextData.occlusionQuerySet = occlusionQuerySet; - renderContextData.occlusionQueryIndex = 0; - renderContextData.occlusionQueryObjects = new Array(occlusionQueryCount); - - renderContextData.lastOcclusionObject = null; - } - - let descriptor; - - if (renderContext.textures === null) { - descriptor = this._getDefaultRenderPassDescriptor(); - } else { - descriptor = this._getRenderPassDescriptor(renderContext); - } - - this.initTimestampQuery(renderContext, descriptor); - - descriptor.occlusionQuerySet = occlusionQuerySet; - - const depthStencilAttachment = descriptor.depthStencilAttachment; - - if (renderContext.textures !== null) { - const colorAttachments = descriptor.colorAttachments; - - for (let i = 0; i < colorAttachments.length; i++) { - const colorAttachment = colorAttachments[i]; - - if (renderContext.clearColor) { - colorAttachment.clearValue = i === 0 ? renderContext.clearColorValue : { r: 0, g: 0, b: 0, a: 1 }; - colorAttachment.loadOp = GPULoadOp.Clear; - colorAttachment.storeOp = GPUStoreOp.Store; - } else { - colorAttachment.loadOp = GPULoadOp.Load; - colorAttachment.storeOp = GPUStoreOp.Store; - } - } - } else { - const colorAttachment = descriptor.colorAttachments[0]; - - if (renderContext.clearColor) { - colorAttachment.clearValue = renderContext.clearColorValue; - colorAttachment.loadOp = GPULoadOp.Clear; - colorAttachment.storeOp = GPUStoreOp.Store; - } else { - colorAttachment.loadOp = GPULoadOp.Load; - colorAttachment.storeOp = GPUStoreOp.Store; - } - } - - // - - if (renderContext.depth) { - if (renderContext.clearDepth) { - depthStencilAttachment.depthClearValue = renderContext.clearDepthValue; - depthStencilAttachment.depthLoadOp = GPULoadOp.Clear; - depthStencilAttachment.depthStoreOp = GPUStoreOp.Store; - } else { - depthStencilAttachment.depthLoadOp = GPULoadOp.Load; - depthStencilAttachment.depthStoreOp = GPUStoreOp.Store; - } - } - - if (renderContext.stencil) { - if (renderContext.clearStencil) { - depthStencilAttachment.stencilClearValue = renderContext.clearStencilValue; - depthStencilAttachment.stencilLoadOp = GPULoadOp.Clear; - depthStencilAttachment.stencilStoreOp = GPUStoreOp.Store; - } else { - depthStencilAttachment.stencilLoadOp = GPULoadOp.Load; - depthStencilAttachment.stencilStoreOp = GPUStoreOp.Store; - } - } - - // - - const encoder = device.createCommandEncoder({ label: 'renderContext_' + renderContext.id }); - const currentPass = encoder.beginRenderPass(descriptor); - - // - - renderContextData.descriptor = descriptor; - renderContextData.encoder = encoder; - renderContextData.currentPass = currentPass; - renderContextData.currentSets = { attributes: {}, bindingGroups: [], pipeline: null, index: null }; - renderContextData.renderBundles = []; - - // - - if (renderContext.viewport) { - this.updateViewport(renderContext); - } - - if (renderContext.scissor) { - const { x, y, width, height } = renderContext.scissorValue; - - currentPass.setScissorRect(x, y, width, height); - } - } - - finishRender(renderContext) { - const renderContextData = this.get(renderContext); - const occlusionQueryCount = renderContext.occlusionQueryCount; - - if (renderContextData.renderBundles.length > 0) { - renderContextData.currentPass.executeBundles(renderContextData.renderBundles); - } - - if (occlusionQueryCount > renderContextData.occlusionQueryIndex) { - renderContextData.currentPass.endOcclusionQuery(); - } - - renderContextData.currentPass.end(); - - if (occlusionQueryCount > 0) { - const bufferSize = occlusionQueryCount * 8; // 8 byte entries for query results - - // - - let queryResolveBuffer = this.occludedResolveCache.get(bufferSize); - - if (queryResolveBuffer === undefined) { - queryResolveBuffer = this.device.createBuffer({ - size: bufferSize, - usage: GPUBufferUsage.QUERY_RESOLVE | GPUBufferUsage.COPY_SRC, - }); - - this.occludedResolveCache.set(bufferSize, queryResolveBuffer); - } - - // - - const readBuffer = this.device.createBuffer({ - size: bufferSize, - usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ, - }); - - // two buffers required here - WebGPU doesn't allow usage of QUERY_RESOLVE & MAP_READ to be combined - renderContextData.encoder.resolveQuerySet( - renderContextData.occlusionQuerySet, - 0, - occlusionQueryCount, - queryResolveBuffer, - 0, - ); - renderContextData.encoder.copyBufferToBuffer(queryResolveBuffer, 0, readBuffer, 0, bufferSize); - - renderContextData.occlusionQueryBuffer = readBuffer; - - // - - this.resolveOccludedAsync(renderContext); - } - - this.prepareTimestampBuffer(renderContext, renderContextData.encoder); - - this.device.queue.submit([renderContextData.encoder.finish()]); - - // - - if (renderContext.textures !== null) { - const textures = renderContext.textures; - - for (let i = 0; i < textures.length; i++) { - const texture = textures[i]; - - if (texture.generateMipmaps === true) { - this.textureUtils.generateMipmaps(texture); - } - } - } - } - - isOccluded(renderContext, object) { - const renderContextData = this.get(renderContext); - - return renderContextData.occluded && renderContextData.occluded.has(object); - } - - async resolveOccludedAsync(renderContext) { - const renderContextData = this.get(renderContext); - - // handle occlusion query results - - const { currentOcclusionQueryBuffer, currentOcclusionQueryObjects } = renderContextData; - - if (currentOcclusionQueryBuffer && currentOcclusionQueryObjects) { - const occluded = new WeakSet(); - - renderContextData.currentOcclusionQueryObjects = null; - renderContextData.currentOcclusionQueryBuffer = null; - - await currentOcclusionQueryBuffer.mapAsync(GPUMapMode.READ); - - const buffer = currentOcclusionQueryBuffer.getMappedRange(); - const results = new BigUint64Array(buffer); - - for (let i = 0; i < currentOcclusionQueryObjects.length; i++) { - if (results[i] !== BigInt(0)) { - occluded.add(currentOcclusionQueryObjects[i]); - } - } - - currentOcclusionQueryBuffer.destroy(); - - renderContextData.occluded = occluded; - } - } - - updateViewport(renderContext) { - const { currentPass } = this.get(renderContext); - const { x, y, width, height, minDepth, maxDepth } = renderContext.viewportValue; - - currentPass.setViewport(x, y, width, height, minDepth, maxDepth); - } - - clear(color, depth, stencil, renderTargetData = null) { - const device = this.device; - const renderer = this.renderer; - - let colorAttachments = []; - - let depthStencilAttachment; - let clearValue; - - let supportsDepth; - let supportsStencil; - - if (color) { - const clearColor = this.getClearColor(); - - if (this.renderer.alpha === true) { - // premultiply alpha - - const a = clearColor.a; - - clearValue = { r: clearColor.r * a, g: clearColor.g * a, b: clearColor.b * a, a: a }; - } else { - clearValue = { r: clearColor.r, g: clearColor.g, b: clearColor.b, a: clearColor.a }; - } - } - - if (renderTargetData === null) { - supportsDepth = renderer.depth; - supportsStencil = renderer.stencil; - - const descriptor = this._getDefaultRenderPassDescriptor(); - - if (color) { - colorAttachments = descriptor.colorAttachments; - - const colorAttachment = colorAttachments[0]; - - colorAttachment.clearValue = clearValue; - colorAttachment.loadOp = GPULoadOp.Clear; - colorAttachment.storeOp = GPUStoreOp.Store; - } - - if (supportsDepth || supportsStencil) { - depthStencilAttachment = descriptor.depthStencilAttachment; - } - } else { - supportsDepth = renderTargetData.depth; - supportsStencil = renderTargetData.stencil; - - if (color) { - for (const texture of renderTargetData.textures) { - const textureData = this.get(texture); - const textureView = textureData.texture.createView(); - - let view, resolveTarget; - - if (textureData.msaaTexture !== undefined) { - view = textureData.msaaTexture.createView(); - resolveTarget = textureView; - } else { - view = textureView; - resolveTarget = undefined; - } - - colorAttachments.push({ - view, - resolveTarget, - clearValue, - loadOp: GPULoadOp.Clear, - storeOp: GPUStoreOp.Store, - }); - } - } - - if (supportsDepth || supportsStencil) { - const depthTextureData = this.get(renderTargetData.depthTexture); - - depthStencilAttachment = { - view: depthTextureData.texture.createView(), - }; - } - } - - // - - if (supportsDepth) { - if (depth) { - depthStencilAttachment.depthLoadOp = GPULoadOp.Clear; - depthStencilAttachment.depthClearValue = renderer.getClearDepth(); - depthStencilAttachment.depthStoreOp = GPUStoreOp.Store; - } else { - depthStencilAttachment.depthLoadOp = GPULoadOp.Load; - depthStencilAttachment.depthStoreOp = GPUStoreOp.Store; - } - } - - // - - if (supportsStencil) { - if (stencil) { - depthStencilAttachment.stencilLoadOp = GPULoadOp.Clear; - depthStencilAttachment.stencilClearValue = renderer.getClearStencil(); - depthStencilAttachment.stencilStoreOp = GPUStoreOp.Store; - } else { - depthStencilAttachment.stencilLoadOp = GPULoadOp.Load; - depthStencilAttachment.stencilStoreOp = GPUStoreOp.Store; - } - } - - // - - const encoder = device.createCommandEncoder({}); - const currentPass = encoder.beginRenderPass({ - colorAttachments, - depthStencilAttachment, - }); - - currentPass.end(); - - device.queue.submit([encoder.finish()]); - } - - // compute - - beginCompute(computeGroup) { - const groupGPU = this.get(computeGroup); - - const descriptor = {}; - - this.initTimestampQuery(computeGroup, descriptor); - - groupGPU.cmdEncoderGPU = this.device.createCommandEncoder(); - - groupGPU.passEncoderGPU = groupGPU.cmdEncoderGPU.beginComputePass(descriptor); - } - - compute(computeGroup, computeNode, bindings, pipeline) { - const { passEncoderGPU } = this.get(computeGroup); - - // pipeline - - const pipelineGPU = this.get(pipeline).pipeline; - passEncoderGPU.setPipeline(pipelineGPU); - - // bind groups - - for (let i = 0, l = bindings.length; i < l; i++) { - const bindGroup = bindings[i]; - const bindingsData = this.get(bindGroup); - - passEncoderGPU.setBindGroup(i, bindingsData.group); - } - - const maxComputeWorkgroupsPerDimension = this.device.limits.maxComputeWorkgroupsPerDimension; - - const computeNodeData = this.get(computeNode); - - if (computeNodeData.dispatchSize === undefined) computeNodeData.dispatchSize = { x: 0, y: 1, z: 1 }; - - const { dispatchSize } = computeNodeData; - - if (computeNode.dispatchCount > maxComputeWorkgroupsPerDimension) { - dispatchSize.x = Math.min(computeNode.dispatchCount, maxComputeWorkgroupsPerDimension); - dispatchSize.y = Math.ceil(computeNode.dispatchCount / maxComputeWorkgroupsPerDimension); - } else { - dispatchSize.x = computeNode.dispatchCount; - } - - passEncoderGPU.dispatchWorkgroups(dispatchSize.x, dispatchSize.y, dispatchSize.z); - } - - finishCompute(computeGroup) { - const groupData = this.get(computeGroup); - - groupData.passEncoderGPU.end(); - - this.prepareTimestampBuffer(computeGroup, groupData.cmdEncoderGPU); - - this.device.queue.submit([groupData.cmdEncoderGPU.finish()]); - } - - async waitForGPU() { - await this.device.queue.onSubmittedWorkDone(); - } - - // render object - - draw(renderObject, info) { - const { object, context, pipeline } = renderObject; - const bindings = renderObject.getBindings(); - const renderContextData = this.get(context); - const pipelineGPU = this.get(pipeline).pipeline; - const currentSets = renderContextData.currentSets; - const passEncoderGPU = renderContextData.currentPass; - - const drawParams = renderObject.getDrawParameters(); - - if (drawParams === null) return; - - // pipeline - - if (currentSets.pipeline !== pipelineGPU) { - passEncoderGPU.setPipeline(pipelineGPU); - - currentSets.pipeline = pipelineGPU; - } - - // bind groups - - const currentBindingGroups = currentSets.bindingGroups; - - for (let i = 0, l = bindings.length; i < l; i++) { - const bindGroup = bindings[i]; - const bindingsData = this.get(bindGroup); - - if (currentBindingGroups[bindGroup.index] !== bindGroup.id) { - passEncoderGPU.setBindGroup(bindGroup.index, bindingsData.group); - currentBindingGroups[bindGroup.index] = bindGroup.id; - } - } - - // attributes - - const index = renderObject.getIndex(); - - const hasIndex = index !== null; - - // index - - if (hasIndex === true) { - if (currentSets.index !== index) { - const buffer = this.get(index).buffer; - const indexFormat = index.array instanceof Uint16Array ? GPUIndexFormat.Uint16 : GPUIndexFormat.Uint32; - - passEncoderGPU.setIndexBuffer(buffer, indexFormat); - - currentSets.index = index; - } - } - - // vertex buffers - - const vertexBuffers = renderObject.getVertexBuffers(); - - for (let i = 0, l = vertexBuffers.length; i < l; i++) { - const vertexBuffer = vertexBuffers[i]; - - if (currentSets.attributes[i] !== vertexBuffer) { - const buffer = this.get(vertexBuffer).buffer; - passEncoderGPU.setVertexBuffer(i, buffer); - - currentSets.attributes[i] = vertexBuffer; - } - } - - // occlusion queries - handle multiple consecutive draw calls for an object - - if (renderContextData.occlusionQuerySet !== undefined) { - const lastObject = renderContextData.lastOcclusionObject; - - if (lastObject !== object) { - if (lastObject !== null && lastObject.occlusionTest === true) { - passEncoderGPU.endOcclusionQuery(); - renderContextData.occlusionQueryIndex++; - } - - if (object.occlusionTest === true) { - passEncoderGPU.beginOcclusionQuery(renderContextData.occlusionQueryIndex); - renderContextData.occlusionQueryObjects[renderContextData.occlusionQueryIndex] = object; - } - - renderContextData.lastOcclusionObject = object; - } - } - - // draw - - if (object.isBatchedMesh === true) { - const starts = object._multiDrawStarts; - const counts = object._multiDrawCounts; - const drawCount = object._multiDrawCount; - const drawInstances = object._multiDrawInstances; - - const bytesPerElement = hasIndex ? index.array.BYTES_PER_ELEMENT : 1; - - for (let i = 0; i < drawCount; i++) { - const count = drawInstances ? drawInstances[i] : 1; - const firstInstance = count > 1 ? 0 : i; - - passEncoderGPU.drawIndexed(counts[i], count, starts[i] / bytesPerElement, 0, firstInstance); - } - } else if (hasIndex === true) { - const { vertexCount: indexCount, instanceCount, firstVertex: firstIndex } = drawParams; - - const indirect = renderObject.getIndirect(); - - if (indirect !== null) { - const buffer = this.get(indirect).buffer; - - passEncoderGPU.drawIndexedIndirect(buffer, 0); - } else { - passEncoderGPU.drawIndexed(indexCount, instanceCount, firstIndex, 0, 0); - } - - info.update(object, indexCount, instanceCount); - } else { - const { vertexCount, instanceCount, firstVertex } = drawParams; - - const indirect = renderObject.getIndirect(); - - if (indirect !== null) { - const buffer = this.get(indirect).buffer; - - passEncoderGPU.drawIndirect(buffer, 0); - } else { - passEncoderGPU.draw(vertexCount, instanceCount, firstVertex, 0); - } - - info.update(object, vertexCount, instanceCount); - } - } - - // cache key - - needsRenderUpdate(renderObject) { - const data = this.get(renderObject); - - const { object, material } = renderObject; - - const utils = this.utils; - - const sampleCount = utils.getSampleCountRenderContext(renderObject.context); - const colorSpace = utils.getCurrentColorSpace(renderObject.context); - const colorFormat = utils.getCurrentColorFormat(renderObject.context); - const depthStencilFormat = utils.getCurrentDepthStencilFormat(renderObject.context); - const primitiveTopology = utils.getPrimitiveTopology(object, material); - - let needsUpdate = false; - - if ( - data.material !== material || - data.materialVersion !== material.version || - data.transparent !== material.transparent || - data.blending !== material.blending || - data.premultipliedAlpha !== material.premultipliedAlpha || - data.blendSrc !== material.blendSrc || - data.blendDst !== material.blendDst || - data.blendEquation !== material.blendEquation || - data.blendSrcAlpha !== material.blendSrcAlpha || - data.blendDstAlpha !== material.blendDstAlpha || - data.blendEquationAlpha !== material.blendEquationAlpha || - data.colorWrite !== material.colorWrite || - data.depthWrite !== material.depthWrite || - data.depthTest !== material.depthTest || - data.depthFunc !== material.depthFunc || - data.stencilWrite !== material.stencilWrite || - data.stencilFunc !== material.stencilFunc || - data.stencilFail !== material.stencilFail || - data.stencilZFail !== material.stencilZFail || - data.stencilZPass !== material.stencilZPass || - data.stencilFuncMask !== material.stencilFuncMask || - data.stencilWriteMask !== material.stencilWriteMask || - data.side !== material.side || - data.alphaToCoverage !== material.alphaToCoverage || - data.sampleCount !== sampleCount || - data.colorSpace !== colorSpace || - data.colorFormat !== colorFormat || - data.depthStencilFormat !== depthStencilFormat || - data.primitiveTopology !== primitiveTopology || - data.clippingContextCacheKey !== renderObject.clippingContext.cacheKey - ) { - data.material = material; - data.materialVersion = material.version; - data.transparent = material.transparent; - data.blending = material.blending; - data.premultipliedAlpha = material.premultipliedAlpha; - data.blendSrc = material.blendSrc; - data.blendDst = material.blendDst; - data.blendEquation = material.blendEquation; - data.blendSrcAlpha = material.blendSrcAlpha; - data.blendDstAlpha = material.blendDstAlpha; - data.blendEquationAlpha = material.blendEquationAlpha; - data.colorWrite = material.colorWrite; - data.depthWrite = material.depthWrite; - data.depthTest = material.depthTest; - data.depthFunc = material.depthFunc; - data.stencilWrite = material.stencilWrite; - data.stencilFunc = material.stencilFunc; - data.stencilFail = material.stencilFail; - data.stencilZFail = material.stencilZFail; - data.stencilZPass = material.stencilZPass; - data.stencilFuncMask = material.stencilFuncMask; - data.stencilWriteMask = material.stencilWriteMask; - data.side = material.side; - data.alphaToCoverage = material.alphaToCoverage; - data.sampleCount = sampleCount; - data.colorSpace = colorSpace; - data.colorFormat = colorFormat; - data.depthStencilFormat = depthStencilFormat; - data.primitiveTopology = primitiveTopology; - data.clippingContextCacheKey = renderObject.clippingContext.cacheKey; - - needsUpdate = true; - } - - return needsUpdate; - } - - getRenderCacheKey(renderObject) { - const { object, material } = renderObject; - - const utils = this.utils; - const renderContext = renderObject.context; - - return [ - material.transparent, - material.blending, - material.premultipliedAlpha, - material.blendSrc, - material.blendDst, - material.blendEquation, - material.blendSrcAlpha, - material.blendDstAlpha, - material.blendEquationAlpha, - material.colorWrite, - material.depthWrite, - material.depthTest, - material.depthFunc, - material.stencilWrite, - material.stencilFunc, - material.stencilFail, - material.stencilZFail, - material.stencilZPass, - material.stencilFuncMask, - material.stencilWriteMask, - material.side, - utils.getSampleCountRenderContext(renderContext), - utils.getCurrentColorSpace(renderContext), - utils.getCurrentColorFormat(renderContext), - utils.getCurrentDepthStencilFormat(renderContext), - utils.getPrimitiveTopology(object, material), - renderObject.getGeometryCacheKey(), - renderObject.clippingContext.cacheKey, - ].join(); - } - - // textures - - createSampler(texture) { - this.textureUtils.createSampler(texture); - } - - destroySampler(texture) { - this.textureUtils.destroySampler(texture); - } - - createDefaultTexture(texture) { - this.textureUtils.createDefaultTexture(texture); - } - - createTexture(texture, options) { - this.textureUtils.createTexture(texture, options); - } - - updateTexture(texture, options) { - this.textureUtils.updateTexture(texture, options); - } - - generateMipmaps(texture) { - this.textureUtils.generateMipmaps(texture); - } - - destroyTexture(texture) { - this.textureUtils.destroyTexture(texture); - } - - copyTextureToBuffer(texture, x, y, width, height, faceIndex) { - return this.textureUtils.copyTextureToBuffer(texture, x, y, width, height, faceIndex); - } - - initTimestampQuery(renderContext, descriptor) { - if (!this.trackTimestamp) return; - - const renderContextData = this.get(renderContext); - - if (!renderContextData.timeStampQuerySet) { - // Create a GPUQuerySet which holds 2 timestamp query results: one for the - // beginning and one for the end of compute pass execution. - const timeStampQuerySet = this.device.createQuerySet({ type: 'timestamp', count: 2 }); - - const timestampWrites = { - querySet: timeStampQuerySet, - beginningOfPassWriteIndex: 0, // Write timestamp in index 0 when pass begins. - endOfPassWriteIndex: 1, // Write timestamp in index 1 when pass ends. - }; - - Object.assign(descriptor, { - timestampWrites, - }); - - renderContextData.timeStampQuerySet = timeStampQuerySet; - } - } - - // timestamp utils - - prepareTimestampBuffer(renderContext, encoder) { - if (!this.trackTimestamp) return; - - const renderContextData = this.get(renderContext); - - const size = 2 * BigInt64Array.BYTES_PER_ELEMENT; - - if (renderContextData.currentTimestampQueryBuffers === undefined) { - renderContextData.currentTimestampQueryBuffers = { - resolveBuffer: this.device.createBuffer({ - label: 'timestamp resolve buffer', - size: size, - usage: GPUBufferUsage.QUERY_RESOLVE | GPUBufferUsage.COPY_SRC, - }), - resultBuffer: this.device.createBuffer({ - label: 'timestamp result buffer', - size: size, - usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ, - }), - isMappingPending: false, - }; - } - - const { resolveBuffer, resultBuffer, isMappingPending } = renderContextData.currentTimestampQueryBuffers; - - if (isMappingPending === true) return; - - encoder.resolveQuerySet(renderContextData.timeStampQuerySet, 0, 2, resolveBuffer, 0); - encoder.copyBufferToBuffer(resolveBuffer, 0, resultBuffer, 0, size); - } - - async resolveTimestampAsync(renderContext, type = 'render') { - if (!this.trackTimestamp) return; - - const renderContextData = this.get(renderContext); - - if (renderContextData.currentTimestampQueryBuffers === undefined) return; - - const { resultBuffer, isMappingPending } = renderContextData.currentTimestampQueryBuffers; - - if (isMappingPending === true) return; - - renderContextData.currentTimestampQueryBuffers.isMappingPending = true; - - resultBuffer.mapAsync(GPUMapMode.READ).then(() => { - const times = new BigUint64Array(resultBuffer.getMappedRange()); - const duration = Number(times[1] - times[0]) / 1000000; - - this.renderer.info.updateTimestamp(type, duration); - - resultBuffer.unmap(); - - renderContextData.currentTimestampQueryBuffers.isMappingPending = false; - }); - } - - // node builder - - createNodeBuilder(object, renderer) { - return new WGSLNodeBuilder(object, renderer); - } - - // program - - createProgram(program) { - const programGPU = this.get(program); - - programGPU.module = { - module: this.device.createShaderModule({ code: program.code, label: program.stage }), - entryPoint: 'main', - }; - } - - destroyProgram(program) { - this.delete(program); - } - - // pipelines - - createRenderPipeline(renderObject, promises) { - this.pipelineUtils.createRenderPipeline(renderObject, promises); - } - - createComputePipeline(computePipeline, bindings) { - this.pipelineUtils.createComputePipeline(computePipeline, bindings); - } - - beginBundle(renderContext) { - const renderContextData = this.get(renderContext); - - renderContextData._currentPass = renderContextData.currentPass; - renderContextData._currentSets = renderContextData.currentSets; - - renderContextData.currentSets = { attributes: {}, bindingGroups: [], pipeline: null, index: null }; - renderContextData.currentPass = this.pipelineUtils.createBundleEncoder(renderContext); - } - - finishBundle(renderContext, bundle) { - const renderContextData = this.get(renderContext); - - const bundleEncoder = renderContextData.currentPass; - const bundleGPU = bundleEncoder.finish(); - - this.get(bundle).bundleGPU = bundleGPU; - - // restore render pass state - - renderContextData.currentSets = renderContextData._currentSets; - renderContextData.currentPass = renderContextData._currentPass; - } - - addBundle(renderContext, bundle) { - const renderContextData = this.get(renderContext); - - renderContextData.renderBundles.push(this.get(bundle).bundleGPU); - } - - // bindings - - createBindings(bindGroup) { - this.bindingUtils.createBindings(bindGroup); - } - - updateBindings(bindGroup) { - this.bindingUtils.createBindings(bindGroup); - } - - updateBinding(binding) { - this.bindingUtils.updateBinding(binding); - } - - // attributes - - createIndexAttribute(attribute) { - this.attributeUtils.createAttribute( - attribute, - GPUBufferUsage.INDEX | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST, - ); - } - - createAttribute(attribute) { - this.attributeUtils.createAttribute( - attribute, - GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST, - ); - } - - createStorageAttribute(attribute) { - this.attributeUtils.createAttribute( - attribute, - GPUBufferUsage.STORAGE | GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST, - ); - } - - createIndirectStorageAttribute(attribute) { - this.attributeUtils.createAttribute( - attribute, - GPUBufferUsage.STORAGE | GPUBufferUsage.INDIRECT | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST, - ); - } - - updateAttribute(attribute) { - this.attributeUtils.updateAttribute(attribute); - } - - destroyAttribute(attribute) { - this.attributeUtils.destroyAttribute(attribute); - } - - // canvas - - updateSize() { - this.colorBuffer = this.textureUtils.getColorBuffer(); - this.defaultRenderPassdescriptor = null; - } - - // utils public - - getMaxAnisotropy() { - return 16; - } - - hasFeature(name) { - return this.device.features.has(name); - } - - copyTextureToTexture(srcTexture, dstTexture, srcRegion = null, dstPosition = null, level = 0) { - let dstX = 0; - let dstY = 0; - let dstLayer = 0; - - let srcX = 0; - let srcY = 0; - let srcLayer = 0; - - let srcWidth = srcTexture.image.width; - let srcHeight = srcTexture.image.height; - - if (srcRegion !== null) { - srcX = srcRegion.x; - srcY = srcRegion.y; - srcLayer = srcRegion.z || 0; - srcWidth = srcRegion.width; - srcHeight = srcRegion.height; - } - - if (dstPosition !== null) { - dstX = dstPosition.x; - dstY = dstPosition.y; - dstLayer = dstPosition.z || 0; - } - - const encoder = this.device.createCommandEncoder({ - label: 'copyTextureToTexture_' + srcTexture.id + '_' + dstTexture.id, - }); - - const sourceGPU = this.get(srcTexture).texture; - const destinationGPU = this.get(dstTexture).texture; - - encoder.copyTextureToTexture( - { - texture: sourceGPU, - mipLevel: level, - origin: { x: srcX, y: srcY, z: srcLayer }, - }, - { - texture: destinationGPU, - mipLevel: level, - origin: { x: dstX, y: dstY, z: dstLayer }, - }, - [srcWidth, srcHeight, 1], - ); - - this.device.queue.submit([encoder.finish()]); - } - - copyFramebufferToTexture(texture, renderContext, rectangle) { - const renderContextData = this.get(renderContext); - - const { encoder, descriptor } = renderContextData; - - let sourceGPU = null; - - if (renderContext.renderTarget) { - if (texture.isDepthTexture) { - sourceGPU = this.get(renderContext.depthTexture).texture; - } else { - sourceGPU = this.get(renderContext.textures[0]).texture; - } - } else { - if (texture.isDepthTexture) { - sourceGPU = this.textureUtils.getDepthBuffer(renderContext.depth, renderContext.stencil); - } else { - sourceGPU = this.context.getCurrentTexture(); - } - } - - const destinationGPU = this.get(texture).texture; - - if (sourceGPU.format !== destinationGPU.format) { - console.error( - 'WebGPUBackend: copyFramebufferToTexture: Source and destination formats do not match.', - sourceGPU.format, - destinationGPU.format, - ); - - return; - } - - renderContextData.currentPass.end(); - - encoder.copyTextureToTexture( - { - texture: sourceGPU, - origin: { x: rectangle.x, y: rectangle.y, z: 0 }, - }, - { - texture: destinationGPU, - }, - [rectangle.z, rectangle.w], - ); - - if (texture.generateMipmaps) this.textureUtils.generateMipmaps(texture); - - for (let i = 0; i < descriptor.colorAttachments.length; i++) { - descriptor.colorAttachments[i].loadOp = GPULoadOp.Load; - } - - if (renderContext.depth) descriptor.depthStencilAttachment.depthLoadOp = GPULoadOp.Load; - if (renderContext.stencil) descriptor.depthStencilAttachment.stencilLoadOp = GPULoadOp.Load; - - renderContextData.currentPass = encoder.beginRenderPass(descriptor); - renderContextData.currentSets = { attributes: {}, bindingGroups: [], pipeline: null, index: null }; - } -} - -export default WebGPUBackend; diff --git a/src-testing/src/renderers/webgpu/WebGPURenderer.Nodes.d.ts b/src-testing/src/renderers/webgpu/WebGPURenderer.Nodes.d.ts deleted file mode 100644 index b9eb0ddeb..000000000 --- a/src-testing/src/renderers/webgpu/WebGPURenderer.Nodes.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -import Renderer, { RendererParameters } from "../common/Renderer.js"; -import { WebGPUBackendParameters } from "./WebGPUBackend.js"; - -export interface WebGPURendererParameters extends RendererParameters, WebGPUBackendParameters { - forceWebGL?: boolean | undefined; -} - -export default class WebGPURenderer extends Renderer { - readonly isWebGPURenderer: true; - - constructor(parameters?: WebGPURendererParameters); -} diff --git a/src-testing/src/renderers/webgpu/WebGPURenderer.ts b/src-testing/src/renderers/webgpu/WebGPURenderer.ts deleted file mode 100644 index 1b4e424f4..000000000 --- a/src-testing/src/renderers/webgpu/WebGPURenderer.ts +++ /dev/null @@ -1,46 +0,0 @@ -import Renderer from '../common/Renderer.js'; -import WebGLBackend from '../webgl-fallback/WebGLBackend.js'; -import WebGPUBackend from './WebGPUBackend.js'; -import StandardNodeLibrary from './nodes/StandardNodeLibrary.js'; -/* -const debugHandler = { - - get: function ( target, name ) { - - // Add |update - if ( /^(create|destroy)/.test( name ) ) console.log( 'WebGPUBackend.' + name ); - - return target[ name ]; - - } - -}; -*/ -class WebGPURenderer extends Renderer { - constructor(parameters = {}) { - let BackendClass; - - if (parameters.forceWebGL) { - BackendClass = WebGLBackend; - } else { - BackendClass = WebGPUBackend; - - parameters.getFallback = () => { - console.warn('THREE.WebGPURenderer: WebGPU is not available, running under WebGL2 backend.'); - - return new WebGLBackend(parameters); - }; - } - - const backend = new BackendClass(parameters); - - //super( new Proxy( backend, debugHandler ) ); - super(backend, parameters); - - this.library = new StandardNodeLibrary(); - - this.isWebGPURenderer = true; - } -} - -export default WebGPURenderer; diff --git a/src-testing/src/renderers/webgpu/nodes/BasicNodeLibrary.ts b/src-testing/src/renderers/webgpu/nodes/BasicNodeLibrary.ts deleted file mode 100644 index 665bffa32..000000000 --- a/src-testing/src/renderers/webgpu/nodes/BasicNodeLibrary.ts +++ /dev/null @@ -1,61 +0,0 @@ -import NodeLibrary from '../../common/nodes/NodeLibrary.js'; - -// Lights -import { PointLight } from '../../../lights/PointLight.js'; -import { PointLightNode } from '../../../nodes/Nodes.js'; -import { DirectionalLight } from '../../../lights/DirectionalLight.js'; -import { DirectionalLightNode } from '../../../nodes/Nodes.js'; -import { RectAreaLight } from '../../../lights/RectAreaLight.js'; -import { RectAreaLightNode } from '../../../nodes/Nodes.js'; -import { SpotLight } from '../../../lights/SpotLight.js'; -import { SpotLightNode } from '../../../nodes/Nodes.js'; -import { AmbientLight } from '../../../lights/AmbientLight.js'; -import { AmbientLightNode } from '../../../nodes/Nodes.js'; -import { HemisphereLight } from '../../../lights/HemisphereLight.js'; -import { HemisphereLightNode } from '../../../nodes/Nodes.js'; -import { LightProbe } from '../../../lights/LightProbe.js'; -import { LightProbeNode } from '../../../nodes/Nodes.js'; -import IESSpotLight from '../../../lights/webgpu/IESSpotLight.js'; -import { IESSpotLightNode } from '../../../nodes/Nodes.js'; - -// Tone Mapping -import { - LinearToneMapping, - ReinhardToneMapping, - CineonToneMapping, - ACESFilmicToneMapping, - AgXToneMapping, - NeutralToneMapping, -} from '../../../constants.js'; -import { - linearToneMapping, - reinhardToneMapping, - cineonToneMapping, - acesFilmicToneMapping, - agxToneMapping, - neutralToneMapping, -} from '../../../nodes/display/ToneMappingFunctions.js'; - -class BasicNodeLibrary extends NodeLibrary { - constructor() { - super(); - - this.addLight(PointLightNode, PointLight); - this.addLight(DirectionalLightNode, DirectionalLight); - this.addLight(RectAreaLightNode, RectAreaLight); - this.addLight(SpotLightNode, SpotLight); - this.addLight(AmbientLightNode, AmbientLight); - this.addLight(HemisphereLightNode, HemisphereLight); - this.addLight(LightProbeNode, LightProbe); - this.addLight(IESSpotLightNode, IESSpotLight); - - this.addToneMapping(linearToneMapping, LinearToneMapping); - this.addToneMapping(reinhardToneMapping, ReinhardToneMapping); - this.addToneMapping(cineonToneMapping, CineonToneMapping); - this.addToneMapping(acesFilmicToneMapping, ACESFilmicToneMapping); - this.addToneMapping(agxToneMapping, AgXToneMapping); - this.addToneMapping(neutralToneMapping, NeutralToneMapping); - } -} - -export default BasicNodeLibrary; diff --git a/src-testing/src/renderers/webgpu/nodes/StandardNodeLibrary.ts b/src-testing/src/renderers/webgpu/nodes/StandardNodeLibrary.ts deleted file mode 100644 index bca482b4d..000000000 --- a/src-testing/src/renderers/webgpu/nodes/StandardNodeLibrary.ts +++ /dev/null @@ -1,107 +0,0 @@ -import NodeLibrary from '../../common/nodes/NodeLibrary.js'; - -// Materials -import { MeshPhongMaterial } from '../../../materials/MeshPhongMaterial.js'; -import MeshPhongNodeMaterial from '../../../materials/nodes/MeshPhongNodeMaterial.js'; -import { MeshStandardMaterial } from '../../../materials/MeshStandardMaterial.js'; -import MeshStandardNodeMaterial from '../../../materials/nodes/MeshStandardNodeMaterial.js'; -import { MeshPhysicalMaterial } from '../../../materials/MeshPhysicalMaterial.js'; -import MeshPhysicalNodeMaterial from '../../../materials/nodes/MeshPhysicalNodeMaterial.js'; -import { MeshToonMaterial } from '../../../materials/MeshToonMaterial.js'; -import MeshToonNodeMaterial from '../../../materials/nodes/MeshToonNodeMaterial.js'; -import { MeshBasicMaterial } from '../../../materials/MeshBasicMaterial.js'; -import MeshBasicNodeMaterial from '../../../materials/nodes/MeshBasicNodeMaterial.js'; -import { MeshLambertMaterial } from '../../../materials/MeshLambertMaterial.js'; -import MeshLambertNodeMaterial from '../../../materials/nodes/MeshLambertNodeMaterial.js'; -import { MeshNormalMaterial } from '../../../materials/MeshNormalMaterial.js'; -import MeshNormalNodeMaterial from '../../../materials/nodes/MeshNormalNodeMaterial.js'; -import { MeshMatcapMaterial } from '../../../materials/MeshMatcapMaterial.js'; -import MeshMatcapNodeMaterial from '../../../materials/nodes/MeshMatcapNodeMaterial.js'; -import { LineBasicMaterial } from '../../../materials/LineBasicMaterial.js'; -import LineBasicNodeMaterial from '../../../materials/nodes/LineBasicNodeMaterial.js'; -import { LineDashedMaterial } from '../../../materials/LineDashedMaterial.js'; -import LineDashedNodeMaterial from '../../../materials/nodes/LineDashedNodeMaterial.js'; -import { PointsMaterial } from '../../../materials/PointsMaterial.js'; -import PointsNodeMaterial from '../../../materials/nodes/PointsNodeMaterial.js'; -import { SpriteMaterial } from '../../../materials/SpriteMaterial.js'; -import SpriteNodeMaterial from '../../../materials/nodes/SpriteNodeMaterial.js'; -import { ShadowMaterial } from '../../../materials/ShadowMaterial.js'; -import ShadowNodeMaterial from '../../../materials/nodes/ShadowNodeMaterial.js'; -//import { MeshDepthMaterial } from '../../../materials/MeshDepthMaterial.js'; -//import MeshDepthNodeMaterial from '../../../materials/nodes/MeshDepthNodeMaterial.js'; -//import { MeshDistanceMaterial } from '../../../materials/MeshDistanceMaterial.js'; -//import MeshDistanceNodeMaterial from '../../../materials/nodes/MeshDistanceNodeMaterial.js'; - -// Lights -import { PointLight } from '../../../lights/PointLight.js'; -import { PointLightNode } from '../../../nodes/Nodes.js'; -import { DirectionalLight } from '../../../lights/DirectionalLight.js'; -import { DirectionalLightNode } from '../../../nodes/Nodes.js'; -import { RectAreaLight } from '../../../lights/RectAreaLight.js'; -import { RectAreaLightNode } from '../../../nodes/Nodes.js'; -import { SpotLight } from '../../../lights/SpotLight.js'; -import { SpotLightNode } from '../../../nodes/Nodes.js'; -import { AmbientLight } from '../../../lights/AmbientLight.js'; -import { AmbientLightNode } from '../../../nodes/Nodes.js'; -import { HemisphereLight } from '../../../lights/HemisphereLight.js'; -import { HemisphereLightNode } from '../../../nodes/Nodes.js'; -import { LightProbe } from '../../../lights/LightProbe.js'; -import { LightProbeNode } from '../../../nodes/Nodes.js'; -import IESSpotLight from '../../../lights/webgpu/IESSpotLight.js'; -import { IESSpotLightNode } from '../../../nodes/Nodes.js'; - -// Tone Mapping -import { - LinearToneMapping, - ReinhardToneMapping, - CineonToneMapping, - ACESFilmicToneMapping, - AgXToneMapping, - NeutralToneMapping, -} from '../../../constants.js'; -import { - linearToneMapping, - reinhardToneMapping, - cineonToneMapping, - acesFilmicToneMapping, - agxToneMapping, - neutralToneMapping, -} from '../../../nodes/display/ToneMappingFunctions.js'; - -class StandardNodeLibrary extends NodeLibrary { - constructor() { - super(); - - this.addMaterial(MeshPhongNodeMaterial, MeshPhongMaterial); - this.addMaterial(MeshStandardNodeMaterial, MeshStandardMaterial); - this.addMaterial(MeshPhysicalNodeMaterial, MeshPhysicalMaterial); - this.addMaterial(MeshToonNodeMaterial, MeshToonMaterial); - this.addMaterial(MeshBasicNodeMaterial, MeshBasicMaterial); - this.addMaterial(MeshLambertNodeMaterial, MeshLambertMaterial); - this.addMaterial(MeshNormalNodeMaterial, MeshNormalMaterial); - this.addMaterial(MeshMatcapNodeMaterial, MeshMatcapMaterial); - this.addMaterial(LineBasicNodeMaterial, LineBasicMaterial); - this.addMaterial(LineDashedNodeMaterial, LineDashedMaterial); - this.addMaterial(PointsNodeMaterial, PointsMaterial); - this.addMaterial(SpriteNodeMaterial, SpriteMaterial); - this.addMaterial(ShadowNodeMaterial, ShadowMaterial); - - this.addLight(PointLightNode, PointLight); - this.addLight(DirectionalLightNode, DirectionalLight); - this.addLight(RectAreaLightNode, RectAreaLight); - this.addLight(SpotLightNode, SpotLight); - this.addLight(AmbientLightNode, AmbientLight); - this.addLight(HemisphereLightNode, HemisphereLight); - this.addLight(LightProbeNode, LightProbe); - this.addLight(IESSpotLightNode, IESSpotLight); - - this.addToneMapping(linearToneMapping, LinearToneMapping); - this.addToneMapping(reinhardToneMapping, ReinhardToneMapping); - this.addToneMapping(cineonToneMapping, CineonToneMapping); - this.addToneMapping(acesFilmicToneMapping, ACESFilmicToneMapping); - this.addToneMapping(agxToneMapping, AgXToneMapping); - this.addToneMapping(neutralToneMapping, NeutralToneMapping); - } -} - -export default StandardNodeLibrary; diff --git a/src-testing/src/renderers/webgpu/nodes/WGSLNodeBuilder.ts b/src-testing/src/renderers/webgpu/nodes/WGSLNodeBuilder.ts deleted file mode 100644 index dc3aa7280..000000000 --- a/src-testing/src/renderers/webgpu/nodes/WGSLNodeBuilder.ts +++ /dev/null @@ -1,1178 +0,0 @@ -import NodeUniformsGroup from '../../common/nodes/NodeUniformsGroup.js'; - -import NodeSampler from '../../common/nodes/NodeSampler.js'; -import { - NodeSampledTexture, - NodeSampledCubeTexture, - NodeSampledTexture3D, -} from '../../common/nodes/NodeSampledTexture.js'; - -import NodeUniformBuffer from '../../common/nodes/NodeUniformBuffer.js'; -import NodeStorageBuffer from '../../common/nodes/NodeStorageBuffer.js'; - -import { NodeBuilder, CodeNode } from '../../../nodes/Nodes.js'; - -import { getFormat } from '../utils/WebGPUTextureUtils.js'; - -import WGSLNodeParser from './WGSLNodeParser.js'; -import { GPUBufferBindingType, GPUStorageTextureAccess } from '../utils/WebGPUConstants.js'; - -import { NoColorSpace, FloatType } from '../../../constants.js'; - -// GPUShaderStage is not defined in browsers not supporting WebGPU -const GPUShaderStage = self.GPUShaderStage; - -const gpuShaderStageLib = { - vertex: GPUShaderStage ? GPUShaderStage.VERTEX : 1, - fragment: GPUShaderStage ? GPUShaderStage.FRAGMENT : 2, - compute: GPUShaderStage ? GPUShaderStage.COMPUTE : 4, -}; - -const supports = { - instance: true, - swizzleAssign: false, - storageBuffer: true, -}; - -const wgslFnOpLib = { - '^^': 'tsl_xor', -}; - -const wgslTypeLib = { - float: 'f32', - int: 'i32', - uint: 'u32', - bool: 'bool', - color: 'vec3', - - vec2: 'vec2', - ivec2: 'vec2', - uvec2: 'vec2', - bvec2: 'vec2', - - vec3: 'vec3', - ivec3: 'vec3', - uvec3: 'vec3', - bvec3: 'vec3', - - vec4: 'vec4', - ivec4: 'vec4', - uvec4: 'vec4', - bvec4: 'vec4', - - mat2: 'mat2x2', - mat3: 'mat3x3', - mat4: 'mat4x4', -}; - -const wgslPolyfill = { - tsl_xor: new CodeNode('fn tsl_xor( a : bool, b : bool ) -> bool { return ( a || b ) && !( a && b ); }'), - mod_float: new CodeNode('fn tsl_mod_float( x : f32, y : f32 ) -> f32 { return x - y * floor( x / y ); }'), - mod_vec2: new CodeNode('fn tsl_mod_vec2( x : vec2f, y : vec2f ) -> vec2f { return x - y * floor( x / y ); }'), - mod_vec3: new CodeNode('fn tsl_mod_vec3( x : vec3f, y : vec3f ) -> vec3f { return x - y * floor( x / y ); }'), - mod_vec4: new CodeNode('fn tsl_mod_vec4( x : vec4f, y : vec4f ) -> vec4f { return x - y * floor( x / y ); }'), - equals_bool: new CodeNode('fn tsl_equals_bool( a : bool, b : bool ) -> bool { return a == b; }'), - equals_bvec2: new CodeNode( - 'fn tsl_equals_bvec2( a : vec2f, b : vec2f ) -> vec2 { return vec2( a.x == b.x, a.y == b.y ); }', - ), - equals_bvec3: new CodeNode( - 'fn tsl_equals_bvec3( a : vec3f, b : vec3f ) -> vec3 { return vec3( a.x == b.x, a.y == b.y, a.z == b.z ); }', - ), - equals_bvec4: new CodeNode( - 'fn tsl_equals_bvec4( a : vec4f, b : vec4f ) -> vec4 { return vec4( a.x == b.x, a.y == b.y, a.z == b.z, a.w == b.w ); }', - ), - repeatWrapping: new CodeNode(` -fn tsl_repeatWrapping( uv : vec2, dimension : vec2 ) -> vec2 { - - let uvScaled = vec2( uv * vec2( dimension ) ); - - return ( ( uvScaled % dimension ) + dimension ) % dimension; - -} -`), - biquadraticTexture: new CodeNode(` -fn tsl_biquadraticTexture( map : texture_2d, coord : vec2f, level : i32 ) -> vec4f { - - let iRes = vec2i( textureDimensions( map, level ) ); - let res = vec2f( iRes ); - - let uvScaled = coord * res; - let uvWrapping = ( ( uvScaled % res ) + res ) % res; - - // https://www.shadertoy.com/view/WtyXRy - - let uv = uvWrapping - 0.5; - let iuv = floor( uv ); - let f = fract( uv ); - - let rg1 = textureLoad( map, vec2i( iuv + vec2( 0.5, 0.5 ) ) % iRes, level ); - let rg2 = textureLoad( map, vec2i( iuv + vec2( 1.5, 0.5 ) ) % iRes, level ); - let rg3 = textureLoad( map, vec2i( iuv + vec2( 0.5, 1.5 ) ) % iRes, level ); - let rg4 = textureLoad( map, vec2i( iuv + vec2( 1.5, 1.5 ) ) % iRes, level ); - - return mix( mix( rg1, rg2, f.x ), mix( rg3, rg4, f.x ), f.y ); - -} -`), -}; - -const wgslMethods = { - dFdx: 'dpdx', - dFdy: '- dpdy', - mod_float: 'tsl_mod_float', - mod_vec2: 'tsl_mod_vec2', - mod_vec3: 'tsl_mod_vec3', - mod_vec4: 'tsl_mod_vec4', - equals_bool: 'tsl_equals_bool', - equals_bvec2: 'tsl_equals_bvec2', - equals_bvec3: 'tsl_equals_bvec3', - equals_bvec4: 'tsl_equals_bvec4', - inversesqrt: 'inverseSqrt', - bitcast: 'bitcast', -}; - -// WebGPU issue: does not support pow() with negative base on Windows - -if (/Windows/g.test(navigator.userAgent)) { - wgslPolyfill.pow_float = new CodeNode( - 'fn tsl_pow_float( a : f32, b : f32 ) -> f32 { return select( -pow( -a, b ), pow( a, b ), a > 0.0 ); }', - ); - wgslPolyfill.pow_vec2 = new CodeNode( - 'fn tsl_pow_vec2( a : vec2f, b : vec2f ) -> vec2f { return vec2f( tsl_pow_float( a.x, b.x ), tsl_pow_float( a.y, b.y ) ); }', - [wgslPolyfill.pow_float], - ); - wgslPolyfill.pow_vec3 = new CodeNode( - 'fn tsl_pow_vec3( a : vec3f, b : vec3f ) -> vec3f { return vec3f( tsl_pow_float( a.x, b.x ), tsl_pow_float( a.y, b.y ), tsl_pow_float( a.z, b.z ) ); }', - [wgslPolyfill.pow_float], - ); - wgslPolyfill.pow_vec4 = new CodeNode( - 'fn tsl_pow_vec4( a : vec4f, b : vec4f ) -> vec4f { return vec4f( tsl_pow_float( a.x, b.x ), tsl_pow_float( a.y, b.y ), tsl_pow_float( a.z, b.z ), tsl_pow_float( a.w, b.w ) ); }', - [wgslPolyfill.pow_float], - ); - - wgslMethods.pow_float = 'tsl_pow_float'; - wgslMethods.pow_vec2 = 'tsl_pow_vec2'; - wgslMethods.pow_vec3 = 'tsl_pow_vec3'; - wgslMethods.pow_vec4 = 'tsl_pow_vec4'; -} - -// - -let diagnostics = ''; - -if (/Firefox|Deno/g.test(navigator.userAgent) !== true) { - diagnostics += 'diagnostic( off, derivative_uniformity );\n'; -} - -// - -class WGSLNodeBuilder extends NodeBuilder { - constructor(object, renderer) { - super(object, renderer, new WGSLNodeParser()); - - this.uniformGroups = {}; - - this.builtins = {}; - - this.directives = {}; - - this.scopedArrays = new Map(); - } - - needsToWorkingColorSpace(texture) { - return texture.isVideoTexture === true && texture.colorSpace !== NoColorSpace; - } - - _generateTextureSample(texture, textureProperty, uvSnippet, depthSnippet, shaderStage = this.shaderStage) { - if (shaderStage === 'fragment') { - if (depthSnippet) { - return `textureSample( ${textureProperty}, ${textureProperty}_sampler, ${uvSnippet}, ${depthSnippet} )`; - } else { - return `textureSample( ${textureProperty}, ${textureProperty}_sampler, ${uvSnippet} )`; - } - } else if (this.isFilteredTexture(texture)) { - return this.generateFilteredTexture(texture, textureProperty, uvSnippet); - } else { - return this.generateTextureLod(texture, textureProperty, uvSnippet, '0'); - } - } - - _generateVideoSample(textureProperty, uvSnippet, shaderStage = this.shaderStage) { - if (shaderStage === 'fragment') { - return `textureSampleBaseClampToEdge( ${textureProperty}, ${textureProperty}_sampler, vec2( ${uvSnippet}.x, 1.0 - ${uvSnippet}.y ) )`; - } else { - console.error(`WebGPURenderer: THREE.VideoTexture does not support ${shaderStage} shader.`); - } - } - - _generateTextureSampleLevel( - texture, - textureProperty, - uvSnippet, - levelSnippet, - depthSnippet, - shaderStage = this.shaderStage, - ) { - if (shaderStage === 'fragment' && this.isUnfilterable(texture) === false) { - return `textureSampleLevel( ${textureProperty}, ${textureProperty}_sampler, ${uvSnippet}, ${levelSnippet} )`; - } else if (this.isFilteredTexture(texture)) { - return this.generateFilteredTexture(texture, textureProperty, uvSnippet, levelSnippet); - } else { - return this.generateTextureLod(texture, textureProperty, uvSnippet, levelSnippet); - } - } - - generateFilteredTexture(texture, textureProperty, uvSnippet, levelSnippet = '0') { - this._include('biquadraticTexture'); - - return `tsl_biquadraticTexture( ${textureProperty}, ${uvSnippet}, i32( ${levelSnippet} ) )`; - } - - generateTextureLod(texture, textureProperty, uvSnippet, levelSnippet = '0') { - this._include('repeatWrapping'); - - const dimension = - texture.isMultisampleRenderTargetTexture === true - ? `textureDimensions( ${textureProperty} )` - : `textureDimensions( ${textureProperty}, 0 )`; - - return `textureLoad( ${textureProperty}, tsl_repeatWrapping( ${uvSnippet}, ${dimension} ), i32( ${levelSnippet} ) )`; - } - - generateTextureLoad(texture, textureProperty, uvIndexSnippet, depthSnippet, levelSnippet = '0u') { - if (depthSnippet) { - return `textureLoad( ${textureProperty}, ${uvIndexSnippet}, ${depthSnippet}, ${levelSnippet} )`; - } else { - return `textureLoad( ${textureProperty}, ${uvIndexSnippet}, ${levelSnippet} )`; - } - } - - generateTextureStore(texture, textureProperty, uvIndexSnippet, valueSnippet) { - return `textureStore( ${textureProperty}, ${uvIndexSnippet}, ${valueSnippet} )`; - } - - isUnfilterable(texture) { - return ( - this.getComponentTypeFromTexture(texture) !== 'float' || - (!this.isAvailable('float32Filterable') && texture.isDataTexture === true && texture.type === FloatType) || - texture.isMultisampleRenderTargetTexture === true - ); - } - - generateTexture(texture, textureProperty, uvSnippet, depthSnippet, shaderStage = this.shaderStage) { - let snippet = null; - - if (texture.isVideoTexture === true) { - snippet = this._generateVideoSample(textureProperty, uvSnippet, shaderStage); - } else if (this.isUnfilterable(texture)) { - snippet = this.generateTextureLod(texture, textureProperty, uvSnippet, '0', depthSnippet, shaderStage); - } else { - snippet = this._generateTextureSample(texture, textureProperty, uvSnippet, depthSnippet, shaderStage); - } - - return snippet; - } - - generateTextureGrad( - texture, - textureProperty, - uvSnippet, - gradSnippet, - depthSnippet, - shaderStage = this.shaderStage, - ) { - if (shaderStage === 'fragment') { - // TODO handle i32 or u32 --> uvSnippet, array_index: A, ddx, ddy - return `textureSampleGrad( ${textureProperty}, ${textureProperty}_sampler, ${uvSnippet}, ${gradSnippet[0]}, ${gradSnippet[1]} )`; - } else { - console.error(`WebGPURenderer: THREE.TextureNode.gradient() does not support ${shaderStage} shader.`); - } - } - - generateTextureCompare( - texture, - textureProperty, - uvSnippet, - compareSnippet, - depthSnippet, - shaderStage = this.shaderStage, - ) { - if (shaderStage === 'fragment') { - return `textureSampleCompare( ${textureProperty}, ${textureProperty}_sampler, ${uvSnippet}, ${compareSnippet} )`; - } else { - console.error( - `WebGPURenderer: THREE.DepthTexture.compareFunction() does not support ${shaderStage} shader.`, - ); - } - } - - generateTextureLevel( - texture, - textureProperty, - uvSnippet, - levelSnippet, - depthSnippet, - shaderStage = this.shaderStage, - ) { - let snippet = null; - - if (texture.isVideoTexture === true) { - snippet = this._generateVideoSample(textureProperty, uvSnippet, shaderStage); - } else { - snippet = this._generateTextureSampleLevel( - texture, - textureProperty, - uvSnippet, - levelSnippet, - depthSnippet, - shaderStage, - ); - } - - return snippet; - } - - generateTextureBias( - texture, - textureProperty, - uvSnippet, - biasSnippet, - depthSnippet, - shaderStage = this.shaderStage, - ) { - if (shaderStage === 'fragment') { - return `textureSampleBias( ${textureProperty}, ${textureProperty}_sampler, ${uvSnippet}, ${biasSnippet} )`; - } else { - console.error(`WebGPURenderer: THREE.TextureNode.biasNode does not support ${shaderStage} shader.`); - } - } - - getPropertyName(node, shaderStage = this.shaderStage) { - if (node.isNodeVarying === true && node.needsInterpolation === true) { - if (shaderStage === 'vertex') { - return `varyings.${node.name}`; - } - } else if (node.isNodeUniform === true) { - const name = node.name; - const type = node.type; - - if (type === 'texture' || type === 'cubeTexture' || type === 'storageTexture' || type === 'texture3D') { - return name; - } else if (type === 'buffer' || type === 'storageBuffer' || type === 'indirectStorageBuffer') { - return `NodeBuffer_${node.id}.${name}`; - } else { - return node.groupNode.name + '.' + name; - } - } - - return super.getPropertyName(node); - } - - getOutputStructName() { - return 'output'; - } - - _getUniformGroupCount(shaderStage) { - return Object.keys(this.uniforms[shaderStage]).length; - } - - getFunctionOperator(op) { - const fnOp = wgslFnOpLib[op]; - - if (fnOp !== undefined) { - this._include(fnOp); - - return fnOp; - } - - return null; - } - - getStorageAccess(node) { - if (node.isStorageTextureNode) { - switch (node.access) { - case GPUStorageTextureAccess.ReadOnly: - return 'read'; - - case GPUStorageTextureAccess.WriteOnly: - return 'write'; - - default: - return 'read_write'; - } - } else { - switch (node.access) { - case GPUBufferBindingType.Storage: - return 'read_write'; - - case GPUBufferBindingType.ReadOnlyStorage: - return 'read'; - - default: - return 'write'; - } - } - } - - getUniformFromNode(node, type, shaderStage, name = null) { - const uniformNode = super.getUniformFromNode(node, type, shaderStage, name); - const nodeData = this.getDataFromNode(node, shaderStage, this.globalCache); - - if (nodeData.uniformGPU === undefined) { - let uniformGPU; - - const group = node.groupNode; - const groupName = group.name; - - const bindings = this.getBindGroupArray(groupName, shaderStage); - - if (type === 'texture' || type === 'cubeTexture' || type === 'storageTexture' || type === 'texture3D') { - let texture = null; - - if (type === 'texture' || type === 'storageTexture') { - texture = new NodeSampledTexture( - uniformNode.name, - uniformNode.node, - group, - node.access ? node.access : null, - ); - } else if (type === 'cubeTexture') { - texture = new NodeSampledCubeTexture( - uniformNode.name, - uniformNode.node, - group, - node.access ? node.access : null, - ); - } else if (type === 'texture3D') { - texture = new NodeSampledTexture3D( - uniformNode.name, - uniformNode.node, - group, - node.access ? node.access : null, - ); - } - - texture.store = node.isStorageTextureNode === true; - texture.setVisibility(gpuShaderStageLib[shaderStage]); - - if ( - shaderStage === 'fragment' && - this.isUnfilterable(node.value) === false && - texture.store === false - ) { - const sampler = new NodeSampler(`${uniformNode.name}_sampler`, uniformNode.node, group); - sampler.setVisibility(gpuShaderStageLib[shaderStage]); - - bindings.push(sampler, texture); - - uniformGPU = [sampler, texture]; - } else { - bindings.push(texture); - - uniformGPU = [texture]; - } - } else if (type === 'buffer' || type === 'storageBuffer' || type === 'indirectStorageBuffer') { - const bufferClass = type === 'buffer' ? NodeUniformBuffer : NodeStorageBuffer; - - const buffer = new bufferClass(node, group); - buffer.setVisibility(gpuShaderStageLib[shaderStage]); - - bindings.push(buffer); - - uniformGPU = buffer; - } else { - const uniformsStage = this.uniformGroups[shaderStage] || (this.uniformGroups[shaderStage] = {}); - - let uniformsGroup = uniformsStage[groupName]; - - if (uniformsGroup === undefined) { - uniformsGroup = new NodeUniformsGroup(groupName, group); - uniformsGroup.setVisibility(gpuShaderStageLib[shaderStage]); - - uniformsStage[groupName] = uniformsGroup; - - bindings.push(uniformsGroup); - } - - uniformGPU = this.getNodeUniform(uniformNode, type); - - uniformsGroup.addUniform(uniformGPU); - } - - nodeData.uniformGPU = uniformGPU; - } - - return uniformNode; - } - - getBuiltin(name, property, type, shaderStage = this.shaderStage) { - const map = this.builtins[shaderStage] || (this.builtins[shaderStage] = new Map()); - - if (map.has(name) === false) { - map.set(name, { - name, - property, - type, - }); - } - - return property; - } - - hasBuiltin(name, shaderStage = this.shaderStage) { - return this.builtins[shaderStage] !== undefined && this.builtins[shaderStage].has(name); - } - - getVertexIndex() { - if (this.shaderStage === 'vertex') { - return this.getBuiltin('vertex_index', 'vertexIndex', 'u32', 'attribute'); - } - - return 'vertexIndex'; - } - - buildFunctionCode(shaderNode) { - const layout = shaderNode.layout; - const flowData = this.flowShaderNode(shaderNode); - - const parameters = []; - - for (const input of layout.inputs) { - parameters.push(input.name + ' : ' + this.getType(input.type)); - } - - // - - let code = `fn ${layout.name}( ${parameters.join(', ')} ) -> ${this.getType(layout.type)} { -${flowData.vars} -${flowData.code} -`; - - if (flowData.result) { - code += `\treturn ${flowData.result};\n`; - } - - code += '\n}\n'; - - // - - return code; - } - - getInstanceIndex() { - if (this.shaderStage === 'vertex') { - return this.getBuiltin('instance_index', 'instanceIndex', 'u32', 'attribute'); - } - - return 'instanceIndex'; - } - - getInvocationLocalIndex() { - return this.getBuiltin('local_invocation_index', 'invocationLocalIndex', 'u32', 'attribute'); - } - - getSubgroupSize() { - this.enableSubGroups(); - - return this.getBuiltin('subgroup_size', 'subgroupSize', 'u32', 'attribute'); - } - - getInvocationSubgroupIndex() { - this.enableSubGroups(); - - return this.getBuiltin('subgroup_invocation_id', 'invocationSubgroupIndex', 'u32', 'attribute'); - } - - getSubgroupIndex() { - this.enableSubGroups(); - - return this.getBuiltin('subgroup_id', 'subgroupIndex', 'u32', 'attribute'); - } - - getDrawIndex() { - return null; - } - - getFrontFacing() { - return this.getBuiltin('front_facing', 'isFront', 'bool'); - } - - getFragCoord() { - return this.getBuiltin('position', 'fragCoord', 'vec4') + '.xy'; - } - - getFragDepth() { - return 'output.' + this.getBuiltin('frag_depth', 'depth', 'f32', 'output'); - } - - isFlipY() { - return false; - } - - enableDirective(name, shaderStage = this.shaderStage) { - const stage = this.directives[shaderStage] || (this.directives[shaderStage] = new Set()); - stage.add(name); - } - - getDirectives(shaderStage) { - const snippets = []; - const directives = this.directives[shaderStage]; - - if (directives !== undefined) { - for (const directive of directives) { - snippets.push(`enable ${directive};`); - } - } - - return snippets.join('\n'); - } - - enableSubGroups() { - this.enableDirective('subgroups'); - } - - enableSubgroupsF16() { - this.enableDirective('subgroups-f16'); - } - - enableClipDistances() { - this.enableDirective('clip_distances'); - } - - enableShaderF16() { - this.enableDirective('f16'); - } - - enableDualSourceBlending() { - this.enableDirective('dual_source_blending'); - } - - getBuiltins(shaderStage) { - const snippets = []; - const builtins = this.builtins[shaderStage]; - - if (builtins !== undefined) { - for (const { name, property, type } of builtins.values()) { - snippets.push(`@builtin( ${name} ) ${property} : ${type}`); - } - } - - return snippets.join(',\n\t'); - } - - getScopedArray(name, scope, bufferType, bufferCount) { - if (this.scopedArrays.has(name) === false) { - this.scopedArrays.set(name, { - name, - scope, - bufferType, - bufferCount, - }); - } - - return name; - } - - getScopedArrays(shaderStage) { - if (shaderStage !== 'compute') { - return; - } - - const snippets = []; - - for (const { name, scope, bufferType, bufferCount } of this.scopedArrays.values()) { - const type = this.getType(bufferType); - - snippets.push(`var<${scope}> ${name}: array< ${type}, ${bufferCount} >;`); - } - - return snippets.join('\n'); - } - - getAttributes(shaderStage) { - const snippets = []; - - if (shaderStage === 'compute') { - this.getBuiltin('global_invocation_id', 'id', 'vec3', 'attribute'); - this.getBuiltin('workgroup_id', 'workgroupId', 'vec3', 'attribute'); - this.getBuiltin('local_invocation_id', 'localId', 'vec3', 'attribute'); - this.getBuiltin('num_workgroups', 'numWorkgroups', 'vec3', 'attribute'); - - if (this.renderer.hasFeature('subgroups')) { - this.enableDirective('subgroups', shaderStage); - this.getBuiltin('subgroup_size', 'subgroupSize', 'u32', 'attribute'); - } - } - - if (shaderStage === 'vertex' || shaderStage === 'compute') { - const builtins = this.getBuiltins('attribute'); - - if (builtins) snippets.push(builtins); - - const attributes = this.getAttributesArray(); - - for (let index = 0, length = attributes.length; index < length; index++) { - const attribute = attributes[index]; - const name = attribute.name; - const type = this.getType(attribute.type); - - snippets.push(`@location( ${index} ) ${name} : ${type}`); - } - } - - return snippets.join(',\n\t'); - } - - getStructMembers(struct) { - const snippets = []; - const members = struct.getMemberTypes(); - - for (let i = 0; i < members.length; i++) { - const member = members[i]; - snippets.push(`\t@location( ${i} ) m${i} : ${member}`); - } - - const builtins = this.getBuiltins('output'); - - if (builtins) snippets.push('\t' + builtins); - - return snippets.join(',\n'); - } - - getStructs(shaderStage) { - const snippets = []; - const structs = this.structs[shaderStage]; - - for (let index = 0, length = structs.length; index < length; index++) { - const struct = structs[index]; - const name = struct.name; - - let snippet = `\struct ${name} {\n`; - snippet += this.getStructMembers(struct); - snippet += '\n}'; - - snippets.push(snippet); - - snippets.push(`\nvar output : ${name};\n\n`); - } - - return snippets.join('\n\n'); - } - - getVar(type, name) { - return `var ${name} : ${this.getType(type)}`; - } - - getVars(shaderStage) { - const snippets = []; - const vars = this.vars[shaderStage]; - - if (vars !== undefined) { - for (const variable of vars) { - snippets.push(`\t${this.getVar(variable.type, variable.name)};`); - } - } - - return `\n${snippets.join('\n')}\n`; - } - - getVaryings(shaderStage) { - const snippets = []; - - if (shaderStage === 'vertex') { - this.getBuiltin('position', 'Vertex', 'vec4', 'vertex'); - } - - if (shaderStage === 'vertex' || shaderStage === 'fragment') { - const varyings = this.varyings; - const vars = this.vars[shaderStage]; - - for (let index = 0; index < varyings.length; index++) { - const varying = varyings[index]; - - if (varying.needsInterpolation) { - let attributesSnippet = `@location( ${index} )`; - - if (/^(int|uint|ivec|uvec)/.test(varying.type)) { - attributesSnippet += ' @interpolate( flat )'; - } - - snippets.push(`${attributesSnippet} ${varying.name} : ${this.getType(varying.type)}`); - } else if (shaderStage === 'vertex' && vars.includes(varying) === false) { - vars.push(varying); - } - } - } - - const builtins = this.getBuiltins(shaderStage); - - if (builtins) snippets.push(builtins); - - const code = snippets.join(',\n\t'); - - return shaderStage === 'vertex' ? this._getWGSLStruct('VaryingsStruct', '\t' + code) : code; - } - - getUniforms(shaderStage) { - const uniforms = this.uniforms[shaderStage]; - - const bindingSnippets = []; - const bufferSnippets = []; - const structSnippets = []; - const uniformGroups = {}; - - for (const uniform of uniforms) { - const groupName = uniform.groupNode.name; - const uniformIndexes = this.bindingsIndexes[groupName]; - - if ( - uniform.type === 'texture' || - uniform.type === 'cubeTexture' || - uniform.type === 'storageTexture' || - uniform.type === 'texture3D' - ) { - const texture = uniform.node.value; - - if ( - shaderStage === 'fragment' && - this.isUnfilterable(texture) === false && - uniform.node.isStorageTextureNode !== true - ) { - if (texture.isDepthTexture === true && texture.compareFunction !== null) { - bindingSnippets.push( - `@binding( ${uniformIndexes.binding++} ) @group( ${uniformIndexes.group} ) var ${uniform.name}_sampler : sampler_comparison;`, - ); - } else { - bindingSnippets.push( - `@binding( ${uniformIndexes.binding++} ) @group( ${uniformIndexes.group} ) var ${uniform.name}_sampler : sampler;`, - ); - } - } - - let textureType; - - let multisampled = ''; - - if (texture.isMultisampleRenderTargetTexture === true) { - multisampled = '_multisampled'; - } - - if (texture.isCubeTexture === true) { - textureType = 'texture_cube'; - } else if (texture.isDataArrayTexture === true || texture.isCompressedArrayTexture === true) { - textureType = 'texture_2d_array'; - } else if (texture.isDepthTexture === true) { - textureType = `texture_depth${multisampled}_2d`; - } else if (texture.isVideoTexture === true) { - textureType = 'texture_external'; - } else if (texture.isData3DTexture === true) { - textureType = 'texture_3d'; - } else if (uniform.node.isStorageTextureNode === true) { - const format = getFormat(texture); - const access = this.getStorageAccess(uniform.node); - - textureType = `texture_storage_2d<${format}, ${access}>`; - } else { - const componentPrefix = this.getComponentTypeFromTexture(texture).charAt(0); - - textureType = `texture${multisampled}_2d<${componentPrefix}32>`; - } - - bindingSnippets.push( - `@binding( ${uniformIndexes.binding++} ) @group( ${uniformIndexes.group} ) var ${uniform.name} : ${textureType};`, - ); - } else if ( - uniform.type === 'buffer' || - uniform.type === 'storageBuffer' || - uniform.type === 'indirectStorageBuffer' - ) { - const bufferNode = uniform.node; - const bufferType = this.getType(bufferNode.bufferType); - const bufferCount = bufferNode.bufferCount; - - const bufferCountSnippet = bufferCount > 0 && uniform.type === 'buffer' ? ', ' + bufferCount : ''; - const bufferTypeSnippet = bufferNode.isAtomic ? `atomic<${bufferType}>` : `${bufferType}`; - const bufferSnippet = `\t${uniform.name} : array< ${bufferTypeSnippet}${bufferCountSnippet} >\n`; - const bufferAccessMode = bufferNode.isStorageBufferNode - ? `storage, ${this.getStorageAccess(bufferNode)}` - : 'uniform'; - - bufferSnippets.push( - this._getWGSLStructBinding( - 'NodeBuffer_' + bufferNode.id, - bufferSnippet, - bufferAccessMode, - uniformIndexes.binding++, - uniformIndexes.group, - ), - ); - } else { - const vectorType = this.getType(this.getVectorType(uniform.type)); - const groupName = uniform.groupNode.name; - - const group = - uniformGroups[groupName] || - (uniformGroups[groupName] = { - index: uniformIndexes.binding++, - id: uniformIndexes.group, - snippets: [], - }); - - group.snippets.push(`\t${uniform.name} : ${vectorType}`); - } - } - - for (const name in uniformGroups) { - const group = uniformGroups[name]; - - structSnippets.push( - this._getWGSLStructBinding(name, group.snippets.join(',\n'), 'uniform', group.index, group.id), - ); - } - - let code = bindingSnippets.join('\n'); - code += bufferSnippets.join('\n'); - code += structSnippets.join('\n'); - - return code; - } - - buildCode() { - const shadersData = this.material !== null ? { fragment: {}, vertex: {} } : { compute: {} }; - - this.sortBindingGroups(); - - for (const shaderStage in shadersData) { - const stageData = shadersData[shaderStage]; - stageData.uniforms = this.getUniforms(shaderStage); - stageData.attributes = this.getAttributes(shaderStage); - stageData.varyings = this.getVaryings(shaderStage); - stageData.structs = this.getStructs(shaderStage); - stageData.vars = this.getVars(shaderStage); - stageData.codes = this.getCodes(shaderStage); - stageData.directives = this.getDirectives(shaderStage); - stageData.scopedArrays = this.getScopedArrays(shaderStage); - - // - - let flow = '// code\n\n'; - flow += this.flowCode[shaderStage]; - - const flowNodes = this.flowNodes[shaderStage]; - const mainNode = flowNodes[flowNodes.length - 1]; - - const outputNode = mainNode.outputNode; - const isOutputStruct = outputNode !== undefined && outputNode.isOutputStructNode === true; - - for (const node of flowNodes) { - const flowSlotData = this.getFlowData(node /*, shaderStage*/); - const slotName = node.name; - - if (slotName) { - if (flow.length > 0) flow += '\n'; - - flow += `\t// flow -> ${slotName}\n\t`; - } - - flow += `${flowSlotData.code}\n\t`; - - if (node === mainNode && shaderStage !== 'compute') { - flow += '// result\n\n\t'; - - if (shaderStage === 'vertex') { - flow += `varyings.Vertex = ${flowSlotData.result};`; - } else if (shaderStage === 'fragment') { - if (isOutputStruct) { - stageData.returnType = outputNode.nodeType; - - flow += `return ${flowSlotData.result};`; - } else { - let structSnippet = '\t@location(0) color: vec4'; - - const builtins = this.getBuiltins('output'); - - if (builtins) structSnippet += ',\n\t' + builtins; - - stageData.returnType = 'OutputStruct'; - stageData.structs += this._getWGSLStruct('OutputStruct', structSnippet); - stageData.structs += '\nvar output : OutputStruct;\n\n'; - - flow += `output.color = ${flowSlotData.result};\n\n\treturn output;`; - } - } - } - } - - stageData.flow = flow; - } - - if (this.material !== null) { - this.vertexShader = this._getWGSLVertexCode(shadersData.vertex); - this.fragmentShader = this._getWGSLFragmentCode(shadersData.fragment); - } else { - this.computeShader = this._getWGSLComputeCode( - shadersData.compute, - (this.object.workgroupSize || [64]).join(', '), - ); - } - } - - getMethod(method, output = null) { - let wgslMethod; - - if (output !== null) { - wgslMethod = this._getWGSLMethod(method + '_' + output); - } - - if (wgslMethod === undefined) { - wgslMethod = this._getWGSLMethod(method); - } - - return wgslMethod || method; - } - - getType(type) { - return wgslTypeLib[type] || type; - } - - isAvailable(name) { - let result = supports[name]; - - if (result === undefined) { - if (name === 'float32Filterable') { - result = this.renderer.hasFeature('float32-filterable'); - } - - supports[name] = result; - } - - return result; - } - - _getWGSLMethod(method) { - if (wgslPolyfill[method] !== undefined) { - this._include(method); - } - - return wgslMethods[method]; - } - - _include(name) { - const codeNode = wgslPolyfill[name]; - codeNode.build(this); - - if (this.currentFunctionNode !== null) { - this.currentFunctionNode.includes.push(codeNode); - } - - return codeNode; - } - - _getWGSLVertexCode(shaderData) { - return `${this.getSignature()} -// directives -${shaderData.directives} - -// uniforms -${shaderData.uniforms} - -// varyings -${shaderData.varyings} -var varyings : VaryingsStruct; - -// codes -${shaderData.codes} - -@vertex -fn main( ${shaderData.attributes} ) -> VaryingsStruct { - - // vars - ${shaderData.vars} - - // flow - ${shaderData.flow} - - return varyings; - -} -`; - } - - _getWGSLFragmentCode(shaderData) { - return `${this.getSignature()} -// global -${diagnostics} - -// uniforms -${shaderData.uniforms} - -// structs -${shaderData.structs} - -// codes -${shaderData.codes} - -@fragment -fn main( ${shaderData.varyings} ) -> ${shaderData.returnType} { - - // vars - ${shaderData.vars} - - // flow - ${shaderData.flow} - -} -`; - } - - _getWGSLComputeCode(shaderData, workgroupSize) { - return `${this.getSignature()} -// directives -${shaderData.directives} - -// system -var instanceIndex : u32; - -// locals -${shaderData.scopedArrays} - -// uniforms -${shaderData.uniforms} - -// codes -${shaderData.codes} - -@compute @workgroup_size( ${workgroupSize} ) -fn main( ${shaderData.attributes} ) { - - // system - instanceIndex = id.x + id.y * numWorkgroups.x * u32(${workgroupSize}) + id.z * numWorkgroups.x * numWorkgroups.y * u32(${workgroupSize}); - - // vars - ${shaderData.vars} - - // flow - ${shaderData.flow} - -} -`; - } - - _getWGSLStruct(name, vars) { - return ` -struct ${name} { -${vars} -};`; - } - - _getWGSLStructBinding(name, vars, access, binding = 0, group = 0) { - const structName = name + 'Struct'; - const structSnippet = this._getWGSLStruct(structName, vars); - - return `${structSnippet} -@binding( ${binding} ) @group( ${group} ) -var<${access}> ${name} : ${structName};`; - } -} - -export default WGSLNodeBuilder; diff --git a/src-testing/src/renderers/webgpu/nodes/WGSLNodeFunction.ts b/src-testing/src/renderers/webgpu/nodes/WGSLNodeFunction.ts deleted file mode 100644 index 33b0d2688..000000000 --- a/src-testing/src/renderers/webgpu/nodes/WGSLNodeFunction.ts +++ /dev/null @@ -1,142 +0,0 @@ -import NodeFunction from '../../../nodes/core/NodeFunction.js'; -import NodeFunctionInput from '../../../nodes/core/NodeFunctionInput.js'; - -const declarationRegexp = /^[fn]*\s*([a-z_0-9]+)?\s*\(([\s\S]*?)\)\s*[\-\>]*\s*([a-z_0-9]+(?:<[\s\S]+?>)?)/i; -const propertiesRegexp = /([a-z_0-9]+)\s*:\s*([a-z_0-9]+(?:<[\s\S]+?>)?)/gi; - -const wgslTypeLib = { - f32: 'float', - i32: 'int', - u32: 'uint', - bool: 'bool', - - 'vec2': 'vec2', - 'vec2': 'ivec2', - 'vec2': 'uvec2', - 'vec2': 'bvec2', - - vec2f: 'vec2', - vec2i: 'ivec2', - vec2u: 'uvec2', - vec2b: 'bvec2', - - 'vec3': 'vec3', - 'vec3': 'ivec3', - 'vec3': 'uvec3', - 'vec3': 'bvec3', - - vec3f: 'vec3', - vec3i: 'ivec3', - vec3u: 'uvec3', - vec3b: 'bvec3', - - 'vec4': 'vec4', - 'vec4': 'ivec4', - 'vec4': 'uvec4', - 'vec4': 'bvec4', - - vec4f: 'vec4', - vec4i: 'ivec4', - vec4u: 'uvec4', - vec4b: 'bvec4', - - 'mat2x2': 'mat2', - mat2x2f: 'mat2', - - 'mat3x3': 'mat3', - mat3x3f: 'mat3', - - 'mat4x4': 'mat4', - mat4x4f: 'mat4', - - sampler: 'sampler', - - texture_1d: 'texture', - - texture_2d: 'texture', - texture_2d_array: 'texture', - texture_multisampled_2d: 'cubeTexture', - - texture_depth_2d: 'depthTexture', - - texture_3d: 'texture3D', - - texture_cube: 'cubeTexture', - texture_cube_array: 'cubeTexture', - - texture_storage_1d: 'storageTexture', - texture_storage_2d: 'storageTexture', - texture_storage_2d_array: 'storageTexture', - texture_storage_3d: 'storageTexture', -}; - -const parse = source => { - source = source.trim(); - - const declaration = source.match(declarationRegexp); - - if (declaration !== null && declaration.length === 4) { - const inputsCode = declaration[2]; - const propsMatches = []; - let match = null; - - while ((match = propertiesRegexp.exec(inputsCode)) !== null) { - propsMatches.push({ name: match[1], type: match[2] }); - } - - // Process matches to correctly pair names and types - const inputs = []; - for (let i = 0; i < propsMatches.length; i++) { - const { name, type } = propsMatches[i]; - - let resolvedType = type; - - if (resolvedType.startsWith('texture')) { - resolvedType = type.split('<')[0]; - } else if (resolvedType.startsWith('ptr')) { - resolvedType = 'pointer'; - } - - resolvedType = wgslTypeLib[resolvedType] || resolvedType; - - inputs.push(new NodeFunctionInput(resolvedType, name)); - } - - const blockCode = source.substring(declaration[0].length); - const outputType = declaration[3] || 'void'; - - const name = declaration[1] !== undefined ? declaration[1] : ''; - const type = wgslTypeLib[outputType] || outputType; - - return { - type, - inputs, - name, - inputsCode, - blockCode, - outputType, - }; - } else { - throw new Error('FunctionNode: Function is not a WGSL code.'); - } -}; - -class WGSLNodeFunction extends NodeFunction { - constructor(source) { - const { type, inputs, name, inputsCode, blockCode, outputType } = parse(source); - - super(type, inputs, name); - - this.inputsCode = inputsCode; - this.blockCode = blockCode; - this.outputType = outputType; - } - - getCode(name = this.name) { - const outputType = this.outputType !== 'void' ? '-> ' + this.outputType : ''; - - return `fn ${name} ( ${this.inputsCode.trim()} ) ${outputType}` + this.blockCode; - } -} - -export default WGSLNodeFunction; diff --git a/src-testing/src/renderers/webgpu/nodes/WGSLNodeParser.ts b/src-testing/src/renderers/webgpu/nodes/WGSLNodeParser.ts deleted file mode 100644 index c32133df4..000000000 --- a/src-testing/src/renderers/webgpu/nodes/WGSLNodeParser.ts +++ /dev/null @@ -1,10 +0,0 @@ -import NodeParser from '../../../nodes/core/NodeParser.js'; -import WGSLNodeFunction from './WGSLNodeFunction.js'; - -class WGSLNodeParser extends NodeParser { - parseFunction(source) { - return new WGSLNodeFunction(source); - } -} - -export default WGSLNodeParser; diff --git a/src-testing/src/renderers/webgpu/utils/WebGPUConstants.d.ts b/src-testing/src/renderers/webgpu/utils/WebGPUConstants.d.ts deleted file mode 100644 index baa36f901..000000000 --- a/src-testing/src/renderers/webgpu/utils/WebGPUConstants.d.ts +++ /dev/null @@ -1,328 +0,0 @@ -export enum GPUPrimitiveTopology { - PointList = "point-list", - LineList = "line-list", - LineStrip = "line-strip", - TriangleList = "triangle-list", - TriangleStrip = "triangle-strip", -} - -export enum GPUCompareFunction { - Never = "never", - Less = "less", - Equal = "equal", - LessEqual = "less-equal", - Greater = "greater", - NotEqual = "not-equal", - GreaterEqual = "greater-equal", - Always = "always", -} - -export enum GPUStoreOp { - Store = "store", - Discard = "discard", -} - -export enum GPULoadOp { - Load = "load", - Clear = "clear", -} - -export enum GPUFrontFace { - CCW = "ccw", - CW = "cw", -} - -export enum GPUCullMode { - None = "none", - Front = "front", - Back = "back", -} - -export enum GPUIndexFormat { - Uint16 = "uint16", - Uint32 = "uint32", -} - -export enum GPUVertexFormat { - Uint8x2 = "uint8x2", - Uint8x4 = "uint8x4", - Sint8x2 = "sint8x2", - Sint8x4 = "sint8x4", - Unorm8x2 = "unorm8x2", - Unorm8x4 = "unorm8x4", - Snorm8x2 = "snorm8x2", - Snorm8x4 = "snorm8x4", - Uint16x2 = "uint16x2", - Uint16x4 = "uint16x4", - Sint16x2 = "sint16x2", - Sint16x4 = "sint16x4", - Unorm16x2 = "unorm16x2", - Unorm16x4 = "unorm16x4", - Snorm16x2 = "snorm16x2", - Snorm16x4 = "snorm16x4", - Float16x2 = "float16x2", - Float16x4 = "float16x4", - Float32 = "float32", - Float32x2 = "float32x2", - Float32x3 = "float32x3", - Float32x4 = "float32x4", - Uint32 = "uint32", - Uint32x2 = "uint32x2", - Uint32x3 = "uint32x3", - Uint32x4 = "uint32x4", - Sint32 = "sint32", - Sint32x2 = "sint32x2", - Sint32x3 = "sint32x3", - Sint32x4 = "sint32x4", -} - -export enum GPUTextureFormat { - // 8-bit formats - - R8Unorm = "r8unorm", - R8Snorm = "r8snorm", - R8Uint = "r8uint", - R8Sint = "r8sint", - - // 16-bit formats - - R16Uint = "r16uint", - R16Sint = "r16sint", - R16Float = "r16float", - RG8Unorm = "rg8unorm", - RG8Snorm = "rg8snorm", - RG8Uint = "rg8uint", - RG8Sint = "rg8sint", - - // 32-bit formats - - R32Uint = "r32uint", - R32Sint = "r32sint", - R32Float = "r32float", - RG16Uint = "rg16uint", - RG16Sint = "rg16sint", - RG16Float = "rg16float", - RGBA8Unorm = "rgba8unorm", - RGBA8UnormSRGB = "rgba8unorm-srgb", - RGBA8Snorm = "rgba8snorm", - RGBA8Uint = "rgba8uint", - RGBA8Sint = "rgba8sint", - BGRA8Unorm = "bgra8unorm", - BGRA8UnormSRGB = "bgra8unorm-srgb", - // Packed 32-bit formats - RGB9E5UFloat = "rgb9e5ufloat", - RGB10A2Unorm = "rgb10a2unorm", - RG11B10uFloat = "rgb10a2unorm", - - // 64-bit formats - - RG32Uint = "rg32uint", - RG32Sint = "rg32sint", - RG32Float = "rg32float", - RGBA16Uint = "rgba16uint", - RGBA16Sint = "rgba16sint", - RGBA16Float = "rgba16float", - - // 128-bit formats - - RGBA32Uint = "rgba32uint", - RGBA32Sint = "rgba32sint", - RGBA32Float = "rgba32float", - - // Depth and stencil formats - - Stencil8 = "stencil8", - Depth16Unorm = "depth16unorm", - Depth24Plus = "depth24plus", - Depth24PlusStencil8 = "depth24plus-stencil8", - Depth32Float = "depth32float", - - // 'depth32float-stencil8' extension - - Depth32FloatStencil8 = "depth32float-stencil8", - - // BC compressed formats usable if 'texture-compression-bc' is both - // supported by the device/user agent and enabled in requestDevice. - - BC1RGBAUnorm = "bc1-rgba-unorm", - BC1RGBAUnormSRGB = "bc1-rgba-unorm-srgb", - BC2RGBAUnorm = "bc2-rgba-unorm", - BC2RGBAUnormSRGB = "bc2-rgba-unorm-srgb", - BC3RGBAUnorm = "bc3-rgba-unorm", - BC3RGBAUnormSRGB = "bc3-rgba-unorm-srgb", - BC4RUnorm = "bc4-r-unorm", - BC4RSnorm = "bc4-r-snorm", - BC5RGUnorm = "bc5-rg-unorm", - BC5RGSnorm = "bc5-rg-snorm", - BC6HRGBUFloat = "bc6h-rgb-ufloat", - BC6HRGBFloat = "bc6h-rgb-float", - BC7RGBAUnorm = "bc7-rgba-unorm", - BC7RGBAUnormSRGB = "bc7-rgba-srgb", - - // ETC2 compressed formats usable if 'texture-compression-etc2' is both - // supported by the device/user agent and enabled in requestDevice. - - ETC2RGB8Unorm = "etc2-rgb8unorm", - ETC2RGB8UnormSRGB = "etc2-rgb8unorm-srgb", - ETC2RGB8A1Unorm = "etc2-rgb8a1unorm", - ETC2RGB8A1UnormSRGB = "etc2-rgb8a1unorm-srgb", - ETC2RGBA8Unorm = "etc2-rgba8unorm", - ETC2RGBA8UnormSRGB = "etc2-rgba8unorm-srgb", - EACR11Unorm = "eac-r11unorm", - EACR11Snorm = "eac-r11snorm", - EACRG11Unorm = "eac-rg11unorm", - EACRG11Snorm = "eac-rg11snorm", - - // ASTC compressed formats usable if 'texture-compression-astc' is both - // supported by the device/user agent and enabled in requestDevice. - - ASTC4x4Unorm = "astc-4x4-unorm", - ASTC4x4UnormSRGB = "astc-4x4-unorm-srgb", - ASTC5x4Unorm = "astc-5x4-unorm", - ASTC5x4UnormSRGB = "astc-5x4-unorm-srgb", - ASTC5x5Unorm = "astc-5x5-unorm", - ASTC5x5UnormSRGB = "astc-5x5-unorm-srgb", - ASTC6x5Unorm = "astc-6x5-unorm", - ASTC6x5UnormSRGB = "astc-6x5-unorm-srgb", - ASTC6x6Unorm = "astc-6x6-unorm", - ASTC6x6UnormSRGB = "astc-6x6-unorm-srgb", - ASTC8x5Unorm = "astc-8x5-unorm", - ASTC8x5UnormSRGB = "astc-8x5-unorm-srgb", - ASTC8x6Unorm = "astc-8x6-unorm", - ASTC8x6UnormSRGB = "astc-8x6-unorm-srgb", - ASTC8x8Unorm = "astc-8x8-unorm", - ASTC8x8UnormSRGB = "astc-8x8-unorm-srgb", - ASTC10x5Unorm = "astc-10x5-unorm", - ASTC10x5UnormSRGB = "astc-10x5-unorm-srgb", - ASTC10x6Unorm = "astc-10x6-unorm", - ASTC10x6UnormSRGB = "astc-10x6-unorm-srgb", - ASTC10x8Unorm = "astc-10x8-unorm", - ASTC10x8UnormSRGB = "astc-10x8-unorm-srgb", - ASTC10x10Unorm = "astc-10x10-unorm", - ASTC10x10UnormSRGB = "astc-10x10-unorm-srgb", - ASTC12x10Unorm = "astc-12x10-unorm", - ASTC12x10UnormSRGB = "astc-12x10-unorm-srgb", - ASTC12x12Unorm = "astc-12x12-unorm", - ASTC12x12UnormSRGB = "astc-12x12-unorm-srgb", -} - -export enum GPUAddressMode { - ClampToEdge = "clamp-to-edge", - Repeat = "repeat", - MirrorRepeat = "mirror-repeat", -} - -export enum GPUFilterMode { - Linear = "linear", - Nearest = "nearest", -} - -export enum GPUBlendFactor { - Zero = "zero", - One = "one", - Src = "src", - OneMinusSrc = "one-minus-src", - SrcAlpha = "src-alpha", - OneMinusSrcAlpha = "one-minus-src-alpha", - Dst = "dst", - OneMinusDstColor = "one-minus-dst", - DstAlpha = "dst-alpha", - OneMinusDstAlpha = "one-minus-dst-alpha", - SrcAlphaSaturated = "src-alpha-saturated", - Constant = "constant", - OneMinusConstant = "one-minus-constant", -} - -export enum GPUBlendOperation { - Add = "add", - Subtract = "subtract", - ReverseSubtract = "reverse-subtract", - Min = "min", - Max = "max", -} - -export enum GPUColorWriteFlags { - None = 0, - Red = 0x1, - Green = 0x2, - Blue = 0x4, - Alpha = 0x8, - All = 0xF, -} - -export enum GPUStencilOperation { - Keep = "keep", - Zero = "zero", - Replace = "replace", - Invert = "invert", - IncrementClamp = "increment-clamp", - DecrementClamp = "decrement-clamp", - IncrementWrap = "increment-wrap", - DecrementWrap = "decrement-wrap", -} - -export enum GPUBufferBindingType { - Uniform = "uniform", - Storage = "storage", - ReadOnlyStorage = "read-only-storage", -} - -export enum GPUStorageTextureAccess { - WriteOnly = "write-only", - ReadOnly = "read-only", - ReadWrite = "read-write", -} - -export enum GPUSamplerBindingType { - Filtering = "filtering", - NonFiltering = "non-filtering", - Comparison = "comparison", -} - -export enum GPUTextureSampleType { - Float = "float", - UnfilterableFloat = "unfilterable-float", - Depth = "depth", - SInt = "sint", - UInt = "uint", -} - -export enum GPUTextureDimension { - OneD = "1d", - TwoD = "2d", - ThreeD = "3d", -} - -export enum GPUTextureViewDimension { - OneD = "1d", - TwoD = "2d", - TwoDArray = "2d-array", - Cube = "cube", - CubeArray = "cube-array", - ThreeD = "3d", -} - -export enum GPUTextureAspect { - All = "all", - StencilOnly = "stencil-only", - DepthOnly = "depth-only", -} - -export enum GPUInputStepMode { - Vertex = "vertex", - Instance = "instance", -} - -export enum GPUFeatureName { - DepthClipControl = "depth-clip-control", - Depth32FloatStencil8 = "depth32float-stencil8", - TextureCompressionBC = "texture-compression-bc", - TextureCompressionETC2 = "texture-compression-etc2", - TextureCompressionASTC = "texture-compression-astc", - TimestampQuery = "timestamp-query", - IndirectFirstInstance = "indirect-first-instance", - ShaderF16 = "shader-f16", - RG11B10UFloat = "rg11b10ufloat-renderable", - BGRA8UNormStorage = "bgra8unorm-storage", - Float32Filterable = "float32-filterable", -} diff --git a/src-testing/src/renderers/webxr/WebXRController.d.ts b/src-testing/src/renderers/webxr/WebXRController.d.ts deleted file mode 100644 index 956a036b4..000000000 --- a/src-testing/src/renderers/webxr/WebXRController.d.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { Object3DEventMap } from "../../core/Object3D.js"; -import { Vector3 } from "../../math/Vector3.js"; -import { Group } from "../../objects/Group.js"; - -export type XRControllerEventType = XRSessionEventType | XRInputSourceEventType | "disconnected" | "connected"; - -export class XRJointSpace extends Group { - readonly jointRadius: number | undefined; -} - -export type XRHandJoints = Record; - -export interface XRHandInputState { - pinching: boolean; -} - -export interface WebXRSpaceEventMap extends Object3DEventMap { - select: { data: XRInputSource }; - selectstart: { data: XRInputSource }; - selectend: { data: XRInputSource }; - squeeze: { data: XRInputSource }; - squeezestart: { data: XRInputSource }; - squeezeend: { data: XRInputSource }; - - connected: { data: XRInputSource }; - disconnected: { data: XRInputSource }; - - pinchend: { handedness: XRHandedness; target: WebXRController }; // This Event break the THREE.EventDispatcher contract, replacing the target to the wrong instance. - pinchstart: { handedness: XRHandedness; target: WebXRController }; // This Event break the THREE.EventDispatcher contract, replacing the target to the wrong instance. - - move: {}; -} - -export class XRHandSpace extends Group { - readonly joints: Partial; - readonly inputState: XRHandInputState; -} - -export class XRTargetRaySpace extends Group { - hasLinearVelocity: boolean; - readonly linearVelocity: Vector3; - hasAngularVelocity: boolean; - readonly angularVelocity: Vector3; -} - -export class XRGripSpace extends Group { - hasLinearVelocity: boolean; - readonly linearVelocity: Vector3; - hasAngularVelocity: boolean; - readonly angularVelocity: Vector3; -} - -export class WebXRController { - constructor(); - - getHandSpace(): XRHandSpace; - getTargetRaySpace(): XRTargetRaySpace; - getGripSpace(): XRGripSpace; - dispatchEvent(event: { type: XRControllerEventType; data?: XRInputSource }): this; - connect(inputSource: XRInputSource): this; - disconnect(inputSource: XRInputSource): this; - update(inputSource: XRInputSource, frame: XRFrame, referenceSpace: XRReferenceSpace): this; -} diff --git a/src-testing/src/renderers/webxr/WebXRDepthSensing.d.ts b/src-testing/src/renderers/webxr/WebXRDepthSensing.d.ts deleted file mode 100644 index 23914f679..000000000 --- a/src-testing/src/renderers/webxr/WebXRDepthSensing.d.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Mesh } from "../../objects/Mesh.js"; -import { Texture } from "../../textures/Texture.js"; -import { WebGLRenderer } from "../WebGLRenderer.js"; -import { WebXRArrayCamera } from "./WebXRManager.js"; - -export class WebXRDepthSensing { - texture: Texture | null; - mesh: Mesh | null; - - depthNear: number; - depthFar: number; - - constructor(); - - init(renderer: WebGLRenderer, depthData: XRWebGLDepthInformation, renderState: XRRenderState): void; - - getMesh(cameraXR: WebXRArrayCamera): Mesh | null; - - reset(): void; - - getDepthTexture(): Texture | null; -} diff --git a/src-testing/src/renderers/webxr/WebXRManager.d.ts b/src-testing/src/renderers/webxr/WebXRManager.d.ts deleted file mode 100644 index 4b2073101..000000000 --- a/src-testing/src/renderers/webxr/WebXRManager.d.ts +++ /dev/null @@ -1,85 +0,0 @@ -/// - -import { ArrayCamera } from "../../cameras/ArrayCamera.js"; -import { PerspectiveCamera } from "../../cameras/PerspectiveCamera.js"; -import { EventDispatcher } from "../../core/EventDispatcher.js"; -import { Vector4 } from "../../math/Vector4.js"; -import { Mesh } from "../../objects/Mesh.js"; -import { Texture } from "../../textures/Texture.js"; -import { WebGLRenderer } from "../WebGLRenderer.js"; -import { XRGripSpace, XRHandSpace, XRTargetRaySpace } from "./WebXRController.js"; - -export type WebXRCamera = PerspectiveCamera & { viewport: Vector4 }; -export type WebXRArrayCamera = Omit & { cameras: [WebXRCamera, WebXRCamera] }; - -export interface WebXRManagerEventMap { - sessionstart: {}; - sessionend: {}; - planeadded: { data: XRPlane }; - planeremoved: { data: XRPlane }; - planechanged: { data: XRPlane }; - planesdetected: { data: XRPlaneSet }; -} - -export class WebXRManager extends EventDispatcher { - /** - * @default true - */ - cameraAutoUpdate: boolean; - - /** - * @default false - */ - enabled: boolean; - - /** - * @default false - */ - isPresenting: boolean; - - constructor(renderer: WebGLRenderer, gl: WebGLRenderingContext); - - getController: (index: number) => XRTargetRaySpace; - - getControllerGrip: (index: number) => XRGripSpace; - - getHand: (index: number) => XRHandSpace; - - setFramebufferScaleFactor: (value: number) => void; - - setReferenceSpaceType: (value: XRReferenceSpaceType) => void; - - getReferenceSpace: () => XRReferenceSpace | null; - - setReferenceSpace: (value: XRReferenceSpace) => void; - - getBaseLayer: () => XRWebGLLayer | XRProjectionLayer; - - getBinding: () => XRWebGLBinding; - - getFrame: () => XRFrame; - - getSession: () => XRSession | null; - - setSession: (value: XRSession | null) => Promise; - - getEnvironmentBlendMode: () => XREnvironmentBlendMode | undefined; - - getDepthTexture: () => Texture | null; - - updateCamera: (camera: PerspectiveCamera) => void; - - getCamera: () => WebXRArrayCamera; - - getFoveation: () => number | undefined; - - setFoveation: (value: number) => void; - - hasDepthSensing: () => boolean; - - getDepthSensingMesh: () => Mesh | null; - - setAnimationLoop: (callback: XRFrameRequestCallback | null) => void; - - dispose: () => void; -} diff --git a/src-testing/src/scenes/Fog.d.ts b/src-testing/src/scenes/Fog.d.ts deleted file mode 100644 index fc0f18019..000000000 --- a/src-testing/src/scenes/Fog.d.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { Color, ColorRepresentation } from "../math/Color.js"; - -export interface FogJSON { - type: string; - name: string; - color: number; - near: number; - far: number; -} - -/** - * This class contains the parameters that define linear fog, i.e., that grows linearly denser with the distance. - * @example - * ```typescript - * const scene = new THREE.Scene(); - * scene.fog = new THREE.Fog(0xcccccc, 10, 15); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/scenes/Fog | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/scenes/Fog.js | Source} - */ -export class Fog { - /** - * The color parameter is passed to the {@link THREE.Color | Color} constructor to set the color property - * @remarks - * Color can be a hexadecimal integer or a CSS-style string. - * @param color - * @param near Expects a `Float` - * @param far Expects a `Float` - */ - constructor(color: ColorRepresentation, near?: number, far?: number); - - /** - * Read-only flag to check if a given object is of type {@link Fog}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isFog: true; - - /** - * Optional name of the object - * @remarks _(doesn't need to be unique)_. - * @defaultValue `""` - */ - name: string; - - /** - * Fog color. - * @remarks If set to black, far away objects will be rendered black. - */ - color: Color; - - /** - * The minimum distance to start applying fog. - * @remarks Objects that are less than **near** units from the active camera won't be affected by fog. - * @defaultValue `1` - * @remarks Expects a `Float` - */ - near: number; - - /** - * The maximum distance at which fog stops being calculated and applied. - * @remarks Objects that are more than **far** units away from the active camera won't be affected by fog. - * @defaultValue `1000` - * @remarks Expects a `Float` - */ - far: number; - - /** - * Returns a new {@link Fog} instance with the same parameters as this one. - */ - clone(): Fog; - - /** - * Return {@link Fog} data in JSON format. - */ - toJSON(): FogJSON; -} diff --git a/src-testing/src/scenes/FogExp2.d.ts b/src-testing/src/scenes/FogExp2.d.ts deleted file mode 100644 index af00981e6..000000000 --- a/src-testing/src/scenes/FogExp2.d.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { Color, ColorRepresentation } from "../math/Color.js"; - -export interface FogExp2JSON { - type: string; - name: string; - color: number; - density: number; -} - -/** - * This class contains the parameters that define exponential squared fog, which gives a clear view near the camera and a faster than exponentially densening fog farther from the camera. - * @example - * ```typescript - * const scene = new THREE.Scene(); - * scene.fog = new THREE.FogExp2(0xcccccc, 0.002); - * ``` - * @see Example: {@link https://threejs.org/examples/#webgl_geometry_terrain | webgl geometry terrain} - * @see {@link https://threejs.org/docs/index.html#api/en/scenes/FogExp2 | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/scenes/FogExp2.js | Source} - */ -export class FogExp2 { - /** - * The color parameter is passed to the {@link THREE.Color | Color} constructor to set the color property - * @remarks Color can be a hexadecimal integer or a CSS-style string. - * @param color - * @param density Expects a `Float` - */ - constructor(color: ColorRepresentation, density?: number); - - /** - * Read-only flag to check if a given object is of type {@link FogExp2}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isFogExp2: true; - - /** - * Optional name of the object - * @remarks _(doesn't need to be unique)_. - * @defaultValue `""` - */ - name: string; - - /** - * Fog color. - * @remarks If set to black, far away objects will be rendered black. - */ - color: Color; - - /** - * Defines how fast the fog will grow dense. - * @defaultValue `0.00025` - * @remarks Expects a `Float` - */ - density: number; - - /** - * Returns a new {@link FogExp2} instance with the same parameters as this one. - */ - clone(): FogExp2; - - /** - * Return {@link FogExp2} data in JSON format. - */ - toJSON(): FogExp2JSON; -} diff --git a/src-testing/src/scenes/Scene.d.ts b/src-testing/src/scenes/Scene.d.ts deleted file mode 100644 index c2f43afd7..000000000 --- a/src-testing/src/scenes/Scene.d.ts +++ /dev/null @@ -1,118 +0,0 @@ -import { JSONMeta, Object3D, Object3DJSON, Object3DJSONObject } from "../core/Object3D.js"; -import { Material } from "../materials/Material.js"; -import { Color } from "../math/Color.js"; -import { Euler, EulerTuple } from "../math/Euler.js"; -import { CubeTexture } from "../textures/CubeTexture.js"; -import { Texture } from "../textures/Texture.js"; -import { Fog, FogJSON } from "./Fog.js"; -import { FogExp2, FogExp2JSON } from "./FogExp2.js"; - -export interface SceneJSONObject extends Object3DJSONObject { - fog?: FogJSON | FogExp2JSON; - - backgroundBlurriness?: number; - backgroundIntensity?: number; - backgroundRotation: EulerTuple; - - environmentIntensity?: number; - environmentRotation: EulerTuple; -} - -export interface SceneJSON extends Object3DJSON { - object: SceneJSONObject; -} - -/** - * Scenes allow you to set up what and where is to be rendered by three.js - * @remarks - * This is where you place objects, lights and cameras. - * @see Example: {@link https://threejs.org/examples/#webgl_multiple_scenes_comparison | webgl multiple scenes comparison} - * @see {@link https://threejs.org/docs/index.html#manual/en/introduction/Creating-a-scene | Manual: Creating a scene} - * @see {@link https://threejs.org/docs/index.html#api/en/scenes/Scene | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/scenes/Scene.js | Source} - */ -export class Scene extends Object3D { - /** - * Create a new {@link Scene} object. - */ - constructor(); - - /** - * Read-only flag to check if a given object is of type {@link Scene}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isScene: true; - - /** - * @defaultValue `Scene` - */ - type: "Scene"; - - /** - * A {@link Fog | fog} instance defining the type of fog that affects everything rendered in the scene. - * @defaultValue `null` - */ - fog: Fog | FogExp2 | null; - - /** - * Sets the blurriness of the background. Only influences environment maps assigned to {@link THREE.Scene.background | Scene.background}. - * @defaultValue `0` - * @remarks Expects a `Float` between `0` and `1`. - */ - backgroundBlurriness: number; - - /** - * Attenuates the color of the background. Only applies to background textures. - * @defaultValue `1` - * @remarks Expects a `Float` - */ - backgroundIntensity: number; - - /** - * Forces everything in the {@link Scene} to be rendered with the defined material. - * @defaultValue `null` - */ - overrideMaterial: Material | null; - - /** - * Defines the background of the scene. - * @remarks Valid inputs are: - * - A {@link THREE.Color | Color} for defining a uniform colored background. - * - A {@link THREE.Texture | Texture} for defining a (flat) textured background. - * - Texture cubes ({@link THREE.CubeTexture | CubeTexture}) or equirectangular textures for defining a skybox. - * @defaultValue `null` - */ - background: Color | Texture | CubeTexture | null; - - /** - * The rotation of the background in radians. Only influences environment maps assigned to {@link .background}. - * Default is `(0,0,0)`. - */ - backgroundRotation: Euler; - - /** - * Sets the environment map for all physical materials in the scene. - * However, it's not possible to overwrite an existing texture assigned to {@link THREE.MeshStandardMaterial.envMap | MeshStandardMaterial.envMap}. - * @defaultValue `null` - */ - environment: Texture | null; - - /** - * Attenuates the color of the environment. Only influences environment maps assigned to {@link Scene.environment}. - * @default 1 - */ - environmentIntensity: number; - - /** - * The rotation of the environment map in radians. Only influences physical materials in the scene when - * {@link .environment} is used. Default is `(0,0,0)`. - */ - environmentRotation: Euler; - - /** - * Convert the {@link Scene} to three.js {@link https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 | JSON Object/Scene format}. - * @param meta Object containing metadata such as textures or images for the scene. - */ - toJSON(meta?: JSONMeta): SceneJSON; -} diff --git a/src-testing/src/textures/CanvasTexture.d.ts b/src-testing/src/textures/CanvasTexture.d.ts deleted file mode 100644 index 6445338fa..000000000 --- a/src-testing/src/textures/CanvasTexture.d.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { - MagnificationTextureFilter, - Mapping, - MinificationTextureFilter, - PixelFormat, - TextureDataType, - Wrapping, -} from "../constants.js"; -import { OffscreenCanvas, Texture } from "./Texture.js"; - -/** - * Creates a texture from a {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas | canvas element}. - * @remarks - * This is almost the same as the base {@link Texture | Texture} class, - * except that it sets {@link Texture.needsUpdate | needsUpdate} to `true` immediately. - * @see {@link THREE.Texture | Texture} - * @see {@link https://threejs.org/docs/index.html#api/en/textures/CanvasTexture | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/textures/CanvasTexture.js | Source} - */ -export class CanvasTexture extends Texture { - /** - * This creates a new {@link THREE.CanvasTexture | CanvasTexture} object. - * @param canvas The HTML canvas element from which to load the texture. - * @param mapping See {@link Texture.mapping | .mapping}. Default {@link THREE.Texture.DEFAULT_MAPPING} - * @param wrapS See {@link Texture.wrapS | .wrapS}. Default {@link THREE.ClampToEdgeWrapping} - * @param wrapT See {@link Texture.wrapT | .wrapT}. Default {@link THREE.ClampToEdgeWrapping} - * @param magFilter See {@link Texture.magFilter | .magFilter}. Default {@link THREE.LinearFilter} - * @param minFilter See {@link Texture.minFilter | .minFilter}. Default {@link THREE.LinearMipmapLinearFilter} - * @param format See {@link Texture.format | .format}. Default {@link THREE.RGBAFormat} - * @param type See {@link Texture.type | .type}. Default {@link THREE.UnsignedByteType} - * @param anisotropy See {@link Texture.anisotropy | .anisotropy}. Default {@link THREE.Texture.DEFAULT_ANISOTROPY} - */ - constructor( - canvas: TexImageSource | OffscreenCanvas, - mapping?: Mapping, - wrapS?: Wrapping, - wrapT?: Wrapping, - magFilter?: MagnificationTextureFilter, - minFilter?: MinificationTextureFilter, - format?: PixelFormat, - type?: TextureDataType, - anisotropy?: number, - ); - - /** - * Read-only flag to check if a given object is of type {@link CanvasTexture}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isCanvasTexture: true; -} diff --git a/src-testing/src/textures/CompressedArrayTexture.d.ts b/src-testing/src/textures/CompressedArrayTexture.d.ts deleted file mode 100644 index e46c3d478..000000000 --- a/src-testing/src/textures/CompressedArrayTexture.d.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { CompressedPixelFormat, TextureDataType, Wrapping } from "../constants.js"; -import { CompressedTexture, CompressedTextureMipmap } from "./CompressedTexture.js"; - -/** - * Creates an texture 2D array based on data in compressed form, for example from a - * {@link https://en.wikipedia.org/wiki/DirectDraw_Surface | DDS} file. - * @remarks For use with the {@link THREE.CompressedTextureLoader | CompressedTextureLoader}. - * @see {@link https://threejs.org/docs/index.html#api/en/textures/CompressedArrayTexture | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/textures/CompressedArrayTexture.js | Source} - */ -export class CompressedArrayTexture extends CompressedTexture { - /** - * Read-only flag to check if a given object is of type {@link CompressedArrayTexture}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isCompressedArrayTexture: true; - - /** - * Overridden with a object containing width and height. - * @override - */ - get image(): { width: number; height: number; depth: number }; - set image(value: { width: number; height: number; depth: number }); - - /** - * This defines how the texture is wrapped in the depth direction. - * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} - * @defaultValue {@link THREE.ClampToEdgeWrapping} - */ - wrapR: Wrapping; - - /** - * A set of all layers which need to be updated in the texture. See {@link CompressedArrayTexture.addLayerUpdate}. - */ - layerUpdates: Set; - - /** - * Create a new instance of {@link CompressedArrayTexture} - * @param mipmaps The mipmaps array should contain objects with data, width and height. The mipmaps should be of the - * correct format and type. - * @param width The width of the biggest mipmap. - * @param height The height of the biggest mipmap. - * @param depth The number of layers of the 2D array texture - * @param format The format used in the mipmaps. See {@link THREE.CompressedPixelFormat}. - * @param type See {@link Texture.type | .type}. Default {@link THREE.UnsignedByteType} - */ - constructor( - mipmaps: CompressedTextureMipmap[], - width: number, - height: number, - depth: number, - format: CompressedPixelFormat, - type?: TextureDataType, - ); - - /** - * Describes that a specific layer of the texture needs to be updated. Normally when {@link Texture.needsUpdate} is - * set to true, the entire compressed texture array is sent to the GPU. Marking specific layers will only transmit - * subsets of all mipmaps associated with a specific depth in the array which is often much more performant. - */ - addLayerUpdate(layerIndex: number): void; - - /** - * Resets the layer updates registry. See {@link CompressedArrayTexture.addLayerUpdate}. - */ - clearLayoutUpdates(): void; -} diff --git a/src-testing/src/textures/CompressedCubeTexture.d.ts b/src-testing/src/textures/CompressedCubeTexture.d.ts deleted file mode 100644 index 9c72145a0..000000000 --- a/src-testing/src/textures/CompressedCubeTexture.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { CompressedPixelFormat, TextureDataType } from "../constants.js"; -import { CompressedTexture } from "./CompressedTexture.js"; - -export class CompressedCubeTexture extends CompressedTexture { - readonly isCompressedCubeTexture: true; - readonly isCubeTexture: true; - - constructor( - images: Array<{ width: number; height: number }>, - format?: CompressedPixelFormat, - type?: TextureDataType, - ); -} diff --git a/src-testing/src/textures/CompressedTexture.d.ts b/src-testing/src/textures/CompressedTexture.d.ts deleted file mode 100644 index 33ec5b17d..000000000 --- a/src-testing/src/textures/CompressedTexture.d.ts +++ /dev/null @@ -1,94 +0,0 @@ -import { - CompressedPixelFormat, - MagnificationTextureFilter, - Mapping, - MinificationTextureFilter, - TextureDataType, - Wrapping, -} from "../constants.js"; -import { TypedArray } from "../core/BufferAttribute.js"; -import { Texture } from "./Texture.js"; - -export interface CompressedTextureMipmap { - data: TypedArray; - width: number; - height: number; -} - -/** - * Creates a texture based on data in compressed form, for example from a {@link https://en.wikipedia.org/wiki/DirectDraw_Surface | DDS} file. - * @remarks For use with the {@link THREE.CompressedTextureLoader | CompressedTextureLoader}. - * @see {@link https://threejs.org/docs/index.html#api/en/textures/CompressedTexture | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/textures/CompressedTexture.js | Source} - */ -export class CompressedTexture extends Texture { - /** - * This creates a new {@link THREE.CompressedTexture | CompressedTexture} object. - * @param mipmaps The mipmaps array should contain objects with data, width and height. The mipmaps should be of the - * correct format and type. - * @param width The width of the biggest mipmap. - * @param height The height of the biggest mipmap. - * @param format The format used in the mipmaps. See {@link THREE.CompressedPixelFormat}. - * @param type See {@link Texture.type | .type}. Default {@link THREE.UnsignedByteType} - * @param mapping See {@link Texture.mapping | .mapping}. Default {@link THREE.Texture.DEFAULT_MAPPING} - * @param wrapS See {@link Texture.wrapS | .wrapS}. Default {@link THREE.ClampToEdgeWrapping} - * @param wrapT See {@link Texture.wrapT | .wrapT}. Default {@link THREE.ClampToEdgeWrapping} - * @param magFilter See {@link Texture.magFilter | .magFilter}. Default {@link THREE.LinearFilter} - * @param minFilter See {@link Texture.minFilter | .minFilter}. Default {@link THREE.LinearMipmapLinearFilter} - * @param anisotropy See {@link Texture.anisotropy | .anisotropy}. Default {@link THREE.Texture.DEFAULT_ANISOTROPY} - * @param colorSpace See {@link Texture.colorSpace .colorSpace}. Default {@link NoColorSpace} - */ - constructor( - mipmaps?: CompressedTextureMipmap[], - width?: number, - height?: number, - format?: CompressedPixelFormat, - type?: TextureDataType, - mapping?: Mapping, - wrapS?: Wrapping, - wrapT?: Wrapping, - magFilter?: MagnificationTextureFilter, - minFilter?: MinificationTextureFilter, - anisotropy?: number, - colorSpace?: string, - ); - - /** - * Read-only flag to check if a given object is of type {@link CompressedTexture}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isCompressedTexture: true; - - /** - * Overridden with a object containing width and height. - * @override - */ - get image(): { width: number; height: number }; - set image(value: { width: number; height: number }); - - /** - * The mipmaps array should contain objects with data, width and height. The mipmaps should be of the correct - * format and type. - */ - mipmaps: CompressedTextureMipmap[] | undefined; - - /** - * @override - * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} - * @see {@link THREE.CompressedPixelFormat} - */ - format: CompressedPixelFormat; - - /** - * @override No flipping for cube textures. (also flipping doesn't work for compressed textures) - * @defaultValue `false` - */ - flipY: boolean; - - /** - * @override Can't generate mipmaps for compressed textures. mips must be embedded in DDS files - * @defaultValue `false` - */ - generateMipmaps: boolean; -} diff --git a/src-testing/src/textures/CubeTexture.d.ts b/src-testing/src/textures/CubeTexture.d.ts deleted file mode 100644 index f5808aaf9..000000000 --- a/src-testing/src/textures/CubeTexture.d.ts +++ /dev/null @@ -1,89 +0,0 @@ -import { - CubeTextureMapping, - MagnificationTextureFilter, - MinificationTextureFilter, - PixelFormat, - TextureDataType, - Wrapping, -} from "../constants.js"; -import { Texture } from "./Texture.js"; - -/** - * Creates a cube texture made up of six images. - * @remarks - * {@link CubeTexture} is almost equivalent in functionality and usage to {@link Texture}. - * The only differences are that the images are an array of _6_ images as opposed to a single image, - * and the mapping options are {@link THREE.CubeReflectionMapping} (default) or {@link THREE.CubeRefractionMapping} - * @example - * ```typescript - * const loader = new THREE.CubeTextureLoader(); - * loader.setPath('textures/cube/pisa/'); - * const textureCube = loader.load(['px.png', 'nx.png', 'py.png', 'ny.png', 'pz.png', 'nz.png']); - * const material = new THREE.MeshBasicMaterial({ - * color: 0xffffff, - * envMap: textureCube - * }); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/textures/CubeTexture | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/textures/CubeTexture.js | Source} - */ -export class CubeTexture extends Texture { - /** - * This creates a new {@link THREE.CubeTexture | CubeTexture} object. - * @param images - * @param mapping See {@link CubeTexture.mapping | .mapping}. Default {@link THREE.CubeReflectionMapping} - * @param wrapS See {@link Texture.wrapS | .wrapS}. Default {@link THREE.ClampToEdgeWrapping} - * @param wrapT See {@link Texture.wrapT | .wrapT}. Default {@link THREE.ClampToEdgeWrapping} - * @param magFilter See {@link Texture.magFilter | .magFilter}. Default {@link THREE.LinearFilter} - * @param minFilter See {@link Texture.minFilter | .minFilter}. Default {@link THREE.LinearMipmapLinearFilter} - * @param format See {@link Texture.format | .format}. Default {@link THREE.RGBAFormat} - * @param type See {@link Texture.type | .type}. Default {@link THREE.UnsignedByteType} - * @param anisotropy See {@link Texture.anisotropy | .anisotropy}. Default {@link THREE.Texture.DEFAULT_ANISOTROPY} - * @param colorSpace See {@link Texture.colorSpace | .colorSpace}. Default {@link NoColorSpace} - */ - constructor( - images?: any[], // HTMLImageElement or HTMLCanvasElement - mapping?: CubeTextureMapping, - wrapS?: Wrapping, - wrapT?: Wrapping, - magFilter?: MagnificationTextureFilter, - minFilter?: MinificationTextureFilter, - format?: PixelFormat, - type?: TextureDataType, - anisotropy?: number, - colorSpace?: string, - ); - - /** - * Read-only flag to check if a given object is of type {@link CubeTexture}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isCubeTexture: true; - - /** - * An image object, typically created using the {@link THREE.CubeTextureLoader.load | CubeTextureLoader.load()} method. - * @see {@link Texture.image} - */ - get image(): any; - set image(data: any); - - /** - * An image object, typically created using the {@link THREE.CubeTextureLoader.load | CubeTextureLoader.load()} method. - * @see {@link Texture.image} - */ - get images(): any; - set images(data: any); - - /** - * @inheritDoc - * @defaultValue {@link THREE.CubeReflectionMapping} - */ - mapping: CubeTextureMapping; - - /** - * @inheritDoc - * @defaultValue `false` - */ - flipY: boolean; -} diff --git a/src-testing/src/textures/Data3DTexture.d.ts b/src-testing/src/textures/Data3DTexture.d.ts deleted file mode 100644 index 9e5986eed..000000000 --- a/src-testing/src/textures/Data3DTexture.d.ts +++ /dev/null @@ -1,96 +0,0 @@ -import { MagnificationTextureFilter, MinificationTextureFilter, Wrapping } from "../constants.js"; -import { Texture } from "./Texture.js"; -import { Texture3DImageData } from "./types.js"; - -/** - * Creates a three-dimensional texture from raw data, with parameters to divide it into width, height, and depth - * @example - * ```typescript - * This creates a[name] with repeating data, 0 to 255 - * // create a buffer with some data - * const sizeX = 64; - * const sizeY = 64; - * const sizeZ = 64; - * const data = new Uint8Array(sizeX * sizeY * sizeZ); - * let i = 0; - * for (let z = 0; z & lt; sizeZ; z++) { - * for (let y = 0; y & lt; sizeY; y++) { - * for (let x = 0; x & lt; sizeX; x++) { - * data[i] = i % 256; - * i++; - * } - * } - * } - * // use the buffer to create the texture - * const texture = new THREE.Data3DTexture(data, sizeX, sizeY, sizeZ); - * texture.needsUpdate = true; - * ``` - * @see Example: {@link https://threejs.org/examples/#webgl2_materials_texture3d | WebGL2 / materials / texture3d} - * @see Example: {@link https://threejs.org/examples/#webgl2_materials_texture3d_partialupdate | WebGL2 / materials / texture3d / partialupdate} - * @see Example: {@link https://threejs.org/examples/#webgl2_volume_cloud | WebGL2 / volume / cloud} - * @see Example: {@link https://threejs.org/examples/#webgl2_volume_perlin | WebGL2 / volume / perlin} - * @see {@link https://threejs.org/docs/index.html#api/en/textures/Data3DTexture | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/textures/Data3DTexture.js | Source} - */ -export class Data3DTexture extends Texture { - /** - * Create a new instance of {@link Data3DTexture} - * @param data {@link https://developer.mozilla.org/en-US/docs/Web/API/ArrayBufferView | ArrayBufferView} of the texture. Default `null`. - * @param width Width of the texture. Default `1`. - * @param height Height of the texture. Default `1`. - * @param depth Depth of the texture. Default `1`. - */ - constructor(data?: BufferSource | null, width?: number, height?: number, depth?: number); - - /** - * Read-only flag to check if a given object is of type {@link Data3DTexture}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isData3DTexture: true; - - /** - * Overridden with a record type holding data, width and height and depth. - * @override - */ - get image(): Texture3DImageData; - set image(data: Texture3DImageData); - - /** - * @override - * @defaultValue {@link THREE.NearestFilter} - */ - magFilter: MagnificationTextureFilter; - - /** - * @override - * @defaultValue {@link THREE.NearestFilter} - */ - minFilter: MinificationTextureFilter; - - /** - * @override - * @defaultValue {@link THREE.ClampToEdgeWrapping} - */ - wrapR: Wrapping; - - /** - * @override - * @defaultValue `false` - */ - flipY: boolean; - - /** - * @override - * @defaultValue `false` - */ - generateMipmaps: boolean; - - /** - * @override - * @defaultValue `1` - */ - unpackAlignment: number; -} - -export {}; diff --git a/src-testing/src/textures/DataArrayTexture.d.ts b/src-testing/src/textures/DataArrayTexture.d.ts deleted file mode 100644 index d3a82c1e8..000000000 --- a/src-testing/src/textures/DataArrayTexture.d.ts +++ /dev/null @@ -1,123 +0,0 @@ -import { MagnificationTextureFilter, MinificationTextureFilter } from "../constants.js"; -import { Texture } from "./Texture.js"; -import { Texture3DImageData } from "./types.js"; - -/** - * Creates an array of textures directly from raw data, width and height and depth - * @example - * ```typescript - * This creates a[name] where each texture has a different color. - * // create a buffer with color data - * const width = 512; - * const height = 512; - * const depth = 100; - * const size = width * height; - * const data = new Uint8Array(4 * size * depth); - * for (let i = 0; i & lt; depth; i++) { - * const color = new THREE.Color(Math.random(), Math.random(), Math.random()); - * const r = Math.floor(color.r * 255); - * const g = Math.floor(color.g * 255); - * const b = Math.floor(color.b * 255); - * for (let j = 0; j & lt; size; j++) { - * const stride = (i * size + j) * 4; - * data[stride] = r; - * data[stride + 1] = g; - * data[stride + 2] = b; - * data[stride + 3] = 255; - * } - * } - * // used the buffer to create a [name] - * const texture = new THREE.DataArrayTexture(data, width, height, depth); - * texture.needsUpdate = true; - * ``` - * @see Example: {@link https://threejs.org/examples/#webgl2_materials_texture2darray | WebGL2 / materials / texture2darray} - * @see Example: {@link https://threejs.org/examples/#webgl2_rendertarget_texture2darray | WebGL2 / rendertarget / texture2darray} - * @see {@link https://threejs.org/docs/index.html#api/en/textures/DataArrayTexture | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/textures/DataArrayTexture.js | Source} - */ -export class DataArrayTexture extends Texture { - /** - * Read-only flag to check if a given object is of type {@link DataArrayTexture}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isDataArrayTexture: true; - - /** - * Overridden with a record type holding data, width and height and depth. - * @override - */ - get image(): Texture3DImageData; - set image(data: Texture3DImageData); - - /** - * @override - * @defaultValue {@link THREE.NearestFilter} - */ - magFilter: MagnificationTextureFilter; - - /** - * @override - * @defaultValue {@link THREE.NearestFilter} - */ - minFilter: MinificationTextureFilter; - - /** - * @override - * @defaultValue {@link THREE.ClampToEdgeWrapping} - */ - wrapR: boolean; - - /** - * @override - * @defaultValue `false` - */ - generateMipmaps: boolean; - - /** - * @override - * @defaultValue `false` - */ - flipY: boolean; - - /** - * @override - * @defaultValue `1` - */ - unpackAlignment: number; - - /** - * A set of all layers which need to be updated in the texture. See {@link DataArrayTexture.addLayerUpdate}. - */ - layerUpdates: Set; - - /** - * This creates a new {@link THREE.DataArrayTexture | DataArrayTexture} object. - * @remarks The interpretation of the data depends on {@link format} and {@link type}. - * @remarks If the {@link type} is {@link THREE.UnsignedByteType}, a {@link Uint8Array} will be useful for addressing the texel data - * @remarks If the {@link format} is {@link THREE.RGBAFormat}, data needs four values for one texel; Red, Green, Blue and Alpha (typically the opacity). - * @remarks For the packed {@link type | types}, {@link THREE.UnsignedShort4444Type} and {@link THREE.UnsignedShort5551Type} - * all color components of one texel can be addressed as bitfields within an integer element of a {@link Uint16Array}. - * @remarks In order to use the {@link type | types} {@link THREE.FloatType} and {@link THREE.HalfFloatType}, - * the WebGL implementation must support the respective extensions _OES_texture_float_ and _OES_texture_half_float_ - * @remarks In order to use {@link THREE.LinearFilter} for component-wise, bilinear interpolation of the texels based on these types, - * the WebGL extensions _OES_texture_float_linear_ or _OES_texture_half_float_linear_ must also be present. - * @param data {@link https://developer.mozilla.org/en-US/docs/Web/API/ArrayBufferView | ArrayBufferView} of the texture. Default `null`. - * @param width Width of the texture. Default `1`. - * @param height Height of the texture. Default `1`. - * @param depth Depth of the texture. Default `1`. - */ - constructor(data?: BufferSource | null, width?: number, height?: number, depth?: number); - - /** - * Describes that a specific layer of the texture needs to be updated. Normally when {@link Texture.needsUpdate} is - * set to true, the entire compressed texture array is sent to the GPU. Marking specific layers will only transmit - * subsets of all mipmaps associated with a specific depth in the array which is often much more performant. - */ - addLayerUpdate(layerIndex: number): void; - - /** - * Resets the layer updates registry. See {@link DataArrayTexture.addLayerUpdate}. - */ - clearLayoutUpdates(): void; -} diff --git a/src-testing/src/textures/DataTexture.d.ts b/src-testing/src/textures/DataTexture.d.ts deleted file mode 100644 index 605450990..000000000 --- a/src-testing/src/textures/DataTexture.d.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { - MagnificationTextureFilter, - Mapping, - MinificationTextureFilter, - PixelFormat, - TextureDataType, - Wrapping, -} from "../constants.js"; -import { Texture } from "./Texture.js"; -import { TextureImageData } from "./types.js"; - -/** - * Creates a texture directly from raw data, width and height. - * @example - * ```typescript - * // create a buffer with color data - * const width = 512; - * const height = 512; - * const size = width * height; - * const data = new Uint8Array(4 * size); - * const color = new THREE.Color(0xffffff); - * const r = Math.floor(color.r * 255); - * const g = Math.floor(color.g * 255); - * const b = Math.floor(color.b * 255); - * for (let i = 0; i & lt; size; i++) { - * const stride = i * 4; - * data[stride] = r; - * data[stride + 1] = g; - * data[stride + 2] = b; - * data[stride + 3] = 255; - * } - * // used the buffer to create a [name] - * const texture = new THREE.DataTexture(data, width, height); - * texture.needsUpdate = true; - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/textures/DataTexture | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/textures/DataTexture.js | Source} - */ -export class DataTexture extends Texture { - /** - * @param data {@link https://developer.mozilla.org/en-US/docs/Web/API/ArrayBufferView | ArrayBufferView} of the texture. Default `null`. - * @param width Width of the texture. Default `1`. - * @param height Height of the texture. Default `1`. - * @param format See {@link Texture.format | .format}. Default {@link THREE.RGBAFormat} - * @param type See {@link Texture.type | .type}. Default {@link THREE.UnsignedByteType} - * @param mapping See {@link Texture.mapping | .mapping}. Default {@link THREE.Texture.DEFAULT_MAPPING} - * @param wrapS See {@link Texture.wrapS | .wrapS}. Default {@link THREE.ClampToEdgeWrapping} - * @param wrapT See {@link Texture.wrapT | .wrapT}. Default {@link THREE.ClampToEdgeWrapping} - * @param magFilter See {@link Texture.magFilter | .magFilter}. Default {@link THREE.NearestFilter} - * @param minFilter See {@link Texture.minFilter | .minFilter}. Default {@link THREE.NearestFilter} - * @param anisotropy See {@link Texture.anisotropy | .anisotropy}. Default {@link THREE.Texture.DEFAULT_ANISOTROPY} - * @param colorSpace See {@link Texture.colorSpace | .colorSpace}. Default {@link NoColorSpace} - */ - constructor( - data?: BufferSource | null, - width?: number, - height?: number, - format?: PixelFormat, - type?: TextureDataType, - mapping?: Mapping, - wrapS?: Wrapping, - wrapT?: Wrapping, - magFilter?: MagnificationTextureFilter, - minFilter?: MinificationTextureFilter, - anisotropy?: number, - colorSpace?: string, - ); - - /** - * Read-only flag to check if a given object is of type {@link DataTexture}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isDataTexture: true; - - /** - * Overridden with a record type holding data, width and height and depth. - * @override - */ - get image(): TextureImageData; - set image(value: TextureImageData); - - /** - * @override - * @defaultValue {@link THREE.NearestFilter} - */ - magFilter: MagnificationTextureFilter; - - /** - * @override - * @defaultValue {@link THREE.NearestFilter} - */ - minFilter: MinificationTextureFilter; - - /** - * @override - * @defaultValue `false` - */ - flipY: boolean; - - /** - * @override - * @defaultValue `false` - */ - generateMipmaps: boolean; - - /** - * @override - * @defaultValue `1` - */ - unpackAlignment: number; -} diff --git a/src-testing/src/textures/DepthTexture.d.ts b/src-testing/src/textures/DepthTexture.d.ts deleted file mode 100644 index f524e91cc..000000000 --- a/src-testing/src/textures/DepthTexture.d.ts +++ /dev/null @@ -1,104 +0,0 @@ -import { - DepthTexturePixelFormat, - MagnificationTextureFilter, - Mapping, - MinificationTextureFilter, - TextureComparisonFunction, - TextureDataType, - Wrapping, -} from "../constants.js"; -import { Texture } from "./Texture.js"; - -/** - * This class can be used to automatically save the depth information of a rendering into a texture - * @see Example: {@link https://threejs.org/examples/#webgl_depth_texture | depth / texture} - * @see {@link https://threejs.org/docs/index.html#api/en/textures/DepthTexture | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/textures/DepthTexture.js | Source} - */ -export class DepthTexture extends Texture { - /** - * Create a new instance of {@link DepthTexture} - * @param width Width of the texture. - * @param height Height of the texture. - * @param type See {@link Texture.type | .type}. Default {@link THREE.UnsignedByteType} or {@link THREE.UnsignedInt248Type} - * @param mapping See {@link Texture.mapping | .mapping}. Default {@link THREE.Texture.DEFAULT_MAPPING} - * @param wrapS See {@link Texture.wrapS | .wrapS}. Default {@link THREE.ClampToEdgeWrapping} - * @param wrapT See {@link Texture.wrapT | .wrapT}. Default {@link THREE.ClampToEdgeWrapping} - * @param magFilter See {@link Texture.magFilter | .magFilter}. Default {@link THREE.NearestFilter} - * @param minFilter See {@link Texture.minFilter | .minFilter}. Default {@link THREE.NearestFilter} - * @param anisotropy See {@link Texture.anisotropy | .anisotropy}. Default {@link THREE.Texture.DEFAULT_ANISOTROPY} - * @param format See {@link DepthTexture.format | .format}. Default {@link THREE.DepthFormat} - */ - constructor( - width: number, - height: number, - type?: TextureDataType, - mapping?: Mapping, - wrapS?: Wrapping, - wrapT?: Wrapping, - magFilter?: MagnificationTextureFilter, - minFilter?: MinificationTextureFilter, - anisotropy?: number, - format?: DepthTexturePixelFormat, - ); - - /** - * Read-only flag to check if a given object is of type {@link DepthTexture}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isDepthTexture: true; - - /** - * Overridden with a record type holding width and height. - * @override - */ - get image(): { width: number; height: number }; - set image(value: { width: number; height: number }); - - /** - * @override - * @defaultValue `false` - */ - flipY: boolean; - - /** - * @override - * @defaultValue {@link THREE.NearestFilter} - */ - magFilter: MagnificationTextureFilter; - - /** - * @override - * @defaultValue {@link THREE.NearestFilter} - */ - minFilter: MinificationTextureFilter; - - /** - * @override Depth textures do not use mipmaps. - * @defaultValue `false` - */ - generateMipmaps: boolean; - - /** - * @override - * @see {@link Texture.format | Texture.format} - * @defaultValue {@link THREE.DepthFormat}. - */ - format: DepthTexturePixelFormat; - - /** - * @override - * @defaultValue {@link THREE.UnsignedByteType} when {@link format | .format} === {@link THREE.DepthFormat} - * @defaultValue {@link THREE.UnsignedInt248Type} when {@link format | .format} === {@link THREE.DepthStencilFormat} - */ - type: TextureDataType; - - /** - * This is used to define the comparison function used when comparing texels in the depth texture to the value in - * the depth buffer. Default is `null` which means comparison is disabled. - * - * See {@link THREE.TextureComparisonFunction} for functions. - */ - compareFunction: TextureComparisonFunction | null; -} diff --git a/src-testing/src/textures/FramebufferTexture.d.ts b/src-testing/src/textures/FramebufferTexture.d.ts deleted file mode 100644 index ad54c5175..000000000 --- a/src-testing/src/textures/FramebufferTexture.d.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { MagnificationTextureFilter, MinificationTextureFilter } from "../constants.js"; -import { Texture } from "./Texture.js"; - -/** - * This class can only be used in combination with {@link THREE.WebGLRenderer.copyFramebufferToTexture | WebGLRenderer.copyFramebufferToTexture()}. - * @example - * ```typescript - * const pixelRatio = window.devicePixelRatio; - * const textureSize = 128 * pixelRatio; - * - * // instantiate a framebuffer texture - * const frameTexture = new FramebufferTexture( textureSize, textureSize, RGBAFormat ); - * - * // calculate start position for copying part of the frame data - * const vector = new Vector2(); - * vector.x = ( window.innerWidth * pixelRatio / 2 ) - ( textureSize / 2 ); - * vector.y = ( window.innerHeight * pixelRatio / 2 ) - ( textureSize / 2 ); - * - * // render the scene - * renderer.clear(); - * renderer.render( scene, camera ); - * - * // copy part of the rendered frame into the framebuffer texture - * renderer.copyFramebufferToTexture( frameTexture, vector ); - * ``` - * @see Example: {@link https://threejs.org/examples/#webgl_framebuffer_texture | webgl_framebuffer_texture} - * @see {@link https://threejs.org/docs/index.html#api/en/textures/FramebufferTexture | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/textures/FramebufferTexture.js | Source} - */ -export class FramebufferTexture extends Texture { - /** - * Create a new instance of {@link FramebufferTexture} - * @param width The width of the texture. - * @param height The height of the texture. - */ - constructor(width: number, height: number); - - /** - * Read-only flag to check if a given object is of type {@link FramebufferTexture}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isFramebufferTexture: true; - - /** - * @override - * @defaultValue {@link THREE.NearestFilter} - */ - magFilter: MagnificationTextureFilter; - - /** - * @override - * @defaultValue {@link THREE.NearestFilter} - */ - minFilter: MinificationTextureFilter; - - /** - * @override - * @defaultValue `false` - */ - generateMipmaps: boolean; -} diff --git a/src-testing/src/textures/Source.d.ts b/src-testing/src/textures/Source.d.ts deleted file mode 100644 index 404d1d8a1..000000000 --- a/src-testing/src/textures/Source.d.ts +++ /dev/null @@ -1,75 +0,0 @@ -export type SerializedImage = - | string - | { - data: number[]; - width: number; - height: number; - type: string; - }; - -export class SourceJSON { - uuid: string; - url: SerializedImage | SerializedImage[]; -} - -/** - * Represents the data {@link Source} of a texture. - * @see {@link https://threejs.org/docs/index.html#api/en/textures/Source | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/textures/Source.js | Source} - */ -export class Source { - /** - * Create a new instance of {@link Source} - * @param data The data definition of a texture. Default `null` - */ - constructor(data: any); - - /** - * Flag to check if a given object is of type {@link Source}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isSource: true; - - readonly id: number; - - /** - * The actual data of a texture. - * @remarks The type of this property depends on the texture that uses this instance. - */ - data: any; - - /** - * This property is only relevant when {@link .needsUpdate} is set to `true` and provides more control on how - * texture data should be processed. - * When `dataReady` is set to `false`, the engine performs the memory allocation (if necessary) but does not - * transfer the data into the GPU memory. - * @default true - */ - dataReady: boolean; - - /** - * When the property is set to `true`, the engine allocates the memory for the texture (if necessary) and triggers - * the actual texture upload to the GPU next time the source is used. - */ - set needsUpdate(value: boolean); - - /** - * {@link http://en.wikipedia.org/wiki/Universally_unique_identifier | UUID} of this object instance. - * @remarks This gets automatically assigned and shouldn't be edited. - */ - uuid: string; - - /** - * This starts at `0` and counts how many times {@link needsUpdate | .needsUpdate} is set to `true`. - * @remarks Expects a `Integer` - * @defaultValue `0` - */ - version: number; - - /** - * Convert the data {@link Source} to three.js {@link https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 | JSON Object/Scene format}. - * @param meta Optional object containing metadata. - */ - toJSON(meta?: string | {}): SourceJSON; -} diff --git a/src-testing/src/textures/Texture.d.ts b/src-testing/src/textures/Texture.d.ts deleted file mode 100644 index 2dc33c5d1..000000000 --- a/src-testing/src/textures/Texture.d.ts +++ /dev/null @@ -1,476 +0,0 @@ -import { - AnyMapping, - AnyPixelFormat, - MagnificationTextureFilter, - Mapping, - MinificationTextureFilter, - PixelFormat, - PixelFormatGPU, - TextureDataType, - Wrapping, -} from "../constants.js"; -import { EventDispatcher } from "../core/EventDispatcher.js"; -import { Matrix3 } from "../math/Matrix3.js"; -import { Vector2 } from "../math/Vector2.js"; -import { CompressedTextureMipmap } from "./CompressedTexture.js"; -import { CubeTexture } from "./CubeTexture.js"; -import { Source } from "./Source.js"; - -export interface TextureJSON { - metadata: { version: number; type: string; generator: string }; - - uuid: string; - name: string; - - image: string; - - mapping: AnyMapping; - channel: number; - - repeat: [x: number, y: number]; - offset: [x: number, y: number]; - center: [x: number, y: number]; - rotation: number; - - wrap: [wrapS: number, wrapT: number]; - - format: AnyPixelFormat; - internalFormat: PixelFormatGPU | null; - type: TextureDataType; - colorSpace: string; - - minFilter: MinificationTextureFilter; - magFilter: MagnificationTextureFilter; - anisotropy: number; - - flipY: boolean; - - generateMipmaps: boolean; - premultiplyAlpha: boolean; - unpackAlignment: number; - - userData?: Record; -} - -/** Shim for OffscreenCanvas. */ -// eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface OffscreenCanvas extends EventTarget {} - -/** - * Create a {@link Texture} to apply to a surface or as a reflection or refraction map. - * @remarks - * After the initial use of a texture, its **dimensions**, {@link format}, and {@link type} cannot be changed - * Instead, call {@link dispose | .dispose()} on the {@link Texture} and instantiate a new {@link Texture}. - * @example - * ```typescript - * // load a texture, set wrap mode to repeat - * const texture = new THREE.TextureLoader().load("textures/water.jpg"); - * texture.wrapS = THREE.RepeatWrapping; - * texture.wrapT = THREE.RepeatWrapping; - * texture.repeat.set(4, 4); - * ``` - * @see Example: {@link https://threejs.org/examples/#webgl_materials_texture_filters | webgl materials texture filters} - * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} - * @see {@link https://threejs.org/docs/index.html#api/en/textures/Texture | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/Textures/Texture.js | Source} - */ -export class Texture extends EventDispatcher<{ dispose: {} }> { - /** - * This creates a new {@link THREE.Texture | Texture} object. - * @param image See {@link Texture.image | .image}. Default {@link THREE.Texture.DEFAULT_IMAGE} - * @param mapping See {@link Texture.mapping | .mapping}. Default {@link THREE.Texture.DEFAULT_MAPPING} - * @param wrapS See {@link Texture.wrapS | .wrapS}. Default {@link THREE.ClampToEdgeWrapping} - * @param wrapT See {@link Texture.wrapT | .wrapT}. Default {@link THREE.ClampToEdgeWrapping} - * @param magFilter See {@link Texture.magFilter | .magFilter}. Default {@link THREE.LinearFilter} - * @param minFilter See {@link Texture.minFilter | .minFilter}. Default {@link THREE.LinearMipmapLinearFilter} - * @param format See {@link Texture.format | .format}. Default {@link THREE.RGBAFormat} - * @param type See {@link Texture.type | .type}. Default {@link THREE.UnsignedByteType} - * @param anisotropy See {@link Texture.anisotropy | .anisotropy}. Default {@link THREE.Texture.DEFAULT_ANISOTROPY} - * @param colorSpace See {@link Texture.colorSpace | .colorSpace}. Default {@link THREE.NoColorSpace} - */ - constructor( - image?: TexImageSource | OffscreenCanvas, - mapping?: Mapping, - wrapS?: Wrapping, - wrapT?: Wrapping, - magFilter?: MagnificationTextureFilter, - minFilter?: MinificationTextureFilter, - format?: PixelFormat, - type?: TextureDataType, - anisotropy?: number, - colorSpace?: string, - ); - - /** - * @deprecated - */ - constructor( - image: TexImageSource | OffscreenCanvas, - mapping: Mapping, - wrapS: Wrapping, - wrapT: Wrapping, - magFilter: MagnificationTextureFilter, - minFilter: MinificationTextureFilter, - format: PixelFormat, - type: TextureDataType, - anisotropy: number, - ); - - /** - * Read-only flag to check if a given object is of type {@link Texture}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isTexture: true; - - /** - * Unique number for this {@link Texture} instance. - * @remarks Note that ids are assigned in chronological order: 1, 2, 3, ..., incrementing by one for each new object. - * @remarks Expects a `Integer` - */ - readonly id: number; - - /** - * {@link http://en.wikipedia.org/wiki/Universally_unique_identifier | UUID} of this object instance. - * @remarks This gets automatically assigned and shouldn't be edited. - */ - uuid: string; - - /** - * Optional name of the object - * @remarks _(doesn't need to be unique)_. - * @defaultValue `""` - */ - name: string; - - /** - * The data definition of a texture. A reference to the data source can be shared across textures. - * This is often useful in context of spritesheets where multiple textures render the same data - * but with different {@link Texture} transformations. - */ - source: Source; - - /** - * An image object, typically created using the {@link THREE.TextureLoader.load | TextureLoader.load()} method. - * @remarks This can be any image (e.g., PNG, JPG, GIF, DDS) or video (e.g., MP4, OGG/OGV) type supported by three.js. - * @remarks To use video as a {@link Texture} you need to have a playing HTML5 video element as a source - * for your {@link Texture} image and continuously update this {@link Texture} - * as long as video is playing - the {@link THREE.VideoTexture | VideoTexture} class handles this automatically. - */ - get image(): any; - set image(data: any); - - /** - * Array of user-specified mipmaps - * @defaultValue `[]` - */ - mipmaps: CompressedTextureMipmap[] | CubeTexture[] | HTMLCanvasElement[] | undefined; - - /** - * How the image is applied to the object. - * @remarks All {@link Texture} types except {@link THREE.CubeTexture} expect the _values_ be {@link THREE.Mapping} - * @remarks {@link CubeTexture} expect the _values_ be {@link THREE.CubeTextureMapping} - * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} - * @defaultValue _value of_ {@link THREE.Texture.DEFAULT_MAPPING} - */ - mapping: AnyMapping; - - /** - * Lets you select the uv attribute to map the texture to. `0` for `uv`, `1` for `uv1`, `2` for `uv2` and `3` for - * `uv3`. - */ - channel: number; - - /** - * This defines how the {@link Texture} is wrapped *horizontally* and corresponds to **U** in UV mapping. - * @remarks for **WEBGL1** - tiling of images in textures only functions if image dimensions are powers of two - * (2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, ...) in terms of pixels. - * Individual dimensions need not be equal, but each must be a power of two. This is a limitation of WebGL1, not three.js. - * **WEBGL2** does not have this limitation. - * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} - * @see {@link wrapT} - * @see {@link repeat} - * @defaultValue {@link THREE.ClampToEdgeWrapping} - */ - wrapS: Wrapping; - - /** - * This defines how the {@link Texture} is wrapped *vertically* and corresponds to **V** in UV mapping. - * @remarks for **WEBGL1** - tiling of images in textures only functions if image dimensions are powers of two - * (2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, ...) in terms of pixels. - * Individual dimensions need not be equal, but each must be a power of two. This is a limitation of WebGL1, not three.js. - * **WEBGL2** does not have this limitation. - * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} - * @see {@link wrapS} - * @see {@link repeat} - * @defaultValue {@link THREE.ClampToEdgeWrapping} - */ - wrapT: Wrapping; - - /** - * How the {@link Texture} is sampled when a texel covers more than one pixel. - * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} - * @see {@link minFilter} - * @see {@link THREE.MagnificationTextureFilter} - * @defaultValue {@link THREE.LinearFilter} - */ - magFilter: MagnificationTextureFilter; - - /** - * How the {@link Texture} is sampled when a texel covers less than one pixel. - * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} - * @see {@link magFilter} - * @see {@link THREE.MinificationTextureFilter} - * @defaultValue {@link THREE.LinearMipmapLinearFilter} - */ - minFilter: MinificationTextureFilter; - - /** - * The number of samples taken along the axis through the pixel that has the highest density of texels. - * @remarks A higher value gives a less blurry result than a basic mipmap, at the cost of more {@link Texture} samples being used. - * @remarks Use {@link THREE.WebGLCapabilities.getMaxAnisotropy() | renderer.capabilities.getMaxAnisotropy()} to find the maximum valid anisotropy value for the GPU; - * @remarks This value is usually a power of 2. - * @default _value of_ {@link THREE.Texture.DEFAULT_ANISOTROPY}. That is normally `1`. - */ - anisotropy: number; - - /** - * These define how elements of a 2D texture, or texels, are read by shaders. - * @remarks All {@link Texture} types except {@link THREE.DepthTexture} and {@link THREE.CompressedPixelFormat} expect the _values_ be {@link THREE.PixelFormat} - * @remarks {@link DepthTexture} expect the _values_ be {@link THREE.CubeTextureMapping} - * @remarks {@link CompressedPixelFormat} expect the _values_ be {@link THREE.CubeTextureMapping} - * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} - * @see {@link THREE.PixelFormat} - * @defaultValue {@link THREE.RGBAFormat}. - */ - format: AnyPixelFormat; - - /** - * This must correspond to the {@link Texture.format | .format}. - * @remarks {@link THREE.UnsignedByteType}, is the type most used by Texture formats. - * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} - * @see {@link THREE.TextureDataType} - * @defaultValue {@link THREE.UnsignedByteType} - */ - type: TextureDataType; - - /** - * The GPU Pixel Format allows the developer to specify how the data is going to be stored on the GPU. - * @remarks Compatible only with {@link WebGL2RenderingContext | WebGL 2 Rendering Context}. - * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} - * @defaultValue The default value is obtained using a combination of {@link Texture.format | .format} and {@link Texture.type | .type}. - */ - internalFormat: PixelFormatGPU | null; - - /** - * The uv-transform matrix for the texture. - * @remarks - * When {@link Texture.matrixAutoUpdate | .matrixAutoUpdate} property is `true`. - * Will be updated by the renderer from the properties: - * - {@link Texture.offset | .offset} - * - {@link Texture.repeat | .repeat} - * - {@link Texture.rotation | .rotation} - * - {@link Texture.center | .center} - * @remarks - * When {@link Texture.matrixAutoUpdate | .matrixAutoUpdate} property is `false`. - * This matrix may be set manually. - * @see {@link matrixAutoUpdate | .matrixAutoUpdate} - * @defaultValue `new THREE.Matrix3()` - */ - matrix: Matrix3; - - /** - * Whether is to update the texture's uv-transform {@link matrix | .matrix}. - * @remarks Set this to `false` if you are specifying the uv-transform {@link matrix} directly. - * @see {@link matrix | .matrix} - * @defaultValue `true` - */ - matrixAutoUpdate: boolean; - - /** - * How much a single repetition of the texture is offset from the beginning, in each direction **U** and **V**. - * @remarks Typical range is `0.0` to `1.0`. - * @defaultValue `new THREE.Vector2(0, 0)` - */ - offset: Vector2; - - /** - * How many times the texture is repeated across the surface, in each direction **U** and **V**. - * @remarks - * If repeat is set greater than `1` in either direction, the corresponding *Wrap* parameter should - * also be set to {@link THREE.RepeatWrapping} or {@link THREE.MirroredRepeatWrapping} to achieve the desired tiling effect. - * @see {@link wrapS} - * @see {@link wrapT} - * @defaultValue `new THREE.Vector2( 1, 1 )` - */ - repeat: Vector2; - - /** - * The point around which rotation occurs. - * @remarks A value of `(0.5, 0.5)` corresponds to the center of the texture. - * @defaultValue `new THREE.Vector2( 0, 0 )`, _lower left._ - */ - center: Vector2; - - /** - * How much the texture is rotated around the center point, in radians. - * @remarks Positive values are counter-clockwise. - * @defaultValue `0` - */ - rotation: number; - - /** - * Whether to generate mipmaps, _(if possible)_ for a texture. - * @remarks Set this to false if you are creating mipmaps manually. - * @defaultValue true - */ - generateMipmaps: boolean; - - /** - * If set to `true`, the alpha channel, if present, is multiplied into the color channels when the texture is uploaded to the GPU. - * @remarks - * Note that this property has no effect for {@link https://developer.mozilla.org/en-US/docs/Web/API/ImageBitmap | ImageBitmap}. - * You need to configure on bitmap creation instead. See {@link THREE.ImageBitmapLoader | ImageBitmapLoader}. - * @see {@link THREE.ImageBitmapLoader | ImageBitmapLoader}. - * @defaultValue `false` - */ - premultiplyAlpha: boolean; - - /** - * If set to `true`, the texture is flipped along the vertical axis when uploaded to the GPU. - * @remarks - * Note that this property has no effect for {@link https://developer.mozilla.org/en-US/docs/Web/API/ImageBitmap | ImageBitmap}. - * You need to configure on bitmap creation instead. See {@link THREE.ImageBitmapLoader | ImageBitmapLoader}. - * @see {@link THREE.ImageBitmapLoader | ImageBitmapLoader}. - * @defaultValue `true` - */ - flipY: boolean; - - /** - * Specifies the alignment requirements for the start of each pixel row in memory. - * @remarks - * The allowable values are: - * - `1` (byte-alignment) - * - `2` (rows aligned to even-numbered bytes) - * - `4` (word-alignment) - * - `8` (rows start on double-word boundaries). - * @see {@link http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml | glPixelStorei} for more information. - * @defaultValue `4` - */ - unpackAlignment: number; // TODO Fix typing to only allow the expected values. - - /** - * The {@link Textures | {@link Texture} constants} page for details of other color spaces. - * @remarks - * Textures containing color data should be annotated with {@link SRGBColorSpace THREE.SRGBColorSpace} or - * {@link LinearSRGBColorSpace THREE.LinearSRGBColorSpace}. - * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} - * @see {@link THREE.TextureDataType} - * @defaultValue {@link THREE.NoColorSpace} - */ - colorSpace: string; - - /** - * Indicates whether a texture belongs to a render target or not - * @defaultValue `false` - */ - isRenderTargetTexture: boolean; - - /** - * An object that can be used to store custom data about the texture. - * @remarks It should not hold references to functions as these will not be cloned. - * @defaultValue `{}` - */ - userData: Record; - - /** - * This starts at `0` and counts how many times {@link needsUpdate | .needsUpdate} is set to `true`. - * @remarks Expects a `Integer` - * @defaultValue `0` - */ - version: number; - - /** - * Indicates whether this texture should be processed by PMREMGenerator or not (only relevant for render target - * textures) - */ - pmremVersion: number; - - /** - * Set this to `true` to trigger an update next time the texture is used. Particularly important for setting the wrap mode. - */ - set needsUpdate(value: boolean); - - /** - * Indicates whether this texture should be processed by {@link THREE.PMREMGenerator} or not. - * @remarks Only relevant for render target textures. - * @defaultValue `false` - */ - set needsPMREMUpdate(value: boolean); - - /** - * The Global default value for {@link anisotropy | .anisotropy}. - * @defaultValue `1`. - */ - static DEFAULT_ANISOTROPY: number; - - /** - * The Global default value for {@link Texture.image | .image}. - * @defaultValue `null`. - */ - static DEFAULT_IMAGE: any; - - /** - * The Global default value for {@link mapping | .mapping}. - * @defaultValue {@link THREE.UVMapping} - */ - static DEFAULT_MAPPING: Mapping; - - /** - * A callback function, called when the texture is updated _(e.g., when needsUpdate has been set to true and then the texture is used)_. - */ - onUpdate: () => void; - - /** - * Transform the **UV** based on the value of this texture's - * {@link offset | .offset}, - * {@link repeat | .repeat}, - * {@link wrapS | .wrapS}, - * {@link wrapT | .wrapT} and - * {@link flipY | .flipY} properties. - * @param uv - */ - transformUv(uv: Vector2): Vector2; - - /** - * Update the texture's **UV-transform** {@link matrix | .matrix} from the texture properties - * {@link offset | .offset}, - * {@link repeat | .repeat}, - * {@link rotation | .rotation} and - * {@link center | .center}. - */ - updateMatrix(): void; - - /** - * Make copy of the texture - * @remarks Note this is not a **"deep copy"**, the image is shared - * @remarks - * Besides, cloning a texture does not automatically mark it for a texture upload - * You have to set {@link needsUpdate | .needsUpdate} to `true` as soon as it's image property (the data source) is fully loaded or ready. - */ - clone(): this; - - copy(source: Texture): this; - - /** - * Convert the texture to three.js {@link https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 | JSON Object/Scene format}. - * @param meta Optional object containing metadata. - */ - toJSON(meta?: string | {}): TextureJSON; - - /** - * Frees the GPU-related resources allocated by this instance - * @remarks Call this method whenever this instance is no longer used in your app. - */ - dispose(): void; -} diff --git a/src-testing/src/textures/VideoTexture.d.ts b/src-testing/src/textures/VideoTexture.d.ts deleted file mode 100644 index 31dc5d456..000000000 --- a/src-testing/src/textures/VideoTexture.d.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { - MagnificationTextureFilter, - Mapping, - MinificationTextureFilter, - PixelFormat, - TextureDataType, - Wrapping, -} from "../constants.js"; -import { Texture } from "./Texture.js"; - -/** - * Creates a texture for use with a video. - * @remarks - * Note: After the initial use of a texture, the video cannot be changed - * Instead, call {@link dispose | .dispose()} on the texture and instantiate a new one. - * @example - * ```typescript - * // assuming you have created a HTML video element with id="video" - * const video = document.getElementById('video'); - * const texture = new THREE.VideoTexture(video); - * ``` - * @see Example: {@link https://threejs.org/examples/#webgl_materials_video | materials / video} - * @see Example: {@link https://threejs.org/examples/#webgl_materials_video_webcam | materials / video / webcam} - * @see Example: {@link https://threejs.org/examples/#webgl_video_kinect | video / kinect} - * @see Example: {@link https://threejs.org/examples/#webgl_video_panorama_equirectangular | video / panorama / equirectangular} - * @see Example: {@link https://threejs.org/examples/#webxr_vr_video | vr / video} - * @see {@link https://threejs.org/docs/index.html#api/en/textures/VideoTexture | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/textures/VideoTexture.js | Source} - */ -export class VideoTexture extends Texture { - /** - * Create a new instance of {@link VideoTexture} - * @param video The video element to use as the texture. - * @param mapping See {@link Texture.mapping | .mapping}. Default {@link THREE.Texture.DEFAULT_MAPPING} - * @param wrapS See {@link Texture.wrapS | .wrapS}. Default {@link THREE.ClampToEdgeWrapping} - * @param wrapT See {@link Texture.wrapT | .wrapT}. Default {@link THREE.ClampToEdgeWrapping} - * @param magFilter See {@link Texture.magFilter | .magFilter}. Default {@link THREE.LinearFilter} - * @param minFilter See {@link Texture.minFilter | .minFilter}. Default {@link THREE.LinearFilter} - * @param format See {@link Texture.format | .format}. Default {@link THREE.RGBAFormat} - * @param type See {@link Texture.type | .type}. Default {@link THREE.UnsignedByteType} - * @param anisotropy See {@link Texture.anisotropy | .anisotropy}. Default {@link THREE.Texture.DEFAULT_ANISOTROPY} - */ - constructor( - video: HTMLVideoElement, - mapping?: Mapping, - wrapS?: Wrapping, - wrapT?: Wrapping, - magFilter?: MagnificationTextureFilter, - minFilter?: MinificationTextureFilter, - format?: PixelFormat, - type?: TextureDataType, - anisotropy?: number, - ); - - /** - * Read-only flag to check if a given object is of type {@link VideoTexture}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isVideoTexture: true; - - /** - * @override - * @defaultValue {@link THREE.LinearFilter} - */ - magFilter: MagnificationTextureFilter; - - /** - * @override - * @defaultValue {@link THREE.LinearFilter} - */ - minFilter: MinificationTextureFilter; - - /** - * @override - * @defaultValue `false` - */ - generateMipmaps: boolean; - - /** - * @override - * You will **not** need to set this manually here as it is handled by the {@link update | update()} method. - */ - set needsUpdate(value: boolean); - - /** - * This is called automatically and sets {@link needsUpdate | .needsUpdate } to `true` every time a new frame is available. - */ - update(): void; -} diff --git a/src-testing/src/textures/types.d.ts b/src-testing/src/textures/types.d.ts deleted file mode 100644 index 86b7f2fd2..000000000 --- a/src-testing/src/textures/types.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -export interface TextureImageData { - data: Uint8Array | Uint8ClampedArray; - height: number; - width: number; -} - -export interface Texture3DImageData extends TextureImageData { - depth: number; -} diff --git a/src-testing/src/utils.d.ts b/src-testing/src/utils.d.ts deleted file mode 100644 index 3fda1cfda..000000000 --- a/src-testing/src/utils.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -export function createCanvasElement(): HTMLCanvasElement; - -export function probeAsync(gl: WebGLRenderingContext, sync: WebGLSync, interval: number): Promise; From 57b93995ad83c9205d5c7ab7b60d9dd71123b7ad Mon Sep 17 00:00:00 2001 From: Nathan Bierema Date: Sun, 10 Nov 2024 17:19:06 -0500 Subject: [PATCH 5/7] Add src --- src-testing/src/Three.Legacy.d.ts | 20 + src-testing/src/Three.WebGPU.Nodes.d.ts | 205 +++ src-testing/src/Three.WebGPU.d.ts | 206 +++ src-testing/src/Three.d.ts | 214 +++ .../src/animation/AnimationAction.d.ts | 86 + src-testing/src/animation/AnimationClip.d.ts | 59 + src-testing/src/animation/AnimationMixer.d.ts | 39 + .../src/animation/AnimationObjectGroup.d.ts | 17 + src-testing/src/animation/AnimationUtils.d.ts | 60 + src-testing/src/animation/KeyframeTrack.d.ts | 55 + .../src/animation/PropertyBinding.d.ts | 43 + src-testing/src/animation/PropertyMixer.d.ts | 17 + .../tracks/BooleanKeyframeTrack.d.ts | 10 + .../animation/tracks/ColorKeyframeTrack.d.ts | 11 + .../animation/tracks/NumberKeyframeTrack.d.ts | 11 + .../tracks/QuaternionKeyframeTrack.d.ts | 11 + .../animation/tracks/StringKeyframeTrack.d.ts | 10 + .../animation/tracks/VectorKeyframeTrack.d.ts | 11 + src-testing/src/audio/Audio.d.ts | 273 ++++ src-testing/src/audio/AudioAnalyser.d.ts | 58 + src-testing/src/audio/AudioContext.d.ts | 19 + src-testing/src/audio/AudioListener.d.ts | 96 ++ src-testing/src/audio/PositionalAudio.d.ts | 101 ++ src-testing/src/cameras/ArrayCamera.d.ts | 32 + src-testing/src/cameras/Camera.d.ts | 74 + src-testing/src/cameras/CubeCamera.d.ts | 68 + .../src/cameras/OrthographicCamera.d.ts | 174 ++ .../src/cameras/PerspectiveCamera.d.ts | 254 +++ src-testing/src/cameras/StereoCamera.d.ts | 50 + src-testing/src/constants.d.ts | 918 +++++++++++ src-testing/src/core/BufferAttribute.d.ts | 622 +++++++ src-testing/src/core/BufferGeometry.d.ts | 433 +++++ src-testing/src/core/Clock.d.ts | 72 + src-testing/src/core/EventDispatcher.d.ts | 82 + src-testing/src/core/GLBufferAttribute.d.ts | 121 ++ .../src/core/InstancedBufferAttribute.d.ts | 32 + .../src/core/InstancedBufferGeometry.d.ts | 37 + .../src/core/InstancedInterleavedBuffer.d.ts | 22 + src-testing/src/core/InterleavedBuffer.d.ts | 150 ++ .../src/core/InterleavedBufferAttribute.d.ts | 201 +++ src-testing/src/core/Layers.d.ts | 72 + src-testing/src/core/Object3D.d.ts | 674 ++++++++ src-testing/src/core/Raycaster.d.ts | 208 +++ src-testing/src/core/RenderTarget.d.ts | 95 ++ src-testing/src/core/Uniform.d.ts | 38 + src-testing/src/core/UniformsGroup.d.ts | 33 + src-testing/src/extras/Controls.d.ts | 54 + src-testing/src/extras/DataUtils.d.ts | 22 + src-testing/src/extras/Earcut.d.ts | 15 + src-testing/src/extras/ImageUtils.d.ts | 32 + src-testing/src/extras/PMREMGenerator.d.ts | 82 + src-testing/src/extras/ShapeUtils.d.ts | 25 + src-testing/src/extras/TextureUtils.d.ts | 42 + src-testing/src/extras/core/Curve.d.ts | 162 ++ src-testing/src/extras/core/CurvePath.d.ts | 77 + .../src/extras/core/Interpolations.d.ts | 36 + src-testing/src/extras/core/Path.d.ts | 166 ++ src-testing/src/extras/core/Shape.d.ts | 86 + src-testing/src/extras/core/ShapePath.d.ts | 98 ++ src-testing/src/extras/curves/ArcCurve.d.ts | 41 + .../src/extras/curves/CatmullRomCurve3.d.ts | 77 + .../src/extras/curves/CubicBezierCurve.d.ts | 72 + .../src/extras/curves/CubicBezierCurve3.d.ts | 72 + src-testing/src/extras/curves/Curves.d.ts | 10 + .../src/extras/curves/EllipseCurve.d.ts | 115 ++ src-testing/src/extras/curves/LineCurve.d.ts | 42 + src-testing/src/extras/curves/LineCurve3.d.ts | 42 + .../extras/curves/QuadraticBezierCurve.d.ts | 64 + .../extras/curves/QuadraticBezierCurve3.d.ts | 64 + .../src/extras/curves/SplineCurve.d.ts | 52 + src-testing/src/geometries/BoxGeometry.d.ts | 59 + .../src/geometries/CapsuleGeometry.d.ts | 48 + .../src/geometries/CircleGeometry.d.ts | 51 + src-testing/src/geometries/ConeGeometry.d.ts | 64 + .../src/geometries/CylinderGeometry.d.ts | 64 + .../src/geometries/DodecahedronGeometry.d.ts | 25 + src-testing/src/geometries/EdgesGeometry.d.ts | 41 + .../src/geometries/ExtrudeGeometry.d.ts | 152 ++ src-testing/src/geometries/Geometries.d.ts | 21 + .../src/geometries/IcosahedronGeometry.d.ts | 26 + src-testing/src/geometries/LatheGeometry.d.ts | 55 + .../src/geometries/OctahedronGeometry.d.ts | 25 + src-testing/src/geometries/PlaneGeometry.d.ts | 48 + .../src/geometries/PolyhedronGeometry.d.ts | 54 + src-testing/src/geometries/RingGeometry.d.ts | 59 + src-testing/src/geometries/ShapeGeometry.d.ts | 53 + .../src/geometries/SphereGeometry.d.ts | 67 + .../src/geometries/TetrahedronGeometry.d.ts | 25 + src-testing/src/geometries/TorusGeometry.d.ts | 49 + .../src/geometries/TorusKnotGeometry.d.ts | 59 + src-testing/src/geometries/TubeGeometry.d.ts | 86 + .../src/geometries/WireframeGeometry.d.ts | 40 + src-testing/src/helpers/ArrowHelper.d.ts | 93 ++ src-testing/src/helpers/AxesHelper.d.ts | 50 + src-testing/src/helpers/Box3Helper.d.ts | 44 + src-testing/src/helpers/BoxHelper.d.ts | 64 + src-testing/src/helpers/CameraHelper.d.ts | 80 + .../src/helpers/DirectionalLightHelper.d.ts | 81 + src-testing/src/helpers/GridHelper.d.ts | 47 + .../src/helpers/HemisphereLightHelper.d.ts | 72 + src-testing/src/helpers/PlaneHelper.d.ts | 50 + src-testing/src/helpers/PointLightHelper.d.ts | 73 + src-testing/src/helpers/PolarGridHelper.d.ts | 55 + src-testing/src/helpers/SkeletonHelper.d.ts | 78 + src-testing/src/helpers/SpotLightHelper.d.ts | 77 + src-testing/src/lights/AmbientLight.d.ts | 36 + src-testing/src/lights/DirectionalLight.d.ts | 103 ++ .../src/lights/DirectionalLightShadow.d.ts | 73 + src-testing/src/lights/HemisphereLight.d.ts | 61 + src-testing/src/lights/Light.d.ts | 82 + src-testing/src/lights/LightProbe.d.ts | 47 + src-testing/src/lights/LightShadow.d.ts | 169 ++ src-testing/src/lights/PointLight.d.ts | 102 ++ src-testing/src/lights/PointLightShadow.d.ts | 22 + src-testing/src/lights/RectAreaLight.d.ts | 82 + src-testing/src/lights/SpotLight.d.ts | 164 ++ src-testing/src/lights/SpotLightShadow.d.ts | 72 + .../src/lights/webgpu/IESSpotLight.d.ts | 6 + src-testing/src/loaders/AnimationLoader.d.ts | 9 + src-testing/src/loaders/AudioLoader.d.ts | 6 + .../src/loaders/BufferGeometryLoader.d.ts | 10 + src-testing/src/loaders/Cache.d.ts | 21 + .../src/loaders/CompressedTextureLoader.d.ts | 14 + .../src/loaders/CubeTextureLoader.d.ts | 14 + .../src/loaders/DataTextureLoader.d.ts | 14 + src-testing/src/loaders/FileLoader.d.ts | 19 + .../src/loaders/ImageBitmapLoader.d.ts | 22 + src-testing/src/loaders/ImageLoader.d.ts | 17 + src-testing/src/loaders/Loader.d.ts | 50 + src-testing/src/loaders/LoaderUtils.d.ts | 10 + src-testing/src/loaders/LoadingManager.d.ts | 69 + src-testing/src/loaders/MaterialLoader.d.ts | 21 + src-testing/src/loaders/ObjectLoader.d.ts | 35 + src-testing/src/loaders/TextureLoader.d.ts | 18 + src-testing/src/loaders/nodes/NodeLoader.d.ts | 21 + .../src/loaders/nodes/NodeMaterialLoader.d.ts | 11 + .../src/loaders/nodes/NodeObjectLoader.d.ts | 22 + .../src/materials/LineBasicMaterial.d.ts | 55 + .../src/materials/LineDashedMaterial.d.ts | 35 + src-testing/src/materials/Material.d.ts | 629 ++++++++ src-testing/src/materials/Materials.d.ts | 18 + .../src/materials/MeshBasicMaterial.d.ts | 134 ++ .../src/materials/MeshDepthMaterial.d.ts | 71 + .../src/materials/MeshDistanceMaterial.d.ts | 57 + .../src/materials/MeshLambertMaterial.d.ts | 199 +++ .../src/materials/MeshMatcapMaterial.d.ts | 112 ++ .../src/materials/MeshNormalMaterial.d.ts | 88 + .../src/materials/MeshPhongMaterial.d.ts | 223 +++ .../src/materials/MeshPhysicalMaterial.d.ts | 231 +++ .../src/materials/MeshStandardMaterial.d.ts | 213 +++ .../src/materials/MeshToonMaterial.d.ts | 173 ++ src-testing/src/materials/PointsMaterial.d.ts | 56 + .../src/materials/RawShaderMaterial.d.ts | 12 + src-testing/src/materials/ShaderMaterial.d.ts | 162 ++ src-testing/src/materials/ShadowMaterial.d.ts | 34 + src-testing/src/materials/SpriteMaterial.d.ts | 61 + .../nodes/InstancedPointsNodeMaterial.d.ts | 33 + .../materials/nodes/Line2NodeMaterial.d.ts | 53 + .../nodes/LineBasicNodeMaterial.d.ts | 22 + .../nodes/LineDashedNodeMaterial.d.ts | 29 + .../nodes/MeshBasicNodeMaterial.d.ts | 36 + .../nodes/MeshLambertNodeMaterial.d.ts | 49 + .../nodes/MeshMatcapNodeMaterial.d.ts | 32 + .../nodes/MeshNormalNodeMaterial.d.ts | 28 + .../nodes/MeshPhongNodeMaterial.d.ts | 56 + .../nodes/MeshPhysicalNodeMaterial.d.ts | 93 ++ .../materials/nodes/MeshSSSNodeMaterial.d.ts | 16 + .../nodes/MeshStandardNodeMaterial.d.ts | 56 + .../materials/nodes/MeshToonNodeMaterial.d.ts | 42 + .../src/materials/nodes/NodeMaterial.ts | 535 +++++++ .../src/materials/nodes/NodeMaterials.d.ts | 18 + .../materials/nodes/PointsNodeMaterial.d.ts | 21 + .../materials/nodes/ShadowNodeMaterial.d.ts | 17 + .../materials/nodes/SpriteNodeMaterial.d.ts | 26 + .../materials/nodes/VolumeNodeMaterial.d.ts | 10 + .../nodes/manager/NodeMaterialObserver.ts | 308 ++++ src-testing/src/math/Box2.d.ts | 48 + src-testing/src/math/Box3.d.ts | 66 + src-testing/src/math/Color.d.ts | 375 +++++ src-testing/src/math/ColorManagement.d.ts | 49 + src-testing/src/math/Cylindrical.d.ts | 26 + src-testing/src/math/Euler.d.ts | 50 + src-testing/src/math/Frustum.d.ts | 30 + src-testing/src/math/Interpolant.d.ts | 10 + src-testing/src/math/Line3.d.ts | 29 + src-testing/src/math/MathUtils.d.ts | 137 ++ src-testing/src/math/Matrix2.d.ts | 53 + src-testing/src/math/Matrix3.d.ts | 184 +++ src-testing/src/math/Matrix4.d.ts | 284 ++++ src-testing/src/math/Plane.d.ts | 47 + src-testing/src/math/Quaternion.d.ts | 189 +++ src-testing/src/math/Ray.d.ts | 60 + src-testing/src/math/Sphere.d.ts | 47 + src-testing/src/math/Spherical.d.ts | 27 + src-testing/src/math/SphericalHarmonics3.d.ts | 50 + src-testing/src/math/Triangle.d.ts | 110 ++ src-testing/src/math/Vector2.d.ts | 321 ++++ src-testing/src/math/Vector3.d.ts | 301 ++++ src-testing/src/math/Vector4.d.ts | 239 +++ .../math/interpolants/CubicInterpolant.d.ts | 7 + .../interpolants/DiscreteInterpolant.d.ts | 7 + .../math/interpolants/LinearInterpolant.d.ts | 7 + .../QuaternionLinearInterpolant.d.ts | 7 + src-testing/src/nodes/Nodes.ts | 144 ++ src-testing/src/nodes/TSL.d.ts | 156 ++ .../src/nodes/accessors/AccessorsUtils.d.ts | 9 + .../src/nodes/accessors/BatchNode.d.ts | 13 + .../src/nodes/accessors/Bitangent.d.ts | 9 + .../nodes/accessors/BufferAttributeNode.ts | 135 ++ .../src/nodes/accessors/BufferNode.d.ts | 17 + src-testing/src/nodes/accessors/Camera.d.ts | 14 + .../src/nodes/accessors/ClippingNode.d.ts | 16 + .../src/nodes/accessors/CubeTextureNode.d.ts | 28 + .../src/nodes/accessors/InstanceNode.d.ts | 13 + .../src/nodes/accessors/MaterialNode.d.ts | 129 ++ .../nodes/accessors/MaterialProperties.d.ts | 4 + .../accessors/MaterialReferenceNode.d.ts | 15 + .../src/nodes/accessors/ModelNode.d.ts | 24 + .../accessors/ModelViewProjectionNode.d.ts | 8 + .../src/nodes/accessors/MorphNode.d.ts | 15 + src-testing/src/nodes/accessors/Normal.d.ts | 25 + .../src/nodes/accessors/Object3DNode.d.ts | 22 + .../src/nodes/accessors/PointUVNode.d.ts | 10 + src-testing/src/nodes/accessors/Position.d.ts | 10 + .../nodes/accessors/ReferenceBaseNode.d.ts | 27 + .../src/nodes/accessors/ReferenceNode.d.ts | 29 + .../src/nodes/accessors/ReflectVector.d.ts | 9 + .../accessors/RendererReferenceNode.d.ts | 15 + .../src/nodes/accessors/SceneNode.d.ts | 20 + .../src/nodes/accessors/SkinningNode.d.ts | 30 + .../nodes/accessors/StorageBufferNode.d.ts | 38 + .../nodes/accessors/StorageTextureNode.d.ts | 40 + src-testing/src/nodes/accessors/Tangent.d.ts | 12 + .../src/nodes/accessors/Texture3DNode.d.ts | 17 + .../src/nodes/accessors/TextureBicubic.d.ts | 4 + .../src/nodes/accessors/TextureNode.ts | 370 +++++ .../src/nodes/accessors/TextureSizeNode.d.ts | 18 + src-testing/src/nodes/accessors/UV.d.ts | 4 + .../src/nodes/accessors/UniformArrayNode.d.ts | 30 + .../src/nodes/accessors/UserDataNode.d.ts | 15 + .../src/nodes/accessors/VelocityNode.d.ts | 20 + .../src/nodes/accessors/VertexColorNode.d.ts | 12 + src-testing/src/nodes/code/CodeNode.ts | 68 + .../src/nodes/code/ExpressionNode.d.ts | 9 + .../src/nodes/code/FunctionCallNode.d.ts | 25 + src-testing/src/nodes/code/FunctionNode.ts | 87 + .../src/nodes/code/ScriptableNode.d.ts | 22 + .../src/nodes/code/ScriptableValueNode.d.ts | 10 + src-testing/src/nodes/core/AssignNode.d.ts | 18 + src-testing/src/nodes/core/AttributeNode.d.ts | 16 + src-testing/src/nodes/core/BypassNode.d.ts | 18 + src-testing/src/nodes/core/CacheNode.d.ts | 20 + src-testing/src/nodes/core/ConstNode.d.ts | 9 + src-testing/src/nodes/core/ContextNode.ts | 61 + src-testing/src/nodes/core/IndexNode.d.ts | 28 + src-testing/src/nodes/core/InputNode.ts | 67 + src-testing/src/nodes/core/LightingModel.d.ts | 46 + src-testing/src/nodes/core/MRTNode.d.ts | 24 + src-testing/src/nodes/core/Node.ts | 401 +++++ src-testing/src/nodes/core/NodeAttribute.ts | 11 + src-testing/src/nodes/core/NodeBuilder.ts | 1208 ++++++++++++++ src-testing/src/nodes/core/NodeCache.ts | 26 + src-testing/src/nodes/core/NodeCode.ts | 11 + src-testing/src/nodes/core/NodeFrame.ts | 127 ++ src-testing/src/nodes/core/NodeFunction.ts | 16 + .../src/nodes/core/NodeFunctionInput.d.ts | 7 + src-testing/src/nodes/core/NodeParser.ts | 7 + src-testing/src/nodes/core/NodeUniform.ts | 27 + src-testing/src/nodes/core/NodeUtils.ts | 171 ++ src-testing/src/nodes/core/NodeVar.ts | 10 + src-testing/src/nodes/core/NodeVarying.ts | 13 + .../src/nodes/core/OutputStructNode.d.ts | 12 + src-testing/src/nodes/core/ParameterNode.d.ts | 12 + src-testing/src/nodes/core/PropertyNode.d.ts | 43 + src-testing/src/nodes/core/StackNode.ts | 89 + src-testing/src/nodes/core/StructTypeNode.ts | 20 + src-testing/src/nodes/core/TempNode.d.ts | 10 + src-testing/src/nodes/core/UniformGroup.d.ts | 7 + .../src/nodes/core/UniformGroupNode.ts | 47 + src-testing/src/nodes/core/UniformNode.ts | 91 ++ src-testing/src/nodes/core/VarNode.d.ts | 31 + src-testing/src/nodes/core/VaryingNode.d.ts | 21 + src-testing/src/nodes/core/constants.ts | 28 + src-testing/src/nodes/display/BlendMode.d.ts | 10 + .../src/nodes/display/BumpMapNode.d.ts | 16 + .../src/nodes/display/ColorAdjustment.d.ts | 56 + .../nodes/display/ColorSpaceFunctions.d.ts | 6 + .../src/nodes/display/ColorSpaceNode.d.ts | 60 + .../src/nodes/display/FrontFacingNode.d.ts | 12 + .../src/nodes/display/NormalMapNode.d.ts | 17 + src-testing/src/nodes/display/PassNode.d.ts | 71 + .../src/nodes/display/PosterizeNode.d.ts | 14 + .../src/nodes/display/RenderOutputNode.d.ts | 28 + src-testing/src/nodes/display/ScreenNode.d.ts | 48 + .../nodes/display/ToneMappingFunctions.d.ts | 14 + .../src/nodes/display/ToneMappingNode.d.ts | 32 + .../nodes/display/ToonOutlinePassNode.d.ts | 24 + .../src/nodes/display/ViewportDepthNode.d.ts | 36 + .../display/ViewportDepthTextureNode.d.ts | 14 + .../display/ViewportSharedTextureNode.d.ts | 14 + .../nodes/display/ViewportTextureNode.d.ts | 28 + src-testing/src/nodes/fog/FogExp2Node.d.ts | 14 + src-testing/src/nodes/fog/FogNode.ts | 38 + src-testing/src/nodes/fog/FogRangeNode.d.ts | 19 + .../src/nodes/functions/BSDF/BRDF_GGX.d.ts | 15 + .../nodes/functions/BSDF/BRDF_Lambert.d.ts | 7 + .../src/nodes/functions/BSDF/BRDF_Sheen.d.ts | 7 + .../src/nodes/functions/BSDF/DFGApprox.d.ts | 11 + .../src/nodes/functions/BSDF/D_GGX.d.ts | 10 + .../functions/BSDF/D_GGX_Anisotropic.d.ts | 10 + .../src/nodes/functions/BSDF/F_Schlick.d.ts | 7 + src-testing/src/nodes/functions/BSDF/LTC.d.ts | 9 + .../nodes/functions/BSDF/Schlick_to_F0.d.ts | 10 + .../functions/BSDF/V_GGX_SmithCorrelated.d.ts | 11 + .../V_GGX_SmithCorrelated_Anisotropic.d.ts | 16 + .../nodes/functions/BasicLightingModel.d.ts | 7 + .../nodes/functions/PhongLightingModel.d.ts | 7 + .../functions/PhysicalLightingModel.d.ts | 30 + .../src/nodes/functions/ShadowMaskModel.d.ts | 9 + .../nodes/functions/ToonLightingModel.d.ts | 4 + .../material/getGeometryRoughness.d.ts | 6 + .../functions/material/getRoughness.d.ts | 7 + .../functions/material/getShIrradianceAt.d.ts | 6 + src-testing/src/nodes/geometry/RangeNode.d.ts | 19 + src-testing/src/nodes/gpgpu/ComputeNode.ts | 75 + src-testing/src/nodes/lighting/AONode.d.ts | 8 + .../src/nodes/lighting/AmbientLightNode.d.ts | 8 + .../src/nodes/lighting/AnalyticLightNode.d.ts | 8 + .../nodes/lighting/BasicEnvironmentNode.d.ts | 10 + .../src/nodes/lighting/BasicLightMapNode.d.ts | 8 + .../nodes/lighting/DirectionalLightNode.d.ts | 8 + .../src/nodes/lighting/EnvironmentNode.ts | 114 ++ .../nodes/lighting/HemisphereLightNode.d.ts | 13 + .../src/nodes/lighting/IESSpotLightNode.d.ts | 5 + .../src/nodes/lighting/IrradianceNode.d.ts | 8 + src-testing/src/nodes/lighting/LightNode.d.ts | 18 + .../src/nodes/lighting/LightProbeNode.d.ts | 11 + .../src/nodes/lighting/LightUtils.d.ts | 9 + .../src/nodes/lighting/LightingContextNode.ts | 57 + .../src/nodes/lighting/LightingNode.d.ts | 7 + src-testing/src/nodes/lighting/LightsNode.ts | 200 +++ .../src/nodes/lighting/PointLightNode.d.ts | 20 + .../src/nodes/lighting/RectAreaLightNode.d.ts | 21 + .../src/nodes/lighting/ShadowNode.d.ts | 12 + .../src/nodes/lighting/SpotLightNode.d.ts | 15 + .../src/nodes/materialx/MaterialXNodes.d.ts | 107 ++ .../src/nodes/materialx/lib/mx_hsv.d.ts | 6 + .../src/nodes/materialx/lib/mx_noise.d.ts | 359 +++++ .../materialx/lib/mx_transform_color.d.ts | 4 + .../src/nodes/math/ConditionalNode.d.ts | 39 + src-testing/src/nodes/math/Hash.d.ts | 4 + src-testing/src/nodes/math/MathNode.d.ts | 273 ++++ src-testing/src/nodes/math/MathUtils.d.ts | 6 + src-testing/src/nodes/math/OperatorNode.d.ts | 97 ++ src-testing/src/nodes/math/TriNoise3D.d.ts | 12 + .../src/nodes/parsers/GLSLNodeFunction.d.ts | 9 + .../src/nodes/parsers/GLSLNodeParser.d.ts | 8 + src-testing/src/nodes/pmrem/PMREMNode.d.ts | 22 + src-testing/src/nodes/pmrem/PMREMUtils.d.ts | 28 + src-testing/src/nodes/procedural/Checker.d.ts | 4 + src-testing/src/nodes/tsl/TSLBase.d.ts | 21 + src-testing/src/nodes/tsl/TSLCore.ts | 533 ++++++ .../src/nodes/utils/ArrayElementNode.d.ts | 9 + src-testing/src/nodes/utils/ConvertNode.d.ts | 7 + src-testing/src/nodes/utils/CubeMapNode.d.ts | 13 + src-testing/src/nodes/utils/Discard.d.ts | 11 + .../src/nodes/utils/EquirectUVNode.d.ts | 8 + .../nodes/utils/FunctionOverloadingNode.d.ts | 13 + src-testing/src/nodes/utils/JoinNode.d.ts | 10 + src-testing/src/nodes/utils/LoopNode.d.ts | 22 + src-testing/src/nodes/utils/MatcapUVNode.d.ts | 8 + .../src/nodes/utils/MaxMipLevelNode.d.ts | 14 + src-testing/src/nodes/utils/Oscillators.d.ts | 7 + src-testing/src/nodes/utils/Packing.d.ts | 5 + .../src/nodes/utils/PostProcessingUtils.d.ts | 45 + src-testing/src/nodes/utils/RTTNode.d.ts | 45 + .../src/nodes/utils/ReflectorNode.d.ts | 45 + src-testing/src/nodes/utils/RemapNode.d.ts | 36 + src-testing/src/nodes/utils/RotateNode.d.ts | 15 + src-testing/src/nodes/utils/SetNode.d.ts | 11 + src-testing/src/nodes/utils/SplitNode.d.ts | 15 + .../src/nodes/utils/SpriteSheetUVNode.d.ts | 16 + src-testing/src/nodes/utils/SpriteUtils.d.ts | 6 + .../nodes/utils/StorageArrayElementNode.d.ts | 19 + src-testing/src/nodes/utils/Timer.d.ts | 21 + .../nodes/utils/TriplanarTexturesNode.d.ts | 36 + src-testing/src/nodes/utils/UVUtils.d.ts | 14 + .../src/nodes/utils/ViewportUtils.d.ts | 4 + src-testing/src/objects/BatchedMesh.d.ts | 275 ++++ src-testing/src/objects/Bone.d.ts | 36 + src-testing/src/objects/Group.d.ts | 37 + src-testing/src/objects/InstancedMesh.d.ts | 179 +++ src-testing/src/objects/LOD.d.ts | 111 ++ src-testing/src/objects/Line.d.ts | 87 + src-testing/src/objects/LineLoop.d.ts | 40 + src-testing/src/objects/LineSegments.d.ts | 41 + src-testing/src/objects/Mesh.d.ts | 94 ++ src-testing/src/objects/Points.d.ts | 66 + src-testing/src/objects/Skeleton.d.ts | 120 ++ src-testing/src/objects/SkinnedMesh.d.ts | 160 ++ src-testing/src/objects/Sprite.d.ts | 65 + .../src/renderers/WebGL3DRenderTarget.d.ts | 29 + .../src/renderers/WebGLArrayRenderTarget.d.ts | 29 + .../src/renderers/WebGLCubeRenderTarget.d.ts | 18 + .../src/renderers/WebGLRenderTarget.d.ts | 8 + src-testing/src/renderers/WebGLRenderer.d.ts | 558 +++++++ src-testing/src/renderers/common/Animation.ts | 38 + .../src/renderers/common/Attributes.ts | 56 + src-testing/src/renderers/common/Backend.ts | 170 ++ .../src/renderers/common/Background.ts | 133 ++ src-testing/src/renderers/common/BindGroup.ts | 14 + src-testing/src/renderers/common/Binding.ts | 17 + src-testing/src/renderers/common/Bindings.ts | 160 ++ src-testing/src/renderers/common/Buffer.ts | 28 + .../src/renderers/common/BufferUtils.ts | 23 + .../src/renderers/common/BundleGroup.ts | 20 + src-testing/src/renderers/common/ChainMap.ts | 43 + .../src/renderers/common/ClippingContext.ts | 136 ++ src-testing/src/renderers/common/Color4.ts | 27 + .../src/renderers/common/ComputePipeline.ts | 13 + src-testing/src/renderers/common/Constants.ts | 15 + .../src/renderers/common/CubeRenderTarget.ts | 71 + src-testing/src/renderers/common/DataMap.ts | 38 + .../src/renderers/common/Geometries.ts | 199 +++ .../IndirectStorageBufferAttribute.d.ts | 10 + src-testing/src/renderers/common/Info.ts | 95 ++ .../src/renderers/common/Lighting.d.ts | 15 + src-testing/src/renderers/common/Pipeline.ts | 9 + src-testing/src/renderers/common/Pipelines.ts | 270 ++++ .../src/renderers/common/PostProcessing.d.ts | 21 + .../renderers/common/PostProcessingUtils.d.ts | 66 + .../src/renderers/common/ProgrammableStage.ts | 16 + .../src/renderers/common/QuadMesh.d.ts | 16 + .../src/renderers/common/RenderBundle.ts | 12 + .../src/renderers/common/RenderBundles.ts | 28 + .../src/renderers/common/RenderContext.ts | 56 + .../src/renderers/common/RenderContexts.ts | 47 + .../src/renderers/common/RenderList.ts | 142 ++ .../src/renderers/common/RenderLists.ts | 30 + .../src/renderers/common/RenderObject.ts | 350 ++++ .../src/renderers/common/RenderObjects.ts | 107 ++ .../src/renderers/common/RenderPipeline.ts | 12 + src-testing/src/renderers/common/Renderer.ts | 1425 +++++++++++++++++ .../src/renderers/common/SampledTexture.ts | 68 + src-testing/src/renderers/common/Sampler.ts | 14 + .../src/renderers/common/StorageBuffer.ts | 13 + .../common/StorageBufferAttribute.d.ts | 7 + .../StorageInstancedBufferAttribute.d.ts | 8 + .../src/renderers/common/StorageTexture.d.ts | 5 + src-testing/src/renderers/common/Textures.ts | 294 ++++ src-testing/src/renderers/common/Uniform.ts | 105 ++ .../src/renderers/common/UniformBuffer.ts | 11 + .../src/renderers/common/UniformsGroup.ts | 277 ++++ .../renderers/common/extras/PMREMGenerator.ts | 657 ++++++++ .../common/nodes/NodeBuilderState.ts | 55 + .../src/renderers/common/nodes/NodeLibrary.ts | 76 + .../common/nodes/NodeSampledTexture.d.ts | 29 + .../renderers/common/nodes/NodeSampler.d.ts | 12 + .../src/renderers/common/nodes/NodeUniform.ts | 103 ++ .../common/nodes/NodeUniformsGroup.ts | 30 + .../src/renderers/common/nodes/Nodes.ts | 433 +++++ .../common/nodes/StandardNodeLibrary.d.ts | 5 + .../src/renderers/shaders/ShaderChunk.d.ts | 143 ++ .../src/renderers/shaders/ShaderLib.d.ts | 29 + .../src/renderers/shaders/UniformsLib.d.ts | 189 +++ .../src/renderers/shaders/UniformsUtils.d.ts | 14 + .../renderers/webgl-fallback/WebGLBackend.ts | 1349 ++++++++++++++++ .../webgl-fallback/nodes/GLSLNodeBuilder.ts | 812 ++++++++++ .../src/renderers/webgl/WebGLAttributes.d.ts | 21 + .../renderers/webgl/WebGLBindingStates.d.ts | 26 + .../renderers/webgl/WebGLBufferRenderer.d.ts | 21 + .../renderers/webgl/WebGLCapabilities.d.ts | 48 + .../src/renderers/webgl/WebGLClipping.d.ts | 26 + .../src/renderers/webgl/WebGLCubeMaps.d.ts | 8 + .../src/renderers/webgl/WebGLCubeUVMaps.d.ts | 9 + .../src/renderers/webgl/WebGLExtensions.d.ts | 7 + .../src/renderers/webgl/WebGLGeometries.d.ts | 13 + .../webgl/WebGLIndexedBufferRenderer.d.ts | 15 + .../src/renderers/webgl/WebGLInfo.d.ts | 39 + .../src/renderers/webgl/WebGLLights.d.ts | 49 + .../src/renderers/webgl/WebGLObjects.d.ts | 6 + .../src/renderers/webgl/WebGLProgram.d.ts | 30 + .../src/renderers/webgl/WebGLPrograms.d.ts | 233 +++ .../src/renderers/webgl/WebGLProperties.d.ts | 9 + .../src/renderers/webgl/WebGLRenderLists.d.ts | 66 + .../src/renderers/webgl/WebGLShader.d.ts | 1 + .../src/renderers/webgl/WebGLShadowMap.d.ts | 38 + .../src/renderers/webgl/WebGLState.d.ts | 116 ++ .../src/renderers/webgl/WebGLTextures.d.ts | 30 + .../src/renderers/webgl/WebGLUniforms.d.ts | 12 + .../renderers/webgl/WebGLUniformsGroups.d.ts | 17 + .../src/renderers/webgl/WebGLUtils.d.ts | 11 + .../src/renderers/webgpu/WebGPUBackend.ts | 1297 +++++++++++++++ .../webgpu/WebGPURenderer.Nodes.d.ts | 12 + .../src/renderers/webgpu/WebGPURenderer.ts | 46 + .../webgpu/nodes/BasicNodeLibrary.ts | 61 + .../webgpu/nodes/StandardNodeLibrary.ts | 107 ++ .../renderers/webgpu/nodes/WGSLNodeBuilder.ts | 1178 ++++++++++++++ .../webgpu/nodes/WGSLNodeFunction.ts | 142 ++ .../renderers/webgpu/nodes/WGSLNodeParser.ts | 10 + .../webgpu/utils/WebGPUConstants.d.ts | 328 ++++ .../src/renderers/webxr/WebXRController.d.ts | 63 + .../renderers/webxr/WebXRDepthSensing.d.ts | 22 + .../src/renderers/webxr/WebXRManager.d.ts | 85 + src-testing/src/scenes/Fog.d.ts | 77 + src-testing/src/scenes/FogExp2.d.ts | 66 + src-testing/src/scenes/Scene.d.ts | 118 ++ src-testing/src/textures/CanvasTexture.d.ts | 51 + .../src/textures/CompressedArrayTexture.d.ts | 68 + .../src/textures/CompressedCubeTexture.d.ts | 13 + .../src/textures/CompressedTexture.d.ts | 94 ++ src-testing/src/textures/CubeTexture.d.ts | 89 + src-testing/src/textures/Data3DTexture.d.ts | 96 ++ .../src/textures/DataArrayTexture.d.ts | 123 ++ src-testing/src/textures/DataTexture.d.ts | 112 ++ src-testing/src/textures/DepthTexture.d.ts | 104 ++ .../src/textures/FramebufferTexture.d.ts | 62 + src-testing/src/textures/Source.d.ts | 75 + src-testing/src/textures/Texture.d.ts | 476 ++++++ src-testing/src/textures/VideoTexture.d.ts | 90 ++ src-testing/src/textures/types.d.ts | 9 + src-testing/src/utils.d.ts | 3 + 522 files changed, 42350 insertions(+) create mode 100644 src-testing/src/Three.Legacy.d.ts create mode 100644 src-testing/src/Three.WebGPU.Nodes.d.ts create mode 100644 src-testing/src/Three.WebGPU.d.ts create mode 100644 src-testing/src/Three.d.ts create mode 100644 src-testing/src/animation/AnimationAction.d.ts create mode 100644 src-testing/src/animation/AnimationClip.d.ts create mode 100644 src-testing/src/animation/AnimationMixer.d.ts create mode 100644 src-testing/src/animation/AnimationObjectGroup.d.ts create mode 100644 src-testing/src/animation/AnimationUtils.d.ts create mode 100644 src-testing/src/animation/KeyframeTrack.d.ts create mode 100644 src-testing/src/animation/PropertyBinding.d.ts create mode 100644 src-testing/src/animation/PropertyMixer.d.ts create mode 100644 src-testing/src/animation/tracks/BooleanKeyframeTrack.d.ts create mode 100644 src-testing/src/animation/tracks/ColorKeyframeTrack.d.ts create mode 100644 src-testing/src/animation/tracks/NumberKeyframeTrack.d.ts create mode 100644 src-testing/src/animation/tracks/QuaternionKeyframeTrack.d.ts create mode 100644 src-testing/src/animation/tracks/StringKeyframeTrack.d.ts create mode 100644 src-testing/src/animation/tracks/VectorKeyframeTrack.d.ts create mode 100644 src-testing/src/audio/Audio.d.ts create mode 100644 src-testing/src/audio/AudioAnalyser.d.ts create mode 100644 src-testing/src/audio/AudioContext.d.ts create mode 100644 src-testing/src/audio/AudioListener.d.ts create mode 100644 src-testing/src/audio/PositionalAudio.d.ts create mode 100644 src-testing/src/cameras/ArrayCamera.d.ts create mode 100644 src-testing/src/cameras/Camera.d.ts create mode 100644 src-testing/src/cameras/CubeCamera.d.ts create mode 100644 src-testing/src/cameras/OrthographicCamera.d.ts create mode 100644 src-testing/src/cameras/PerspectiveCamera.d.ts create mode 100644 src-testing/src/cameras/StereoCamera.d.ts create mode 100644 src-testing/src/constants.d.ts create mode 100644 src-testing/src/core/BufferAttribute.d.ts create mode 100644 src-testing/src/core/BufferGeometry.d.ts create mode 100644 src-testing/src/core/Clock.d.ts create mode 100644 src-testing/src/core/EventDispatcher.d.ts create mode 100644 src-testing/src/core/GLBufferAttribute.d.ts create mode 100644 src-testing/src/core/InstancedBufferAttribute.d.ts create mode 100644 src-testing/src/core/InstancedBufferGeometry.d.ts create mode 100644 src-testing/src/core/InstancedInterleavedBuffer.d.ts create mode 100644 src-testing/src/core/InterleavedBuffer.d.ts create mode 100644 src-testing/src/core/InterleavedBufferAttribute.d.ts create mode 100644 src-testing/src/core/Layers.d.ts create mode 100644 src-testing/src/core/Object3D.d.ts create mode 100644 src-testing/src/core/Raycaster.d.ts create mode 100644 src-testing/src/core/RenderTarget.d.ts create mode 100644 src-testing/src/core/Uniform.d.ts create mode 100644 src-testing/src/core/UniformsGroup.d.ts create mode 100644 src-testing/src/extras/Controls.d.ts create mode 100644 src-testing/src/extras/DataUtils.d.ts create mode 100644 src-testing/src/extras/Earcut.d.ts create mode 100644 src-testing/src/extras/ImageUtils.d.ts create mode 100644 src-testing/src/extras/PMREMGenerator.d.ts create mode 100644 src-testing/src/extras/ShapeUtils.d.ts create mode 100644 src-testing/src/extras/TextureUtils.d.ts create mode 100644 src-testing/src/extras/core/Curve.d.ts create mode 100644 src-testing/src/extras/core/CurvePath.d.ts create mode 100644 src-testing/src/extras/core/Interpolations.d.ts create mode 100644 src-testing/src/extras/core/Path.d.ts create mode 100644 src-testing/src/extras/core/Shape.d.ts create mode 100644 src-testing/src/extras/core/ShapePath.d.ts create mode 100644 src-testing/src/extras/curves/ArcCurve.d.ts create mode 100644 src-testing/src/extras/curves/CatmullRomCurve3.d.ts create mode 100644 src-testing/src/extras/curves/CubicBezierCurve.d.ts create mode 100644 src-testing/src/extras/curves/CubicBezierCurve3.d.ts create mode 100644 src-testing/src/extras/curves/Curves.d.ts create mode 100644 src-testing/src/extras/curves/EllipseCurve.d.ts create mode 100644 src-testing/src/extras/curves/LineCurve.d.ts create mode 100644 src-testing/src/extras/curves/LineCurve3.d.ts create mode 100644 src-testing/src/extras/curves/QuadraticBezierCurve.d.ts create mode 100644 src-testing/src/extras/curves/QuadraticBezierCurve3.d.ts create mode 100644 src-testing/src/extras/curves/SplineCurve.d.ts create mode 100644 src-testing/src/geometries/BoxGeometry.d.ts create mode 100644 src-testing/src/geometries/CapsuleGeometry.d.ts create mode 100644 src-testing/src/geometries/CircleGeometry.d.ts create mode 100644 src-testing/src/geometries/ConeGeometry.d.ts create mode 100644 src-testing/src/geometries/CylinderGeometry.d.ts create mode 100644 src-testing/src/geometries/DodecahedronGeometry.d.ts create mode 100644 src-testing/src/geometries/EdgesGeometry.d.ts create mode 100644 src-testing/src/geometries/ExtrudeGeometry.d.ts create mode 100644 src-testing/src/geometries/Geometries.d.ts create mode 100644 src-testing/src/geometries/IcosahedronGeometry.d.ts create mode 100644 src-testing/src/geometries/LatheGeometry.d.ts create mode 100644 src-testing/src/geometries/OctahedronGeometry.d.ts create mode 100644 src-testing/src/geometries/PlaneGeometry.d.ts create mode 100644 src-testing/src/geometries/PolyhedronGeometry.d.ts create mode 100644 src-testing/src/geometries/RingGeometry.d.ts create mode 100644 src-testing/src/geometries/ShapeGeometry.d.ts create mode 100644 src-testing/src/geometries/SphereGeometry.d.ts create mode 100644 src-testing/src/geometries/TetrahedronGeometry.d.ts create mode 100644 src-testing/src/geometries/TorusGeometry.d.ts create mode 100644 src-testing/src/geometries/TorusKnotGeometry.d.ts create mode 100644 src-testing/src/geometries/TubeGeometry.d.ts create mode 100644 src-testing/src/geometries/WireframeGeometry.d.ts create mode 100644 src-testing/src/helpers/ArrowHelper.d.ts create mode 100644 src-testing/src/helpers/AxesHelper.d.ts create mode 100644 src-testing/src/helpers/Box3Helper.d.ts create mode 100644 src-testing/src/helpers/BoxHelper.d.ts create mode 100644 src-testing/src/helpers/CameraHelper.d.ts create mode 100644 src-testing/src/helpers/DirectionalLightHelper.d.ts create mode 100644 src-testing/src/helpers/GridHelper.d.ts create mode 100644 src-testing/src/helpers/HemisphereLightHelper.d.ts create mode 100644 src-testing/src/helpers/PlaneHelper.d.ts create mode 100644 src-testing/src/helpers/PointLightHelper.d.ts create mode 100644 src-testing/src/helpers/PolarGridHelper.d.ts create mode 100644 src-testing/src/helpers/SkeletonHelper.d.ts create mode 100644 src-testing/src/helpers/SpotLightHelper.d.ts create mode 100644 src-testing/src/lights/AmbientLight.d.ts create mode 100644 src-testing/src/lights/DirectionalLight.d.ts create mode 100644 src-testing/src/lights/DirectionalLightShadow.d.ts create mode 100644 src-testing/src/lights/HemisphereLight.d.ts create mode 100644 src-testing/src/lights/Light.d.ts create mode 100644 src-testing/src/lights/LightProbe.d.ts create mode 100644 src-testing/src/lights/LightShadow.d.ts create mode 100644 src-testing/src/lights/PointLight.d.ts create mode 100644 src-testing/src/lights/PointLightShadow.d.ts create mode 100644 src-testing/src/lights/RectAreaLight.d.ts create mode 100644 src-testing/src/lights/SpotLight.d.ts create mode 100644 src-testing/src/lights/SpotLightShadow.d.ts create mode 100644 src-testing/src/lights/webgpu/IESSpotLight.d.ts create mode 100644 src-testing/src/loaders/AnimationLoader.d.ts create mode 100644 src-testing/src/loaders/AudioLoader.d.ts create mode 100644 src-testing/src/loaders/BufferGeometryLoader.d.ts create mode 100644 src-testing/src/loaders/Cache.d.ts create mode 100644 src-testing/src/loaders/CompressedTextureLoader.d.ts create mode 100644 src-testing/src/loaders/CubeTextureLoader.d.ts create mode 100644 src-testing/src/loaders/DataTextureLoader.d.ts create mode 100644 src-testing/src/loaders/FileLoader.d.ts create mode 100644 src-testing/src/loaders/ImageBitmapLoader.d.ts create mode 100644 src-testing/src/loaders/ImageLoader.d.ts create mode 100644 src-testing/src/loaders/Loader.d.ts create mode 100644 src-testing/src/loaders/LoaderUtils.d.ts create mode 100644 src-testing/src/loaders/LoadingManager.d.ts create mode 100644 src-testing/src/loaders/MaterialLoader.d.ts create mode 100644 src-testing/src/loaders/ObjectLoader.d.ts create mode 100644 src-testing/src/loaders/TextureLoader.d.ts create mode 100644 src-testing/src/loaders/nodes/NodeLoader.d.ts create mode 100644 src-testing/src/loaders/nodes/NodeMaterialLoader.d.ts create mode 100644 src-testing/src/loaders/nodes/NodeObjectLoader.d.ts create mode 100644 src-testing/src/materials/LineBasicMaterial.d.ts create mode 100644 src-testing/src/materials/LineDashedMaterial.d.ts create mode 100644 src-testing/src/materials/Material.d.ts create mode 100644 src-testing/src/materials/Materials.d.ts create mode 100644 src-testing/src/materials/MeshBasicMaterial.d.ts create mode 100644 src-testing/src/materials/MeshDepthMaterial.d.ts create mode 100644 src-testing/src/materials/MeshDistanceMaterial.d.ts create mode 100644 src-testing/src/materials/MeshLambertMaterial.d.ts create mode 100644 src-testing/src/materials/MeshMatcapMaterial.d.ts create mode 100644 src-testing/src/materials/MeshNormalMaterial.d.ts create mode 100644 src-testing/src/materials/MeshPhongMaterial.d.ts create mode 100644 src-testing/src/materials/MeshPhysicalMaterial.d.ts create mode 100644 src-testing/src/materials/MeshStandardMaterial.d.ts create mode 100644 src-testing/src/materials/MeshToonMaterial.d.ts create mode 100644 src-testing/src/materials/PointsMaterial.d.ts create mode 100644 src-testing/src/materials/RawShaderMaterial.d.ts create mode 100644 src-testing/src/materials/ShaderMaterial.d.ts create mode 100644 src-testing/src/materials/ShadowMaterial.d.ts create mode 100644 src-testing/src/materials/SpriteMaterial.d.ts create mode 100644 src-testing/src/materials/nodes/InstancedPointsNodeMaterial.d.ts create mode 100644 src-testing/src/materials/nodes/Line2NodeMaterial.d.ts create mode 100644 src-testing/src/materials/nodes/LineBasicNodeMaterial.d.ts create mode 100644 src-testing/src/materials/nodes/LineDashedNodeMaterial.d.ts create mode 100644 src-testing/src/materials/nodes/MeshBasicNodeMaterial.d.ts create mode 100644 src-testing/src/materials/nodes/MeshLambertNodeMaterial.d.ts create mode 100644 src-testing/src/materials/nodes/MeshMatcapNodeMaterial.d.ts create mode 100644 src-testing/src/materials/nodes/MeshNormalNodeMaterial.d.ts create mode 100644 src-testing/src/materials/nodes/MeshPhongNodeMaterial.d.ts create mode 100644 src-testing/src/materials/nodes/MeshPhysicalNodeMaterial.d.ts create mode 100644 src-testing/src/materials/nodes/MeshSSSNodeMaterial.d.ts create mode 100644 src-testing/src/materials/nodes/MeshStandardNodeMaterial.d.ts create mode 100644 src-testing/src/materials/nodes/MeshToonNodeMaterial.d.ts create mode 100644 src-testing/src/materials/nodes/NodeMaterial.ts create mode 100644 src-testing/src/materials/nodes/NodeMaterials.d.ts create mode 100644 src-testing/src/materials/nodes/PointsNodeMaterial.d.ts create mode 100644 src-testing/src/materials/nodes/ShadowNodeMaterial.d.ts create mode 100644 src-testing/src/materials/nodes/SpriteNodeMaterial.d.ts create mode 100644 src-testing/src/materials/nodes/VolumeNodeMaterial.d.ts create mode 100644 src-testing/src/materials/nodes/manager/NodeMaterialObserver.ts create mode 100644 src-testing/src/math/Box2.d.ts create mode 100644 src-testing/src/math/Box3.d.ts create mode 100644 src-testing/src/math/Color.d.ts create mode 100644 src-testing/src/math/ColorManagement.d.ts create mode 100644 src-testing/src/math/Cylindrical.d.ts create mode 100644 src-testing/src/math/Euler.d.ts create mode 100644 src-testing/src/math/Frustum.d.ts create mode 100644 src-testing/src/math/Interpolant.d.ts create mode 100644 src-testing/src/math/Line3.d.ts create mode 100644 src-testing/src/math/MathUtils.d.ts create mode 100644 src-testing/src/math/Matrix2.d.ts create mode 100644 src-testing/src/math/Matrix3.d.ts create mode 100644 src-testing/src/math/Matrix4.d.ts create mode 100644 src-testing/src/math/Plane.d.ts create mode 100644 src-testing/src/math/Quaternion.d.ts create mode 100644 src-testing/src/math/Ray.d.ts create mode 100644 src-testing/src/math/Sphere.d.ts create mode 100644 src-testing/src/math/Spherical.d.ts create mode 100644 src-testing/src/math/SphericalHarmonics3.d.ts create mode 100644 src-testing/src/math/Triangle.d.ts create mode 100644 src-testing/src/math/Vector2.d.ts create mode 100644 src-testing/src/math/Vector3.d.ts create mode 100644 src-testing/src/math/Vector4.d.ts create mode 100644 src-testing/src/math/interpolants/CubicInterpolant.d.ts create mode 100644 src-testing/src/math/interpolants/DiscreteInterpolant.d.ts create mode 100644 src-testing/src/math/interpolants/LinearInterpolant.d.ts create mode 100644 src-testing/src/math/interpolants/QuaternionLinearInterpolant.d.ts create mode 100644 src-testing/src/nodes/Nodes.ts create mode 100644 src-testing/src/nodes/TSL.d.ts create mode 100644 src-testing/src/nodes/accessors/AccessorsUtils.d.ts create mode 100644 src-testing/src/nodes/accessors/BatchNode.d.ts create mode 100644 src-testing/src/nodes/accessors/Bitangent.d.ts create mode 100644 src-testing/src/nodes/accessors/BufferAttributeNode.ts create mode 100644 src-testing/src/nodes/accessors/BufferNode.d.ts create mode 100644 src-testing/src/nodes/accessors/Camera.d.ts create mode 100644 src-testing/src/nodes/accessors/ClippingNode.d.ts create mode 100644 src-testing/src/nodes/accessors/CubeTextureNode.d.ts create mode 100644 src-testing/src/nodes/accessors/InstanceNode.d.ts create mode 100644 src-testing/src/nodes/accessors/MaterialNode.d.ts create mode 100644 src-testing/src/nodes/accessors/MaterialProperties.d.ts create mode 100644 src-testing/src/nodes/accessors/MaterialReferenceNode.d.ts create mode 100644 src-testing/src/nodes/accessors/ModelNode.d.ts create mode 100644 src-testing/src/nodes/accessors/ModelViewProjectionNode.d.ts create mode 100644 src-testing/src/nodes/accessors/MorphNode.d.ts create mode 100644 src-testing/src/nodes/accessors/Normal.d.ts create mode 100644 src-testing/src/nodes/accessors/Object3DNode.d.ts create mode 100644 src-testing/src/nodes/accessors/PointUVNode.d.ts create mode 100644 src-testing/src/nodes/accessors/Position.d.ts create mode 100644 src-testing/src/nodes/accessors/ReferenceBaseNode.d.ts create mode 100644 src-testing/src/nodes/accessors/ReferenceNode.d.ts create mode 100644 src-testing/src/nodes/accessors/ReflectVector.d.ts create mode 100644 src-testing/src/nodes/accessors/RendererReferenceNode.d.ts create mode 100644 src-testing/src/nodes/accessors/SceneNode.d.ts create mode 100644 src-testing/src/nodes/accessors/SkinningNode.d.ts create mode 100644 src-testing/src/nodes/accessors/StorageBufferNode.d.ts create mode 100644 src-testing/src/nodes/accessors/StorageTextureNode.d.ts create mode 100644 src-testing/src/nodes/accessors/Tangent.d.ts create mode 100644 src-testing/src/nodes/accessors/Texture3DNode.d.ts create mode 100644 src-testing/src/nodes/accessors/TextureBicubic.d.ts create mode 100644 src-testing/src/nodes/accessors/TextureNode.ts create mode 100644 src-testing/src/nodes/accessors/TextureSizeNode.d.ts create mode 100644 src-testing/src/nodes/accessors/UV.d.ts create mode 100644 src-testing/src/nodes/accessors/UniformArrayNode.d.ts create mode 100644 src-testing/src/nodes/accessors/UserDataNode.d.ts create mode 100644 src-testing/src/nodes/accessors/VelocityNode.d.ts create mode 100644 src-testing/src/nodes/accessors/VertexColorNode.d.ts create mode 100644 src-testing/src/nodes/code/CodeNode.ts create mode 100644 src-testing/src/nodes/code/ExpressionNode.d.ts create mode 100644 src-testing/src/nodes/code/FunctionCallNode.d.ts create mode 100644 src-testing/src/nodes/code/FunctionNode.ts create mode 100644 src-testing/src/nodes/code/ScriptableNode.d.ts create mode 100644 src-testing/src/nodes/code/ScriptableValueNode.d.ts create mode 100644 src-testing/src/nodes/core/AssignNode.d.ts create mode 100644 src-testing/src/nodes/core/AttributeNode.d.ts create mode 100644 src-testing/src/nodes/core/BypassNode.d.ts create mode 100644 src-testing/src/nodes/core/CacheNode.d.ts create mode 100644 src-testing/src/nodes/core/ConstNode.d.ts create mode 100644 src-testing/src/nodes/core/ContextNode.ts create mode 100644 src-testing/src/nodes/core/IndexNode.d.ts create mode 100644 src-testing/src/nodes/core/InputNode.ts create mode 100644 src-testing/src/nodes/core/LightingModel.d.ts create mode 100644 src-testing/src/nodes/core/MRTNode.d.ts create mode 100644 src-testing/src/nodes/core/Node.ts create mode 100644 src-testing/src/nodes/core/NodeAttribute.ts create mode 100644 src-testing/src/nodes/core/NodeBuilder.ts create mode 100644 src-testing/src/nodes/core/NodeCache.ts create mode 100644 src-testing/src/nodes/core/NodeCode.ts create mode 100644 src-testing/src/nodes/core/NodeFrame.ts create mode 100644 src-testing/src/nodes/core/NodeFunction.ts create mode 100644 src-testing/src/nodes/core/NodeFunctionInput.d.ts create mode 100644 src-testing/src/nodes/core/NodeParser.ts create mode 100644 src-testing/src/nodes/core/NodeUniform.ts create mode 100644 src-testing/src/nodes/core/NodeUtils.ts create mode 100644 src-testing/src/nodes/core/NodeVar.ts create mode 100644 src-testing/src/nodes/core/NodeVarying.ts create mode 100644 src-testing/src/nodes/core/OutputStructNode.d.ts create mode 100644 src-testing/src/nodes/core/ParameterNode.d.ts create mode 100644 src-testing/src/nodes/core/PropertyNode.d.ts create mode 100644 src-testing/src/nodes/core/StackNode.ts create mode 100644 src-testing/src/nodes/core/StructTypeNode.ts create mode 100644 src-testing/src/nodes/core/TempNode.d.ts create mode 100644 src-testing/src/nodes/core/UniformGroup.d.ts create mode 100644 src-testing/src/nodes/core/UniformGroupNode.ts create mode 100644 src-testing/src/nodes/core/UniformNode.ts create mode 100644 src-testing/src/nodes/core/VarNode.d.ts create mode 100644 src-testing/src/nodes/core/VaryingNode.d.ts create mode 100644 src-testing/src/nodes/core/constants.ts create mode 100644 src-testing/src/nodes/display/BlendMode.d.ts create mode 100644 src-testing/src/nodes/display/BumpMapNode.d.ts create mode 100644 src-testing/src/nodes/display/ColorAdjustment.d.ts create mode 100644 src-testing/src/nodes/display/ColorSpaceFunctions.d.ts create mode 100644 src-testing/src/nodes/display/ColorSpaceNode.d.ts create mode 100644 src-testing/src/nodes/display/FrontFacingNode.d.ts create mode 100644 src-testing/src/nodes/display/NormalMapNode.d.ts create mode 100644 src-testing/src/nodes/display/PassNode.d.ts create mode 100644 src-testing/src/nodes/display/PosterizeNode.d.ts create mode 100644 src-testing/src/nodes/display/RenderOutputNode.d.ts create mode 100644 src-testing/src/nodes/display/ScreenNode.d.ts create mode 100644 src-testing/src/nodes/display/ToneMappingFunctions.d.ts create mode 100644 src-testing/src/nodes/display/ToneMappingNode.d.ts create mode 100644 src-testing/src/nodes/display/ToonOutlinePassNode.d.ts create mode 100644 src-testing/src/nodes/display/ViewportDepthNode.d.ts create mode 100644 src-testing/src/nodes/display/ViewportDepthTextureNode.d.ts create mode 100644 src-testing/src/nodes/display/ViewportSharedTextureNode.d.ts create mode 100644 src-testing/src/nodes/display/ViewportTextureNode.d.ts create mode 100644 src-testing/src/nodes/fog/FogExp2Node.d.ts create mode 100644 src-testing/src/nodes/fog/FogNode.ts create mode 100644 src-testing/src/nodes/fog/FogRangeNode.d.ts create mode 100644 src-testing/src/nodes/functions/BSDF/BRDF_GGX.d.ts create mode 100644 src-testing/src/nodes/functions/BSDF/BRDF_Lambert.d.ts create mode 100644 src-testing/src/nodes/functions/BSDF/BRDF_Sheen.d.ts create mode 100644 src-testing/src/nodes/functions/BSDF/DFGApprox.d.ts create mode 100644 src-testing/src/nodes/functions/BSDF/D_GGX.d.ts create mode 100644 src-testing/src/nodes/functions/BSDF/D_GGX_Anisotropic.d.ts create mode 100644 src-testing/src/nodes/functions/BSDF/F_Schlick.d.ts create mode 100644 src-testing/src/nodes/functions/BSDF/LTC.d.ts create mode 100644 src-testing/src/nodes/functions/BSDF/Schlick_to_F0.d.ts create mode 100644 src-testing/src/nodes/functions/BSDF/V_GGX_SmithCorrelated.d.ts create mode 100644 src-testing/src/nodes/functions/BSDF/V_GGX_SmithCorrelated_Anisotropic.d.ts create mode 100644 src-testing/src/nodes/functions/BasicLightingModel.d.ts create mode 100644 src-testing/src/nodes/functions/PhongLightingModel.d.ts create mode 100644 src-testing/src/nodes/functions/PhysicalLightingModel.d.ts create mode 100644 src-testing/src/nodes/functions/ShadowMaskModel.d.ts create mode 100644 src-testing/src/nodes/functions/ToonLightingModel.d.ts create mode 100644 src-testing/src/nodes/functions/material/getGeometryRoughness.d.ts create mode 100644 src-testing/src/nodes/functions/material/getRoughness.d.ts create mode 100644 src-testing/src/nodes/functions/material/getShIrradianceAt.d.ts create mode 100644 src-testing/src/nodes/geometry/RangeNode.d.ts create mode 100644 src-testing/src/nodes/gpgpu/ComputeNode.ts create mode 100644 src-testing/src/nodes/lighting/AONode.d.ts create mode 100644 src-testing/src/nodes/lighting/AmbientLightNode.d.ts create mode 100644 src-testing/src/nodes/lighting/AnalyticLightNode.d.ts create mode 100644 src-testing/src/nodes/lighting/BasicEnvironmentNode.d.ts create mode 100644 src-testing/src/nodes/lighting/BasicLightMapNode.d.ts create mode 100644 src-testing/src/nodes/lighting/DirectionalLightNode.d.ts create mode 100644 src-testing/src/nodes/lighting/EnvironmentNode.ts create mode 100644 src-testing/src/nodes/lighting/HemisphereLightNode.d.ts create mode 100644 src-testing/src/nodes/lighting/IESSpotLightNode.d.ts create mode 100644 src-testing/src/nodes/lighting/IrradianceNode.d.ts create mode 100644 src-testing/src/nodes/lighting/LightNode.d.ts create mode 100644 src-testing/src/nodes/lighting/LightProbeNode.d.ts create mode 100644 src-testing/src/nodes/lighting/LightUtils.d.ts create mode 100644 src-testing/src/nodes/lighting/LightingContextNode.ts create mode 100644 src-testing/src/nodes/lighting/LightingNode.d.ts create mode 100644 src-testing/src/nodes/lighting/LightsNode.ts create mode 100644 src-testing/src/nodes/lighting/PointLightNode.d.ts create mode 100644 src-testing/src/nodes/lighting/RectAreaLightNode.d.ts create mode 100644 src-testing/src/nodes/lighting/ShadowNode.d.ts create mode 100644 src-testing/src/nodes/lighting/SpotLightNode.d.ts create mode 100644 src-testing/src/nodes/materialx/MaterialXNodes.d.ts create mode 100644 src-testing/src/nodes/materialx/lib/mx_hsv.d.ts create mode 100644 src-testing/src/nodes/materialx/lib/mx_noise.d.ts create mode 100644 src-testing/src/nodes/materialx/lib/mx_transform_color.d.ts create mode 100644 src-testing/src/nodes/math/ConditionalNode.d.ts create mode 100644 src-testing/src/nodes/math/Hash.d.ts create mode 100644 src-testing/src/nodes/math/MathNode.d.ts create mode 100644 src-testing/src/nodes/math/MathUtils.d.ts create mode 100644 src-testing/src/nodes/math/OperatorNode.d.ts create mode 100644 src-testing/src/nodes/math/TriNoise3D.d.ts create mode 100644 src-testing/src/nodes/parsers/GLSLNodeFunction.d.ts create mode 100644 src-testing/src/nodes/parsers/GLSLNodeParser.d.ts create mode 100644 src-testing/src/nodes/pmrem/PMREMNode.d.ts create mode 100644 src-testing/src/nodes/pmrem/PMREMUtils.d.ts create mode 100644 src-testing/src/nodes/procedural/Checker.d.ts create mode 100644 src-testing/src/nodes/tsl/TSLBase.d.ts create mode 100644 src-testing/src/nodes/tsl/TSLCore.ts create mode 100644 src-testing/src/nodes/utils/ArrayElementNode.d.ts create mode 100644 src-testing/src/nodes/utils/ConvertNode.d.ts create mode 100644 src-testing/src/nodes/utils/CubeMapNode.d.ts create mode 100644 src-testing/src/nodes/utils/Discard.d.ts create mode 100644 src-testing/src/nodes/utils/EquirectUVNode.d.ts create mode 100644 src-testing/src/nodes/utils/FunctionOverloadingNode.d.ts create mode 100644 src-testing/src/nodes/utils/JoinNode.d.ts create mode 100644 src-testing/src/nodes/utils/LoopNode.d.ts create mode 100644 src-testing/src/nodes/utils/MatcapUVNode.d.ts create mode 100644 src-testing/src/nodes/utils/MaxMipLevelNode.d.ts create mode 100644 src-testing/src/nodes/utils/Oscillators.d.ts create mode 100644 src-testing/src/nodes/utils/Packing.d.ts create mode 100644 src-testing/src/nodes/utils/PostProcessingUtils.d.ts create mode 100644 src-testing/src/nodes/utils/RTTNode.d.ts create mode 100644 src-testing/src/nodes/utils/ReflectorNode.d.ts create mode 100644 src-testing/src/nodes/utils/RemapNode.d.ts create mode 100644 src-testing/src/nodes/utils/RotateNode.d.ts create mode 100644 src-testing/src/nodes/utils/SetNode.d.ts create mode 100644 src-testing/src/nodes/utils/SplitNode.d.ts create mode 100644 src-testing/src/nodes/utils/SpriteSheetUVNode.d.ts create mode 100644 src-testing/src/nodes/utils/SpriteUtils.d.ts create mode 100644 src-testing/src/nodes/utils/StorageArrayElementNode.d.ts create mode 100644 src-testing/src/nodes/utils/Timer.d.ts create mode 100644 src-testing/src/nodes/utils/TriplanarTexturesNode.d.ts create mode 100644 src-testing/src/nodes/utils/UVUtils.d.ts create mode 100644 src-testing/src/nodes/utils/ViewportUtils.d.ts create mode 100644 src-testing/src/objects/BatchedMesh.d.ts create mode 100644 src-testing/src/objects/Bone.d.ts create mode 100644 src-testing/src/objects/Group.d.ts create mode 100644 src-testing/src/objects/InstancedMesh.d.ts create mode 100644 src-testing/src/objects/LOD.d.ts create mode 100644 src-testing/src/objects/Line.d.ts create mode 100644 src-testing/src/objects/LineLoop.d.ts create mode 100644 src-testing/src/objects/LineSegments.d.ts create mode 100644 src-testing/src/objects/Mesh.d.ts create mode 100644 src-testing/src/objects/Points.d.ts create mode 100644 src-testing/src/objects/Skeleton.d.ts create mode 100644 src-testing/src/objects/SkinnedMesh.d.ts create mode 100644 src-testing/src/objects/Sprite.d.ts create mode 100644 src-testing/src/renderers/WebGL3DRenderTarget.d.ts create mode 100644 src-testing/src/renderers/WebGLArrayRenderTarget.d.ts create mode 100644 src-testing/src/renderers/WebGLCubeRenderTarget.d.ts create mode 100644 src-testing/src/renderers/WebGLRenderTarget.d.ts create mode 100644 src-testing/src/renderers/WebGLRenderer.d.ts create mode 100644 src-testing/src/renderers/common/Animation.ts create mode 100644 src-testing/src/renderers/common/Attributes.ts create mode 100644 src-testing/src/renderers/common/Backend.ts create mode 100644 src-testing/src/renderers/common/Background.ts create mode 100644 src-testing/src/renderers/common/BindGroup.ts create mode 100644 src-testing/src/renderers/common/Binding.ts create mode 100644 src-testing/src/renderers/common/Bindings.ts create mode 100644 src-testing/src/renderers/common/Buffer.ts create mode 100644 src-testing/src/renderers/common/BufferUtils.ts create mode 100644 src-testing/src/renderers/common/BundleGroup.ts create mode 100644 src-testing/src/renderers/common/ChainMap.ts create mode 100644 src-testing/src/renderers/common/ClippingContext.ts create mode 100644 src-testing/src/renderers/common/Color4.ts create mode 100644 src-testing/src/renderers/common/ComputePipeline.ts create mode 100644 src-testing/src/renderers/common/Constants.ts create mode 100644 src-testing/src/renderers/common/CubeRenderTarget.ts create mode 100644 src-testing/src/renderers/common/DataMap.ts create mode 100644 src-testing/src/renderers/common/Geometries.ts create mode 100644 src-testing/src/renderers/common/IndirectStorageBufferAttribute.d.ts create mode 100644 src-testing/src/renderers/common/Info.ts create mode 100644 src-testing/src/renderers/common/Lighting.d.ts create mode 100644 src-testing/src/renderers/common/Pipeline.ts create mode 100644 src-testing/src/renderers/common/Pipelines.ts create mode 100644 src-testing/src/renderers/common/PostProcessing.d.ts create mode 100644 src-testing/src/renderers/common/PostProcessingUtils.d.ts create mode 100644 src-testing/src/renderers/common/ProgrammableStage.ts create mode 100644 src-testing/src/renderers/common/QuadMesh.d.ts create mode 100644 src-testing/src/renderers/common/RenderBundle.ts create mode 100644 src-testing/src/renderers/common/RenderBundles.ts create mode 100644 src-testing/src/renderers/common/RenderContext.ts create mode 100644 src-testing/src/renderers/common/RenderContexts.ts create mode 100644 src-testing/src/renderers/common/RenderList.ts create mode 100644 src-testing/src/renderers/common/RenderLists.ts create mode 100644 src-testing/src/renderers/common/RenderObject.ts create mode 100644 src-testing/src/renderers/common/RenderObjects.ts create mode 100644 src-testing/src/renderers/common/RenderPipeline.ts create mode 100644 src-testing/src/renderers/common/Renderer.ts create mode 100644 src-testing/src/renderers/common/SampledTexture.ts create mode 100644 src-testing/src/renderers/common/Sampler.ts create mode 100644 src-testing/src/renderers/common/StorageBuffer.ts create mode 100644 src-testing/src/renderers/common/StorageBufferAttribute.d.ts create mode 100644 src-testing/src/renderers/common/StorageInstancedBufferAttribute.d.ts create mode 100644 src-testing/src/renderers/common/StorageTexture.d.ts create mode 100644 src-testing/src/renderers/common/Textures.ts create mode 100644 src-testing/src/renderers/common/Uniform.ts create mode 100644 src-testing/src/renderers/common/UniformBuffer.ts create mode 100644 src-testing/src/renderers/common/UniformsGroup.ts create mode 100644 src-testing/src/renderers/common/extras/PMREMGenerator.ts create mode 100644 src-testing/src/renderers/common/nodes/NodeBuilderState.ts create mode 100644 src-testing/src/renderers/common/nodes/NodeLibrary.ts create mode 100644 src-testing/src/renderers/common/nodes/NodeSampledTexture.d.ts create mode 100644 src-testing/src/renderers/common/nodes/NodeSampler.d.ts create mode 100644 src-testing/src/renderers/common/nodes/NodeUniform.ts create mode 100644 src-testing/src/renderers/common/nodes/NodeUniformsGroup.ts create mode 100644 src-testing/src/renderers/common/nodes/Nodes.ts create mode 100644 src-testing/src/renderers/common/nodes/StandardNodeLibrary.d.ts create mode 100644 src-testing/src/renderers/shaders/ShaderChunk.d.ts create mode 100644 src-testing/src/renderers/shaders/ShaderLib.d.ts create mode 100644 src-testing/src/renderers/shaders/UniformsLib.d.ts create mode 100644 src-testing/src/renderers/shaders/UniformsUtils.d.ts create mode 100644 src-testing/src/renderers/webgl-fallback/WebGLBackend.ts create mode 100644 src-testing/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.ts create mode 100644 src-testing/src/renderers/webgl/WebGLAttributes.d.ts create mode 100644 src-testing/src/renderers/webgl/WebGLBindingStates.d.ts create mode 100644 src-testing/src/renderers/webgl/WebGLBufferRenderer.d.ts create mode 100644 src-testing/src/renderers/webgl/WebGLCapabilities.d.ts create mode 100644 src-testing/src/renderers/webgl/WebGLClipping.d.ts create mode 100644 src-testing/src/renderers/webgl/WebGLCubeMaps.d.ts create mode 100644 src-testing/src/renderers/webgl/WebGLCubeUVMaps.d.ts create mode 100644 src-testing/src/renderers/webgl/WebGLExtensions.d.ts create mode 100644 src-testing/src/renderers/webgl/WebGLGeometries.d.ts create mode 100644 src-testing/src/renderers/webgl/WebGLIndexedBufferRenderer.d.ts create mode 100644 src-testing/src/renderers/webgl/WebGLInfo.d.ts create mode 100644 src-testing/src/renderers/webgl/WebGLLights.d.ts create mode 100644 src-testing/src/renderers/webgl/WebGLObjects.d.ts create mode 100644 src-testing/src/renderers/webgl/WebGLProgram.d.ts create mode 100644 src-testing/src/renderers/webgl/WebGLPrograms.d.ts create mode 100644 src-testing/src/renderers/webgl/WebGLProperties.d.ts create mode 100644 src-testing/src/renderers/webgl/WebGLRenderLists.d.ts create mode 100644 src-testing/src/renderers/webgl/WebGLShader.d.ts create mode 100644 src-testing/src/renderers/webgl/WebGLShadowMap.d.ts create mode 100644 src-testing/src/renderers/webgl/WebGLState.d.ts create mode 100644 src-testing/src/renderers/webgl/WebGLTextures.d.ts create mode 100644 src-testing/src/renderers/webgl/WebGLUniforms.d.ts create mode 100644 src-testing/src/renderers/webgl/WebGLUniformsGroups.d.ts create mode 100644 src-testing/src/renderers/webgl/WebGLUtils.d.ts create mode 100644 src-testing/src/renderers/webgpu/WebGPUBackend.ts create mode 100644 src-testing/src/renderers/webgpu/WebGPURenderer.Nodes.d.ts create mode 100644 src-testing/src/renderers/webgpu/WebGPURenderer.ts create mode 100644 src-testing/src/renderers/webgpu/nodes/BasicNodeLibrary.ts create mode 100644 src-testing/src/renderers/webgpu/nodes/StandardNodeLibrary.ts create mode 100644 src-testing/src/renderers/webgpu/nodes/WGSLNodeBuilder.ts create mode 100644 src-testing/src/renderers/webgpu/nodes/WGSLNodeFunction.ts create mode 100644 src-testing/src/renderers/webgpu/nodes/WGSLNodeParser.ts create mode 100644 src-testing/src/renderers/webgpu/utils/WebGPUConstants.d.ts create mode 100644 src-testing/src/renderers/webxr/WebXRController.d.ts create mode 100644 src-testing/src/renderers/webxr/WebXRDepthSensing.d.ts create mode 100644 src-testing/src/renderers/webxr/WebXRManager.d.ts create mode 100644 src-testing/src/scenes/Fog.d.ts create mode 100644 src-testing/src/scenes/FogExp2.d.ts create mode 100644 src-testing/src/scenes/Scene.d.ts create mode 100644 src-testing/src/textures/CanvasTexture.d.ts create mode 100644 src-testing/src/textures/CompressedArrayTexture.d.ts create mode 100644 src-testing/src/textures/CompressedCubeTexture.d.ts create mode 100644 src-testing/src/textures/CompressedTexture.d.ts create mode 100644 src-testing/src/textures/CubeTexture.d.ts create mode 100644 src-testing/src/textures/Data3DTexture.d.ts create mode 100644 src-testing/src/textures/DataArrayTexture.d.ts create mode 100644 src-testing/src/textures/DataTexture.d.ts create mode 100644 src-testing/src/textures/DepthTexture.d.ts create mode 100644 src-testing/src/textures/FramebufferTexture.d.ts create mode 100644 src-testing/src/textures/Source.d.ts create mode 100644 src-testing/src/textures/Texture.d.ts create mode 100644 src-testing/src/textures/VideoTexture.d.ts create mode 100644 src-testing/src/textures/types.d.ts create mode 100644 src-testing/src/utils.d.ts diff --git a/src-testing/src/Three.Legacy.d.ts b/src-testing/src/Three.Legacy.d.ts new file mode 100644 index 000000000..07f4743b9 --- /dev/null +++ b/src-testing/src/Three.Legacy.d.ts @@ -0,0 +1,20 @@ +import { RenderTargetOptions } from "./core/RenderTarget.js"; +import { WebGLRenderTarget } from "./renderers/WebGLRenderTarget.js"; +import { Texture } from "./textures/Texture.js"; + +/** + * @deprecated THREE.WebGLMultipleRenderTargets has been deprecated and will be removed in r172. Use THREE.WebGLRenderTarget and set the "count" parameter to enable MRT. + */ +export class WebGLMultipleRenderTargets extends WebGLRenderTarget { + readonly isWebGLMultipleRenderTargets: true; + + /** + * @deprecated THREE.WebGLMultipleRenderTargets has been deprecated and will be removed in r172. Use THREE.WebGLRenderTarget and set the "count" parameter to enable MRT. + * @param width The width of the render target. + * @param height The height of the render target. + * @param count The number of render targets. + * @param options object that holds texture parameters for an auto-generated target texture and depthBuffer/stencilBuffer booleans. + * For an explanation of the texture parameters see {@link Texture}. + */ + constructor(width?: number, height?: number, count?: number, options?: RenderTargetOptions); +} diff --git a/src-testing/src/Three.WebGPU.Nodes.d.ts b/src-testing/src/Three.WebGPU.Nodes.d.ts new file mode 100644 index 000000000..ac876f6fe --- /dev/null +++ b/src-testing/src/Three.WebGPU.Nodes.d.ts @@ -0,0 +1,205 @@ +export * from "./animation/AnimationAction.js"; +export * from "./animation/AnimationClip.js"; +export * from "./animation/AnimationMixer.js"; +export * from "./animation/AnimationObjectGroup.js"; +export { AnimationUtils } from "./animation/AnimationUtils.js"; +export * from "./animation/KeyframeTrack.js"; +export * from "./animation/PropertyBinding.js"; +export * from "./animation/PropertyMixer.js"; +export * from "./animation/tracks/BooleanKeyframeTrack.js"; +export * from "./animation/tracks/ColorKeyframeTrack.js"; +export * from "./animation/tracks/NumberKeyframeTrack.js"; +export * from "./animation/tracks/QuaternionKeyframeTrack.js"; +export * from "./animation/tracks/StringKeyframeTrack.js"; +export * from "./animation/tracks/VectorKeyframeTrack.js"; +export * from "./audio/Audio.js"; +export * from "./audio/AudioAnalyser.js"; +export * from "./audio/AudioContext.js"; +export * from "./audio/AudioListener.js"; +export * from "./audio/PositionalAudio.js"; +export * from "./cameras/ArrayCamera.js"; +export * from "./cameras/Camera.js"; +export * from "./cameras/CubeCamera.js"; +export * from "./cameras/OrthographicCamera.js"; +export * from "./cameras/PerspectiveCamera.js"; +export * from "./cameras/StereoCamera.js"; +export * from "./constants.js"; +export * from "./core/BufferAttribute.js"; +export * from "./core/BufferGeometry.js"; +export * from "./core/Clock.js"; +export * from "./core/EventDispatcher.js"; +export * from "./core/GLBufferAttribute.js"; +export * from "./core/InstancedBufferAttribute.js"; +export * from "./core/InstancedBufferGeometry.js"; +export * from "./core/InstancedInterleavedBuffer.js"; +export * from "./core/InterleavedBuffer.js"; +export * from "./core/InterleavedBufferAttribute.js"; +export * from "./core/Layers.js"; +export * from "./core/Object3D.js"; +export * from "./core/Raycaster.js"; +export * from "./core/RenderTarget.js"; +export * from "./core/Uniform.js"; +export * from "./core/UniformsGroup.js"; +export * from "./extras/Controls.js"; +export * from "./extras/core/Curve.js"; +export * from "./extras/core/CurvePath.js"; +export * from "./extras/core/Path.js"; +export * from "./extras/core/Shape.js"; +export * from "./extras/core/ShapePath.js"; +export * from "./extras/curves/Curves.js"; +export { DataUtils } from "./extras/DataUtils.js"; +export * from "./extras/ImageUtils.js"; +// export * from "./extras/PMREMGenerator.js"; +export * from "./extras/ShapeUtils.js"; +export { TextureUtils } from "./extras/TextureUtils.js"; +export * from "./geometries/Geometries.js"; +export * from "./helpers/ArrowHelper.js"; +export * from "./helpers/AxesHelper.js"; +export * from "./helpers/Box3Helper.js"; +export * from "./helpers/BoxHelper.js"; +export * from "./helpers/CameraHelper.js"; +export * from "./helpers/DirectionalLightHelper.js"; +export * from "./helpers/GridHelper.js"; +export * from "./helpers/HemisphereLightHelper.js"; +export * from "./helpers/PlaneHelper.js"; +export * from "./helpers/PointLightHelper.js"; +export * from "./helpers/PolarGridHelper.js"; +export * from "./helpers/SkeletonHelper.js"; +export * from "./helpers/SpotLightHelper.js"; +export * from "./lights/AmbientLight.js"; +export * from "./lights/DirectionalLight.js"; +export type { DirectionalLightShadow } from "./lights/DirectionalLightShadow.js"; +export * from "./lights/HemisphereLight.js"; +export * from "./lights/Light.js"; +export * from "./lights/LightProbe.js"; +export type { LightShadow, LightShadowJSON } from "./lights/LightShadow.js"; +export * from "./lights/PointLight.js"; +export type { PointLightShadow } from "./lights/PointLightShadow.js"; +export * from "./lights/RectAreaLight.js"; +export * from "./lights/SpotLight.js"; +export type { SpotLightShadow } from "./lights/SpotLightShadow.js"; +export * from "./loaders/AnimationLoader.js"; +export * from "./loaders/AudioLoader.js"; +export * from "./loaders/BufferGeometryLoader.js"; +export * from "./loaders/Cache.js"; +export * from "./loaders/CompressedTextureLoader.js"; +export * from "./loaders/CubeTextureLoader.js"; +export * from "./loaders/DataTextureLoader.js"; +export * from "./loaders/FileLoader.js"; +export * from "./loaders/ImageBitmapLoader.js"; +export * from "./loaders/ImageLoader.js"; +export * from "./loaders/Loader.js"; +export * from "./loaders/LoaderUtils.js"; +export * from "./loaders/LoadingManager.js"; +export * from "./loaders/MaterialLoader.js"; +export * from "./loaders/ObjectLoader.js"; +export * from "./loaders/TextureLoader.js"; +export * from "./materials/Materials.js"; +export * from "./materials/nodes/NodeMaterials.js"; +export * from "./math/Box2.js"; +export * from "./math/Box3.js"; +export * from "./math/Color.js"; +export { ColorManagement, ColorSpaceDefinition } from "./math/ColorManagement.js"; +export * from "./math/Cylindrical.js"; +export * from "./math/Euler.js"; +export * from "./math/Frustum.js"; +export * from "./math/Interpolant.js"; +export * from "./math/interpolants/CubicInterpolant.js"; +export * from "./math/interpolants/DiscreteInterpolant.js"; +export * from "./math/interpolants/LinearInterpolant.js"; +export * from "./math/interpolants/QuaternionLinearInterpolant.js"; +export * from "./math/Line3.js"; +export { MathUtils } from "./math/MathUtils.js"; +export * from "./math/Matrix2.js"; +export * from "./math/Matrix3.js"; +export * from "./math/Matrix4.js"; +export * from "./math/Plane.js"; +export * from "./math/Quaternion.js"; +export * from "./math/Ray.js"; +export * from "./math/Sphere.js"; +export * from "./math/Spherical.js"; +export * from "./math/SphericalHarmonics3.js"; +export * from "./math/Triangle.js"; +export * from "./math/Vector2.js"; +export * from "./math/Vector3.js"; +export * from "./math/Vector4.js"; +export * from "./objects/BatchedMesh.js"; +export * from "./objects/Bone.js"; +export * from "./objects/Group.js"; +export * from "./objects/InstancedMesh.js"; +export * from "./objects/Line.js"; +export * from "./objects/LineLoop.js"; +export * from "./objects/LineSegments.js"; +export * from "./objects/LOD.js"; +export * from "./objects/Mesh.js"; +export * from "./objects/Points.js"; +export * from "./objects/Skeleton.js"; +export * from "./objects/SkinnedMesh.js"; +export * from "./objects/Sprite.js"; +// export * from "./renderers/shaders/ShaderChunk.js"; +// export * from "./renderers/shaders/ShaderLib.js"; +// export * from "./renderers/shaders/UniformsLib.js"; +// export { UniformsUtils } from './renderers/shaders/UniformsUtils.js'; +export type { WebGLProgramParameters, WebGLProgramParametersWithUniforms } from "./renderers/webgl/WebGLPrograms.js"; +export type { WebGLShadowMap } from "./renderers/webgl/WebGLShadowMap.js"; +// export * from "./renderers/webgl/WebGLUtils.js"; +export * from "./renderers/WebGL3DRenderTarget.js"; +export * from "./renderers/WebGLArrayRenderTarget.js"; +export * from "./renderers/WebGLCubeRenderTarget.js"; +// export * from "./renderers/WebGLRenderer.js"; +export * from "./renderers/WebGLRenderTarget.js"; +export type { + WebXRController, + WebXRSpaceEventMap, + XRControllerEventType, + XRGripSpace, + XRHandInputState, + XRHandJoints, + XRHandSpace, + XRJointSpace, + XRTargetRaySpace, +} from "./renderers/webxr/WebXRController.js"; +export type { WebXRDepthSensing } from "./renderers/webxr/WebXRDepthSensing.js"; +export type { + WebXRArrayCamera, + WebXRCamera, + WebXRManager, + WebXRManagerEventMap, +} from "./renderers/webxr/WebXRManager.js"; +export * from "./scenes/Fog.js"; +export * from "./scenes/FogExp2.js"; +export * from "./scenes/Scene.js"; +export * from "./textures/CanvasTexture.js"; +export * from "./textures/CompressedArrayTexture.js"; +export * from "./textures/CompressedCubeTexture.js"; +export * from "./textures/CompressedTexture.js"; +export * from "./textures/CubeTexture.js"; +export * from "./textures/Data3DTexture.js"; +export * from "./textures/DataArrayTexture.js"; +export * from "./textures/DataTexture.js"; +export * from "./textures/DepthTexture.js"; +export * from "./textures/FramebufferTexture.js"; +export * from "./textures/Source.js"; +export * from "./textures/Texture.js"; +export * from "./textures/VideoTexture.js"; +export * from "./Three.Legacy.js"; +export { createCanvasElement } from "./utils.js"; + +export { default as IESSpotLight } from "./lights/webgpu/IESSpotLight.js"; +export { default as NodeLoader } from "./loaders/nodes/NodeLoader.js"; +export { default as NodeMaterialLoader } from "./loaders/nodes/NodeMaterialLoader.js"; +export { default as NodeObjectLoader } from "./loaders/nodes/NodeObjectLoader.js"; +export * from "./nodes/Nodes.js"; +export * from "./nodes/TSL.js"; +export { default as PMREMGenerator } from "./renderers/common/extras/PMREMGenerator.js"; +export { default as PostProcessing } from "./renderers/common/PostProcessing.js"; +import * as PostProcessingUtils from "./renderers/common/PostProcessingUtils.js"; +export { PostProcessingUtils }; +export { default as IndirectStorageBufferAttribute } from "./renderers/common/IndirectStorageBufferAttribute.js"; +export { default as Lighting } from "./renderers/common/Lighting.js"; +export { default as QuadMesh } from "./renderers/common/QuadMesh.js"; +export type { default as Renderer } from "./renderers/common/Renderer.js"; +export { default as StorageBufferAttribute } from "./renderers/common/StorageBufferAttribute.js"; +export { default as StorageInstancedBufferAttribute } from "./renderers/common/StorageInstancedBufferAttribute.js"; +export { default as StorageTexture } from "./renderers/common/StorageTexture.js"; +export { default as WebGPURenderer } from "./renderers/webgpu/WebGPURenderer.Nodes.js"; diff --git a/src-testing/src/Three.WebGPU.d.ts b/src-testing/src/Three.WebGPU.d.ts new file mode 100644 index 000000000..254ef5332 --- /dev/null +++ b/src-testing/src/Three.WebGPU.d.ts @@ -0,0 +1,206 @@ +export * from "./animation/AnimationAction.js"; +export * from "./animation/AnimationClip.js"; +export * from "./animation/AnimationMixer.js"; +export * from "./animation/AnimationObjectGroup.js"; +export { AnimationUtils } from "./animation/AnimationUtils.js"; +export * from "./animation/KeyframeTrack.js"; +export * from "./animation/PropertyBinding.js"; +export * from "./animation/PropertyMixer.js"; +export * from "./animation/tracks/BooleanKeyframeTrack.js"; +export * from "./animation/tracks/ColorKeyframeTrack.js"; +export * from "./animation/tracks/NumberKeyframeTrack.js"; +export * from "./animation/tracks/QuaternionKeyframeTrack.js"; +export * from "./animation/tracks/StringKeyframeTrack.js"; +export * from "./animation/tracks/VectorKeyframeTrack.js"; +export * from "./audio/Audio.js"; +export * from "./audio/AudioAnalyser.js"; +export * from "./audio/AudioContext.js"; +export * from "./audio/AudioListener.js"; +export * from "./audio/PositionalAudio.js"; +export * from "./cameras/ArrayCamera.js"; +export * from "./cameras/Camera.js"; +export * from "./cameras/CubeCamera.js"; +export * from "./cameras/OrthographicCamera.js"; +export * from "./cameras/PerspectiveCamera.js"; +export * from "./cameras/StereoCamera.js"; +export * from "./constants.js"; +export * from "./core/BufferAttribute.js"; +export * from "./core/BufferGeometry.js"; +export * from "./core/Clock.js"; +export * from "./core/EventDispatcher.js"; +export * from "./core/GLBufferAttribute.js"; +export * from "./core/InstancedBufferAttribute.js"; +export * from "./core/InstancedBufferGeometry.js"; +export * from "./core/InstancedInterleavedBuffer.js"; +export * from "./core/InterleavedBuffer.js"; +export * from "./core/InterleavedBufferAttribute.js"; +export * from "./core/Layers.js"; +export * from "./core/Object3D.js"; +export * from "./core/Raycaster.js"; +export * from "./core/RenderTarget.js"; +export * from "./core/Uniform.js"; +export * from "./core/UniformsGroup.js"; +export * from "./extras/Controls.js"; +export * from "./extras/core/Curve.js"; +export * from "./extras/core/CurvePath.js"; +export * from "./extras/core/Path.js"; +export * from "./extras/core/Shape.js"; +export * from "./extras/core/ShapePath.js"; +export * from "./extras/curves/Curves.js"; +export { DataUtils } from "./extras/DataUtils.js"; +export * from "./extras/ImageUtils.js"; +// export * from "./extras/PMREMGenerator.js"; +export * from "./extras/ShapeUtils.js"; +export { TextureUtils } from "./extras/TextureUtils.js"; +export * from "./geometries/Geometries.js"; +export * from "./helpers/ArrowHelper.js"; +export * from "./helpers/AxesHelper.js"; +export * from "./helpers/Box3Helper.js"; +export * from "./helpers/BoxHelper.js"; +export * from "./helpers/CameraHelper.js"; +export * from "./helpers/DirectionalLightHelper.js"; +export * from "./helpers/GridHelper.js"; +export * from "./helpers/HemisphereLightHelper.js"; +export * from "./helpers/PlaneHelper.js"; +export * from "./helpers/PointLightHelper.js"; +export * from "./helpers/PolarGridHelper.js"; +export * from "./helpers/SkeletonHelper.js"; +export * from "./helpers/SpotLightHelper.js"; +export * from "./lights/AmbientLight.js"; +export * from "./lights/DirectionalLight.js"; +export type { DirectionalLightShadow } from "./lights/DirectionalLightShadow.js"; +export * from "./lights/HemisphereLight.js"; +export * from "./lights/Light.js"; +export * from "./lights/LightProbe.js"; +export type { LightShadow, LightShadowJSON } from "./lights/LightShadow.js"; +export * from "./lights/PointLight.js"; +export type { PointLightShadow } from "./lights/PointLightShadow.js"; +export * from "./lights/RectAreaLight.js"; +export * from "./lights/SpotLight.js"; +export type { SpotLightShadow } from "./lights/SpotLightShadow.js"; +export * from "./loaders/AnimationLoader.js"; +export * from "./loaders/AudioLoader.js"; +export * from "./loaders/BufferGeometryLoader.js"; +export * from "./loaders/Cache.js"; +export * from "./loaders/CompressedTextureLoader.js"; +export * from "./loaders/CubeTextureLoader.js"; +export * from "./loaders/DataTextureLoader.js"; +export * from "./loaders/FileLoader.js"; +export * from "./loaders/ImageBitmapLoader.js"; +export * from "./loaders/ImageLoader.js"; +export * from "./loaders/Loader.js"; +export * from "./loaders/LoaderUtils.js"; +export * from "./loaders/LoadingManager.js"; +export * from "./loaders/MaterialLoader.js"; +export * from "./loaders/ObjectLoader.js"; +export * from "./loaders/TextureLoader.js"; +export * from "./materials/Materials.js"; +export * from "./math/Box2.js"; +export * from "./math/Box3.js"; +export * from "./math/Color.js"; +export { ColorManagement, ColorSpaceDefinition } from "./math/ColorManagement.js"; +export * from "./math/Cylindrical.js"; +export * from "./math/Euler.js"; +export * from "./math/Frustum.js"; +export * from "./math/Interpolant.js"; +export * from "./math/interpolants/CubicInterpolant.js"; +export * from "./math/interpolants/DiscreteInterpolant.js"; +export * from "./math/interpolants/LinearInterpolant.js"; +export * from "./math/interpolants/QuaternionLinearInterpolant.js"; +export * from "./math/Line3.js"; +export { MathUtils } from "./math/MathUtils.js"; +export * from "./math/Matrix2.js"; +export * from "./math/Matrix3.js"; +export * from "./math/Matrix4.js"; +export * from "./math/Plane.js"; +export * from "./math/Quaternion.js"; +export * from "./math/Ray.js"; +export * from "./math/Sphere.js"; +export * from "./math/Spherical.js"; +export * from "./math/SphericalHarmonics3.js"; +export * from "./math/Triangle.js"; +export * from "./math/Vector2.js"; +export * from "./math/Vector3.js"; +export * from "./math/Vector4.js"; +export * from "./objects/BatchedMesh.js"; +export * from "./objects/Bone.js"; +export * from "./objects/Group.js"; +export * from "./objects/InstancedMesh.js"; +export * from "./objects/Line.js"; +export * from "./objects/LineLoop.js"; +export * from "./objects/LineSegments.js"; +export * from "./objects/LOD.js"; +export * from "./objects/Mesh.js"; +export * from "./objects/Points.js"; +export * from "./objects/Skeleton.js"; +export * from "./objects/SkinnedMesh.js"; +export * from "./objects/Sprite.js"; +// export * from "./renderers/shaders/ShaderChunk.js"; +// export * from "./renderers/shaders/ShaderLib.js"; +// export * from "./renderers/shaders/UniformsLib.js"; +// export { UniformsUtils } from './renderers/shaders/UniformsUtils.js'; +export type { WebGLProgramParameters, WebGLProgramParametersWithUniforms } from "./renderers/webgl/WebGLPrograms.js"; +export type { WebGLShadowMap } from "./renderers/webgl/WebGLShadowMap.js"; +// export * from "./renderers/webgl/WebGLUtils.js"; +export * from "./renderers/WebGL3DRenderTarget.js"; +export * from "./renderers/WebGLArrayRenderTarget.js"; +export * from "./renderers/WebGLCubeRenderTarget.js"; +// export * from "./renderers/WebGLRenderer.js"; +export * from "./renderers/WebGLRenderTarget.js"; +export type { + WebXRController, + WebXRSpaceEventMap, + XRControllerEventType, + XRGripSpace, + XRHandInputState, + XRHandJoints, + XRHandSpace, + XRJointSpace, + XRTargetRaySpace, +} from "./renderers/webxr/WebXRController.js"; +export type { WebXRDepthSensing } from "./renderers/webxr/WebXRDepthSensing.js"; +export type { + WebXRArrayCamera, + WebXRCamera, + WebXRManager, + WebXRManagerEventMap, +} from "./renderers/webxr/WebXRManager.js"; +export * from "./scenes/Fog.js"; +export * from "./scenes/FogExp2.js"; +export * from "./scenes/Scene.js"; +export * from "./textures/CanvasTexture.js"; +export * from "./textures/CompressedArrayTexture.js"; +export * from "./textures/CompressedCubeTexture.js"; +export * from "./textures/CompressedTexture.js"; +export * from "./textures/CubeTexture.js"; +export * from "./textures/Data3DTexture.js"; +export * from "./textures/DataArrayTexture.js"; +export * from "./textures/DataTexture.js"; +export * from "./textures/DepthTexture.js"; +export * from "./textures/FramebufferTexture.js"; +export * from "./textures/Source.js"; +export * from "./textures/Texture.js"; +export * from "./textures/VideoTexture.js"; +export * from "./Three.Legacy.js"; +export { createCanvasElement } from "./utils.js"; + +export { default as IESSpotLight } from "./lights/webgpu/IESSpotLight.js"; +export { default as NodeLoader } from "./loaders/nodes/NodeLoader.js"; +export { default as NodeMaterialLoader } from "./loaders/nodes/NodeMaterialLoader.js"; +export { default as NodeObjectLoader } from "./loaders/nodes/NodeObjectLoader.js"; +export * from "./materials/nodes/NodeMaterials.js"; +export * from "./nodes/Nodes.js"; +export * from "./nodes/TSL.js"; +export { default as BundleGroup } from "./renderers/common/BundleGroup.js"; +export { default as PMREMGenerator } from "./renderers/common/extras/PMREMGenerator.js"; +export { default as PostProcessing } from "./renderers/common/PostProcessing.js"; +import * as PostProcessingUtils from "./renderers/common/PostProcessingUtils.js"; +export { PostProcessingUtils }; +export { default as IndirectStorageBufferAttribute } from "./renderers/common/IndirectStorageBufferAttribute.js"; +export { default as Lighting } from "./renderers/common/Lighting.js"; +export { default as QuadMesh } from "./renderers/common/QuadMesh.js"; +export type { default as Renderer } from "./renderers/common/Renderer.js"; +export { default as StorageBufferAttribute } from "./renderers/common/StorageBufferAttribute.js"; +export { default as StorageInstancedBufferAttribute } from "./renderers/common/StorageInstancedBufferAttribute.js"; +export { default as StorageTexture } from "./renderers/common/StorageTexture.js"; +export { default as WebGPURenderer } from "./renderers/webgpu/WebGPURenderer.js"; diff --git a/src-testing/src/Three.d.ts b/src-testing/src/Three.d.ts new file mode 100644 index 000000000..ade1c92b9 --- /dev/null +++ b/src-testing/src/Three.d.ts @@ -0,0 +1,214 @@ +export * from "./animation/AnimationAction.js"; +export * from "./animation/AnimationClip.js"; +export * from "./animation/AnimationMixer.js"; +export * from "./animation/AnimationObjectGroup.js"; +export { AnimationUtils } from "./animation/AnimationUtils.js"; +export * from "./animation/KeyframeTrack.js"; +export * from "./animation/PropertyBinding.js"; +export * from "./animation/PropertyMixer.js"; +export * from "./animation/tracks/BooleanKeyframeTrack.js"; +export * from "./animation/tracks/ColorKeyframeTrack.js"; +export * from "./animation/tracks/NumberKeyframeTrack.js"; +export * from "./animation/tracks/QuaternionKeyframeTrack.js"; +export * from "./animation/tracks/StringKeyframeTrack.js"; +export * from "./animation/tracks/VectorKeyframeTrack.js"; +export * from "./audio/Audio.js"; +export * from "./audio/AudioAnalyser.js"; +export * from "./audio/AudioContext.js"; +export * from "./audio/AudioListener.js"; +export * from "./audio/PositionalAudio.js"; +export * from "./cameras/ArrayCamera.js"; +export * from "./cameras/Camera.js"; +export * from "./cameras/CubeCamera.js"; +export * from "./cameras/OrthographicCamera.js"; +export * from "./cameras/PerspectiveCamera.js"; +export * from "./cameras/StereoCamera.js"; +export * from "./constants.js"; +export * from "./core/BufferAttribute.js"; +export * from "./core/BufferGeometry.js"; +export * from "./core/Clock.js"; +export * from "./core/EventDispatcher.js"; +export * from "./core/GLBufferAttribute.js"; +export * from "./core/InstancedBufferAttribute.js"; +export * from "./core/InstancedBufferGeometry.js"; +export * from "./core/InstancedInterleavedBuffer.js"; +export * from "./core/InterleavedBuffer.js"; +export * from "./core/InterleavedBufferAttribute.js"; +export * from "./core/Layers.js"; +export * from "./core/Object3D.js"; +export * from "./core/Raycaster.js"; +export * from "./core/RenderTarget.js"; +export * from "./core/Uniform.js"; +export * from "./core/UniformsGroup.js"; +export * from "./extras/Controls.js"; +export * from "./extras/core/Curve.js"; +export * from "./extras/core/CurvePath.js"; +export * from "./extras/core/Path.js"; +export * from "./extras/core/Shape.js"; +export * from "./extras/core/ShapePath.js"; +export * from "./extras/curves/Curves.js"; +export { DataUtils } from "./extras/DataUtils.js"; +export * from "./extras/ImageUtils.js"; +export * from "./extras/PMREMGenerator.js"; +export * from "./extras/ShapeUtils.js"; +export { TextureUtils } from "./extras/TextureUtils.js"; +export * from "./geometries/Geometries.js"; +export * from "./helpers/ArrowHelper.js"; +export * from "./helpers/AxesHelper.js"; +export * from "./helpers/Box3Helper.js"; +export * from "./helpers/BoxHelper.js"; +export * from "./helpers/CameraHelper.js"; +export * from "./helpers/DirectionalLightHelper.js"; +export * from "./helpers/GridHelper.js"; +export * from "./helpers/HemisphereLightHelper.js"; +export * from "./helpers/PlaneHelper.js"; +export * from "./helpers/PointLightHelper.js"; +export * from "./helpers/PolarGridHelper.js"; +export * from "./helpers/SkeletonHelper.js"; +export * from "./helpers/SpotLightHelper.js"; +export * from "./lights/AmbientLight.js"; +export * from "./lights/DirectionalLight.js"; +export type { DirectionalLightShadow } from "./lights/DirectionalLightShadow.js"; +export * from "./lights/HemisphereLight.js"; +export * from "./lights/Light.js"; +export * from "./lights/LightProbe.js"; +export type { LightShadow, LightShadowJSON } from "./lights/LightShadow.js"; +export * from "./lights/PointLight.js"; +export type { PointLightShadow } from "./lights/PointLightShadow.js"; +export * from "./lights/RectAreaLight.js"; +export * from "./lights/SpotLight.js"; +export type { SpotLightShadow } from "./lights/SpotLightShadow.js"; +export * from "./loaders/AnimationLoader.js"; +export * from "./loaders/AudioLoader.js"; +export * from "./loaders/BufferGeometryLoader.js"; +export * from "./loaders/Cache.js"; +export * from "./loaders/CompressedTextureLoader.js"; +export * from "./loaders/CubeTextureLoader.js"; +export * from "./loaders/DataTextureLoader.js"; +export * from "./loaders/FileLoader.js"; +export * from "./loaders/ImageBitmapLoader.js"; +export * from "./loaders/ImageLoader.js"; +export * from "./loaders/Loader.js"; +export * from "./loaders/LoaderUtils.js"; +export * from "./loaders/LoadingManager.js"; +export * from "./loaders/MaterialLoader.js"; +export * from "./loaders/ObjectLoader.js"; +export * from "./loaders/TextureLoader.js"; +export * from "./materials/Materials.js"; +export * from "./math/Box2.js"; +export * from "./math/Box3.js"; +export * from "./math/Color.js"; +export { ColorManagement, ColorSpaceDefinition } from "./math/ColorManagement.js"; +export * from "./math/Cylindrical.js"; +export * from "./math/Euler.js"; +export * from "./math/Frustum.js"; +export * from "./math/Interpolant.js"; +export * from "./math/interpolants/CubicInterpolant.js"; +export * from "./math/interpolants/DiscreteInterpolant.js"; +export * from "./math/interpolants/LinearInterpolant.js"; +export * from "./math/interpolants/QuaternionLinearInterpolant.js"; +export * from "./math/Line3.js"; +export { MathUtils } from "./math/MathUtils.js"; +export * from "./math/Matrix2.js"; +export * from "./math/Matrix3.js"; +export * from "./math/Matrix4.js"; +export * from "./math/Plane.js"; +export * from "./math/Quaternion.js"; +export * from "./math/Ray.js"; +export * from "./math/Sphere.js"; +export * from "./math/Spherical.js"; +export * from "./math/SphericalHarmonics3.js"; +export * from "./math/Triangle.js"; +export * from "./math/Vector2.js"; +export * from "./math/Vector3.js"; +export * from "./math/Vector4.js"; +export * from "./objects/BatchedMesh.js"; +export * from "./objects/Bone.js"; +export * from "./objects/Group.js"; +export * from "./objects/InstancedMesh.js"; +export * from "./objects/Line.js"; +export * from "./objects/LineLoop.js"; +export * from "./objects/LineSegments.js"; +export * from "./objects/LOD.js"; +export * from "./objects/Mesh.js"; +export * from "./objects/Points.js"; +export * from "./objects/Skeleton.js"; +export * from "./objects/SkinnedMesh.js"; +export * from "./objects/Sprite.js"; +export * from "./renderers/shaders/ShaderChunk.js"; +export * from "./renderers/shaders/ShaderLib.js"; +export * from "./renderers/shaders/UniformsLib.js"; +export { UniformsUtils } from "./renderers/shaders/UniformsUtils.js"; +export type { WebGLAttributes } from "./renderers/webgl/WebGLAttributes.js"; +export type { WebGLBindingStates } from "./renderers/webgl/WebGLBindingStates.js"; +export type { WebGLBufferRenderer } from "./renderers/webgl/WebGLBufferRenderer.js"; +export type { WebGLCapabilities, WebGLCapabilitiesParameters } from "./renderers/webgl/WebGLCapabilities.js"; +export type { WebGLClipping } from "./renderers/webgl/WebGLClipping.js"; +export type { WebGLCubeMaps } from "./renderers/webgl/WebGLCubeMaps.js"; +export type { WebGLCubeUVMaps } from "./renderers/webgl/WebGLCubeUVMaps.js"; +export type { WebGLExtensions } from "./renderers/webgl/WebGLExtensions.js"; +export type { WebGLGeometries } from "./renderers/webgl/WebGLGeometries.js"; +export type { WebGLIndexedBufferRenderer } from "./renderers/webgl/WebGLIndexedBufferRenderer.js"; +export type { WebGLInfo } from "./renderers/webgl/WebGLInfo.js"; +export type { WebGLLights, WebGLLightsState } from "./renderers/webgl/WebGLLights.js"; +export type { WebGLObjects } from "./renderers/webgl/WebGLObjects.js"; +export type { WebGLProgram } from "./renderers/webgl/WebGLProgram.js"; +export type { + WebGLProgramParameters, + WebGLProgramParametersWithUniforms, + WebGLPrograms, +} from "./renderers/webgl/WebGLPrograms.js"; +export type { WebGLProperties } from "./renderers/webgl/WebGLProperties.js"; +export type { RenderItem, WebGLRenderList, WebGLRenderLists } from "./renderers/webgl/WebGLRenderLists.js"; +export type { WebGLShader } from "./renderers/webgl/WebGLShader.js"; +export type { WebGLShadowMap } from "./renderers/webgl/WebGLShadowMap.js"; +export type { + WebGLColorBuffer, + WebGLDepthBuffer, + WebGLState, + WebGLStencilBuffer, +} from "./renderers/webgl/WebGLState.js"; +export type { WebGLTextures } from "./renderers/webgl/WebGLTextures.js"; +export type { WebGLUniforms } from "./renderers/webgl/WebGLUniforms.js"; +export * from "./renderers/webgl/WebGLUtils.js"; +export * from "./renderers/WebGL3DRenderTarget.js"; +export * from "./renderers/WebGLArrayRenderTarget.js"; +export * from "./renderers/WebGLCubeRenderTarget.js"; +export * from "./renderers/WebGLRenderer.js"; +export * from "./renderers/WebGLRenderTarget.js"; +export type { + WebXRController, + WebXRSpaceEventMap, + XRControllerEventType, + XRGripSpace, + XRHandInputState, + XRHandJoints, + XRHandSpace, + XRJointSpace, + XRTargetRaySpace, +} from "./renderers/webxr/WebXRController.js"; +export type { WebXRDepthSensing } from "./renderers/webxr/WebXRDepthSensing.js"; +export type { + WebXRArrayCamera, + WebXRCamera, + WebXRManager, + WebXRManagerEventMap, +} from "./renderers/webxr/WebXRManager.js"; +export * from "./scenes/Fog.js"; +export * from "./scenes/FogExp2.js"; +export * from "./scenes/Scene.js"; +export * from "./textures/CanvasTexture.js"; +export * from "./textures/CompressedArrayTexture.js"; +export * from "./textures/CompressedCubeTexture.js"; +export * from "./textures/CompressedTexture.js"; +export * from "./textures/CubeTexture.js"; +export * from "./textures/Data3DTexture.js"; +export * from "./textures/DataArrayTexture.js"; +export * from "./textures/DataTexture.js"; +export * from "./textures/DepthTexture.js"; +export * from "./textures/FramebufferTexture.js"; +export * from "./textures/Source.js"; +export * from "./textures/Texture.js"; +export * from "./textures/VideoTexture.js"; +export * from "./Three.Legacy.js"; +export { createCanvasElement } from "./utils.js"; diff --git a/src-testing/src/animation/AnimationAction.d.ts b/src-testing/src/animation/AnimationAction.d.ts new file mode 100644 index 000000000..3fa3852a2 --- /dev/null +++ b/src-testing/src/animation/AnimationAction.d.ts @@ -0,0 +1,86 @@ +import { AnimationActionLoopStyles, AnimationBlendMode } from "../constants.js"; +import { Object3D } from "../core/Object3D.js"; +import { AnimationClip } from "./AnimationClip.js"; +import { AnimationMixer } from "./AnimationMixer.js"; +// Animation //////////////////////////////////////////////////////////////////////////////////////// + +export class AnimationAction { + constructor(mixer: AnimationMixer, clip: AnimationClip, localRoot?: Object3D, blendMode?: AnimationBlendMode); + + blendMode: AnimationBlendMode; + + /** + * @default THREE.LoopRepeat + */ + loop: AnimationActionLoopStyles; + + /** + * @default 0 + */ + time: number; + + /** + * @default 1 + */ + timeScale: number; + + /** + * @default 1 + */ + weight: number; + + /** + * @default Infinity + */ + repetitions: number; + + /** + * @default false + */ + paused: boolean; + + /** + * @default true + */ + enabled: boolean; + + /** + * @default false + */ + clampWhenFinished: boolean; + + /** + * @default true + */ + zeroSlopeAtStart: boolean; + + /** + * @default true + */ + zeroSlopeAtEnd: boolean; + + play(): AnimationAction; + stop(): AnimationAction; + reset(): AnimationAction; + isRunning(): boolean; + isScheduled(): boolean; + startAt(time: number): AnimationAction; + setLoop(mode: AnimationActionLoopStyles, repetitions: number): AnimationAction; + setEffectiveWeight(weight: number): AnimationAction; + getEffectiveWeight(): number; + fadeIn(duration: number): AnimationAction; + fadeOut(duration: number): AnimationAction; + crossFadeFrom(fadeOutAction: AnimationAction, duration: number, warp: boolean): AnimationAction; + crossFadeTo(fadeInAction: AnimationAction, duration: number, warp: boolean): AnimationAction; + stopFading(): AnimationAction; + setEffectiveTimeScale(timeScale: number): AnimationAction; + getEffectiveTimeScale(): number; + setDuration(duration: number): AnimationAction; + syncWith(action: AnimationAction): AnimationAction; + halt(duration: number): AnimationAction; + warp(statTimeScale: number, endTimeScale: number, duration: number): AnimationAction; + stopWarping(): AnimationAction; + getMixer(): AnimationMixer; + getClip(): AnimationClip; + getRoot(): Object3D; +} diff --git a/src-testing/src/animation/AnimationClip.d.ts b/src-testing/src/animation/AnimationClip.d.ts new file mode 100644 index 000000000..4efc3df72 --- /dev/null +++ b/src-testing/src/animation/AnimationClip.d.ts @@ -0,0 +1,59 @@ +import { AnimationBlendMode } from "../constants.js"; +import { Vector3 } from "../math/Vector3.js"; +import { Bone } from "../objects/Bone.js"; +import { KeyframeTrack, KeyframeTrackJSON } from "./KeyframeTrack.js"; + +export interface AnimationClipJSON { + name: string; + duration: number; + tracks: KeyframeTrackJSON[]; + uuid: string; + blendMode: AnimationBlendMode; +} + +export interface MorphTarget { + name: string; + vertices: Vector3[]; +} + +export class AnimationClip { + constructor(name?: string, duration?: number, tracks?: KeyframeTrack[], blendMode?: AnimationBlendMode); + + name: string; + tracks: KeyframeTrack[]; + + /** + * @default THREE.NormalAnimationBlendMode + */ + blendMode: AnimationBlendMode; + + /** + * @default -1 + */ + duration: number; + uuid: string; + results: any[]; + + resetDuration(): AnimationClip; + trim(): AnimationClip; + validate(): boolean; + optimize(): AnimationClip; + clone(): this; + toJSON(clip: AnimationClip): any; + + static CreateFromMorphTargetSequence( + name: string, + morphTargetSequence: MorphTarget[], + fps: number, + noLoop: boolean, + ): AnimationClip; + static findByName(clipArray: AnimationClip[], name: string): AnimationClip; + static CreateClipsFromMorphTargetSequences( + morphTargets: MorphTarget[], + fps: number, + noLoop: boolean, + ): AnimationClip[]; + static parse(json: AnimationClipJSON): AnimationClip; + static parseAnimation(animation: AnimationClipJSON, bones: Bone[]): AnimationClip; + static toJSON(clip: AnimationClip): AnimationClipJSON; +} diff --git a/src-testing/src/animation/AnimationMixer.d.ts b/src-testing/src/animation/AnimationMixer.d.ts new file mode 100644 index 000000000..95712d893 --- /dev/null +++ b/src-testing/src/animation/AnimationMixer.d.ts @@ -0,0 +1,39 @@ +import { AnimationBlendMode } from "../constants.js"; +import { EventDispatcher } from "../core/EventDispatcher.js"; +import { Object3D } from "../core/Object3D.js"; +import { AnimationAction } from "./AnimationAction.js"; +import { AnimationClip } from "./AnimationClip.js"; +import { AnimationObjectGroup } from "./AnimationObjectGroup.js"; + +export interface AnimationMixerEventMap { + loop: { action: AnimationAction; loopDelta: number }; + finished: { action: AnimationAction; direction: number }; +} + +export class AnimationMixer extends EventDispatcher { + constructor(root: Object3D | AnimationObjectGroup); + + /** + * @default 0 + */ + time: number; + + /** + * @default 1.0 + */ + timeScale: number; + + clipAction( + clip: AnimationClip, + root?: Object3D | AnimationObjectGroup, + blendMode?: AnimationBlendMode, + ): AnimationAction; + existingAction(clip: AnimationClip, root?: Object3D | AnimationObjectGroup): AnimationAction | null; + stopAllAction(): AnimationMixer; + update(deltaTime: number): AnimationMixer; + setTime(timeInSeconds: number): AnimationMixer; + getRoot(): Object3D | AnimationObjectGroup; + uncacheClip(clip: AnimationClip): void; + uncacheRoot(root: Object3D | AnimationObjectGroup): void; + uncacheAction(clip: AnimationClip, root?: Object3D | AnimationObjectGroup): void; +} diff --git a/src-testing/src/animation/AnimationObjectGroup.d.ts b/src-testing/src/animation/AnimationObjectGroup.d.ts new file mode 100644 index 000000000..9d4f29ca9 --- /dev/null +++ b/src-testing/src/animation/AnimationObjectGroup.d.ts @@ -0,0 +1,17 @@ +export class AnimationObjectGroup { + constructor(...args: any[]); + + uuid: string; + stats: { + bindingsPerObject: number; + objects: { + total: number; + inUse: number; + }; + }; + readonly isAnimationObjectGroup: true; + + add(...args: any[]): void; + remove(...args: any[]): void; + uncache(...args: any[]): void; +} diff --git a/src-testing/src/animation/AnimationUtils.d.ts b/src-testing/src/animation/AnimationUtils.d.ts new file mode 100644 index 000000000..4a712ed30 --- /dev/null +++ b/src-testing/src/animation/AnimationUtils.d.ts @@ -0,0 +1,60 @@ +import { AnimationClip } from "./AnimationClip.js"; + +declare function convertArray(array: any, type: any, forceClone: boolean): any; + +declare function isTypedArray(object: any): boolean; + +declare function getKeyframeOrder(times: number[]): number[]; + +declare function sortedArray(values: any[], stride: number, order: number[]): any[]; + +declare function flattenJSON(jsonKeys: string[], times: any[], values: any[], valuePropertyName: string): void; + +/** + * @param sourceClip + * @param name + * @param startFrame + * @param endFrame + * @param [fps=30] + */ +declare function subclip( + sourceClip: AnimationClip, + name: string, + startFrame: number, + endFrame: number, + fps?: number, +): AnimationClip; + +/** + * @param targetClip + * @param [referenceFrame=0] + * @param [referenceClip=targetClip] + * @param [fps=30] + */ +declare function makeClipAdditive( + targetClip: AnimationClip, + referenceFrame?: number, + referenceClip?: AnimationClip, + fps?: number, +): AnimationClip; + +declare const AnimationUtils: { + convertArray: typeof convertArray; + isTypedArray: typeof isTypedArray; + getKeyframeOrder: typeof getKeyframeOrder; + sortedArray: typeof sortedArray; + flattenJSON: typeof flattenJSON; + subclip: typeof subclip; + makeClipAdditive: typeof makeClipAdditive; +}; + +export { + AnimationUtils, + convertArray, + flattenJSON, + getKeyframeOrder, + isTypedArray, + makeClipAdditive, + sortedArray, + subclip, +}; diff --git a/src-testing/src/animation/KeyframeTrack.d.ts b/src-testing/src/animation/KeyframeTrack.d.ts new file mode 100644 index 000000000..2a48e2651 --- /dev/null +++ b/src-testing/src/animation/KeyframeTrack.d.ts @@ -0,0 +1,55 @@ +import { InterpolationModes } from "../constants.js"; +import { Interpolant } from "../math/Interpolant.js"; +import { CubicInterpolant } from "../math/interpolants/CubicInterpolant.js"; +import { DiscreteInterpolant } from "../math/interpolants/DiscreteInterpolant.js"; +import { LinearInterpolant } from "../math/interpolants/LinearInterpolant.js"; + +export interface KeyframeTrackJSON { + name: string; + times: number[]; + values: number[]; + interpolation?: InterpolationModes; + type: string; +} + +export class KeyframeTrack { + /** + * @param name + * @param times + * @param values + * @param [interpolation=THREE.InterpolateLinear] + */ + constructor(name: string, times: ArrayLike, values: ArrayLike, interpolation?: InterpolationModes); + + name: string; + times: Float32Array; + values: Float32Array; + + ValueTypeName: string; + TimeBufferType: Float32Array; + ValueBufferType: Float32Array; + + /** + * @default THREE.InterpolateLinear + */ + DefaultInterpolation: InterpolationModes; + + InterpolantFactoryMethodDiscrete(result: any): DiscreteInterpolant; + InterpolantFactoryMethodLinear(result: any): LinearInterpolant; + InterpolantFactoryMethodSmooth(result: any): CubicInterpolant; + + setInterpolation(interpolation: InterpolationModes): KeyframeTrack; + getInterpolation(): InterpolationModes; + createInterpolant(): Interpolant; + + getValueSize(): number; + + shift(timeOffset: number): KeyframeTrack; + scale(timeScale: number): KeyframeTrack; + trim(startTime: number, endTime: number): KeyframeTrack; + validate(): boolean; + optimize(): KeyframeTrack; + clone(): this; + + static toJSON(track: KeyframeTrack): KeyframeTrackJSON; +} diff --git a/src-testing/src/animation/PropertyBinding.d.ts b/src-testing/src/animation/PropertyBinding.d.ts new file mode 100644 index 000000000..fec777634 --- /dev/null +++ b/src-testing/src/animation/PropertyBinding.d.ts @@ -0,0 +1,43 @@ +export interface ParseTrackNameResults { + nodeName: string; + objectName: string; + objectIndex: string; + propertyName: string; + propertyIndex: string; +} + +declare class Composite { + constructor(targetGroup: any, path: any, parsedPath?: any); + + getValue(array: any, offset: number): any; + setValue(array: any, offset: number): void; + bind(): void; + unbind(): void; +} + +declare class PropertyBinding { + constructor(rootNode: any, path: string, parsedPath?: any); + + path: string; + parsedPath: any; + node: any; + rootNode: any; + + getValue(targetArray: any, offset: number): any; + setValue(sourceArray: any, offset: number): void; + bind(): void; + unbind(): void; + + BindingType: { [bindingType: string]: number }; + Versioning: { [versioning: string]: number }; + + GetterByBindingType: Array<() => void>; + SetterByBindingTypeAndVersioning: Array void>>; + + static create(root: any, path: any, parsedPath?: any): PropertyBinding | Composite; + static sanitizeNodeName(name: string): string; + static parseTrackName(trackName: string): ParseTrackNameResults; + static findNode(root: any, nodeName: string): any; +} + +export { PropertyBinding }; diff --git a/src-testing/src/animation/PropertyMixer.d.ts b/src-testing/src/animation/PropertyMixer.d.ts new file mode 100644 index 000000000..f413291fa --- /dev/null +++ b/src-testing/src/animation/PropertyMixer.d.ts @@ -0,0 +1,17 @@ +export class PropertyMixer { + constructor(binding: any, typeName: string, valueSize: number); + + binding: any; + valueSize: number; + buffer: any; + cumulativeWeight: number; + cumulativeWeightAdditive: number; + useCount: number; + referenceCount: number; + + accumulate(accuIndex: number, weight: number): void; + accumulateAdditive(weight: number): void; + apply(accuIndex: number): void; + saveOriginalState(): void; + restoreOriginalState(): void; +} diff --git a/src-testing/src/animation/tracks/BooleanKeyframeTrack.d.ts b/src-testing/src/animation/tracks/BooleanKeyframeTrack.d.ts new file mode 100644 index 000000000..45b65448a --- /dev/null +++ b/src-testing/src/animation/tracks/BooleanKeyframeTrack.d.ts @@ -0,0 +1,10 @@ +import { KeyframeTrack } from "../KeyframeTrack.js"; + +export class BooleanKeyframeTrack extends KeyframeTrack { + constructor(name: string, times: ArrayLike, values: ArrayLike); + + /** + * @default 'bool' + */ + ValueTypeName: string; +} diff --git a/src-testing/src/animation/tracks/ColorKeyframeTrack.d.ts b/src-testing/src/animation/tracks/ColorKeyframeTrack.d.ts new file mode 100644 index 000000000..60d0fe9f7 --- /dev/null +++ b/src-testing/src/animation/tracks/ColorKeyframeTrack.d.ts @@ -0,0 +1,11 @@ +import { InterpolationModes } from "../../constants.js"; +import { KeyframeTrack } from "../KeyframeTrack.js"; + +export class ColorKeyframeTrack extends KeyframeTrack { + constructor(name: string, times: ArrayLike, values: ArrayLike, interpolation?: InterpolationModes); + + /** + * @default 'color' + */ + ValueTypeName: string; +} diff --git a/src-testing/src/animation/tracks/NumberKeyframeTrack.d.ts b/src-testing/src/animation/tracks/NumberKeyframeTrack.d.ts new file mode 100644 index 000000000..e27ff0337 --- /dev/null +++ b/src-testing/src/animation/tracks/NumberKeyframeTrack.d.ts @@ -0,0 +1,11 @@ +import { InterpolationModes } from "../../constants.js"; +import { KeyframeTrack } from "../KeyframeTrack.js"; + +export class NumberKeyframeTrack extends KeyframeTrack { + constructor(name: string, times: ArrayLike, values: ArrayLike, interpolation?: InterpolationModes); + + /** + * @default 'number' + */ + ValueTypeName: string; +} diff --git a/src-testing/src/animation/tracks/QuaternionKeyframeTrack.d.ts b/src-testing/src/animation/tracks/QuaternionKeyframeTrack.d.ts new file mode 100644 index 000000000..29942bad5 --- /dev/null +++ b/src-testing/src/animation/tracks/QuaternionKeyframeTrack.d.ts @@ -0,0 +1,11 @@ +import { InterpolationModes } from "../../constants.js"; +import { KeyframeTrack } from "../KeyframeTrack.js"; + +export class QuaternionKeyframeTrack extends KeyframeTrack { + constructor(name: string, times: ArrayLike, values: ArrayLike, interpolation?: InterpolationModes); + + /** + * @default 'quaternion' + */ + ValueTypeName: string; +} diff --git a/src-testing/src/animation/tracks/StringKeyframeTrack.d.ts b/src-testing/src/animation/tracks/StringKeyframeTrack.d.ts new file mode 100644 index 000000000..9bbfd2027 --- /dev/null +++ b/src-testing/src/animation/tracks/StringKeyframeTrack.d.ts @@ -0,0 +1,10 @@ +import { KeyframeTrack } from "../KeyframeTrack.js"; + +export class StringKeyframeTrack extends KeyframeTrack { + constructor(name: string, times: ArrayLike, values: ArrayLike); + + /** + * @default 'string' + */ + ValueTypeName: string; +} diff --git a/src-testing/src/animation/tracks/VectorKeyframeTrack.d.ts b/src-testing/src/animation/tracks/VectorKeyframeTrack.d.ts new file mode 100644 index 000000000..0909d4493 --- /dev/null +++ b/src-testing/src/animation/tracks/VectorKeyframeTrack.d.ts @@ -0,0 +1,11 @@ +import { InterpolationModes } from "../../constants.js"; +import { KeyframeTrack } from "../KeyframeTrack.js"; + +export class VectorKeyframeTrack extends KeyframeTrack { + constructor(name: string, times: ArrayLike, values: ArrayLike, interpolation?: InterpolationModes); + + /** + * @default 'vector' + */ + ValueTypeName: string; +} diff --git a/src-testing/src/audio/Audio.d.ts b/src-testing/src/audio/Audio.d.ts new file mode 100644 index 000000000..63a944b5e --- /dev/null +++ b/src-testing/src/audio/Audio.d.ts @@ -0,0 +1,273 @@ +import { Object3D } from "../core/Object3D.js"; +import { AudioContext } from "./AudioContext.js"; +import { AudioListener } from "./AudioListener.js"; + +// Extras / Audio ///////////////////////////////////////////////////////////////////// + +/** + * Create a non-positional ( global ) {@link Audio} object. + * This uses the {@link https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API | Web {@link Audio} API}. + * @example + * ```typescript + * // create an AudioListener and add it to the camera + * const listener = new THREE.AudioListener(); + * camera.add(listener); + * // create a global {@link Audio} source + * const sound = new THREE.Audio(listener); + * // load a sound and set it as the {@link Audio} object's buffer + * const audioLoader = new THREE.AudioLoader(); + * audioLoader.load('sounds/ambient.ogg', function (buffer) { + * sound.setBuffer(buffer); + * sound.setLoop(true); + * sound.setVolume(0.5); + * sound.play(); + * }); + * ``` + * @see Example: {@link https://threejs.org/examples/#webaudio_sandbox | webaudio / sandbox } + * @see Example: {@link https://threejs.org/examples/#webaudio_visualizer | webaudio / visualizer } + * @see {@link https://threejs.org/docs/index.html#api/en/audio/Audio | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/audio/Audio.js | Source} + */ +export class Audio extends Object3D { + /** + * Create a new instance of {@link Audio} + * @param listener (required) {@link AudioListener | AudioListener} instance. + */ + constructor(listener: AudioListener); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `Audio` + */ + readonly type: string | "Audio"; + + /** + * A reference to the listener object of this audio. + */ + listener: AudioListener; + + /** + * The {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioContext | AudioContext} of the {@link AudioListener | listener} given in the constructor. + */ + context: AudioContext; + + /** + * A {@link https://developer.mozilla.org/en-US/docs/Web/API/GainNode | GainNode} created using + * {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioContext/createGain | AudioContext.createGain}(). + */ + gain: GainNode; + + /** + * Whether to start playback automatically. + * @defaultValue `false` + */ + autoplay: boolean; + + buffer: AudioBuffer | null; + + /** + * Modify pitch, measured in cents. +/- 100 is a semitone. +/- 1200 is an octave. + * @defaultValue `0` + */ + detune: number; + + /** + * @default false + */ + loop: boolean; + + /** + * @default 0 + */ + loopStart: number; + + /** + * @default 0 + */ + loopEnd: number; + + /** + * An offset to the time within the {@link Audio} buffer that playback should begin. + * Same as the {@link Audio.offset | offset} parameter of {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/start | AudioBufferSourceNode.start()}. + * @defaultValue `0` + */ + offset: number; + + /** + * Overrides the duration of the audio. Same as the {@link Audio.duration | duration} parameter of + * {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/start | AudioBufferSourceNode.start()}. + * @defaultValue `undefined` _to play the whole buffer_. + */ + duration: number | undefined; + + /** + * Speed of playback. + * @defaultValue `1` + */ + playbackRate: number; + + /** + * Whether the {@link Audio} is currently playing. + * @defaultValue `false` + */ + isPlaying: boolean; + + /** + * Whether playback can be controlled using the {@link Audio.play | play}(), {@link Audio.pause | pause}() etc. methods. + * @defaultValue `true` + */ + hasPlaybackControl: boolean; + + /** + * Type of the {@link Audio} source. + * @defaultValue 'empty'. + */ + sourceType: string; + + /** + * An {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode | AudioBufferSourceNode} created using + * {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioContext/createBufferSource | AudioContext.createBufferSource()}. + */ + source: AudioScheduledSourceNode | null; + + /** + * Represents an array of {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioNode | AudioNodes}. + * Can be used to apply a variety of low-order filters to create more complex sound effects. + * In most cases, the array contains instances of {@link https://developer.mozilla.org/en-US/docs/Web/API/BiquadFilterNode | BiquadFilterNodes}. + * Filters are set via {@link THREE.Audio.setFilter | Audio.setFilter} or {@link THREE.Audio.setFilters | Audio.setFilters}. + * @defaultValue `[]` + */ + filters: AudioNode[]; + + /** + * Return the {@link Audio.gain | gainNode}. + */ + getOutput(): NodeType; + + /** + * Setup the {@link Audio.source | source} to the audioBuffer, and sets {@link Audio.sourceType | sourceType} to 'audioNode'. + * @remarks Also sets {@link Audio.hasPlaybackControl | hasPlaybackControl} to false. + */ + setNodeSource(audioNode: AudioScheduledSourceNode): this; + + /** + * Applies the given object of type {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement | HTMLMediaElement} as the source of this audio. + * @remarks Also sets {@link Audio.hasPlaybackControl | hasPlaybackControl} to false. + */ + setMediaElementSource(mediaElement: HTMLMediaElement): this; + + /** + * Applies the given object of type {@link https://developer.mozilla.org/en-US/docs/Web/API/MediaStream | MediaStream} as the source of this audio. + * @remarks Also sets {@link Audio.hasPlaybackControl | hasPlaybackControl} to false. + */ + setMediaStreamSource(mediaStream: MediaStream): this; + + /** + * Setup the {@link Audio.source | source} to the audioBuffer, and sets {@link Audio.sourceType | sourceType} to 'buffer'. + * @remarks If {@link Audio.autoplay | autoplay}, also starts playback. + */ + setBuffer(audioBuffer: AudioBuffer): this; + + /** + * If {@link Audio.hasPlaybackControl | hasPlaybackControl} is true, starts playback. + */ + play(delay?: number): this; + + /** + * If {@link Audio.hasPlaybackControl | hasPlaybackControl} is true, pauses playback. + */ + pause(): this; + + /** + * If {@link Audio.hasPlaybackControl | hasPlaybackControl} is enabled, stops playback. + * @param delay (optional) - The delay, in seconds, at which the audio should start playing. + */ + stop(delay?: number): this; + + /** + * Called automatically when playback finished. + */ + onEnded(): void; + + /** + * Connect to the {@link THREE.Audio.source | Audio.source} + * @remarks This is used internally on initialisation and when setting / removing filters. + */ + connect(): this; + /** + * Disconnect from the {@link THREE.Audio.source | Audio.source} + * @remarks This is used internally when setting / removing filters. + */ + disconnect(): this; + + /** + * Returns the detuning of oscillation in cents. + */ + getDetune(): number; + /** + * Defines the detuning of oscillation in cents. + * @param value Expects a `Float` + */ + setDetune(value: number): this; + + /** + * Returns the first element of the {@link Audio.filters | filters} array. + */ + getFilter(): AudioNode; + /** + * Applies a single filter node to the audio. + */ + setFilter(filter: AudioNode): this; + + /** + * Returns the {@link Audio.filters | filters} array. + */ + getFilters(): AudioNode[]; + /** + * Applies an array of filter nodes to the audio. + * @param value Arrays of filters. + */ + setFilters(value: AudioNode[]): this; + + /** + * Return the value of {@link Audio.playbackRate | playbackRate}. + */ + getPlaybackRate(): number; + /** + * If {@link Audio.hasPlaybackControl | hasPlaybackControl} is enabled, set the {@link Audio.playbackRate | playbackRate} to `value`. + * @param value Expects a `Float` + */ + setPlaybackRate(value: number): this; + + /** + * Return the value of {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/loop | source.loop} (whether playback should loop). + */ + getLoop(): boolean; + /** + * Set {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/loop | source.loop} to `value` (whether playback should loop). + * @param value + */ + setLoop(value: boolean): this; + + /** + * Set {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/loopStart | source.loopStart} to `value`. + * @param value Expects a `Float` + */ + setLoopStart(value: number): this; + /** + * Set {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/loopEnd | source.loopEnd} to `value`. + * @param value Expects a `Float` + */ + setLoopEnd(value: number): this; + + /** + * Return the current volume. + */ + getVolume(): number; + /** + * Set the volume. + * @param value Expects a `Float` + */ + setVolume(value: number): this; +} diff --git a/src-testing/src/audio/AudioAnalyser.d.ts b/src-testing/src/audio/AudioAnalyser.d.ts new file mode 100644 index 000000000..474583ec7 --- /dev/null +++ b/src-testing/src/audio/AudioAnalyser.d.ts @@ -0,0 +1,58 @@ +import { Audio } from "./Audio.js"; + +/** + * Create a {@link AudioAnalyser} object, which uses an {@link https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode | AnalyserNode} to analyse audio data. + * This uses the {@link https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API | Web Audio API}. + * @example + * ```typescript + * // create an AudioListener and add it to the camera + * const listener = new THREE.AudioListener(); + * camera.add(listener); + * // create an Audio source + * const sound = new THREE.Audio(listener); + * // load a sound and set it as the Audio object's buffer + * const audioLoader = new THREE.AudioLoader(); + * audioLoader.load('sounds/ambient.ogg', function (buffer) { + * sound.setBuffer(buffer); + * sound.setLoop(true); + * sound.setVolume(0.5); + * sound.play(); + * }); + * // create an AudioAnalyser, passing in the sound and desired fftSize + * const analyser = new THREE.AudioAnalyser(sound, 32); + * // get the average frequency of the sound + * const data = analyser.getAverageFrequency(); + * ``` + * @see Example: {@link https://threejs.org/examples/#webaudio_sandbox | webaudio / sandbox } + * @see Example: {@link https://threejs.org/examples/#webaudio_visualizer | webaudio / visualizer } + * @see {@link https://threejs.org/docs/index.html#api/en/audio/AudioAnalyser | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/audio/AudioAnalyser.js | Source} + */ +export class AudioAnalyser { + /** + * Create a new {@link {@link AudioAnalyser} | AudioAnalyser}. + * @param audio + * @param fftSize See {@link https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode/fftSize | AnalyserNode.fftSize }. Expects a `unsigned integer`. Default `2048`. + */ + constructor(audio: Audio, fftSize?: number); + + /** + * An {@link https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode | AnalyserNode} used to analyze audio. + */ + analyser: AnalyserNode; + + /** + * A Uint8Array with size determined by {@link https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode/frequencyBinCount | analyser.frequencyBinCount} used to hold analysis data. + */ + data: Uint8Array; + + /** + * Uses the Web Audio's {@link https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode/getByteFrequencyData | getByteFrequencyData} method + */ + getFrequencyData(): Uint8Array; + + /** + * Get the average of the frequencies returned by the {@link AudioAnalyser.getFrequencyData | getFrequencyData} method. + */ + getAverageFrequency(): number; +} diff --git a/src-testing/src/audio/AudioContext.d.ts b/src-testing/src/audio/AudioContext.d.ts new file mode 100644 index 000000000..50a7f3d6e --- /dev/null +++ b/src-testing/src/audio/AudioContext.d.ts @@ -0,0 +1,19 @@ +/** + * This contains methods for setting up an {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioContext | AudioContext}. + * Used internally by the {@link AudioListener | AudioListener} and {@link AudioLoader | AudioLoader} classes. + * This uses the {@link https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API | Web Audio API}. + * @see {@link https://threejs.org/docs/index.html#api/en/audio/AudioContext | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/audio/AudioContext.js | Source} + */ +export namespace AudioContext { + /** + * Return the value of the variable `context` in the outer scope, if defined, otherwise set it to a new {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioContext | AudioContext}. + */ + function getContext(): AudioContext; + + /** + * Set the variable `context` in the outer scope to `value`. + * @param value + */ + function setContext(context: AudioContext): void; +} diff --git a/src-testing/src/audio/AudioListener.d.ts b/src-testing/src/audio/AudioListener.d.ts new file mode 100644 index 000000000..a49e4d5c7 --- /dev/null +++ b/src-testing/src/audio/AudioListener.d.ts @@ -0,0 +1,96 @@ +import { Object3D } from "../core/Object3D.js"; +import { AudioContext } from "./AudioContext.js"; + +/** + * The {@link AudioListener} represents a virtual {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioListener | listener} of the all positional and non-positional audio effects in the scene. + * A three.js application usually creates a single instance of {@link AudioListener} * @remarks + * It is a mandatory construtor parameter for audios entities like {@link Audio | Audio} and {@link PositionalAudio | PositionalAudio}. + * In most cases, the listener object is a child of the camera + * So the 3D transformation of the camera represents the 3D transformation of the listener. + * @example + * ```typescript + * // create an {@link AudioListener} and add it to the camera + * const listener = new THREE.AudioListener(); + * camera.add(listener); + * // create a global audio source + * const sound = new THREE.Audio(listener); + * // load a sound and set it as the Audio object's buffer + * const audioLoader = new THREE.AudioLoader(); + * audioLoader.load('sounds/ambient.ogg', function (buffer) { + * sound.setBuffer(buffer); + * sound.setLoop(true); + * sound.setVolume(0.5); + * sound.play(); + * }); + * ``` + * @see Example: {@link https://threejs.org/examples/#webaudio_sandbox | webaudio / sandbox } + * @see Example: {@link https://threejs.org/examples/#webaudio_timing | webaudio / timing } + * @see Example: {@link https://threejs.org/examples/#webaudio_visualizer | webaudio / visualizer } + * @see {@link https://threejs.org/docs/index.html#api/en/audio/AudioListener | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/audio/AudioListener.js | Source} + */ +export class AudioListener extends Object3D { + /** + * Create a new AudioListener. + */ + constructor(); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `AudioListener` + */ + readonly type: string | "AudioListener"; + + /** + * The {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioContext | AudioContext} of the {@link {@link AudioListener} | listener} given in the constructor. + */ + context: AudioContext; + + /** + * A {@link https://developer.mozilla.org/en-US/docs/Web/API/GainNode | GainNode} created using + * {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioContext/createGain | AudioContext.createGain()}. + */ + gain: GainNode; + + /** + * @defaultValue `null` + */ + filter: AudioNode; + + /** + * Time delta value for audio entities. Use in context of {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioParam/linearRampToValueAtTime | AudioParam.linearRampToValueAtTimeDefault()}. + * @defaultValue `0` + */ + timeDelta: number; + + /** + * Return the {@link AudioListener.gain | gainNode}. + */ + getInput(): GainNode; + /** + * Set the {@link AudioListener.filter | filter} property to `null`. + */ + removeFilter(): this; + + /** + * Returns the value of the {@link AudioListener.filter | filter} property. + */ + getFilter(): AudioNode; + /** + * Set the {@link AudioListener.filter | filter} property to `value`. + * @param value + */ + setFilter(value: AudioNode): this; + + /** + * Return the volume. + */ + getMasterVolume(): number; + + /** + * Set the volume. + * @param value + */ + setMasterVolume(value: number): this; +} diff --git a/src-testing/src/audio/PositionalAudio.d.ts b/src-testing/src/audio/PositionalAudio.d.ts new file mode 100644 index 000000000..d72d10674 --- /dev/null +++ b/src-testing/src/audio/PositionalAudio.d.ts @@ -0,0 +1,101 @@ +import { Audio } from "./Audio.js"; +import { AudioListener } from "./AudioListener.js"; + +/** + * Create a positional audio object. + * This uses the {@link https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API | Web Audio API}. + * @example + * ```typescript + * // create an AudioListener and add it to the camera + * const listener = new THREE.AudioListener(); + * camera.add(listener); + * // create the {@link PositionalAudio} object (passing in the listener) + * const sound = new THREE.PositionalAudio(listener); + * // load a sound and set it as the {@link PositionalAudio} object's buffer + * const audioLoader = new THREE.AudioLoader(); + * audioLoader.load('sounds/song.ogg', function (buffer) { + * sound.setBuffer(buffer); + * sound.setRefDistance(20); + * sound.play(); + * }); + * // create an object for the sound to play from + * const sphere = new THREE.SphereGeometry(20, 32, 16); + * const material = new THREE.MeshPhongMaterial({ + * color: 0xff2200 + * }); + * const mesh = new THREE.Mesh(sphere, material); + * scene.add(mesh); + * // finally add the sound to the mesh + * mesh.add(sound); + * ``` + * @see Example: {@link https://threejs.org/examples/#webaudio_orientation | webaudio / orientation } + * @see Example: {@link https://threejs.org/examples/#webaudio_sandbox | webaudio / sandbox } + * @see Example: {@link https://threejs.org/examples/#webaudio_timing | webaudio / timing } + * @see {@link https://threejs.org/docs/index.html#api/en/audio/PositionalAudio | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/audio/PositionalAudio.js | Source} + */ +export class PositionalAudio extends Audio { + /** + * Create a new instance of {@link PositionalAudio} + * @param listener (required) {@link AudioListener | AudioListener} instance. + */ + constructor(listener: AudioListener); + + /** + * The PositionalAudio's {@link https://developer.mozilla.org/en-US/docs/Web/API/PannerNode | PannerNode}. + */ + panner: PannerNode; + + /** + * Returns the {@link PositionalAudio.panner | panner}. + */ + getOutput(): PannerNode; + + /** + * Returns the value of {@link https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/refDistance | panner.refDistance}. + */ + getRefDistance(): number; + /** + * Sets the value of {@link https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/refDistance | panner.refDistance}. + * @param value Expects a `Float` + */ + setRefDistance(value: number): this; + + /** + * Returns the value of {@link https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/rolloffFactor | panner.rolloffFactor}. + */ + getRolloffFactor(): number; + /** + * Sets the value of {@link https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/rolloffFactor | panner.rolloffFactor}. + * @param value Expects a `Float` + */ + setRolloffFactor(value: number): this; + + /** + * Returns the value of {@link https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/distanceModel | panner.distanceModel}. + */ + getDistanceModel(): string; + /** + * Sets the value of {@link https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/distanceModel | panner.distanceModel}. + * @param value + */ + setDistanceModel(value: string): this; + + /** + * Returns the value of {@link https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/maxDistance | panner.maxDistance}. + */ + getMaxDistance(): number; + /** + * Sets the value of {@link https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/maxDistance | panner.maxDistance}. + * @param value Expects a `Float` + */ + setMaxDistance(value: number): this; + + /** + * This method can be used in order to transform an omnidirectional sound into a {@link https://developer.mozilla.org/en-US/docs/Web/API/PannerNode | directional sound}. + * @param coneInnerAngle Expects a `Float` + * @param coneOuterAngle Expects a `Float` + * @param coneOuterGain Expects a `Float` + */ + setDirectionalCone(coneInnerAngle: number, coneOuterAngle: number, coneOuterGain: number): this; +} diff --git a/src-testing/src/cameras/ArrayCamera.d.ts b/src-testing/src/cameras/ArrayCamera.d.ts new file mode 100644 index 000000000..e9e9a221d --- /dev/null +++ b/src-testing/src/cameras/ArrayCamera.d.ts @@ -0,0 +1,32 @@ +import { PerspectiveCamera } from "./PerspectiveCamera.js"; + +/** + * {@link ArrayCamera} can be used in order to efficiently render a scene with a predefined set of cameras + * @remarks + * This is an important performance aspect for rendering VR scenes. + * An instance of {@link ArrayCamera} always has an array of sub cameras + * It's mandatory to define for each sub camera the `viewport` property which determines the part of the viewport that is rendered with this camera. + * @see Example: {@link https://threejs.org/examples/#webgl_camera_array | camera / array } + * @see {@link https://threejs.org/docs/index.html#api/en/cameras/ArrayCamera | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/cameras/ArrayCamera.js | Source} + */ +export class ArrayCamera extends PerspectiveCamera { + /** + * An array of cameras. + * @param array. Default `[]`. + */ + constructor(cameras?: PerspectiveCamera[]); + + /** + * Read-only flag to check if a given object is of type {@link ArrayCamera}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isArrayCamera: true; + + /** + * An array of cameras. + * @defaultValue `[]` + */ + cameras: PerspectiveCamera[]; +} diff --git a/src-testing/src/cameras/Camera.d.ts b/src-testing/src/cameras/Camera.d.ts new file mode 100644 index 000000000..b49add52e --- /dev/null +++ b/src-testing/src/cameras/Camera.d.ts @@ -0,0 +1,74 @@ +import { CoordinateSystem } from "../constants.js"; +import { Layers } from "../core/Layers.js"; +import { Object3D } from "../core/Object3D.js"; +import { Matrix4 } from "../math/Matrix4.js"; +import { Vector3 } from "../math/Vector3.js"; +import { Vector4 } from "../math/Vector4.js"; + +/** + * Abstract base class for cameras + * @remarks + * This class should always be inherited when you build a new camera. + * @see {@link https://threejs.org/docs/index.html#api/en/cameras/Camera | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/cameras/Camera.js | Source} + */ +export class Camera extends Object3D { + /** + * @remarks + * Note that this class is not intended to be called directly; you probably want a + * {@link THREE.PerspectiveCamera | PerspectiveCamera} or + * {@link THREE.OrthographicCamera | OrthographicCamera} instead. + */ + constructor(); + + /** + * Read-only flag to check if a given object is of type {@link Camera}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isCamera: true; + + /** + * @override + * @defaultValue `Camera` + */ + override readonly type: string | "Camera"; + + /** + * @override + * The {@link THREE.Layers | layers} that the {@link Camera} is a member of. + * @remarks Objects must share at least one layer with the {@link Camera} to be n when the camera's viewpoint is rendered. + * @defaultValue `new THREE.Layers()` + */ + override layers: Layers; + + /** + * This is the inverse of matrixWorld. + * @remarks MatrixWorld contains the Matrix which has the world transform of the {@link Camera} . + * @defaultValue {@link THREE.Matrix4 | `new THREE.Matrix4()`} + */ + matrixWorldInverse: Matrix4; + + /** + * This is the matrix which contains the projection. + * @defaultValue {@link THREE.Matrix4 | `new THREE.Matrix4()`} + */ + projectionMatrix: Matrix4; + + /** + * This is the inverse of projectionMatrix. + * @defaultValue {@link THREE.Matrix4 | `new THREE.Matrix4()`} + */ + projectionMatrixInverse: Matrix4; + + coordinateSystem: CoordinateSystem; + + viewport?: Vector4; + + /** + * Returns a {@link THREE.Vector3 | Vector3} representing the world space direction in which the {@link Camera} is looking. + * @remarks Note: A {@link Camera} looks down its local, negative z-axis. + * @param target The result will be copied into this Vector3. + */ + getWorldDirection(target: Vector3): Vector3; +} diff --git a/src-testing/src/cameras/CubeCamera.d.ts b/src-testing/src/cameras/CubeCamera.d.ts new file mode 100644 index 000000000..e6e82fb19 --- /dev/null +++ b/src-testing/src/cameras/CubeCamera.d.ts @@ -0,0 +1,68 @@ +import { CoordinateSystem } from "../constants.js"; +import { Object3D } from "../core/Object3D.js"; +import { WebGLCubeRenderTarget } from "../renderers/WebGLCubeRenderTarget.js"; +import { WebGLRenderer } from "../renderers/WebGLRenderer.js"; + +/** + * Creates **6** {@link THREE.PerspectiveCamera | cameras} that render to a {@link THREE.WebGLCubeRenderTarget | WebGLCubeRenderTarget}. + * @remarks The cameras are added to the {@link children} array. + * @example + * ```typescript + * // Create cube render target + * const cubeRenderTarget = new THREE.WebGLCubeRenderTarget( 128, { generateMipmaps: true, minFilter: THREE.LinearMipmapLinearFilter } ); + * + * // Create cube camera + * const cubeCamera = new THREE.CubeCamera( 1, 100000, cubeRenderTarget ); + * scene.add( cubeCamera ); + * + * // Create car + * const chromeMaterial = new THREE.MeshLambertMaterial( { color: 0xffffff, envMap: cubeRenderTarget.texture } ); + * const car = new THREE.Mesh( carGeometry, chromeMaterial ); + * scene.add( car ); + * + * // Update the render target cube + * car.visible = false; + * cubeCamera.position.copy( car.position ); + * cubeCamera.update( renderer, scene ); + * + * // Render the scene + * car.visible = true; + * renderer.render( scene, camera ); + * ``` + * @see Example: {@link https://threejs.org/examples/#webgl_materials_cubemap_dynamic | materials / cubemap / dynamic } + * @see {@link https://threejs.org/docs/index.html#api/en/cameras/CubeCamera | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/cameras/CubeCamera.js | Source} + */ +export class CubeCamera extends Object3D { + /** + * Constructs a {@link CubeCamera} that contains 6 {@link PerspectiveCamera | PerspectiveCameras} that render to a {@link THREE.WebGLCubeRenderTarget | WebGLCubeRenderTarget}. + * @param near The near clipping distance. + * @param far The far clipping distance. + * @param renderTarget The destination cube render target. + */ + constructor(near: number, far: number, renderTarget: WebGLCubeRenderTarget); + + /** + * @override + * @defaultValue `CubeCamera` + */ + override readonly type: string | "CubeCamera"; + + /** + * The destination cube render target. + */ + renderTarget: WebGLCubeRenderTarget; + + coordinateSystem: CoordinateSystem; + + activeMipmapLevel: number; + + updateCoordinateSystem(): void; + + /** + * Call this to update the {@link CubeCamera.renderTarget | renderTarget}. + * @param renderer The current WebGL renderer + * @param scene The current scene + */ + update(renderer: WebGLRenderer, scene: Object3D): void; +} diff --git a/src-testing/src/cameras/OrthographicCamera.d.ts b/src-testing/src/cameras/OrthographicCamera.d.ts new file mode 100644 index 000000000..745d11416 --- /dev/null +++ b/src-testing/src/cameras/OrthographicCamera.d.ts @@ -0,0 +1,174 @@ +import { JSONMeta, Object3DJSON, Object3DJSONObject } from "../core/Object3D.js"; +import { Camera } from "./Camera.js"; + +export interface OrthographicCameraJSONObject extends Object3DJSONObject { + zoom: number; + left: number; + right: number; + top: number; + bottom: number; + near: number; + far: number; + + view?: { + enabled: boolean; + fullWidth: number; + fullHeight: number; + offsetX: number; + offsetY: number; + width: number; + height: number; + }; +} + +export interface OrthographicCameraJSON extends Object3DJSON { + object: OrthographicCameraJSONObject; +} + +/** + * Camera that uses {@link https://en.wikipedia.org/wiki/Orthographic_projection | orthographic projection}. + * In this projection mode, an object's size in the rendered image stays constant regardless of its distance from the camera. + * This can be useful for rendering 2D scenes and UI elements, amongst other things. + * @example + * ```typescript + * const camera = new THREE.OrthographicCamera(width / -2, width / 2, height / 2, height / -2, 1, 1000); + * scene.add(camera); + * ``` + * @see Example: {@link https://threejs.org/examples/#webgl_camera | camera } + * @see Example: {@link https://threejs.org/examples/#webgl_interactive_cubes_ortho | interactive / cubes / ortho } + * @see Example: {@link https://threejs.org/examples/#webgl_materials_cubemap_dynamic | materials / cubemap / dynamic } + * @see Example: {@link https://threejs.org/examples/#webgl_postprocessing_advanced | postprocessing / advanced } + * @see Example: {@link https://threejs.org/examples/#webgl_postprocessing_dof2 | postprocessing / dof2 } + * @see Example: {@link https://threejs.org/examples/#webgl_postprocessing_godrays | postprocessing / godrays } + * @see Example: {@link https://threejs.org/examples/#webgl_rtt | rtt } + * @see Example: {@link https://threejs.org/examples/#webgl_shaders_tonemapping | shaders / tonemapping } + * @see Example: {@link https://threejs.org/examples/#webgl_shadowmap | shadowmap } + * @see {@link https://threejs.org/docs/index.html#api/en/cameras/OrthographicCamera | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/cameras/OrthographicCamera.js | Source} + */ +export class OrthographicCamera extends Camera { + /** + * Creates a new {@link OrthographicCamera}. + * @remarks Together these define the camera's {@link https://en.wikipedia.org/wiki/Viewing_frustum | viewing frustum}. + * @param left Camera frustum left plane. Default `-1`. + * @param right Camera frustum right plane. Default `1`. + * @param top Camera frustum top plane. Default `1`. + * @param bottom Camera frustum bottom plane. Default `-1`. + * @param near Camera frustum near plane. Default `0.1`. + * @param far Camera frustum far plane. Default `2000`. + */ + constructor(left?: number, right?: number, top?: number, bottom?: number, near?: number, far?: number); + + /** + * Read-only flag to check if a given object is of type {@link OrthographicCamera}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isOrthographicCamera: true; + + /** + * @override + * @defaultValue `OrthographicCamera` + */ + override readonly type: string | "OrthographicCamera"; + + /** + * Gets or sets the zoom factor of the camera. + * @defaultValue `1` + */ + zoom: number; + + /** + * Set by {@link setViewOffset | .setViewOffset()}. + * @defaultValue `null` + */ + view: null | { + enabled: boolean; + fullWidth: number; + fullHeight: number; + offsetX: number; + offsetY: number; + width: number; + height: number; + }; + + /** + * Camera frustum left plane. + * @remarks Expects a `Float` + * @defaultValue `-1` + */ + left: number; + + /** + * Camera frustum right plane. + * @remarks Expects a `Float` + * @defaultValue `1` + */ + right: number; + + /** + * Camera frustum top plane. + * @remarks Expects a `Float` + * @defaultValue `1` + */ + top: number; + + /** + * Camera frustum bottom plane. + * @remarks Expects a `Float`. + * @defaultValue `-1` + */ + bottom: number; + + /** + * Camera frustum near plane.`. + * @remarks The valid range is between `0` and the current value of the {@link far | .far} plane. + * @remarks Note that, unlike for the {@link THREE.PerspectiveCamera | PerspectiveCamera}, `0` is a valid value for an {@link THREE.OrthographicCamera | OrthographicCamera's} near plane. + * @remarks Expects a `Float` + * @defaultValue `0.1` + */ + near: number; + + /** + * Camera frustum far plane. + * @remarks Must be greater than the current value of {@link near | .near} plane. + * @remarks Expects a `Float` + * @defaultValue `2000` + */ + far: number; + + /** + * Updates the camera projection matrix + * @remarks Must be called after any change of parameters. + */ + updateProjectionMatrix(): void; + + /** + * Sets an offset in a larger {@link https://en.wikipedia.org/wiki/Viewing_frustum | viewing frustum} + * @remarks + * This is useful for multi-window or multi-monitor/multi-machine setups + * For an example on how to use it see {@link PerspectiveCamera.setViewOffset | PerspectiveCamera}. + * @see {@link THREE.PerspectiveCamera.setViewOffset | PerspectiveCamera}. + * @param fullWidth Full width of multiview setup Expects a `Float`. + * @param fullHeight Full height of multiview setup Expects a `Float`. + * @param x Horizontal offset of subcamera Expects a `Float`. + * @param y Vertical offset of subcamera Expects a `Float`. + * @param width Width of subcamera Expects a `Float`. + * @param height Height of subcamera Expects a `Float`. + */ + setViewOffset( + fullWidth: number, + fullHeight: number, + offsetX: number, + offsetY: number, + width: number, + height: number, + ): void; + + /** + * Removes any offset set by the {@link setViewOffset | .setViewOffset} method. + */ + clearViewOffset(): void; + + toJSON(meta?: JSONMeta): OrthographicCameraJSON; +} diff --git a/src-testing/src/cameras/PerspectiveCamera.d.ts b/src-testing/src/cameras/PerspectiveCamera.d.ts new file mode 100644 index 000000000..60567105f --- /dev/null +++ b/src-testing/src/cameras/PerspectiveCamera.d.ts @@ -0,0 +1,254 @@ +import { JSONMeta, Object3DJSON, Object3DJSONObject } from "../core/Object3D.js"; +import { Vector2 } from "../math/Vector2.js"; +import { Camera } from "./Camera.js"; + +export interface PerspectiveCameraJSONObject extends Object3DJSONObject { + fov: number; + zoom: number; + + near: number; + far: number; + focus: number; + + aspect: number; + + view?: { + enabled: boolean; + fullWidth: number; + fullHeight: number; + offsetX: number; + offsetY: number; + width: number; + height: number; + }; + + filmGauge: number; + filmOffset: number; +} + +export interface PerspectiveCameraJSON extends Object3DJSON { + object: PerspectiveCameraJSONObject; +} + +/** + * Camera that uses {@link https://en.wikipedia.org/wiki/Perspective_(graphical) | perspective projection}. + * This projection mode is designed to mimic the way the human eye sees + * @remarks + * It is the most common projection mode used for rendering a 3D scene. + * @example + * ```typescript + * const camera = new THREE.PerspectiveCamera(45, width / height, 1, 1000); + * scene.add(camera); + * ``` + * @see Example: {@link https://threejs.org/examples/#webgl_animation_skinning_blending | animation / skinning / blending } + * @see Example: {@link https://threejs.org/examples/#webgl_animation_skinning_morph | animation / skinning / morph } + * @see Example: {@link https://threejs.org/examples/#webgl_effects_stereo | effects / stereo } + * @see Example: {@link https://threejs.org/examples/#webgl_interactive_cubes | interactive / cubes } + * @see Example: {@link https://threejs.org/examples/#webgl_loader_collada_skinning | loader / collada / skinning } + * @see {@link https://threejs.org/docs/index.html#api/en/cameras/PerspectiveCamera | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/cameras/PerspectiveCamera.js | Source} + */ +export class PerspectiveCamera extends Camera { + /** + * Creates a new {@link PerspectiveCamera}. + * @remarks Together these define the camera's {@link https://en.wikipedia.org/wiki/Viewing_frustum | viewing frustum}. + * @param fov Camera frustum vertical field of view. Default `50`. + * @param aspect Camera frustum aspect ratio. Default `1`. + * @param near Camera frustum near plane. Default `0.1`. + * @param far Camera frustum far plane. Default `2000`. + */ + constructor(fov?: number, aspect?: number, near?: number, far?: number); + + /** + * Read-only flag to check if a given object is of type {@link Camera}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isPerspectiveCamera: true; + + /** + * @override + * @defaultValue `PerspectiveCamera` + */ + override readonly type: string | "PerspectiveCamera"; + + /** + * Gets or sets the zoom factor of the camera. + * @defaultValue `1` + */ + zoom: number; + + /** + * Camera frustum vertical field of view, from bottom to top of view, in degrees. + * @remarks Expects a `Float` + * @defaultValue `50` + */ + fov: number; + + /** + * Camera frustum aspect ratio, usually the canvas width / canvas height. + * @remarks Expects a `Float` + * @defaultValue `1`, _(square canvas)_. + */ + aspect: number; + + /** + * Camera frustum near plane. + * @remarks The valid range is greater than `0` and less than the current value of the {@link far | .far} plane. + * @remarks Note that, unlike for the {@link THREE.OrthographicCamera | OrthographicCamera}, `0` is **not** a valid value for a {@link PerspectiveCamera |PerspectiveCamera's}. near plane. + * @defaultValue `0.1` + * @remarks Expects a `Float` + */ + near: number; + + /** + * Camera frustum far plane. + * @remarks Must be greater than the current value of {@link near | .near} plane. + * @remarks Expects a `Float` + * @defaultValue `2000` + */ + far: number; + + /** + * Object distance used for stereoscopy and depth-of-field effects. + * @remarks This parameter does not influence the projection matrix unless a {@link THREE.StereoCamera | StereoCamera} is being used. + * @remarks Expects a `Float` + * @defaultValue `10` + */ + focus: number; + + /** + * Frustum window specification or null. + * This is set using the {@link setViewOffset | .setViewOffset} method and cleared using {@link clearViewOffset | .clearViewOffset}. + * @defaultValue `null` + */ + view: null | { + enabled: boolean; + fullWidth: number; + fullHeight: number; + offsetX: number; + offsetY: number; + width: number; + height: number; + }; + + /** + * Film size used for the larger axis. + * This parameter does not influence the projection matrix unless {@link filmOffset | .filmOffset} is set to a nonzero value. + * @remarks Expects a `Float` + * @defaultValue `35`, _millimeters_. + */ + filmGauge: number; + + /** + * Horizontal off-center offset in the same unit as {@link filmGauge | .filmGauge}. + * @remarks Expects a `Float` + * @defaultValue `0` + */ + filmOffset: number; + + /** + * Returns the focal length of the current {@link .fov | fov} in respect to {@link filmGauge | .filmGauge}. + */ + getFocalLength(): number; + + /** + * Sets the FOV by focal length in respect to the current {@link filmGauge | .filmGauge}. + * @remarks By default, the focal length is specified for a `35mm` (full frame) camera. + * @param focalLength Expects a `Float` + */ + setFocalLength(focalLength: number): void; + + /** + * Returns the current vertical field of view angle in degrees considering {@link zoom | .zoom}. + */ + getEffectiveFOV(): number; + + /** + * Returns the width of the image on the film + * @remarks + * If {@link aspect | .aspect}. is greater than or equal to one (landscape format), the result equals {@link filmGauge | .filmGauge}. + */ + getFilmWidth(): number; + + /** + * Returns the height of the image on the film + * @remarks + * If {@link aspect | .aspect}. is less than or equal to one (portrait format), the result equals {@link filmGauge | .filmGauge}. + */ + getFilmHeight(): number; + + /** + * Computes the 2D bounds of the camera's viewable rectangle at a given distance along the viewing direction. + * Sets minTarget and maxTarget to the coordinates of the lower-left and upper-right corners of the view rectangle. + */ + getViewBounds(distance: number, minTarget: Vector2, maxTarget: Vector2): void; + + /** + * Computes the width and height of the camera's viewable rectangle at a given distance along the viewing direction. + * Copies the result into the target Vector2, where x is width and y is height. + */ + getViewSize(distance: number, target: Vector2): Vector2; + + /** + * Sets an offset in a larger frustum. + * @remarks + * This is useful for multi-window or multi-monitor/multi-machine setups. + * + * For example, if you have 3x2 monitors and each monitor is _1920x1080_ and + * the monitors are in grid like this + * ``` + * ┌───┬───┬───┐ + * │ A │ B │ C │ + * ├───┼───┼───┤ + * │ D │ E │ F │ + * └───┴───┴───┘ + * ``` + * then for each monitor you would call it like this + * ```typescript + * const w = 1920; + * const h = 1080; + * const fullWidth = w * 3; + * const fullHeight = h * 2; + * + * // Monitor - A + * camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 0, w, h ); + * // Monitor - B + * camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 0, w, h ); + * // Monitor - C + * camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 0, w, h ); + * // Monitor - D + * camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 1, w, h ); + * // Monitor - E + * camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 1, w, h ); + * // Monitor - F + * camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 1, w, h ); + * ``` + * Note there is no reason monitors have to be the same size or in a grid. + * @param fullWidth Full width of multiview setup Expects a `Float`. + * @param fullHeight Full height of multiview setup Expects a `Float`. + * @param x Horizontal offset of subcamera Expects a `Float`. + * @param y Vertical offset of subcamera Expects a `Float`. + * @param width Width of subcamera Expects a `Float`. + * @param height Height of subcamera Expects a `Float`. + */ + setViewOffset(fullWidth: number, fullHeight: number, x: number, y: number, width: number, height: number): void; + + /** + * Removes any offset set by the {@link setViewOffset | .setViewOffset} method. + */ + clearViewOffset(): void; + + /** + * Updates the camera projection matrix + * @remarks Must be called after any change of parameters. + */ + updateProjectionMatrix(): void; + + /** + * @deprecated Use {@link PerspectiveCamera.setFocalLength | .setFocalLength()} and {@link PerspectiveCamera.filmGauge | .filmGauge} instead. + */ + setLens(focalLength: number, frameHeight?: number): void; + + toJSON(meta?: JSONMeta): PerspectiveCameraJSON; +} diff --git a/src-testing/src/cameras/StereoCamera.d.ts b/src-testing/src/cameras/StereoCamera.d.ts new file mode 100644 index 000000000..3f359e3e0 --- /dev/null +++ b/src-testing/src/cameras/StereoCamera.d.ts @@ -0,0 +1,50 @@ +import { Camera } from "./Camera.js"; +import { PerspectiveCamera } from "./PerspectiveCamera.js"; + +/** + * Dual {@link PerspectiveCamera | PerspectiveCamera}s used for effects such as + * {@link https://en.wikipedia.org/wiki/Anaglyph_3D | 3D Anaglyph} or + * {@link https://en.wikipedia.org/wiki/parallax_barrier | Parallax Barrier}. + * @see Example: {@link https://threejs.org/examples/#webgl_effects_anaglyph | effects / anaglyph } + * @see Example: {@link https://threejs.org/examples/#webgl_effects_parallaxbarrier | effects / parallaxbarrier } + * @see Example: {@link https://threejs.org/examples/#webgl_effects_stereo | effects / stereo } + * @see {@link https://threejs.org/docs/index.html#api/en/cameras/StereoCamera | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/cameras/StereoCamera.js | Source} + */ +export class StereoCamera extends Camera { + constructor(); + + type: "StereoCamera"; + + /** + * @remarks Expects a `Float` + * @defaultValue `1` + */ + aspect: number; + + /** + * @remarks Expects a `Float` + * @defaultValue `0.064` + */ + eyeSep: number; + + /** + * The Left camera. + * A {@link PerspectiveCamera } added to {@link THREE.PerspectiveCamera.layers | layer 1} + * @remarks Objects to be rendered by the **left** camera must also be added to this layer. + */ + cameraL: PerspectiveCamera; + + /** + * The Right camera. + * A {@link PerspectiveCamera } added to {@link THREE.PerspectiveCamera.layers | layer 2} + * @remarks Objects to be rendered by the **right** camera must also be added to this layer. + */ + cameraR: PerspectiveCamera; + + /** + * Update the stereo cameras based on the camera passed in. + * @param camera + */ + update(camera: PerspectiveCamera): void; +} diff --git a/src-testing/src/constants.d.ts b/src-testing/src/constants.d.ts new file mode 100644 index 000000000..f5d26b42a --- /dev/null +++ b/src-testing/src/constants.d.ts @@ -0,0 +1,918 @@ +export const REVISION: string; + +// https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent.button +export enum MOUSE { + LEFT = 0, + MIDDLE = 1, + RIGHT = 2, + ROTATE = 0, + DOLLY = 1, + PAN = 2, +} + +export enum TOUCH { + ROTATE = 0, + PAN = 1, + DOLLY_PAN = 2, + DOLLY_ROTATE = 3, +} + +// GL STATE CONSTANTS +export const CullFaceNone: 0; +export const CullFaceBack: 1; +export const CullFaceFront: 2; +export const CullFaceFrontBack: 3; +export type CullFace = typeof CullFaceNone | typeof CullFaceBack | typeof CullFaceFront | typeof CullFaceFrontBack; + +// Shadowing Type +export const BasicShadowMap: 0; +export const PCFShadowMap: 1; +export const PCFSoftShadowMap: 2; +export const VSMShadowMap: 3; +export type ShadowMapType = typeof BasicShadowMap | typeof PCFShadowMap | typeof PCFSoftShadowMap | typeof VSMShadowMap; + +// MATERIAL CONSTANTS + +// side +export const FrontSide: 0; +export const BackSide: 1; +export const DoubleSide: 2; +/** + * Defines which side of faces will be rendered - front, back or both. + * Default is {@link FrontSide}. + */ +export type Side = typeof FrontSide | typeof BackSide | typeof DoubleSide; + +// blending modes +export const NoBlending: 0; +export const NormalBlending: 1; +export const AdditiveBlending: 2; +export const SubtractiveBlending: 3; +export const MultiplyBlending: 4; +export const CustomBlending: 5; +export type Blending = + | typeof NoBlending + | typeof NormalBlending + | typeof AdditiveBlending + | typeof SubtractiveBlending + | typeof MultiplyBlending + | typeof CustomBlending; + +// custom blending equations +// (numbers start from 100 not to clash with other +// mappings to OpenGL constants defined in Texture.js) +export const AddEquation: 100; +export const SubtractEquation: 101; +export const ReverseSubtractEquation: 102; +export const MinEquation: 103; +export const MaxEquation: 104; +export type BlendingEquation = + | typeof AddEquation + | typeof SubtractEquation + | typeof ReverseSubtractEquation + | typeof MinEquation + | typeof MaxEquation; + +// custom blending factors +export const ZeroFactor: 200; +export const OneFactor: 201; +export const SrcColorFactor: 202; +export const OneMinusSrcColorFactor: 203; +export const SrcAlphaFactor: 204; +export const OneMinusSrcAlphaFactor: 205; +export const DstAlphaFactor: 206; +export const OneMinusDstAlphaFactor: 207; +export const DstColorFactor: 208; +export const OneMinusDstColorFactor: 209; +export const SrcAlphaSaturateFactor: 210; +export const ConstantColorFactor: 211; +export const OneMinusConstantColorFactor: 212; +export const ConstantAlphaFactor: 213; +export const OneMinusConstantAlphaFactor: 214; +export type BlendingDstFactor = + | typeof ZeroFactor + | typeof OneFactor + | typeof SrcColorFactor + | typeof OneMinusSrcColorFactor + | typeof SrcAlphaFactor + | typeof OneMinusSrcAlphaFactor + | typeof DstAlphaFactor + | typeof OneMinusDstAlphaFactor + | typeof DstColorFactor + | typeof OneMinusDstColorFactor + | typeof ConstantColorFactor + | typeof OneMinusConstantColorFactor + | typeof ConstantAlphaFactor + | typeof OneMinusConstantAlphaFactor; +export type BlendingSrcFactor = BlendingDstFactor | typeof SrcAlphaSaturateFactor; + +// depth modes +export const NeverDepth: 0; +export const AlwaysDepth: 1; +export const LessDepth: 2; +export const LessEqualDepth: 3; +export const EqualDepth: 4; +export const GreaterEqualDepth: 5; +export const GreaterDepth: 6; +export const NotEqualDepth: 7; +export type DepthModes = + | typeof NeverDepth + | typeof AlwaysDepth + | typeof LessDepth + | typeof LessEqualDepth + | typeof EqualDepth + | typeof GreaterEqualDepth + | typeof GreaterDepth + | typeof NotEqualDepth; + +// TEXTURE CONSTANTS +// Operations +export const MultiplyOperation: 0; +export const MixOperation: 1; +export const AddOperation: 2; +export type Combine = typeof MultiplyOperation | typeof MixOperation | typeof AddOperation; + +// Tone Mapping modes +export const NoToneMapping: 0; +export const LinearToneMapping: 1; +export const ReinhardToneMapping: 2; +export const CineonToneMapping: 3; +export const ACESFilmicToneMapping: 4; +export const CustomToneMapping: 5; +export const AgXToneMapping: 6; +export const NeutralToneMapping: 7; +export type ToneMapping = + | typeof NoToneMapping + | typeof LinearToneMapping + | typeof ReinhardToneMapping + | typeof CineonToneMapping + | typeof ACESFilmicToneMapping + | typeof CustomToneMapping + | typeof AgXToneMapping + | typeof NeutralToneMapping; + +// Bind modes +export const AttachedBindMode: "attached"; +export const DetachedBindMode: "detached"; +export type BindMode = typeof AttachedBindMode | typeof DetachedBindMode; + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +// Mapping modes + +/** + * Maps the texture using the mesh's UV coordinates. + * @remarks This is the _default_ value and behaver for Texture Mapping. + */ +export const UVMapping: 300; + +/** + * @remarks This is the _default_ value and behaver for Cube Texture Mapping. + */ +export const CubeReflectionMapping: 301; +export const CubeRefractionMapping: 302; +export const CubeUVReflectionMapping: 306; + +export const EquirectangularReflectionMapping: 303; +export const EquirectangularRefractionMapping: 304; + +/** + * Texture Mapping Modes for non-cube Textures + * @remarks {@link UVMapping} is the _default_ value and behaver for Texture Mapping. + * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} + */ +export type Mapping = + | typeof UVMapping + | typeof EquirectangularReflectionMapping + | typeof EquirectangularRefractionMapping; + +/** + * Texture Mapping Modes for cube Textures + * @remarks {@link CubeReflectionMapping} is the _default_ value and behaver for Cube Texture Mapping. + * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} + */ +export type CubeTextureMapping = + | typeof CubeReflectionMapping + | typeof CubeRefractionMapping + | typeof CubeUVReflectionMapping; + +/** + * Texture Mapping Modes for any type of Textures + * @see {@link Mapping} and {@link CubeTextureMapping} + * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} + */ +export type AnyMapping = Mapping | CubeTextureMapping; + +/////////////////////////////////////////////////////////////////////////////// +// Wrapping modes + +/** With {@link RepeatWrapping} the texture will simply repeat to infinity. */ +export const RepeatWrapping: 1000; +/** + * With {@link ClampToEdgeWrapping} the last pixel of the texture stretches to the edge of the mesh. + * @remarks This is the _default_ value and behaver for Wrapping Mapping. + */ +export const ClampToEdgeWrapping: 1001; +/** With {@link MirroredRepeatWrapping} the texture will repeats to infinity, mirroring on each repeat. */ +export const MirroredRepeatWrapping: 1002; + +/** + * Texture Wrapping Modes + * @remarks {@link ClampToEdgeWrapping} is the _default_ value and behaver for Wrapping Mapping. + * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} + */ +export type Wrapping = typeof RepeatWrapping | typeof ClampToEdgeWrapping | typeof MirroredRepeatWrapping; + +/////////////////////////////////////////////////////////////////////////////// +// Filters + +/** {@link NearestFilter} returns the value of the texture element that is nearest (in Manhattan distance) to the specified texture coordinates. */ +export const NearestFilter: 1003; + +/** + * {@link NearestMipmapNearestFilter} chooses the mipmap that most closely matches the size of the pixel being textured + * and uses the {@link NearestFilter} criterion (the texel nearest to the center of the pixel) to produce a texture value. + */ +export const NearestMipmapNearestFilter: 1004; +/** + * {@link NearestMipmapNearestFilter} chooses the mipmap that most closely matches the size of the pixel being textured + * and uses the {@link NearestFilter} criterion (the texel nearest to the center of the pixel) to produce a texture value. + */ +export const NearestMipMapNearestFilter: 1004; + +/** + * {@link NearestMipmapLinearFilter} chooses the two mipmaps that most closely match the size of the pixel being textured + * and uses the {@link NearestFilter} criterion to produce a texture value from each mipmap. + * The final texture value is a weighted average of those two values. + */ +export const NearestMipmapLinearFilter: 1005; +/** + * {@link NearestMipMapLinearFilter} chooses the two mipmaps that most closely match the size of the pixel being textured + * and uses the {@link NearestFilter} criterion to produce a texture value from each mipmap. + * The final texture value is a weighted average of those two values. + */ +export const NearestMipMapLinearFilter: 1005; + +/** + * {@link LinearFilter} returns the weighted average of the four texture elements that are closest to the specified texture coordinates, + * and can include items wrapped or repeated from other parts of a texture, + * depending on the values of {@link THREE.Texture.wrapS | wrapS} and {@link THREE.Texture.wrapT | wrapT}, and on the exact mapping. + */ +export const LinearFilter: 1006; + +/** + * {@link LinearMipmapNearestFilter} chooses the mipmap that most closely matches the size of the pixel being textured and + * uses the {@link LinearFilter} criterion (a weighted average of the four texels that are closest to the center of the pixel) to produce a texture value. + */ +export const LinearMipmapNearestFilter: 1007; +/** + * {@link LinearMipMapNearestFilter} chooses the mipmap that most closely matches the size of the pixel being textured and + * uses the {@link LinearFilter} criterion (a weighted average of the four texels that are closest to the center of the pixel) to produce a texture value. + */ +export const LinearMipMapNearestFilter: 1007; + +/** + * {@link LinearMipmapLinearFilter} is the default and chooses the two mipmaps that most closely match the size of the pixel being textured and + * uses the {@link LinearFilter} criterion to produce a texture value from each mipmap. + * The final texture value is a weighted average of those two values. + */ +export const LinearMipmapLinearFilter: 1008; + +/** + * {@link LinearMipMapLinearFilter} is the default and chooses the two mipmaps that most closely match the size of the pixel being textured and + * uses the {@link LinearFilter} criterion to produce a texture value from each mipmap. + * The final texture value is a weighted average of those two values. + */ +export const LinearMipMapLinearFilter: 1008; + +/** + * Texture Magnification Filter Modes. + * For use with a texture's {@link THREE.Texture.magFilter | magFilter} property, + * these define the texture magnification function to be used when the pixel being textured maps to an area less than or equal to one texture element (texel). + * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} + * @see {@link https://sbcode.net/threejs/mipmaps/ | Texture Mipmaps (non-official)} + */ +export type MagnificationTextureFilter = typeof NearestFilter | typeof LinearFilter; + +/** + * Texture Minification Filter Modes. + * For use with a texture's {@link THREE.Texture.minFilter | minFilter} property, + * these define the texture minifying function that is used whenever the pixel being textured maps to an area greater than one texture element (texel). + * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} + * @see {@link https://sbcode.net/threejs/mipmaps/ | Texture Mipmaps (non-official)} + */ +export type MinificationTextureFilter = + | typeof NearestFilter + | typeof NearestMipmapNearestFilter + | typeof NearestMipMapNearestFilter + | typeof NearestMipmapLinearFilter + | typeof NearestMipMapLinearFilter + | typeof LinearFilter + | typeof LinearMipmapNearestFilter + | typeof LinearMipMapNearestFilter + | typeof LinearMipmapLinearFilter + | typeof LinearMipMapLinearFilter; + +/** + * Texture all Magnification and Minification Filter Modes. + * @see {@link MagnificationTextureFilter} and {@link MinificationTextureFilter} + * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} + * @see {@link https://sbcode.net/threejs/mipmaps/ | Texture Mipmaps (non-official)} + */ +export type TextureFilter = MagnificationTextureFilter | MinificationTextureFilter; + +/////////////////////////////////////////////////////////////////////////////// +// Data types + +export const UnsignedByteType: 1009; +export const ByteType: 1010; +export const ShortType: 1011; +export const UnsignedShortType: 1012; +export const IntType: 1013; +export const UnsignedIntType: 1014; +export const FloatType: 1015; +export const HalfFloatType: 1016; +export const UnsignedShort4444Type: 1017; +export const UnsignedShort5551Type: 1018; +export const UnsignedInt248Type: 1020; +export const UnsignedInt5999Type: 35902; + +export type AttributeGPUType = typeof FloatType | typeof IntType; + +/** + * Texture Types. + * @remarks Must correspond to the correct {@link PixelFormat | format}. + * @see {@link THREE.Texture.type} + * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} + */ +export type TextureDataType = + | typeof UnsignedByteType + | typeof ByteType + | typeof ShortType + | typeof UnsignedShortType + | typeof IntType + | typeof UnsignedIntType + | typeof FloatType + | typeof HalfFloatType + | typeof UnsignedShort4444Type + | typeof UnsignedShort5551Type + | typeof UnsignedInt248Type + | typeof UnsignedInt5999Type; + +/////////////////////////////////////////////////////////////////////////////// +// Pixel formats + +/** {@link AlphaFormat} discards the red, green and blue components and reads just the alpha component. */ +export const AlphaFormat: 1021; + +export const RGBFormat: 1022; + +/** {@link RGBAFormat} is the default and reads the red, green, blue and alpha components. */ +export const RGBAFormat: 1023; + +/** + * {@link LuminanceFormat} reads each element as a single luminance component. + * This is then converted to a floating point, clamped to the range `[0,1]`, and then assembled into an RGBA element by + * placing the luminance value in the red, green and blue channels, and attaching `1.0` to the alpha channel. + */ +export const LuminanceFormat: 1024; + +/** + * {@link LuminanceAlphaFormat} reads each element as a luminance/alpha double. + * The same process occurs as for the {@link LuminanceFormat}, except that the alpha channel may have values other than `1.0`. + */ +export const LuminanceAlphaFormat: 1025; + +/** + * {@link DepthFormat} reads each element as a single depth value, converts it to floating point, and clamps to the range `[0,1]`. + * @remarks This is the default for {@link THREE.DepthTexture}. + */ +export const DepthFormat: 1026; + +/** + * {@link DepthStencilFormat} reads each element is a pair of depth and stencil values. + * The depth component of the pair is interpreted as in {@link DepthFormat}. + * The stencil component is interpreted based on the depth + stencil internal format. + */ +export const DepthStencilFormat: 1027; + +/** + * {@link RedFormat} discards the green and blue components and reads just the red component. + */ +export const RedFormat: 1028; + +/** + * {@link RedIntegerFormat} discards the green and blue components and reads just the red component. + * The texels are read as integers instead of floating point. + */ +export const RedIntegerFormat: 1029; + +/** + * {@link RGFormat} discards the alpha, and blue components and reads the red, and green components. + */ +export const RGFormat: 1030; + +/** + * {@link RGIntegerFormat} discards the alpha, and blue components and reads the red, and green components. + * The texels are read as integers instead of floating point. + */ +export const RGIntegerFormat: 1031; + +/** + * {@link RGBIntegerFormat} discrads the alpha components and reads the red, green, and blue components. + */ +export const RGBIntegerFormat: 1032; + +/** + * {@link RGBAIntegerFormat} reads the red, green, blue and alpha component + * @remarks This is the default for {@link THREE.Texture}. + */ +export const RGBAIntegerFormat: 1033; + +/** + * All Texture Pixel Formats Modes. + * @remarks Note that the texture must have the correct {@link THREE.Texture.type} set, as described in {@link TextureDataType}. + * @see {@link WebGLRenderingContext.texImage2D} for details. + * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} + */ +export type PixelFormat = + | typeof AlphaFormat + | typeof RGBFormat + | typeof RGBAFormat + | typeof LuminanceFormat + | typeof LuminanceAlphaFormat + | typeof DepthFormat + | typeof DepthStencilFormat + | typeof RedFormat + | typeof RedIntegerFormat + | typeof RGFormat + | typeof RGIntegerFormat + | typeof RGBIntegerFormat + | typeof RGBAIntegerFormat; + +/** + * All Texture Pixel Formats Modes for {@link THREE.DepthTexture}. + * @see {@link WebGLRenderingContext.texImage2D} for details. + * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} + */ +export type DepthTexturePixelFormat = typeof DepthFormat | typeof DepthStencilFormat; + +/////////////////////////////////////////////////////////////////////////////// +// Compressed texture formats +// DDS / ST3C Compressed texture formats + +/** + * A DXT1-compressed image in an RGB image format. + * @remarks Require support for the _WEBGL_compressed_texture_s3tc_ WebGL extension. + */ +export const RGB_S3TC_DXT1_Format: 33776; +/** + * A DXT1-compressed image in an RGB image format with a simple on/off alpha value. + * @remarks Require support for the _WEBGL_compressed_texture_s3tc_ WebGL extension. + */ +export const RGBA_S3TC_DXT1_Format: 33777; +/** + * A DXT3-compressed image in an RGBA image format. Compared to a 32-bit RGBA texture, it offers 4:1 compression. + * @remarks Require support for the _WEBGL_compressed_texture_s3tc_ WebGL extension. + */ +export const RGBA_S3TC_DXT3_Format: 33778; +/** + * A DXT5-compressed image in an RGBA image format. It also provides a 4:1 compression, but differs to the DXT3 compression in how the alpha compression is done. + * @remarks Require support for the _WEBGL_compressed_texture_s3tc_ WebGL extension. + */ +export const RGBA_S3TC_DXT5_Format: 33779; + +// PVRTC compressed './texture formats + +/** + * RGB compression in 4-bit mode. One block for each 4×4 pixels. + * @remarks Require support for the _WEBGL_compressed_texture_pvrtc_ WebGL extension. + */ +export const RGB_PVRTC_4BPPV1_Format: 35840; +/** + * RGB compression in 2-bit mode. One block for each 8×4 pixels. + * @remarks Require support for the _WEBGL_compressed_texture_pvrtc_ WebGL extension. + */ +export const RGB_PVRTC_2BPPV1_Format: 35841; +/** + * RGBA compression in 4-bit mode. One block for each 4×4 pixels. + * @remarks Require support for the _WEBGL_compressed_texture_pvrtc_ WebGL extension. + */ +export const RGBA_PVRTC_4BPPV1_Format: 35842; +/** + * RGBA compression in 2-bit mode. One block for each 8×4 pixels. + * @remarks Require support for the _WEBGL_compressed_texture_pvrtc_ WebGL extension. + */ +export const RGBA_PVRTC_2BPPV1_Format: 35843; + +// ETC compressed texture formats + +/** + * @remarks Require support for the _WEBGL_compressed_texture_etc1_ (ETC1) or _WEBGL_compressed_texture_etc_ (ETC2) WebGL extension. + */ +export const RGB_ETC1_Format: 36196; +/** + * @remarks Require support for the _WEBGL_compressed_texture_etc1_ (ETC1) or _WEBGL_compressed_texture_etc_ (ETC2) WebGL extension. + */ +export const RGB_ETC2_Format: 37492; +/** + * @remarks Require support for the _WEBGL_compressed_texture_etc1_ (ETC1) or _WEBGL_compressed_texture_etc_ (ETC2) WebGL extension. + */ +export const RGBA_ETC2_EAC_Format: 37496; + +// ASTC compressed texture formats + +/** + * @remarks Require support for the _WEBGL_compressed_texture_astc_ WebGL extension. + */ +export const RGBA_ASTC_4x4_Format: 37808; +/** + * @remarks Require support for the _WEBGL_compressed_texture_astc_ WebGL extension. + */ +export const RGBA_ASTC_5x4_Format: 37809; +/** + * @remarks Require support for the _WEBGL_compressed_texture_astc_ WebGL extension. + */ +export const RGBA_ASTC_5x5_Format: 37810; +/** + * @remarks Require support for the _WEBGL_compressed_texture_astc_ WebGL extension. + */ +export const RGBA_ASTC_6x5_Format: 37811; +/** + * @remarks Require support for the _WEBGL_compressed_texture_astc_ WebGL extension. + */ +export const RGBA_ASTC_6x6_Format: 37812; +/** + * @remarks Require support for the _WEBGL_compressed_texture_astc_ WebGL extension. + */ +export const RGBA_ASTC_8x5_Format: 37813; +/** + * @remarks Require support for the _WEBGL_compressed_texture_astc_ WebGL extension. + */ +export const RGBA_ASTC_8x6_Format: 37814; +/** + * @remarks Require support for the _WEBGL_compressed_texture_astc_ WebGL extension. + */ +export const RGBA_ASTC_8x8_Format: 37815; +/** + * @remarks Require support for the _WEBGL_compressed_texture_astc_ WebGL extension. + */ +export const RGBA_ASTC_10x5_Format: 37816; +/** + * @remarks Require support for the _WEBGL_compressed_texture_astc_ WebGL extension. + */ +export const RGBA_ASTC_10x6_Format: 37817; +/** + * @remarks Require support for the _WEBGL_compressed_texture_astc_ WebGL extension. + */ +export const RGBA_ASTC_10x8_Format: 37818; +/** + * @remarks Require support for the _WEBGL_compressed_texture_astc_ WebGL extension. + */ +export const RGBA_ASTC_10x10_Format: 37819; +/** + * @remarks Require support for the _WEBGL_compressed_texture_astc_ WebGL extension. + */ +export const RGBA_ASTC_12x10_Format: 37820; +/** + * @remarks Require support for the _WEBGL_compressed_texture_astc_ WebGL extension. + */ +export const RGBA_ASTC_12x12_Format: 37821; + +// BPTC compressed texture formats + +/** + * @remarks Require support for the _EXT_texture_compression_bptc_ WebGL extension. + */ +export const RGBA_BPTC_Format: 36492; +export const RGB_BPTC_SIGNED_Format = 36494; +export const RGB_BPTC_UNSIGNED_Format = 36495; + +// RGTC compressed texture formats +export const RED_RGTC1_Format: 36283; +export const SIGNED_RED_RGTC1_Format: 36284; +export const RED_GREEN_RGTC2_Format: 36285; +export const SIGNED_RED_GREEN_RGTC2_Format: 36286; + +/** + * For use with a {@link THREE.CompressedTexture}'s {@link THREE.CompressedTexture.format | .format} property. + * @remarks Compressed Require support for correct WebGL extension. + */ +export type CompressedPixelFormat = + | typeof RGB_S3TC_DXT1_Format + | typeof RGBA_S3TC_DXT1_Format + | typeof RGBA_S3TC_DXT3_Format + | typeof RGBA_S3TC_DXT5_Format + | typeof RGB_PVRTC_4BPPV1_Format + | typeof RGB_PVRTC_2BPPV1_Format + | typeof RGBA_PVRTC_4BPPV1_Format + | typeof RGBA_PVRTC_2BPPV1_Format + | typeof RGB_ETC1_Format + | typeof RGB_ETC2_Format + | typeof RGBA_ETC2_EAC_Format + | typeof RGBA_ASTC_4x4_Format + | typeof RGBA_ASTC_5x4_Format + | typeof RGBA_ASTC_5x5_Format + | typeof RGBA_ASTC_6x5_Format + | typeof RGBA_ASTC_6x6_Format + | typeof RGBA_ASTC_8x5_Format + | typeof RGBA_ASTC_8x6_Format + | typeof RGBA_ASTC_8x8_Format + | typeof RGBA_ASTC_10x5_Format + | typeof RGBA_ASTC_10x6_Format + | typeof RGBA_ASTC_10x8_Format + | typeof RGBA_ASTC_10x10_Format + | typeof RGBA_ASTC_12x10_Format + | typeof RGBA_ASTC_12x12_Format + | typeof RGBA_BPTC_Format + | typeof RGB_BPTC_SIGNED_Format + | typeof RGB_BPTC_UNSIGNED_Format + | typeof RED_RGTC1_Format + | typeof SIGNED_RED_RGTC1_Format + | typeof RED_GREEN_RGTC2_Format + | typeof SIGNED_RED_GREEN_RGTC2_Format; + +/////////////////////////////////////////////////////////////////////////////// + +/** + * All Possible Texture Pixel Formats Modes. For any Type or SubType of Textures. + * @remarks Note that the texture must have the correct {@link THREE.Texture.type} set, as described in {@link TextureDataType}. + * @see {@link WebGLRenderingContext.texImage2D} for details. + * @see {@link PixelFormat} and {@link DepthTexturePixelFormat} and {@link CompressedPixelFormat} + * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} + */ +export type AnyPixelFormat = PixelFormat | DepthTexturePixelFormat | CompressedPixelFormat; + +/////////////////////////////////////////////////////////////////////////////// +// Loop styles for AnimationAction +export const LoopOnce: 2200; +export const LoopRepeat: 2201; +export const LoopPingPong: 2202; +export type AnimationActionLoopStyles = typeof LoopOnce | typeof LoopRepeat | typeof LoopPingPong; + +// Interpolation +export const InterpolateDiscrete: 2300; +export const InterpolateLinear: 2301; +export const InterpolateSmooth: 2302; +export type InterpolationModes = typeof InterpolateDiscrete | typeof InterpolateLinear | typeof InterpolateSmooth; + +// Interpolant ending modes +export const ZeroCurvatureEnding: 2400; +export const ZeroSlopeEnding: 2401; +export const WrapAroundEnding: 2402; +export type InterpolationEndingModes = typeof ZeroCurvatureEnding | typeof ZeroSlopeEnding | typeof WrapAroundEnding; + +// Animation blending modes +export const NormalAnimationBlendMode: 2500; +export const AdditiveAnimationBlendMode: 2501; +export type AnimationBlendMode = typeof NormalAnimationBlendMode | typeof AdditiveAnimationBlendMode; + +// Triangle Draw modes +export const TrianglesDrawMode: 0; +export const TriangleStripDrawMode: 1; +export const TriangleFanDrawMode: 2; +export type TrianglesDrawModes = typeof TrianglesDrawMode | typeof TriangleStripDrawMode | typeof TriangleFanDrawMode; + +/////////////////////////////////////////////////////////////////////////////// +// Depth packing strategies + +export const BasicDepthPacking: 3200; +export const RGBADepthPacking: 3201; +export const RGBDepthPacking: 3202; +export const RGDepthPacking: 3203; +export type DepthPackingStrategies = + | typeof BasicDepthPacking + | typeof RGBADepthPacking + | typeof RGBDepthPacking + | typeof RGDepthPacking; + +/////////////////////////////////////////////////////////////////////////////// +// Normal Map types + +export const TangentSpaceNormalMap: 0; +export const ObjectSpaceNormalMap: 1; +export type NormalMapTypes = typeof TangentSpaceNormalMap | typeof ObjectSpaceNormalMap; + +export const NoColorSpace: ""; +export const SRGBColorSpace: "srgb"; +export const LinearSRGBColorSpace: "srgb-linear"; +export type ColorSpace = + | typeof NoColorSpace + | typeof SRGBColorSpace + | typeof LinearSRGBColorSpace; + +export const LinearTransfer: "linear"; +export const SRGBTransfer: "srgb"; +export type ColorSpaceTransfer = typeof LinearTransfer | typeof SRGBTransfer; + +// Stencil Op types +export const ZeroStencilOp: 0; +export const KeepStencilOp: 7680; +export const ReplaceStencilOp: 7681; +export const IncrementStencilOp: 7682; +export const DecrementStencilOp: 7283; +export const IncrementWrapStencilOp: 34055; +export const DecrementWrapStencilOp: 34056; +export const InvertStencilOp: 5386; +export type StencilOp = + | typeof ZeroStencilOp + | typeof KeepStencilOp + | typeof ReplaceStencilOp + | typeof IncrementStencilOp + | typeof DecrementStencilOp + | typeof IncrementWrapStencilOp + | typeof DecrementWrapStencilOp + | typeof InvertStencilOp; + +// Stencil Func types +export const NeverStencilFunc: 512; +export const LessStencilFunc: 513; +export const EqualStencilFunc: 514; +export const LessEqualStencilFunc: 515; +export const GreaterStencilFunc: 516; +export const NotEqualStencilFunc: 517; +export const GreaterEqualStencilFunc: 518; +export const AlwaysStencilFunc: 519; +export type StencilFunc = + | typeof NeverStencilFunc + | typeof LessStencilFunc + | typeof EqualStencilFunc + | typeof LessEqualStencilFunc + | typeof GreaterStencilFunc + | typeof NotEqualStencilFunc + | typeof GreaterEqualStencilFunc + | typeof AlwaysStencilFunc; + +export const NeverCompare: 512; +export const LessCompare: 513; +export const EqualCompare: 514; +export const LessEqualCompare: 515; +export const GreaterCompare: 516; +export const NotEqualCompare: 517; +export const GreaterEqualCompare: 518; +export const AlwaysCompare: 519; +export type TextureComparisonFunction = + | typeof NeverCompare + | typeof LessCompare + | typeof EqualCompare + | typeof LessEqualCompare + | typeof GreaterCompare + | typeof NotEqualCompare + | typeof GreaterEqualCompare + | typeof AlwaysCompare; + +// usage types +export const StaticDrawUsage: 35044; +export const DynamicDrawUsage: 35048; +export const StreamDrawUsage: 35040; +export const StaticReadUsage: 35045; +export const DynamicReadUsage: 35049; +export const StreamReadUsage: 35041; +export const StaticCopyUsage: 35046; +export const DynamicCopyUsage: 35050; +export const StreamCopyUsage: 35042; +export type Usage = + | typeof StaticDrawUsage + | typeof DynamicDrawUsage + | typeof StreamDrawUsage + | typeof StaticReadUsage + | typeof DynamicReadUsage + | typeof StreamReadUsage + | typeof StaticCopyUsage + | typeof DynamicCopyUsage + | typeof StreamCopyUsage; + +export const GLSL1: "100"; +export const GLSL3: "300 es"; +export type GLSLVersion = typeof GLSL1 | typeof GLSL3; + +export const WebGLCoordinateSystem: 2000; +export const WebGPUCoordinateSystem: 2001; +export type CoordinateSystem = typeof WebGLCoordinateSystem | typeof WebGPUCoordinateSystem; + +/////////////////////////////////////////////////////////////////////////////// +// Texture - Internal Pixel Formats + +/** + * For use with a texture's {@link THREE.Texture.internalFormat} property, these define how elements of a {@link THREE.Texture}, or texels, are stored on the GPU. + * - `R8` stores the red component on 8 bits. + * - `R8_SNORM` stores the red component on 8 bits. The component is stored as normalized. + * - `R8I` stores the red component on 8 bits. The component is stored as an integer. + * - `R8UI` stores the red component on 8 bits. The component is stored as an unsigned integer. + * - `R16I` stores the red component on 16 bits. The component is stored as an integer. + * - `R16UI` stores the red component on 16 bits. The component is stored as an unsigned integer. + * - `R16F` stores the red component on 16 bits. The component is stored as floating point. + * - `R32I` stores the red component on 32 bits. The component is stored as an integer. + * - `R32UI` stores the red component on 32 bits. The component is stored as an unsigned integer. + * - `R32F` stores the red component on 32 bits. The component is stored as floating point. + * - `RG8` stores the red and green components on 8 bits each. + * - `RG8_SNORM` stores the red and green components on 8 bits each. Every component is stored as normalized. + * - `RG8I` stores the red and green components on 8 bits each. Every component is stored as an integer. + * - `RG8UI` stores the red and green components on 8 bits each. Every component is stored as an unsigned integer. + * - `RG16I` stores the red and green components on 16 bits each. Every component is stored as an integer. + * - `RG16UI` stores the red and green components on 16 bits each. Every component is stored as an unsigned integer. + * - `RG16F` stores the red and green components on 16 bits each. Every component is stored as floating point. + * - `RG32I` stores the red and green components on 32 bits each. Every component is stored as an integer. + * - `RG32UI` stores the red and green components on 32 bits. Every component is stored as an unsigned integer. + * - `RG32F` stores the red and green components on 32 bits. Every component is stored as floating point. + * - `RGB8` stores the red, green, and blue components on 8 bits each. RGB8_SNORM` stores the red, green, and blue components on 8 bits each. Every component is stored as normalized. + * - `RGB8I` stores the red, green, and blue components on 8 bits each. Every component is stored as an integer. + * - `RGB8UI` stores the red, green, and blue components on 8 bits each. Every component is stored as an unsigned integer. + * - `RGB16I` stores the red, green, and blue components on 16 bits each. Every component is stored as an integer. + * - `RGB16UI` stores the red, green, and blue components on 16 bits each. Every component is stored as an unsigned integer. + * - `RGB16F` stores the red, green, and blue components on 16 bits each. Every component is stored as floating point + * - `RGB32I` stores the red, green, and blue components on 32 bits each. Every component is stored as an integer. + * - `RGB32UI` stores the red, green, and blue components on 32 bits each. Every component is stored as an unsigned integer. + * - `RGB32F` stores the red, green, and blue components on 32 bits each. Every component is stored as floating point + * - `R11F_G11F_B10F` stores the red, green, and blue components respectively on 11 bits, 11 bits, and 10bits. Every component is stored as floating point. + * - `RGB565` stores the red, green, and blue components respectively on 5 bits, 6 bits, and 5 bits. + * - `RGB9_E5` stores the red, green, and blue components on 9 bits each. + * - `RGBA8` stores the red, green, blue, and alpha components on 8 bits each. + * - `RGBA8_SNORM` stores the red, green, blue, and alpha components on 8 bits. Every component is stored as normalized. + * - `RGBA8I` stores the red, green, blue, and alpha components on 8 bits each. Every component is stored as an integer. + * - `RGBA8UI` stores the red, green, blue, and alpha components on 8 bits. Every component is stored as an unsigned integer. + * - `RGBA16I` stores the red, green, blue, and alpha components on 16 bits. Every component is stored as an integer. + * - `RGBA16UI` stores the red, green, blue, and alpha components on 16 bits. Every component is stored as an unsigned integer. + * - `RGBA16F` stores the red, green, blue, and alpha components on 16 bits. Every component is stored as floating point. + * - `RGBA32I` stores the red, green, blue, and alpha components on 32 bits. Every component is stored as an integer. + * - `RGBA32UI` stores the red, green, blue, and alpha components on 32 bits. Every component is stored as an unsigned integer. + * - `RGBA32F` stores the red, green, blue, and alpha components on 32 bits. Every component is stored as floating point. + * - `RGB5_A1` stores the red, green, blue, and alpha components respectively on 5 bits, 5 bits, 5 bits, and 1 bit. + * - `RGB10_A2` stores the red, green, blue, and alpha components respectively on 10 bits, 10 bits, 10 bits and 2 bits. + * - `RGB10_A2UI` stores the red, green, blue, and alpha components respectively on 10 bits, 10 bits, 10 bits and 2 bits. Every component is stored as an unsigned integer. + * - `SRGB8` stores the red, green, and blue components on 8 bits each. + * - `SRGB8_ALPHA8` stores the red, green, blue, and alpha components on 8 bits each. + * - `DEPTH_COMPONENT16` stores the depth component on 16bits. + * - `DEPTH_COMPONENT24` stores the depth component on 24bits. + * - `DEPTH_COMPONENT32F` stores the depth component on 32bits. The component is stored as floating point. + * - `DEPTH24_STENCIL8` stores the depth, and stencil components respectively on 24 bits and 8 bits. The stencil component is stored as an unsigned integer. + * - `DEPTH32F_STENCIL8` stores the depth, and stencil components respectively on 32 bits and 8 bits. The depth component is stored as floating point, and the stencil component as an unsigned integer. + * @remark Note that the texture must have the correct {@link THREE.Texture.type} set, as well as the correct {@link THREE.Texture.format}. + * @see {@link WebGLRenderingContext.texImage2D} and {@link WebGLRenderingContext.texImage3D} for more details regarding the possible combination + * of {@link THREE.Texture.format}, {@link THREE.Texture.internalFormat}, and {@link THREE.Texture.type}. + * @see {@link https://registry.khronos.org/webgl/specs/latest/2.0/ | WebGL2 Specification} and + * {@link https://registry.khronos.org/OpenGL/specs/es/3.0/es_spec_3.0.pdf | OpenGL ES 3.0 Specification} For more in-depth information regarding internal formats. + */ +export type PixelFormatGPU = + | "ALPHA" + | "RGB" + | "RGBA" + | "LUMINANCE" + | "LUMINANCE_ALPHA" + | "RED_INTEGER" + | "R8" + | "R8_SNORM" + | "R8I" + | "R8UI" + | "R16I" + | "R16UI" + | "R16F" + | "R32I" + | "R32UI" + | "R32F" + | "RG8" + | "RG8_SNORM" + | "RG8I" + | "RG8UI" + | "RG16I" + | "RG16UI" + | "RG16F" + | "RG32I" + | "RG32UI" + | "RG32F" + | "RGB565" + | "RGB8" + | "RGB8_SNORM" + | "RGB8I" + | "RGB8UI" + | "RGB16I" + | "RGB16UI" + | "RGB16F" + | "RGB32I" + | "RGB32UI" + | "RGB32F" + | "RGB9_E5" + | "SRGB8" + | "R11F_G11F_B10F" + | "RGBA4" + | "RGBA8" + | "RGBA8_SNORM" + | "RGBA8I" + | "RGBA8UI" + | "RGBA16I" + | "RGBA16UI" + | "RGBA16F" + | "RGBA32I" + | "RGBA32UI" + | "RGBA32F" + | "RGB5_A1" + | "RGB10_A2" + | "RGB10_A2UI" + | "SRGB8_ALPHA8" + | "SRGB8" + | "DEPTH_COMPONENT16" + | "DEPTH_COMPONENT24" + | "DEPTH_COMPONENT32F" + | "DEPTH24_STENCIL8" + | "DEPTH32F_STENCIL8"; diff --git a/src-testing/src/core/BufferAttribute.d.ts b/src-testing/src/core/BufferAttribute.d.ts new file mode 100644 index 000000000..01e8e882d --- /dev/null +++ b/src-testing/src/core/BufferAttribute.d.ts @@ -0,0 +1,622 @@ +import { AttributeGPUType, Usage } from "../constants.js"; +import { Matrix3 } from "../math/Matrix3.js"; +import { Matrix4 } from "../math/Matrix4.js"; + +export type TypedArray = + | Int8Array + | Uint8Array + | Uint8ClampedArray + | Int16Array + | Uint16Array + | Int32Array + | Uint32Array + | Float32Array + | Float64Array; + +export interface BufferAttributeJSON { + itemSize: number; + type: string; + array: number[]; + normalized: boolean; + + name?: string; + usage?: Usage; +} + +/** + * This class stores data for an attribute (such as vertex positions, face indices, normals, colors, UVs, and any custom attributes ) + * associated with a {@link THREE.BufferGeometry | BufferGeometry}, which allows for more efficient passing of data to the GPU + * @remarks + * When working with _vector-like_ data, the _`.fromBufferAttribute( attribute, index )`_ helper methods on + * {@link THREE.Vector2.fromBufferAttribute | Vector2}, + * {@link THREE.Vector3.fromBufferAttribute | Vector3}, + * {@link THREE.Vector4.fromBufferAttribute | Vector4}, and + * {@link THREE.Color.fromBufferAttribute | Color} classes may be helpful. + * @see {@link THREE.BufferGeometry | BufferGeometry} for details and a usage examples. + * @see Example: {@link https://threejs.org/examples/#webgl_buffergeometry | WebGL / BufferGeometry - Clean up Memory} + * @see {@link https://threejs.org/docs/index.html#api/en/core/BufferAttribute | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/BufferAttribute.js | Source} + */ +export class BufferAttribute { + /** + * This creates a new {@link THREE.GLBufferAttribute | GLBufferAttribute} object. + * @param array Must be a `TypedArray`. Used to instantiate the buffer. + * This array should have `itemSize * numVertices` elements, where numVertices is the number of vertices in the associated {@link THREE.BufferGeometry | BufferGeometry}. + * @param itemSize the number of values of the {@link array} that should be associated with a particular vertex. + * For instance, if this attribute is storing a 3-component vector (such as a _position_, _normal_, or _color_), + * then itemSize should be `3`. + * @param normalized Applies to integer data only. + * Indicates how the underlying data in the buffer maps to the values in the GLSL code. + * For instance, if {@link array} is an instance of `UInt16Array`, and {@link normalized} is true, + * the values `0` - `+65535` in the array data will be mapped to `0.0f` - `+1.0f` in the GLSL attribute. + * An `Int16Array` (signed) would map from `-32768` - `+32767` to `-1.0f` - `+1.0f`. + * If normalized is false, the values will be converted to floats unmodified, + * i.e. `32767` becomes `32767.0f`. + * Default `false`. + * @throws `TypeError` When the {@link array} is not a `TypedArray`; + */ + constructor(array: TypedArray, itemSize: number, normalized?: boolean); + + /** + * Optional name for this attribute instance. + * @defaultValue '' + */ + name: string; + + /** + * The {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray | TypedArray} holding data stored in the buffer. + * @returns `TypedArray` + */ + array: TypedArray; + + /** + * The length of vectors that are being stored in the {@link BufferAttribute.array | array}. + * @remarks Expects a `Integer` + */ + itemSize: number; + + /** + * Defines the intended usage pattern of the data store for optimization purposes. + * Corresponds to the {@link BufferAttribute.usage | usage} parameter of + * {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/bufferData | WebGLRenderingContext.bufferData}. + * @remarks + * After the initial use of a buffer, its usage cannot be changed. Instead, instantiate a new one and set the desired usage before the next render. + * @see {@link https://threejs.org/docs/index.html#api/en/constants/BufferAttributeUsage | Buffer Attribute Usage Constants} for all possible values. + * @see {@link BufferAttribute.setUsage | setUsage} + * @defaultValue {@link THREE.StaticDrawUsage | THREE.StaticDrawUsage}. + */ + usage: Usage; + + /** + * Configures the bound GPU type for use in shaders. Either {@link FloatType} or {@link IntType}, default is {@link FloatType}. + * + * Note: this only has an effect for integer arrays and is not configurable for float arrays. For lower precision + * float types, see https://threejs.org/docs/#api/en/core/bufferAttributeTypes/BufferAttributeTypes. + */ + gpuType: AttributeGPUType; + + /** + * This can be used to only update some components of stored vectors (for example, just the component related to + * color). Use the {@link .addUpdateRange} function to add ranges to this array. + */ + updateRanges: Array<{ + /** + * Position at which to start update. + */ + start: number; + /** + * The number of components to update. + */ + count: number; + }>; + + /** + * A version number, incremented every time the {@link BufferAttribute.needsUpdate | needsUpdate} property is set to true. + * @remarks Expects a `Integer` + * @defaultValue `0` + */ + version: number; + + /** + * Indicates how the underlying data in the buffer maps to the values in the GLSL shader code. + * @see `constructor` above for details. + * @defaultValue `false` + */ + normalized: boolean; + + /** + * Represents the number of items this buffer attribute stores. It is internally computed by dividing the + * {@link BufferAttribute.array | array}'s length by the {@link BufferAttribute.itemSize | itemSize}. Read-only + * property. + */ + readonly count: number; + + /** + * Flag to indicate that this attribute has changed and should be re-sent to the GPU. + * Set this to true when you modify the value of the array. + * @remarks Setting this to true also increments the {@link BufferAttribute.version | version}. + * @remarks _set-only property_. + */ + set needsUpdate(value: boolean); + + /** + * Read-only flag to check if a given object is of type {@link BufferAttribute}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isBufferAttribute: true; + + /** + * A callback function that is executed after the Renderer has transferred the attribute array data to the GPU. + */ + onUploadCallback: () => void; + + /** + * Sets the value of the {@link onUploadCallback} property. + * @see Example: {@link https://threejs.org/examples/#webgl_buffergeometry | WebGL / BufferGeometry} this is used to free memory after the buffer has been transferred to the GPU. + * @see {@link onUploadCallback} + * @param callback function that is executed after the Renderer has transferred the attribute array data to the GPU. + */ + onUpload(callback: () => void): this; + + /** + * Set {@link BufferAttribute.usage | usage} + * @remarks + * After the initial use of a buffer, its usage cannot be changed. Instead, instantiate a new one and set the desired usage before the next render. + * @see {@link https://threejs.org/docs/index.html#api/en/constants/BufferAttributeUsage | Buffer Attribute Usage Constants} for all possible values. + * @see {@link BufferAttribute.usage | usage} + * @param value Corresponds to the {@link BufferAttribute.usage | usage} parameter of + * {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/bufferData | WebGLRenderingContext.bufferData}. + */ + setUsage(usage: Usage): this; + + /** + * Adds a range of data in the data array to be updated on the GPU. Adds an object describing the range to the + * {@link .updateRanges} array. + */ + addUpdateRange(start: number, count: number): void; + + /** + * Clears the {@link .updateRanges} array. + */ + clearUpdateRanges(): void; + + /** + * @returns a copy of this {@link BufferAttribute}. + */ + clone(): BufferAttribute; + + /** + * Copies another {@link BufferAttribute} to this {@link BufferAttribute}. + * @param bufferAttribute + */ + copy(source: BufferAttribute): this; + + /** + * Copy a vector from bufferAttribute[index2] to {@link BufferAttribute.array | array}[index1]. + * @param index1 + * @param bufferAttribute + * @param index2 + */ + copyAt(index1: number, attribute: BufferAttribute, index2: number): this; + + /** + * Copy the array given here (which can be a normal array or `TypedArray`) into {@link BufferAttribute.array | array}. + * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set | TypedArray.set} for notes on requirements if copying a `TypedArray`. + */ + copyArray(array: ArrayLike): this; + + /** + * Applies matrix {@link Matrix3 | m} to every Vector3 element of this {@link BufferAttribute}. + * @param m + */ + applyMatrix3(m: Matrix3): this; + + /** + * Applies matrix {@link Matrix4 | m} to every Vector3 element of this {@link BufferAttribute}. + * @param m + */ + applyMatrix4(m: Matrix4): this; + + /** + * Applies normal matrix {@link Matrix3 | m} to every Vector3 element of this {@link BufferAttribute}. + * @param m + */ + applyNormalMatrix(m: Matrix3): this; + + /** + * Applies matrix {@link Matrix4 | m} to every Vector3 element of this {@link BufferAttribute}, interpreting the elements as a direction vectors. + * @param m + */ + transformDirection(m: Matrix4): this; + + /** + * Calls {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set | TypedArray.set}( {@link value}, {@link offset} ) + * on the {@link BufferAttribute.array | array}. + * @param value {@link Array | Array} or `TypedArray` from which to copy values. + * @param offset index of the {@link BufferAttribute.array | array} at which to start copying. Expects a `Integer`. Default `0`. + * @throws `RangeError` When {@link offset} is negative or is too large. + */ + set(value: ArrayLike | ArrayBufferView, offset?: number): this; + + /** + * Returns the given component of the vector at the given index. + */ + getComponent(index: number, component: number): number; + + /** + * Sets the given component of the vector at the given index. + */ + setComponent(index: number, component: number, value: number): void; + + /** + * Returns the x component of the vector at the given index. + * @param index Expects a `Integer` + */ + getX(index: number): number; + + /** + * Sets the x component of the vector at the given index. + * @param index Expects a `Integer` + * @param x + */ + setX(index: number, x: number): this; + + /** + * Returns the y component of the vector at the given index. + * @param index Expects a `Integer` + */ + getY(index: number): number; + + /** + * Sets the y component of the vector at the given index. + * @param index Expects a `Integer` + * @param y + */ + setY(index: number, y: number): this; + + /** + * Returns the z component of the vector at the given index. + * @param index Expects a `Integer` + */ + getZ(index: number): number; + + /** + * Sets the z component of the vector at the given index. + * @param index Expects a `Integer` + * @param z + */ + setZ(index: number, z: number): this; + + /** + * Returns the w component of the vector at the given index. + * @param index Expects a `Integer` + */ + getW(index: number): number; + + /** + * Sets the w component of the vector at the given index. + * @param index Expects a `Integer` + * @param w + */ + setW(index: number, z: number): this; + + /** + * Sets the x and y components of the vector at the given index. + * @param index Expects a `Integer` + * @param x + * @param y + */ + setXY(index: number, x: number, y: number): this; + + /** + * Sets the x, y and z components of the vector at the given index. + * @param index Expects a `Integer` + * @param x + * @param y + * @param z + */ + setXYZ(index: number, x: number, y: number, z: number): this; + + /** + * Sets the x, y, z and w components of the vector at the given index. + * @param index Expects a `Integer` + * @param x + * @param y + * @param z + * @param w + */ + setXYZW(index: number, x: number, y: number, z: number, w: number): this; + + /** + * Convert this object to three.js to the `data.attributes` part of {@link https://github.com/mrdoob/three.js/wiki/JSON-Geometry-format-4 | JSON Geometry format v4}, + */ + toJSON(): BufferAttributeJSON; +} + +/** + * A {@link THREE.BufferAttribute | BufferAttribute} for {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Int8Array: Int8Array} + * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray#typedarray_objects | TypedArray} + * @see {@link THREE.BufferAttribute | BufferAttribute} for details and for inherited methods and properties. + * @see {@link https://threejs.org/docs/index.html#api/en/core/bufferAttributeTypes/BufferAttributeTypes | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/BufferAttribute.js | Source} + */ +export class Int8BufferAttribute extends BufferAttribute { + /** + * This creates a new {@link THREE.Int8BufferAttribute | Int8BufferAttribute} object. + * @param array This can be a typed or untyped (normal) array or an integer length. An array value will be converted to `Int8Array`. + * If a length is given a new `TypedArray` will created, initialized with all elements set to zero. + * @param itemSize the number of values of the {@link array} that should be associated with a particular vertex. + * For instance, if this attribute is storing a 3-component vector (such as a _position_, _normal_, or _color_), + * then itemSize should be `3`. + * @param normalized Applies to integer data only. + * Indicates how the underlying data in the buffer maps to the values in the GLSL code. + * For instance, if {@link array} is an instance of `UInt16Array`, and {@link normalized} is true, + * the values `0` - `+65535` in the array data will be mapped to `0.0f` - `+1.0f` in the GLSL attribute. + * An `Int16Array` (signed) would map from `-32768` - `+32767` to `-1.0f` - `+1.0f`. + * If normalized is false, the values will be converted to floats unmodified, + * i.e. `32767` becomes `32767.0f`. + * Default `false`. + */ + constructor( + array: Iterable | ArrayLike | ArrayBuffer | number, + itemSize: number, + normalized?: boolean, + ); +} + +/** + * A {@link THREE.BufferAttribute | BufferAttribute} for {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array: Uint8Array} + * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray#typedarray_objects | TypedArray} + * @see {@link THREE.BufferAttribute | BufferAttribute} for details and for inherited methods and properties. + * @see {@link https://threejs.org/docs/index.html#api/en/core/bufferAttributeTypes/BufferAttributeTypes | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/BufferAttribute.js | Source} + */ +export class Uint8BufferAttribute extends BufferAttribute { + /** + * This creates a new {@link THREE.Uint8BufferAttribute | Uint8BufferAttribute} object. + * @param array This can be a typed or untyped (normal) array or an integer length. An array value will be converted to `Uint8Array`. + * If a length is given a new `TypedArray` will created, initialized with all elements set to zero. + * @param itemSize the number of values of the {@link array} that should be associated with a particular vertex. + * For instance, if this attribute is storing a 3-component vector (such as a _position_, _normal_, or _color_), + * then itemSize should be `3`. + * @param normalized Applies to integer data only. + * Indicates how the underlying data in the buffer maps to the values in the GLSL code. + * For instance, if {@link array} is an instance of `UInt16Array`, and {@link normalized} is true, + * the values `0` - `+65535` in the array data will be mapped to `0.0f` - `+1.0f` in the GLSL attribute. + * An `Int16Array` (signed) would map from `-32768` - `+32767` to `-1.0f` - `+1.0f`. + * If normalized is false, the values will be converted to floats unmodified, + * i.e. `32767` becomes `32767.0f`. + * Default `false`. + * @see {@link THREE.BufferAttribute | BufferAttribute} + */ + constructor( + array: Iterable | ArrayLike | ArrayBuffer | number, + itemSize: number, + normalized?: boolean, + ); +} + +/** + * A {@link THREE.BufferAttribute | BufferAttribute} for {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8ClampedArray: Uint8ClampedArray} + * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray#typedarray_objects | TypedArray} + * @see {@link THREE.BufferAttribute | BufferAttribute} for details and for inherited methods and properties. + * @see {@link https://threejs.org/docs/index.html#api/en/core/bufferAttributeTypes/BufferAttributeTypes | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/BufferAttribute.js | Source} + */ +export class Uint8ClampedBufferAttribute extends BufferAttribute { + /** + * This creates a new {@link THREE.Uint8ClampedBufferAttribute | Uint8ClampedBufferAttribute} object. + * @param array This can be a typed or untyped (normal) array or an integer length. An array value will be converted to `Uint8ClampedArray`. + * If a length is given a new `TypedArray` will created, initialized with all elements set to zero. + * @param itemSize the number of values of the {@link array} that should be associated with a particular vertex. + * For instance, if this attribute is storing a 3-component vector (such as a _position_, _normal_, or _color_), + * then itemSize should be `3`. + * @param normalized Applies to integer data only. + * Indicates how the underlying data in the buffer maps to the values in the GLSL code. + * For instance, if {@link array} is an instance of `UInt16Array`, and {@link normalized} is true, + * the values `0` - `+65535` in the array data will be mapped to `0.0f` - `+1.0f` in the GLSL attribute. + * An `Int16Array` (signed) would map from `-32768` - `+32767` to `-1.0f` - `+1.0f`. + * If normalized is false, the values will be converted to floats unmodified, + * i.e. `32767` becomes `32767.0f`. + * Default `false`. + * @see {@link THREE.BufferAttribute | BufferAttribute} + */ + constructor( + array: Iterable | ArrayLike | ArrayBuffer | number, + itemSize: number, + normalized?: boolean, + ); +} + +/** + * A {@link THREE.BufferAttribute | BufferAttribute} for {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Int16Array: Int16Array} + * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray#typedarray_objects | TypedArray} + * @see {@link THREE.BufferAttribute | BufferAttribute} for details and for inherited methods and properties. + * @see {@link https://threejs.org/docs/index.html#api/en/core/bufferAttributeTypes/BufferAttributeTypes | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/BufferAttribute.js | Source} + */ +export class Int16BufferAttribute extends BufferAttribute { + /** + * This creates a new {@link THREE.Int16BufferAttribute | Int16BufferAttribute} object. + * @param array This can be a typed or untyped (normal) array or an integer length. An array value will be converted to `Int16Array`. + * If a length is given a new `TypedArray` will created, initialized with all elements set to zero. + * @param itemSize the number of values of the {@link array} that should be associated with a particular vertex. + * For instance, if this attribute is storing a 3-component vector (such as a _position_, _normal_, or _color_), + * then itemSize should be `3`. + * @param normalized Applies to integer data only. + * Indicates how the underlying data in the buffer maps to the values in the GLSL code. + * For instance, if {@link array} is an instance of `UInt16Array`, and {@link normalized} is true, + * the values `0` - `+65535` in the array data will be mapped to `0.0f` - `+1.0f` in the GLSL attribute. + * An `Int16Array` (signed) would map from `-32768` - `+32767` to `-1.0f` - `+1.0f`. + * If normalized is false, the values will be converted to floats unmodified, + * i.e. `32767` becomes `32767.0f`. + * Default `false`. + * @see {@link THREE.BufferAttribute | BufferAttribute} + */ + constructor( + array: Iterable | ArrayLike | ArrayBuffer | number, + itemSize: number, + normalized?: boolean, + ); +} + +/** + * A {@link THREE.BufferAttribute | BufferAttribute} for {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint16Array: Uint16Array} + * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray#typedarray_objects | TypedArray} + * @see {@link THREE.BufferAttribute | BufferAttribute} for details and for inherited methods and properties. + * @see {@link https://threejs.org/docs/index.html#api/en/core/bufferAttributeTypes/BufferAttributeTypes | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/BufferAttribute.js | Source} + */ +export class Uint16BufferAttribute extends BufferAttribute { + /** + * This creates a new {@link THREE.Uint16BufferAttribute | Uint16BufferAttribute} object. + * @param array This can be a typed or untyped (normal) array or an integer length. An array value will be converted to `Uint16Array`. + * If a length is given a new `TypedArray` will created, initialized with all elements set to zero. + * @param itemSize the number of values of the {@link array} that should be associated with a particular vertex. + * For instance, if this attribute is storing a 3-component vector (such as a _position_, _normal_, or _color_), + * then itemSize should be `3`. + * @param normalized Applies to integer data only. + * Indicates how the underlying data in the buffer maps to the values in the GLSL code. + * For instance, if {@link array} is an instance of `UInt16Array`, and {@link normalized} is true, + * the values `0` - `+65535` in the array data will be mapped to `0.0f` - `+1.0f` in the GLSL attribute. + * An `Int16Array` (signed) would map from `-32768` - `+32767` to `-1.0f` - `+1.0f`. + * If normalized is false, the values will be converted to floats unmodified, + * i.e. `32767` becomes `32767.0f`. + * Default `false`. + * @see {@link THREE.BufferAttribute | BufferAttribute} + */ + constructor( + array: Iterable | ArrayLike | ArrayBuffer | number, + itemSize: number, + normalized?: boolean, + ); +} + +/** + * A {@link THREE.BufferAttribute | BufferAttribute} for {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Int32Array: Int32Array} + * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray#typedarray_objects | TypedArray} + * @see {@link THREE.BufferAttribute | BufferAttribute} for details and for inherited methods and properties. + * @see {@link https://threejs.org/docs/index.html#api/en/core/bufferAttributeTypes/BufferAttributeTypes | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/BufferAttribute.js | Source} + */ +export class Int32BufferAttribute extends BufferAttribute { + /** + * This creates a new {@link THREE.Int32BufferAttribute | Int32BufferAttribute} object. + * @param array This can be a typed or untyped (normal) array or an integer length. An array value will be converted to `Int32Array`. + * If a length is given a new `TypedArray` will created, initialized with all elements set to zero. + * @param itemSize the number of values of the {@link array} that should be associated with a particular vertex. + * For instance, if this attribute is storing a 3-component vector (such as a _position_, _normal_, or _color_), + * then itemSize should be `3`. + * @param normalized Applies to integer data only. + * Indicates how the underlying data in the buffer maps to the values in the GLSL code. + * For instance, if {@link array} is an instance of `UInt16Array`, and {@link normalized} is true, + * the values `0` - `+65535` in the array data will be mapped to `0.0f` - `+1.0f` in the GLSL attribute. + * An `Int16Array` (signed) would map from `-32768` - `+32767` to `-1.0f` - `+1.0f`. + * If normalized is false, the values will be converted to floats unmodified, + * i.e. `32767` becomes `32767.0f`. + * Default `false`. + * @see {@link THREE.BufferAttribute | BufferAttribute} + */ + constructor( + array: Iterable | ArrayLike | ArrayBuffer | number, + itemSize: number, + normalized?: boolean, + ); +} + +/** + * A {@link THREE.BufferAttribute | BufferAttribute} for {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint32Array: Uint32Array} + * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray#typedarray_objects | TypedArray} + * @see {@link THREE.BufferAttribute | BufferAttribute} for details and for inherited methods and properties. + * @see {@link https://threejs.org/docs/index.html#api/en/core/bufferAttributeTypes/BufferAttributeTypes | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/BufferAttribute.js | Source} + */ +export class Uint32BufferAttribute extends BufferAttribute { + /** + * This creates a new {@link THREE.Uint32BufferAttribute | Uint32BufferAttribute} object. + * @param array This can be a typed or untyped (normal) array or an integer length. An array value will be converted to `Uint32Array`. + * If a length is given a new `TypedArray` will created, initialized with all elements set to zero. + * @param itemSize the number of values of the {@link array} that should be associated with a particular vertex. + * For instance, if this attribute is storing a 3-component vector (such as a _position_, _normal_, or _color_), + * then itemSize should be `3`. + * @param normalized Applies to integer data only. + * Indicates how the underlying data in the buffer maps to the values in the GLSL code. + * For instance, if {@link array} is an instance of `UInt16Array`, and {@link normalized} is true, + * the values `0` - `+65535` in the array data will be mapped to `0.0f` - `+1.0f` in the GLSL attribute. + * An `Int16Array` (signed) would map from `-32768` - `+32767` to `-1.0f` - `+1.0f`. + * If normalized is false, the values will be converted to floats unmodified, + * i.e. `32767` becomes `32767.0f`. + * Default `false`. + * @see {@link THREE.BufferAttribute | BufferAttribute} + */ + constructor( + array: Iterable | ArrayLike | ArrayBuffer | number, + itemSize: number, + normalized?: boolean, + ); +} + +/** + * A {@link THREE.BufferAttribute | BufferAttribute} for {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint16Array: Uint16Array} + * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray#typedarray_objects | TypedArray} + * @see {@link THREE.BufferAttribute | BufferAttribute} for details and for inherited methods and properties. + * @see {@link https://threejs.org/docs/index.html#api/en/core/bufferAttributeTypes/BufferAttributeTypes | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/BufferAttribute.js | Source} + */ +export class Float16BufferAttribute extends BufferAttribute { + /** + * This creates a new {@link THREE.Float16BufferAttribute | Float16BufferAttribute} object. + * @param array This can be a typed or untyped (normal) array or an integer length. An array value will be converted to `Uint16Array`. + * If a length is given a new `TypedArray` will created, initialized with all elements set to zero. + * @param itemSize the number of values of the {@link array} that should be associated with a particular vertex. + * For instance, if this attribute is storing a 3-component vector (such as a _position_, _normal_, or _color_), + * then itemSize should be `3`. + * @param normalized Applies to integer data only. + * Indicates how the underlying data in the buffer maps to the values in the GLSL code. + * For instance, if {@link array} is an instance of `UInt16Array`, and {@link normalized} is true, + * the values `0` - `+65535` in the array data will be mapped to `0.0f` - `+1.0f` in the GLSL attribute. + * An `Int16Array` (signed) would map from `-32768` - `+32767` to `-1.0f` - `+1.0f`. + * If normalized is false, the values will be converted to floats unmodified, + * i.e. `32767` becomes `32767.0f`. + * Default `false`. + * @see {@link THREE.BufferAttribute | BufferAttribute} + */ + constructor( + array: Iterable | ArrayLike | ArrayBuffer | number, + itemSize: number, + normalized?: boolean, + ); +} + +/** + * A {@link THREE.BufferAttribute | BufferAttribute} for {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float32Array: Float32Array} + * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray#typedarray_objects | TypedArray} + * @see {@link THREE.BufferAttribute | BufferAttribute} for details and for inherited methods and properties. + * @see {@link https://threejs.org/docs/index.html#api/en/core/bufferAttributeTypes/BufferAttributeTypes | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/BufferAttribute.js | Source} + */ +export class Float32BufferAttribute extends BufferAttribute { + /** + * This creates a new {@link THREE.Float32BufferAttribute | Float32BufferAttribute} object. + * @param array This can be a typed or untyped (normal) array or an integer length. An array value will be converted to `Float32Array`. + * If a length is given a new `TypedArray` will created, initialized with all elements set to zero. + * @param itemSize the number of values of the {@link array} that should be associated with a particular vertex. + * For instance, if this attribute is storing a 3-component vector (such as a _position_, _normal_, or _color_), + * then itemSize should be `3`. + * @param normalized Applies to integer data only. + * Indicates how the underlying data in the buffer maps to the values in the GLSL code. + * For instance, if {@link array} is an instance of `UInt16Array`, and {@link normalized} is true, + * the values `0` - `+65535` in the array data will be mapped to `0.0f` - `+1.0f` in the GLSL attribute. + * An `Int16Array` (signed) would map from `-32768` - `+32767` to `-1.0f` - `+1.0f`. + * If normalized is false, the values will be converted to floats unmodified, + * i.e. `32767` becomes `32767.0f`. + * Default `false`. + * @see {@link THREE.BufferAttribute | BufferAttribute} + */ + constructor( + array: Iterable | ArrayLike | ArrayBuffer | number, + itemSize: number, + normalized?: boolean, + ); +} diff --git a/src-testing/src/core/BufferGeometry.d.ts b/src-testing/src/core/BufferGeometry.d.ts new file mode 100644 index 000000000..516d5f765 --- /dev/null +++ b/src-testing/src/core/BufferGeometry.d.ts @@ -0,0 +1,433 @@ +import { Box3 } from "../math/Box3.js"; +import { Matrix4 } from "../math/Matrix4.js"; +import { Quaternion } from "../math/Quaternion.js"; +import { Sphere } from "../math/Sphere.js"; +import { Vector2 } from "../math/Vector2.js"; +import { Vector3, Vector3Tuple } from "../math/Vector3.js"; +import IndirectStorageBufferAttribute from "../renderers/common/IndirectStorageBufferAttribute.js"; +import { BufferAttribute, BufferAttributeJSON } from "./BufferAttribute.js"; +import { EventDispatcher } from "./EventDispatcher.js"; +import { GLBufferAttribute } from "./GLBufferAttribute.js"; +import { InterleavedBufferAttribute } from "./InterleavedBufferAttribute.js"; + +export type NormalBufferAttributes = Record; +export type NormalOrGLBufferAttributes = Record< + string, + BufferAttribute | InterleavedBufferAttribute | GLBufferAttribute +>; + +export interface BufferGeometryJSON { + metadata?: { version: number; type: string; generator: string }; + + uuid: string; + type: string; + + name?: string; + userData?: Record; + + data?: { + attributes: Record; + + index?: { type: string; array: number[] }; + + morphAttributes?: Record; + morphTargetsRelative?: boolean; + + groups?: GeometryGroup[]; + + boundingSphere?: { center: Vector3Tuple; radius: number }; + }; +} + +export interface GeometryGroup { + /** + * Specifies the first element in this draw call – the first vertex for non-indexed geometry, otherwise the first triangle index. + * @remarks Expects a `Integer` + */ + start: number; + /** + * Specifies how many vertices (or indices) are included. + * @remarks Expects a `Integer` + */ + count: number; + /** + * Specifies the material array index to use. + * @remarks Expects a `Integer` + */ + materialIndex?: number | undefined; +} + +/** + * A representation of mesh, line, or point geometry + * Includes vertex positions, face indices, normals, colors, UVs, and custom attributes within buffers, reducing the cost of passing all this data to the GPU. + * @remarks + * To read and edit data in BufferGeometry attributes, see {@link THREE.BufferAttribute | BufferAttribute} documentation. + * @example + * ```typescript + * const geometry = new THREE.BufferGeometry(); + * + * // create a simple square shape. We duplicate the top left and bottom right + * // vertices because each vertex needs to appear once per triangle. + * const vertices = new Float32Array( [ + * -1.0, -1.0, 1.0, // v0 + * 1.0, -1.0, 1.0, // v1 + * 1.0, 1.0, 1.0, // v2 + * + * 1.0, 1.0, 1.0, // v3 + * -1.0, 1.0, 1.0, // v4 + * -1.0, -1.0, 1.0 // v5 + * ] ); + * + * // itemSize = 3 because there are 3 values (components) per vertex + * geometry.setAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) ); + * const material = new THREE.MeshBasicMaterial( { color: 0xff0000 } ); + * const mesh = new THREE.Mesh( geometry, material ); + * ``` + * @example + * ```typescript + * const geometry = new THREE.BufferGeometry(); + * + * const vertices = new Float32Array( [ + * -1.0, -1.0, 1.0, // v0 + * 1.0, -1.0, 1.0, // v1 + * 1.0, 1.0, 1.0, // v2 + * -1.0, 1.0, 1.0, // v3 + * ] ); + * geometry.setAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) ); + * + * const indices = [ + * 0, 1, 2, + * 2, 3, 0, + * ]; + * + * geometry.setIndex( indices ); + * geometry.setAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) ); + * + * const material = new THREE.MeshBasicMaterial( { color: 0xff0000 } ); + * const mesh = new THREE.Mesh( geometry, material ); + * ``` + * @see Example: {@link https://threejs.org/examples/#webgl_buffergeometry | Mesh with non-indexed faces} + * @see Example: {@link https://threejs.org/examples/#webgl_buffergeometry_indexed | Mesh with indexed faces} + * @see Example: {@link https://threejs.org/examples/#webgl_buffergeometry_lines | Lines} + * @see Example: {@link https://threejs.org/examples/#webgl_buffergeometry_lines_indexed | Indexed Lines} + * @see Example: {@link https://threejs.org/examples/#webgl_buffergeometry_custom_attributes_particles | Particles} + * @see Example: {@link https://threejs.org/examples/#webgl_buffergeometry_rawshader | Raw Shaders} + * @see {@link https://threejs.org/docs/index.html#api/en/core/BufferGeometry | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/BufferGeometry.js | Source} + */ +export class BufferGeometry< + Attributes extends NormalOrGLBufferAttributes = NormalBufferAttributes, +> extends EventDispatcher<{ dispose: {} }> { + /** + * This creates a new {@link THREE.BufferGeometry | BufferGeometry} object. + */ + constructor(); + + /** + * Unique number for this {@link THREE.BufferGeometry | BufferGeometry} instance. + * @remarks Expects a `Integer` + */ + id: number; + + /** + * {@link http://en.wikipedia.org/wiki/Universally_unique_identifier | UUID} of this object instance. + * @remarks This gets automatically assigned and shouldn't be edited. + */ + uuid: string; + + /** + * Optional name for this {@link THREE.BufferGeometry | BufferGeometry} instance. + * @defaultValue `''` + */ + name: string; + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `BufferGeometry` + */ + readonly type: string | "BufferGeometry"; + + /** + * Allows for vertices to be re-used across multiple triangles; this is called using "indexed triangles". + * Each triangle is associated with the indices of three vertices. This attribute therefore stores the index of each vertex for each triangular face. + * If this attribute is not set, the {@link THREE.WebGLRenderer | renderer} assumes that each three contiguous positions represent a single triangle. + * @defaultValue `null` + */ + index: BufferAttribute | null; + + indirect: IndirectStorageBufferAttribute | null; + + /** + * This hashmap has as id the name of the attribute to be set and as value the {@link THREE.BufferAttribute | buffer} to set it to. Rather than accessing this property directly, + * use {@link setAttribute | .setAttribute} and {@link getAttribute | .getAttribute} to access attributes of this geometry. + * @defaultValue `{}` + */ + attributes: Attributes; + + /** + * Hashmap of {@link THREE.BufferAttribute | BufferAttributes} holding details of the geometry's morph targets. + * @remarks + * Once the geometry has been rendered, the morph attribute data cannot be changed. + * You will have to call {@link dispose | .dispose}(), and create a new instance of {@link THREE.BufferGeometry | BufferGeometry}. + * @defaultValue `{}` + */ + morphAttributes: { + [name: string]: Array; // TODO Replace for 'Record<>' + }; + + /** + * Used to control the morph target behavior; when set to true, the morph target data is treated as relative offsets, rather than as absolute positions/normals. + * @defaultValue `false` + */ + morphTargetsRelative: boolean; + + /** + * Split the geometry into groups, each of which will be rendered in a separate WebGL draw call. This allows an array of materials to be used with the geometry. + * @remarks Every vertex and index must belong to exactly one group — groups must not share vertices or indices, and must not leave vertices or indices unused. + * @remarks Use {@link addGroup | .addGroup} to add groups, rather than modifying this array directly. + * @defaultValue `[]` + */ + groups: GeometryGroup[]; + + /** + * Bounding box for the {@link THREE.BufferGeometry | BufferGeometry}, which can be calculated with {@link computeBoundingBox | .computeBoundingBox()}. + * @remarks Bounding boxes aren't computed by default. They need to be explicitly computed, otherwise they are `null`. + * @defaultValue `null` + */ + boundingBox: Box3 | null; + + /** + * Bounding sphere for the {@link THREE.BufferGeometry | BufferGeometry}, which can be calculated with {@link computeBoundingSphere | .computeBoundingSphere()}. + * @remarks bounding spheres aren't computed by default. They need to be explicitly computed, otherwise they are `null`. + * @defaultValue `null` + */ + boundingSphere: Sphere | null; + + /** + * Determines the part of the geometry to render. This should not be set directly, instead use {@link setDrawRange | .setDrawRange(...)}. + * @remarks For non-indexed {@link THREE.BufferGeometry | BufferGeometry}, count is the number of vertices to render. + * @remarks For indexed {@link THREE.BufferGeometry | BufferGeometry}, count is the number of indices to render. + * @defaultValue `{ start: 0, count: Infinity }` + */ + drawRange: { start: number; count: number }; + + /** + * An object that can be used to store custom data about the BufferGeometry. It should not hold references to functions as these will not be cloned. + * @defaultValue `{}` + */ + userData: Record; + + /** + * Read-only flag to check if a given object is of type {@link BufferGeometry}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isBufferGeometry: true; + + /** + * Return the {@link index | .index} buffer. + */ + getIndex(): BufferAttribute | null; + + /** + * Set the {@link THREE.BufferGeometry.index | .index} buffer. + * @param index + */ + setIndex(index: BufferAttribute | number[] | null): this; + + setIndirect(indirect: IndirectStorageBufferAttribute | null): this; + + getIndirect(): IndirectStorageBufferAttribute | null; + + /** + * Sets an {@link attributes | attribute} to this geometry with the specified name. + * @remarks + * Use this rather than the attributes property, because an internal hashmap of {@link attributes | .attributes} is maintained to speed up iterating over attributes. + * @param name + * @param attribute + */ + setAttribute(name: K, attribute: Attributes[K]): this; + + /** + * Returns the {@link attributes | attribute} with the specified name. + * @param name + */ + getAttribute(name: K): Attributes[K]; + + /** + * Deletes the {@link attributes | attribute} with the specified name. + * @param name + */ + deleteAttribute(name: keyof Attributes): this; + + /** + * Returns true if the {@link attributes | attribute} with the specified name exists. + * @param name + */ + hasAttribute(name: keyof Attributes): boolean; + + /** + * Adds a group to this geometry + * @see the {@link BufferGeometry.groups | groups} property for details. + * @param start + * @param count + * @param materialIndex + */ + addGroup(start: number, count: number, materialIndex?: number): void; + + /** + * Clears all groups. + */ + clearGroups(): void; + + /** + * Set the {@link drawRange | .drawRange} property + * @remarks For non-indexed BufferGeometry, count is the number of vertices to render + * @remarks For indexed BufferGeometry, count is the number of indices to render. + * @param start + * @param count is the number of vertices or indices to render. Expects a `Integer` + */ + setDrawRange(start: number, count: number): void; + + /** + * Applies the matrix transform to the geometry. + * @param matrix + */ + applyMatrix4(matrix: Matrix4): this; + + /** + * Applies the rotation represented by the quaternion to the geometry. + * @param quaternion + */ + applyQuaternion(quaternion: Quaternion): this; + + /** + * Rotate the geometry about the X axis. This is typically done as a one time operation, and not during a loop. + * @remarks Use {@link THREE.Object3D.rotation | Object3D.rotation} for typical real-time mesh rotation. + * @param angle radians. Expects a `Float` + */ + rotateX(angle: number): this; + + /** + * Rotate the geometry about the Y axis. + * @remarks This is typically done as a one time operation, and not during a loop. + * @remarks Use {@link THREE.Object3D.rotation | Object3D.rotation} for typical real-time mesh rotation. + * @param angle radians. Expects a `Float` + */ + rotateY(angle: number): this; + + /** + * Rotate the geometry about the Z axis. + * @remarks This is typically done as a one time operation, and not during a loop. + * @remarks Use {@link THREE.Object3D.rotation | Object3D.rotation} for typical real-time mesh rotation. + * @param angle radians. Expects a `Float` + */ + rotateZ(angle: number): this; + + /** + * Translate the geometry. + * @remarks This is typically done as a one time operation, and not during a loop. + * @remarks Use {@link THREE.Object3D.position | Object3D.position} for typical real-time mesh rotation. + * @param x Expects a `Float` + * @param y Expects a `Float` + * @param z Expects a `Float` + */ + translate(x: number, y: number, z: number): this; + + /** + * Scale the geometry data. + * @remarks This is typically done as a one time operation, and not during a loop. + * @remarks Use {@link THREE.Object3D.scale | Object3D.scale} for typical real-time mesh scaling. + * @param x Expects a `Float` + * @param y Expects a `Float` + * @param z Expects a `Float` + */ + scale(x: number, y: number, z: number): this; + + /** + * Rotates the geometry to face a point in space. + * @remarks This is typically done as a one time operation, and not during a loop. + * @remarks Use {@link THREE.Object3D.lookAt | Object3D.lookAt} for typical real-time mesh usage. + * @param vector A world vector to look at. + */ + lookAt(vector: Vector3): this; + + /** + * Center the geometry based on the bounding box. + */ + center(): this; + + /** + * Defines a geometry by creating a `position` attribute based on the given array of points. The array can hold + * instances of {@link Vector2} or {@link Vector3}. When using two-dimensional data, the `z` coordinate for all + * vertices is set to `0`. + * + * If the method is used with an existing `position` attribute, the vertex data are overwritten with the data from + * the array. The length of the array must match the vertex count. + */ + setFromPoints(points: Vector3[] | Vector2[]): this; + + /** + * Computes the bounding box of the geometry, and updates the {@link .boundingBox} attribute. The bounding box is + * not computed by the engine; it must be computed by your app. You may need to recompute the bounding box if the + * geometry vertices are modified. + */ + computeBoundingBox(): void; + + /** + * Computes the bounding sphere of the geometry, and updates the {@link .boundingSphere} attribute. The engine + * automatically computes the bounding sphere when it is needed, e.g., for ray casting or view frustum culling. You + * may need to recompute the bounding sphere if the geometry vertices are modified. + */ + computeBoundingSphere(): void; + + /** + * Calculates and adds a tangent attribute to this geometry. + * The computation is only supported for indexed geometries and if position, normal, and uv attributes are defined + * @remarks + * When using a tangent space normal map, prefer the MikkTSpace algorithm provided by + * {@link BufferGeometryUtils.computeMikkTSpaceTangents} instead. + */ + computeTangents(): void; + + /** + * Computes vertex normals for the given vertex data. For indexed geometries, the method sets each vertex normal to + * be the average of the face normals of the faces that share that vertex. For non-indexed geometries, vertices are + * not shared, and the method sets each vertex normal to be the same as the face normal. + */ + computeVertexNormals(): void; + + /** + * Every normal vector in a geometry will have a magnitude of 1 + * @remarks This will correct lighting on the geometry surfaces. + */ + normalizeNormals(): void; + + /** + * Return a non-index version of an indexed BufferGeometry. + */ + toNonIndexed(): BufferGeometry; + + /** + * Convert the buffer geometry to three.js {@link https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 | JSON Object/Scene format}. + */ + toJSON(): BufferGeometryJSON; + + /** + * Creates a clone of this BufferGeometry + */ + clone(): this; + + /** + * Copies another BufferGeometry to this BufferGeometry. + * @param source + */ + copy(source: BufferGeometry): this; + + /** + * Frees the GPU-related resources allocated by this instance. + * @remarks Call this method whenever this instance is no longer used in your app. + */ + dispose(): void; +} diff --git a/src-testing/src/core/Clock.d.ts b/src-testing/src/core/Clock.d.ts new file mode 100644 index 000000000..05307083c --- /dev/null +++ b/src-testing/src/core/Clock.d.ts @@ -0,0 +1,72 @@ +/** + * Object for keeping track of time + * @remarks + * This uses {@link https://developer.mozilla.org/en-US/docs/Web/API/Performance/now | performance.now} if it is available, + * otherwise it reverts to the less accurate {@link https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Date/now | Date.now}. + * @see {@link https://threejs.org/docs/index.html#api/en/core/Clock | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/Clock.js | Source} + */ +export class Clock { + /** + * Create a new instance of {@link THREE.Clock | Clock} + * @param autoStart - Whether to automatically start the clock when {@link getDelta | .getDelta()} is called for the first time. Default `true` + */ + constructor(autoStart?: boolean); + + /** + * If set, starts the clock automatically when {@link getDelta | .getDelta()} is called for the first time. + * @defaultValue `true` + */ + autoStart: boolean; + + /** + * Holds the time at which the clock's {@link start | .start()} method was last called. + * @defaultValue `0` + */ + startTime: number; + + /** + * Holds the time at which the clock's {@link start | .start()}, {@link getElapsedTime | .getElapsedTime()} or {@link getDelta | .getDelta()} methods were last called. + * @defaultValue `0` + */ + oldTime: number; + + /** + * Keeps track of the total time that the clock has been running. + * @defaultValue `0` + */ + elapsedTime: number; + + /** + * Whether the clock is running or not. + * @defaultValue `false` + */ + running: boolean; + + /** + * Starts clock. + * @remarks + * Also sets the {@link startTime | .startTime} and {@link oldTime | .oldTime} to the current time, + * sets {@link elapsedTime | .elapsedTime} to `0` and {@link running | .running} to `true`. + */ + start(): void; + + /** + * Stops clock and sets {@link oldTime | oldTime} to the current time. + */ + stop(): void; + + /** + * Get the seconds passed since the clock started and sets {@link oldTime | .oldTime} to the current time. + * @remarks + * If {@link autoStart | .autoStart} is `true` and the clock is not running, also starts the clock. + */ + getElapsedTime(): number; + + /** + * Get the seconds passed since the time {@link oldTime | .oldTime} was set and sets {@link oldTime | .oldTime} to the current time. + * @remarks + * If {@link autoStart | .autoStart} is `true` and the clock is not running, also starts the clock. + */ + getDelta(): number; +} diff --git a/src-testing/src/core/EventDispatcher.d.ts b/src-testing/src/core/EventDispatcher.d.ts new file mode 100644 index 000000000..403dd1c2e --- /dev/null +++ b/src-testing/src/core/EventDispatcher.d.ts @@ -0,0 +1,82 @@ +/** + * The minimal basic Event that can be dispatched by a {@link EventDispatcher<>}. + */ +export interface BaseEvent { + readonly type: TEventType; +} + +/** + * The minimal expected contract of a fired Event that was dispatched by a {@link EventDispatcher<>}. + */ +export interface Event { + readonly type: TEventType; + readonly target: TTarget; +} + +export type EventListener = ( + event: TEventData & Event, +) => void; + +/** + * JavaScript events for custom objects + * @example + * ```typescript + * // Adding events to a custom object + * class Car extends EventDispatcher { + * start() { + * this.dispatchEvent( { type: 'start', message: 'vroom vroom!' } ); + * } + * }; + * // Using events with the custom object + * const car = new Car(); + * car.addEventListener( 'start', ( event ) => { + * alert( event.message ); + * } ); + * car.start(); + * ``` + * @see {@link https://github.com/mrdoob/eventdispatcher.js | mrdoob EventDispatcher on GitHub} + * @see {@link https://threejs.org/docs/index.html#api/en/core/EventDispatcher | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/EventDispatcher.js | Source} + */ +export class EventDispatcher { + /** + * Creates {@link THREE.EventDispatcher | EventDispatcher} object. + */ + constructor(); + + /** + * Adds a listener to an event type. + * @param type The type of event to listen to. + * @param listener The function that gets called when the event is fired. + */ + addEventListener>( + type: T, + listener: EventListener, + ): void; + + /** + * Checks if listener is added to an event type. + * @param type The type of event to listen to. + * @param listener The function that gets called when the event is fired. + */ + hasEventListener>( + type: T, + listener: EventListener, + ): boolean; + + /** + * Removes a listener from an event type. + * @param type The type of the listener that gets removed. + * @param listener The listener function that gets removed. + */ + removeEventListener>( + type: T, + listener: EventListener, + ): void; + + /** + * Fire an event type. + * @param event The event that gets fired. + */ + dispatchEvent>(event: BaseEvent & TEventMap[T]): void; +} diff --git a/src-testing/src/core/GLBufferAttribute.d.ts b/src-testing/src/core/GLBufferAttribute.d.ts new file mode 100644 index 000000000..c549518dd --- /dev/null +++ b/src-testing/src/core/GLBufferAttribute.d.ts @@ -0,0 +1,121 @@ +/** + * This buffer attribute class does not construct a VBO. + * Instead, it uses whatever VBO is passed in constructor and can later be altered via the {@link buffer | .buffer} property. + * @remarks + * It is required to pass additional params alongside the VBO + * Those are: the GL context, the GL data type, the number of components per vertex, the number of bytes per component, and the number of vertices. + * @remarks + * The most common use case for this class is when some kind of GPGPU calculation interferes or even produces the VBOs in question. + * @see Example: {@link https://threejs.org/examples/#webgl_buffergeometry_glbufferattribute | WebGL / buffergeometry / glbufferattribute} + * @see {@link https://threejs.org/docs/index.html#api/en/core/GLBufferAttribute | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/GLBufferAttribute.js | Source} + */ +export class GLBufferAttribute { + /** + * This creates a new GLBufferAttribute object. + * @param buffer Must be a {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGLBuffer | WebGLBuffer}. See {@link GLBufferAttribute.buffer | .buffer} + * @param type One of {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Constants#Data_types | WebGL Data Types}. See {@link GLBufferAttribute.type | .type} + * @param itemSize How many values make up each item (vertex). See {@link GLBufferAttribute.itemSize | .itemSize} + * @param elementSize `1`, `2` or `4`. The corresponding size (in bytes) for the given {@link type} param. See {@link GLBufferAttribute.elementSize | .elementSize} + * @param count The expected number of vertices in VBO. See {@link GLBufferAttribute.count | .count} + */ + constructor(buffer: WebGLBuffer, type: GLenum, itemSize: number, elementSize: 1 | 2 | 4, count: number); + + /** + * Read-only flag to check if a given object is of type {@link GLBufferAttribute}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isGLBufferAttribute: true; + + /** + * Optional name for this attribute instance. + * @defaultValue `""` + */ + name: string; + + /** + * The current {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGLBuffer | WebGLBuffer} instance. + */ + buffer: WebGLBuffer; + + /** + * A {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Constants#Data_types | WebGL Data Type} describing the underlying VBO contents. + * + * #### WebGL Data Type (`GLenum`) + * - gl.BYTE: 0x1400 + * - gl.UNSIGNED_BYTE: 0x1401 + * - gl.SHORT: 0x1402 + * - gl.UNSIGNED_SHORT: 0x1403 + * - gl.INT: 0x1404 + * - gl.UNSIGNED_INT: 0x1405 + * - gl.FLOAT: 0x1406 + * @remarks Set this property together with {@link elementSize | .elementSize}. The recommended way is using the {@link setType | .setType()} method. + * @remarks Expects a `DataType` `GLenum` _possible values:_ `0x1400` `0x1401` `0x1402` `0x1403` `0x1404` `0x1405` `0x1406` + */ + type: GLenum; + + /** + * How many values make up each item (vertex). + * @remarks The number of values of the array that should be associated with a particular vertex. + * For instance, if this attribute is storing a 3-component vector (such as a position, normal, or color), then itemSize should be 3. + * @remarks Expects a `Integer` + */ + itemSize: number; + + /** + * Stores the corresponding size in bytes for the current {@link type | .type} property value. + * + * The corresponding size (_in bytes_) for the given "type" param. + * #### WebGL Data Type (`GLenum`) + * - gl.BYTE: 1 + * - gl.UNSIGNED_BYTE: 1 + * - gl.SHORT: 2 + * - gl.UNSIGNED_SHORT: 2 + * - gl.INT: 4 + * - gl.UNSIGNED_INT: 4 + * - gl.FLOAT: 4 + * @remarks Set this property together with {@link type | .type}. The recommended way is using the {@link setType | .setType} method. + * @see `constructor`` for a list of known type sizes. + * @remarks Expects a `1`, `2` or `4` + */ + elementSize: 1 | 2 | 4; + + /** + * The expected number of vertices in VBO. + * @remarks Expects a `Integer` + */ + count: number; + + /** + * A version number, incremented every time the needsUpdate property is set to true. + * @remarks Expects a `Integer` + */ + version: number; + + /** + * Setting this to true increments {@link version | .version}. + * @remarks _set-only property_. + */ + set needsUpdate(value: boolean); + + /** + * Sets the {@link buffer | .buffer} property. + */ + setBuffer(buffer: WebGLBuffer): this; + + /** + * Sets the both {@link GLBufferAttribute.type | type} and {@link GLBufferAttribute.elementSize | elementSize} properties. + */ + setType(type: GLenum, elementSize: 1 | 2 | 4): this; + + /** + * Sets the {@link GLBufferAttribute.itemSize | itemSize} property. + */ + setItemSize(itemSize: number): this; + + /** + * Sets the {@link GLBufferAttribute.count | count} property. + */ + setCount(count: number): this; +} diff --git a/src-testing/src/core/InstancedBufferAttribute.d.ts b/src-testing/src/core/InstancedBufferAttribute.d.ts new file mode 100644 index 000000000..fde083b81 --- /dev/null +++ b/src-testing/src/core/InstancedBufferAttribute.d.ts @@ -0,0 +1,32 @@ +import { BufferAttribute, TypedArray } from "./BufferAttribute.js"; + +/** + * An instanced version of {@link THREE.BufferAttribute | BufferAttribute}. + * @see {@link https://threejs.org/docs/index.html#api/en/core/InstancedBufferAttribute | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/InstancedBufferAttribute.js | Source} + */ +export class InstancedBufferAttribute extends BufferAttribute { + /** + * Create a new instance of {@link THREE.InstancedBufferAttribute | InstancedBufferAttribute} + * @param array + * @param itemSize + * @param normalized + * @param meshPerAttribute + */ + constructor(array: TypedArray, itemSize: number, normalized?: boolean, meshPerAttribute?: number); + + /** + * Defines how often a value of this buffer attribute should be repeated. + * A value of one means that each value of the instanced attribute is used for a single instance. + * A value of two means that each value is used for two consecutive instances (and so on). + * @defaultValue `1` + */ + meshPerAttribute: number; + + /** + * Read-only flag to check if a given object is of type {@link InstancedBufferAttribute}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isInstancedBufferAttribute: true; +} diff --git a/src-testing/src/core/InstancedBufferGeometry.d.ts b/src-testing/src/core/InstancedBufferGeometry.d.ts new file mode 100644 index 000000000..421294c49 --- /dev/null +++ b/src-testing/src/core/InstancedBufferGeometry.d.ts @@ -0,0 +1,37 @@ +import { BufferGeometry } from "./BufferGeometry.js"; + +/** + * An instanced version of {@link THREE.BufferGeometry | BufferGeometry}. + * @see {@link https://threejs.org/docs/index.html#api/en/core/InstancedBufferGeometry | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/InstancedBufferGeometry.js | Source} + */ +export class InstancedBufferGeometry extends BufferGeometry { + /** + * Create a new instance of {@link InstancedBufferGeometry} + */ + constructor(); + + /** + * @defaultValue `InstancedBufferGeometry` + */ + type: string; + + /** + * Read-only flag to check if a given object is of type {@link InstancedBufferGeometry}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isInstancedBufferGeometry: true; + + /** + * @defaultValue `Infinity` + */ + instanceCount: number; + + /** + * Copies the given {@link InstancedBufferGeometry} to this instance. + * @param source + * @override + */ + copy(source: InstancedBufferGeometry): this; +} diff --git a/src-testing/src/core/InstancedInterleavedBuffer.d.ts b/src-testing/src/core/InstancedInterleavedBuffer.d.ts new file mode 100644 index 000000000..3c78beae4 --- /dev/null +++ b/src-testing/src/core/InstancedInterleavedBuffer.d.ts @@ -0,0 +1,22 @@ +import { TypedArray } from "./BufferAttribute.js"; +import { InterleavedBuffer } from "./InterleavedBuffer.js"; + +/** + * An instanced version of {@link THREE.InterleavedBuffer | InterleavedBuffer}. + * @see {@link https://threejs.org/docs/index.html#api/en/core/InstancedInterleavedBuffer | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/InstancedInterleavedBuffer.js | Source} + */ +export class InstancedInterleavedBuffer extends InterleavedBuffer { + /** + * Create a new instance of {@link InstancedInterleavedBuffer} + * @param array + * @param itemSize + * @param meshPerAttribute + */ + constructor(array: TypedArray, stride: number, meshPerAttribute?: number); + + /** + * @defaultValue `1` + */ + meshPerAttribute: number; +} diff --git a/src-testing/src/core/InterleavedBuffer.d.ts b/src-testing/src/core/InterleavedBuffer.d.ts new file mode 100644 index 000000000..89819f6c2 --- /dev/null +++ b/src-testing/src/core/InterleavedBuffer.d.ts @@ -0,0 +1,150 @@ +import { Usage } from "../constants.js"; +import { TypedArray } from "./BufferAttribute.js"; +import { InterleavedBufferAttribute } from "./InterleavedBufferAttribute.js"; + +/** + * **"Interleaved"** means that multiple attributes, possibly of different types, (e.g., _position, normal, uv, color_) are packed into a single array buffer. + * An introduction into interleaved arrays can be found here: {@link https://blog.tojicode.com/2011/05/interleaved-array-basics.html | Interleaved array basics} + * @see Example: {@link https://threejs.org/examples/#webgl_buffergeometry_points_interleaved | webgl / buffergeometry / points / interleaved} + * @see {@link https://threejs.org/docs/index.html#api/en/core/InterleavedBuffer | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/InterleavedBuffer.js | Source} + */ +export class InterleavedBuffer { + readonly isInterleavedBuffer: true; + + /** + * Create a new instance of {@link InterleavedBuffer} + * @param array A {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray | TypedArray} with a shared buffer. Stores the geometry data. + * @param stride The number of typed-array elements per vertex. Expects a `Integer` + */ + constructor(array: TypedArray, stride: number); + + /** + * A {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray | TypedArray} with a shared buffer. Stores the geometry data. + */ + array: TypedArray; + + /** + * The number of {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray | TypedArray} elements per vertex. + * @remarks Expects a `Integer` + */ + stride: number; + + /** + * Defines the intended usage pattern of the data store for optimization purposes. + * Corresponds to the {@link BufferAttribute.usage | usage} parameter of + * {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/bufferData | WebGLRenderingContext.bufferData}. + * @remarks + * After the initial use of a buffer, its usage cannot be changed. Instead, instantiate a new one and set the desired usage before the next render. + * @see {@link https://threejs.org/docs/index.html#api/en/constants/BufferAttributeUsage | Buffer Attribute Usage Constants} for all possible values. + * @see {@link BufferAttribute.setUsage | setUsage} + * @defaultValue {@link THREE.StaticDrawUsage | THREE.StaticDrawUsage}. + */ + usage: Usage; + + /** + * This can be used to only update some components of stored data. Use the {@link .addUpdateRange} function to add + * ranges to this array. + */ + updateRanges: Array<{ + /** + * Position at which to start update. + */ + start: number; + /** + * The number of components to update. + */ + count: number; + }>; + + /** + * A version number, incremented every time the {@link BufferAttribute.needsUpdate | needsUpdate} property is set to true. + * @remarks Expects a `Integer` + * @defaultValue `0` + */ + version: number; + + /** + * Gives the total number of elements in the array. + * @remarks Expects a `Integer` + * @defaultValue 0 + */ + count: number; + + /** + * Flag to indicate that this attribute has changed and should be re-sent to the GPU. + * Set this to true when you modify the value of the array. + * @remarks Setting this to true also increments the {@link BufferAttribute.version | version}. + * @remarks _set-only property_. + */ + set needsUpdate(value: boolean); + + /** + * {@link http://en.wikipedia.org/wiki/Universally_unique_identifier | UUID} of this object instance. + * @remarks This gets automatically assigned and shouldn't be edited. + */ + uuid: string; + + /** + * Calls {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set | TypedArray.set}( {@link value}, {@link offset} ) + * on the {@link BufferAttribute.array | array}. + * @param value The source `TypedArray`. + * @param offset index of the {@link BufferAttribute.array | array} at which to start copying. Expects a `Integer`. Default `0`. + * @throws `RangeError` When {@link offset} is negative or is too large. + */ + set(value: ArrayLike, offset: number): this; + + /** + * Set {@link BufferAttribute.usage | usage} + * @remarks + * After the initial use of a buffer, its usage cannot be changed. Instead, instantiate a new one and set the desired usage before the next render. + * @see {@link https://threejs.org/docs/index.html#api/en/constants/BufferAttributeUsage | Buffer Attribute Usage Constants} for all possible values. + * @see {@link BufferAttribute.usage | usage} + * @param value Corresponds to the {@link BufferAttribute.usage | usage} parameter of + * {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/bufferData | WebGLRenderingContext.bufferData}. + */ + setUsage(value: Usage): this; + + /** + * Adds a range of data in the data array to be updated on the GPU. Adds an object describing the range to the + * {@link .updateRanges} array. + */ + addUpdateRange(start: number, count: number): void; + + /** + * Clears the {@link .updateRanges} array. + */ + clearUpdateRanges(): void; + + /** + * Copies another {@link InterleavedBuffer} to this {@link InterleavedBuffer} instance. + * @param source + */ + copy(source: InterleavedBuffer): this; + + /** + * Copies data from {@link attribute}[{@link index2}] to {@link InterleavedBuffer.array | array}[{@link index1}]. + * @param index1 Expects a `Integer` + * @param attribute + * @param index2 Expects a `Integer` + */ + copyAt(index1: number, attribute: InterleavedBufferAttribute, index2: number): this; + + /** + * Creates a clone of this {@link InterleavedBuffer}. + * @param data This object holds shared array buffers required for properly cloning geometries with interleaved attributes. + */ + clone(data: {}): InterleavedBuffer; + + /** + * Serializes this {@link InterleavedBuffer}. + * Converting to {@link https://github.com/mrdoob/three.js/wiki/JSON-Geometry-format-4 | JSON Geometry format v4}, + * @param data This object holds shared array buffers required for properly serializing geometries with interleaved attributes. + */ + toJSON(data: {}): { + uuid: string; + buffer: string; + type: string; + stride: number; + }; +} diff --git a/src-testing/src/core/InterleavedBufferAttribute.d.ts b/src-testing/src/core/InterleavedBufferAttribute.d.ts new file mode 100644 index 000000000..955049938 --- /dev/null +++ b/src-testing/src/core/InterleavedBufferAttribute.d.ts @@ -0,0 +1,201 @@ +import { Matrix3 } from "../math/Matrix3.js"; +import { Matrix4 } from "../math/Matrix4.js"; +import { BufferAttribute, TypedArray } from "./BufferAttribute.js"; +import { InterleavedBuffer } from "./InterleavedBuffer.js"; + +/** + * @see {@link https://threejs.org/docs/index.html#api/en/core/InterleavedBufferAttribute | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/InterleavedBufferAttribute.js | Source} + */ +export class InterleavedBufferAttribute { + /** + * Create a new instance of {@link THREE.InterleavedBufferAttribute | InterleavedBufferAttribute}. + * @param interleavedBuffer + * @param itemSize + * @param offset + * @param normalized Default `false`. + */ + constructor(interleavedBuffer: InterleavedBuffer, itemSize: number, offset: number, normalized?: boolean); + + /** + * Optional name for this attribute instance. + * @defaultValue `''` + */ + name: string; + + /** + * The {@link InterleavedBuffer | InterleavedBuffer} instance passed in the constructor. + */ + data: InterleavedBuffer; + + /** + * How many values make up each item. + * @remarks Expects a `Integer` + */ + itemSize: number; + + /** + * The offset in the underlying array buffer where an item starts. + * @remarks Expects a `Integer` + */ + offset: number; + + /** + * @defaultValue `false` + */ + normalized: boolean; + + /** + * The value of {@link data | .data}.{@link InterleavedBuffer.count | count}. + * If the buffer is storing a 3-component item (such as a _position, normal, or color_), then this will count the number of such items stored. + * @remarks _get-only property_. + * @remarks Expects a `Integer` + */ + get count(): number; + + /** + * The value of {@link InterleavedBufferAttribute.data | data}.{@link InterleavedBuffer.array | array}. + * @remarks _get-only property_. + */ + get array(): TypedArray; + + /** + * Flag to indicate that the {@link data | .data} ({@link InterleavedBuffer}) attribute has changed and should be re-sent to the GPU. + * @remarks Setting this to have the same result of setting true also increments the {@link InterleavedBuffer.needsUpdate | InterleavedBuffer.needsUpdate} of {@link data | .data}. + * @remarks Setting this to true also increments the {@link InterleavedBuffer.version | InterleavedBuffer.version}. + * @remarks _set-only property_. + */ + set needsUpdate(value: boolean); + + /** + * Read-only flag to check if a given object is of type {@link InterleavedBufferAttribute}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isInterleavedBufferAttribute: true; + + /** + * Applies matrix {@link Matrix4 | m} to every Vector3 element of this InterleavedBufferAttribute. + * @param m + */ + applyMatrix4(m: Matrix4): this; + + /** + * Applies normal matrix {@link Matrix3 | m} to every Vector3 element of this InterleavedBufferAttribute. + * @param m + */ + applyNormalMatrix(m: Matrix3): this; + + /** + * Applies matrix {@link Matrix4 | m} to every Vector3 element of this InterleavedBufferAttribute, interpreting the elements as a direction vectors. + * @param m + */ + transformDirection(m: Matrix4): this; + + /** + * Returns the given component of the vector at the given index. + */ + getComponent(index: number, component: number): number; + + /** + * Sets the given component of the vector at the given index. + */ + setComponent(index: number, component: number, value: number): this; + + /** + * Returns the x component of the item at the given index. + * @param index Expects a `Integer` + */ + getX(index: number): number; + + /** + * Sets the x component of the item at the given index. + * @param index Expects a `Integer` + * @param x Expects a `Float` + */ + setX(index: number, x: number): this; + + /** + * Returns the y component of the item at the given index. + * @param index Expects a `Integer` + */ + getY(index: number): number; + + /** + * Sets the y component of the item at the given index. + * @param index Expects a `Integer` + * @param y Expects a `Float` + */ + setY(index: number, y: number): this; + + /** + * Returns the z component of the item at the given index. + * @param index Expects a `Integer` + */ + getZ(index: number): number; + + /** + * Sets the z component of the item at the given index. + * @param index Expects a `Integer` + * @param z Expects a `Float` + */ + setZ(index: number, z: number): this; + + /** + * Returns the w component of the item at the given index. + * @param index Expects a `Integer` + */ + getW(index: number): number; + + /** + * Sets the w component of the item at the given index. + * @param index Expects a `Integer` + * @param w Expects a `Float` + */ + setW(index: number, z: number): this; + + /** + * Sets the x and y components of the item at the given index. + * @param index Expects a `Integer` + * @param x Expects a `Float` + * @param y Expects a `Float` + */ + setXY(index: number, x: number, y: number): this; + /** + * Sets the x, y and z components of the item at the given index. + * @param index Expects a `Integer` + * @param x Expects a `Float` + * @param y Expects a `Float` + * @param z Expects a `Float` + */ + setXYZ(index: number, x: number, y: number, z: number): this; + + /** + * Sets the x, y, z and w components of the item at the given index. + * @param index Expects a `Integer` + * @param x Expects a `Float` + * @param y Expects a `Float` + * @param z Expects a `Float` + * @param w Expects a `Float` + */ + setXYZW(index: number, x: number, y: number, z: number, w: number): this; + + /** + * Creates a clone of this {@link InterleavedBufferAttribute}. + * @param data This object holds shared array buffers required for properly cloning geometries with interleaved attributes. + */ + clone(data?: {}): BufferAttribute; + + /** + * Serializes this {@link InterleavedBufferAttribute}. + * Converting to {@link https://github.com/mrdoob/three.js/wiki/JSON-Geometry-format-4 | JSON Geometry format v4}, + * @param data This object holds shared array buffers required for properly serializing geometries with interleaved attributes. + */ + toJSON(data?: {}): { + isInterleavedBufferAttribute: true; + itemSize: number; + data: string; + offset: number; + normalized: boolean; + }; +} diff --git a/src-testing/src/core/Layers.d.ts b/src-testing/src/core/Layers.d.ts new file mode 100644 index 000000000..ad95f892d --- /dev/null +++ b/src-testing/src/core/Layers.d.ts @@ -0,0 +1,72 @@ +/** + * A {@link THREE.Layers | Layers} object assigns an {@link THREE.Object3D | Object3D} to 1 or more of 32 layers numbered `0` to `31` - internally the + * layers are stored as a {@link https://en.wikipedia.org/wiki/Mask_(computing) | bit mask}, and + * by default all Object3Ds are a member of layer `0`. + * @remarks + * This can be used to control visibility - an object must share a layer with a {@link Camera | camera} to be visible when that camera's view is rendered. + * @remarks + * All classes that inherit from {@link THREE.Object3D | Object3D} have an {@link THREE.Object3D.layers | Object3D.layers} property which is an instance of this class. + * @see Example: {@link https://threejs.org/examples/#webgl_layers | WebGL / layers} + * @see Example: {@link https://threejs.org/examples/#webxr_vr_layers | Webxr / vr / layers} + * @see {@link https://threejs.org/docs/index.html#api/en/core/Layers | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/Layers.js | Source} + */ +export class Layers { + /** + * Create a new Layers object, with membership initially set to layer 0. + */ + constructor(); + + /** + * A bit mask storing which of the 32 layers this layers object is currently a member of. + * @defaultValue `1 | 0` + * @remarks Expects a `Integer` + */ + mask: number; + + /** + * Set membership to `layer`, and remove membership all other layers. + * @param layer An integer from 0 to 31. + */ + set(layer: number): void; + + /** + * Add membership of this `layer`. + * @param layer An integer from 0 to 31. + */ + enable(layer: number): void; + + /** + * Add membership to all layers. + */ + enableAll(): void; + + /** + * Toggle membership of `layer`. + * @param layer An integer from 0 to 31. + */ + toggle(layer: number): void; + + /** + * Remove membership of this `layer`. + * @param layer An integer from 0 to 31. + */ + disable(layer: number): void; + + /** + * Remove membership from all layers. + */ + disableAll(): void; + + /** + * Returns true if this and the passed `layers` object have at least one layer in common. + * @param layers A Layers object + */ + test(layers: Layers): boolean; + + /** + * Returns true if the given layer is enabled. + * @param layer An integer from 0 to 31. + */ + isEnabled(layer: number): boolean; +} diff --git a/src-testing/src/core/Object3D.d.ts b/src-testing/src/core/Object3D.d.ts new file mode 100644 index 000000000..20bba57ce --- /dev/null +++ b/src-testing/src/core/Object3D.d.ts @@ -0,0 +1,674 @@ +import { AnimationClip, AnimationClipJSON } from "../animation/AnimationClip.js"; +import { Camera } from "../cameras/Camera.js"; +import { ShapeJSON } from "../extras/core/Shape.js"; +import { Material, MaterialJSON } from "../materials/Material.js"; +import { Euler } from "../math/Euler.js"; +import { Matrix3 } from "../math/Matrix3.js"; +import { Matrix4, Matrix4Tuple } from "../math/Matrix4.js"; +import { Quaternion } from "../math/Quaternion.js"; +import { Vector3, Vector3Tuple } from "../math/Vector3.js"; +import { Group } from "../objects/Group.js"; +import { SkeletonJSON } from "../objects/Skeleton.js"; +import { WebGLRenderer } from "../renderers/WebGLRenderer.js"; +import { Scene } from "../scenes/Scene.js"; +import { SourceJSON } from "../textures/Source.js"; +import { TextureJSON } from "../textures/Texture.js"; +import { BufferGeometry, BufferGeometryJSON } from "./BufferGeometry.js"; +import { EventDispatcher } from "./EventDispatcher.js"; +import { Layers } from "./Layers.js"; +import { Intersection, Raycaster } from "./Raycaster.js"; + +export interface Object3DJSONObject { + uuid: string; + type: string; + + name?: string; + castShadow?: boolean; + receiveShadow?: boolean; + visible?: boolean; + frustumCulled?: boolean; + renderOrder?: number; + userData?: Record; + + layers: number; + matrix: Matrix4Tuple; + up: Vector3Tuple; + + matrixAutoUpdate?: boolean; + + material?: string | string[]; + + children?: string[]; + + animations?: string[]; +} + +export interface Object3DJSON { + metadata?: { version: number; type: string; generator: string }; + object: Object3DJSONObject; +} + +export interface JSONMeta { + geometries: Record; + materials: Record; + textures: Record; + images: Record; + shapes: Record; + skeletons: Record; + animations: Record; + nodes: Record; +} + +export interface Object3DEventMap { + /** + * Fires when the object has been added to its parent object. + */ + added: {}; + + /** + * Fires when the object has been removed from its parent object. + */ + removed: {}; + + /** + * Fires when a new child object has been added. + */ + childadded: { child: Object3D }; + + /** + * Fires when a new child object has been removed. + */ + childremoved: { child: Object3D }; +} + +/** + * This is the base class for most objects in three.js and provides a set of properties and methods for manipulating objects in 3D space. + * @remarks Note that this can be used for grouping objects via the {@link THREE.Object3D.add | .add()} method which adds the object as a child, + * however it is better to use {@link THREE.Group | Group} for this. + * @see {@link https://threejs.org/docs/index.html#api/en/core/Object3D | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/Object3D.js | Source} + */ +export class Object3D extends EventDispatcher { + /** + * This creates a new {@link Object3D} object. + */ + constructor(); + + /** + * Flag to check if a given object is of type {@link Object3D}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isObject3D: true; + + /** + * Unique number for this {@link Object3D} instance. + * @remarks Note that ids are assigned in chronological order: 1, 2, 3, ..., incrementing by one for each new object. + * Expects a `Integer` + */ + readonly id: number; + + /** + * {@link http://en.wikipedia.org/wiki/Universally_unique_identifier | UUID} of this object instance. + * @remarks This gets automatically assigned and shouldn't be edited. + */ + uuid: string; + + /** + * Optional name of the object + * @remarks _(doesn't need to be unique)_. + * @defaultValue `""` + */ + name: string; + + /** + * A Read-only _string_ to check `this` object type. + * @remarks This can be used to find a specific type of Object3D in a scene. + * Sub-classes will update this value. + * @defaultValue `Object3D` + */ + readonly type: string; + + /** + * Object's parent in the {@link https://en.wikipedia.org/wiki/Scene_graph | scene graph}. + * @remarks An object can have at most one parent. + * @defaultValue `null` + */ + parent: Object3D | null; + + /** + * Array with object's children. + * @see {@link THREE.Object3DGroup | Group} for info on manually grouping objects. + * @defaultValue `[]` + */ + + children: Object3D[]; + + /** + * This is used by the {@link lookAt | lookAt} method, for example, to determine the orientation of the result. + * @defaultValue {@link DEFAULT_UP | Object3D.DEFAULT_UP} - that is `(0, 1, 0)`. + */ + up: Vector3; + + /** + * Object's local position. + * @defaultValue `new THREE.Vector3()` - that is `(0, 0, 0)`. + */ + readonly position: Vector3; + + /** + * Object's local rotation ({@link https://en.wikipedia.org/wiki/Euler_angles | Euler angles}), in radians. + * @defaultValue `new THREE.Euler()` - that is `(0, 0, 0, Euler.DEFAULT_ORDER)`. + */ + readonly rotation: Euler; + + /** + * Object's local rotation as a {@link THREE.Quaternion | Quaternion}. + * @defaultValue `new THREE.Quaternion()` - that is `(0, 0, 0, 1)`. + */ + readonly quaternion: Quaternion; + + /** + * The object's local scale. + * @defaultValue `new THREE.Vector3( 1, 1, 1 )` + */ + readonly scale: Vector3; + + /** + * @defaultValue `new THREE.Matrix4()` + */ + readonly modelViewMatrix: Matrix4; + + /** + * @defaultValue `new THREE.Matrix3()` + */ + readonly normalMatrix: Matrix3; + + /** + * The local transform matrix. + * @defaultValue `new THREE.Matrix4()` + */ + matrix: Matrix4; + + /** + * The global transform of the object. + * @remarks If the {@link Object3D} has no parent, then it's identical to the local transform {@link THREE.Object3D.matrix | .matrix}. + * @defaultValue `new THREE.Matrix4()` + */ + matrixWorld: Matrix4; + + /** + * When this is set, it calculates the matrix of position, (rotation or quaternion) and + * scale every frame and also recalculates the matrixWorld property. + * @defaultValue {@link DEFAULT_MATRIX_AUTO_UPDATE} - that is `(true)`. + */ + matrixAutoUpdate: boolean; + + /** + * If set, then the renderer checks every frame if the object and its children need matrix updates. + * When it isn't, then you have to maintain all matrices in the object and its children yourself. + * @defaultValue {@link DEFAULT_MATRIX_WORLD_AUTO_UPDATE} - that is `(true)`. + */ + matrixWorldAutoUpdate: boolean; + + /** + * When this is set, it calculates the matrixWorld in that frame and resets this property to false. + * @defaultValue `false` + */ + matrixWorldNeedsUpdate: boolean; + + /** + * The layer membership of the object. + * @remarks The object is only visible if it has at least one layer in common with the {@link THREE.Object3DCamera | Camera} in use. + * This property can also be used to filter out unwanted objects in ray-intersection tests when using {@link THREE.Raycaster | Raycaster}. + * @defaultValue `new THREE.Layers()` + */ + layers: Layers; + + /** + * Object gets rendered if `true`. + * @defaultValue `true` + */ + visible: boolean; + + /** + * Whether the object gets rendered into shadow map. + * @defaultValue `false` + */ + castShadow: boolean; + + /** + * Whether the material receives shadows. + * @defaultValue `false` + */ + receiveShadow: boolean; + + /** + * When this is set, it checks every frame if the object is in the frustum of the camera before rendering the object. + * If set to `false` the object gets rendered every frame even if it is not in the frustum of the camera. + * @defaultValue `true` + */ + frustumCulled: boolean; + + /** + * This value allows the default rendering order of {@link https://en.wikipedia.org/wiki/Scene_graph | scene graph} + * objects to be overridden although opaque and transparent objects remain sorted independently. + * @remarks When this property is set for an instance of {@link Group | Group}, all descendants objects will be sorted and rendered together. + * Sorting is from lowest to highest renderOrder. + * @defaultValue `0` + */ + renderOrder: number; + + /** + * Array with object's animation clips. + * @defaultValue `[]` + */ + animations: AnimationClip[]; + + /** + * An object that can be used to store custom data about the {@link Object3D}. + * @remarks It should not hold references to _functions_ as these **will not** be cloned. + * @default `{}` + */ + userData: Record; + + /** + * Custom depth material to be used when rendering to the depth map. + * @remarks Can only be used in context of meshes. + * When shadow-casting with a {@link THREE.DirectionalLight | DirectionalLight} or {@link THREE.SpotLight | SpotLight}, + * if you are modifying vertex positions in the vertex shader you must specify a customDepthMaterial for proper shadows. + * @defaultValue `undefined` + */ + customDepthMaterial?: Material | undefined; + + /** + * Same as {@link customDepthMaterial}, but used with {@link THREE.Object3DPointLight | PointLight}. + * @defaultValue `undefined` + */ + customDistanceMaterial?: Material | undefined; + + /** + * An optional callback that is executed immediately before a 3D object is rendered to a shadow map. + * @remarks This function is called with the following parameters: renderer, scene, camera, shadowCamera, geometry, + * depthMaterial, group. + * Please notice that this callback is only executed for `renderable` 3D objects. Meaning 3D objects which + * define their visual appearance with geometries and materials like instances of {@link Mesh}, {@link Line}, + * {@link Points} or {@link Sprite}. Instances of {@link Object3D}, {@link Group} or {@link Bone} are not renderable + * and thus this callback is not executed for such objects. + */ + onBeforeShadow( + renderer: WebGLRenderer, + scene: Scene, + camera: Camera, + shadowCamera: Camera, + geometry: BufferGeometry, + depthMaterial: Material, + group: Group, + ): void; + + /** + * An optional callback that is executed immediately after a 3D object is rendered to a shadow map. + * @remarks This function is called with the following parameters: renderer, scene, camera, shadowCamera, geometry, + * depthMaterial, group. + * Please notice that this callback is only executed for `renderable` 3D objects. Meaning 3D objects which + * define their visual appearance with geometries and materials like instances of {@link Mesh}, {@link Line}, + * {@link Points} or {@link Sprite}. Instances of {@link Object3D}, {@link Group} or {@link Bone} are not renderable + * and thus this callback is not executed for such objects. + */ + onAfterShadow( + renderer: WebGLRenderer, + scene: Scene, + camera: Camera, + shadowCamera: Camera, + geometry: BufferGeometry, + depthMaterial: Material, + group: Group, + ): void; + + /** + * An optional callback that is executed immediately before a 3D object is rendered. + * @remarks This function is called with the following parameters: renderer, scene, camera, geometry, material, group. + * Please notice that this callback is only executed for `renderable` 3D objects. Meaning 3D objects which + * define their visual appearance with geometries and materials like instances of {@link Mesh}, {@link Line}, + * {@link Points} or {@link Sprite}. Instances of {@link Object3D}, {@link Group} or {@link Bone} are not renderable + * and thus this callback is not executed for such objects. + */ + onBeforeRender( + renderer: WebGLRenderer, + scene: Scene, + camera: Camera, + geometry: BufferGeometry, + material: Material, + group: Group, + ): void; + + /** + * An optional callback that is executed immediately after a 3D object is rendered. + * @remarks This function is called with the following parameters: renderer, scene, camera, geometry, material, group. + * Please notice that this callback is only executed for `renderable` 3D objects. Meaning 3D objects which + * define their visual appearance with geometries and materials like instances of {@link Mesh}, {@link Line}, + * {@link Points} or {@link Sprite}. Instances of {@link Object3D}, {@link Group} or {@link Bone} are not renderable + * and thus this callback is not executed for such objects. + */ + onAfterRender( + renderer: WebGLRenderer, + scene: Scene, + camera: Camera, + geometry: BufferGeometry, + material: Material, + group: Group, + ): void; + + /** + * The default {@link up} direction for objects, also used as the default position for {@link THREE.DirectionalLight | DirectionalLight}, + * {@link THREE.HemisphereLight | HemisphereLight} and {@link THREE.Spotlight | Spotlight} (which creates lights shining from the top down). + * @defaultValue `new THREE.Vector3( 0, 1, 0)` + */ + static DEFAULT_UP: Vector3; + + /** + * The default setting for {@link matrixAutoUpdate} for newly created Object3Ds. + * @defaultValue `true` + */ + static DEFAULT_MATRIX_AUTO_UPDATE: boolean; + + /** + * The default setting for {@link matrixWorldAutoUpdate} for newly created Object3Ds. + * @defaultValue `true` + */ + static DEFAULT_MATRIX_WORLD_AUTO_UPDATE: boolean; + + /** + * Applies the matrix transform to the object and updates the object's position, rotation and scale. + * @param matrix + */ + applyMatrix4(matrix: Matrix4): void; + + /** + * Applies the rotation represented by the quaternion to the object. + * @param quaternion + */ + applyQuaternion(quaternion: Quaternion): this; + + /** + * Calls {@link THREE.Quaternion.setFromAxisAngle | setFromAxisAngle}({@link axis}, {@link angle}) on the {@link quaternion | .quaternion}. + * @param axis A normalized vector in object space. + * @param angle Angle in radians. Expects a `Float` + */ + setRotationFromAxisAngle(axis: Vector3, angle: number): void; + + /** + * Calls {@link THREE.Quaternion.setFromEuler | setFromEuler}({@link euler}) on the {@link quaternion | .quaternion}. + * @param euler Euler angle specifying rotation amount. + */ + setRotationFromEuler(euler: Euler): void; + + /** + * Calls {@link THREE.Quaternion.setFromRotationMatrix | setFromRotationMatrix}({@link m}) on the {@link quaternion | .quaternion}. + * @remarks Note that this assumes that the upper 3x3 of m is a pure rotation matrix (i.e, unscaled). + * @param m Rotate the quaternion by the rotation component of the matrix. + */ + setRotationFromMatrix(m: Matrix4): void; + + /** + * Copy the given {@link THREE.Quaternion | Quaternion} into {@link quaternion | .quaternion}. + * @param q Normalized Quaternion. + */ + setRotationFromQuaternion(q: Quaternion): void; + + /** + * Rotate an object along an axis in object space. + * @remarks The axis is assumed to be normalized. + * @param axis A normalized vector in object space. + * @param angle The angle in radians. Expects a `Float` + */ + rotateOnAxis(axis: Vector3, angle: number): this; + + /** + * Rotate an object along an axis in world space. + * @remarks The axis is assumed to be normalized + * Method Assumes no rotated parent. + * @param axis A normalized vector in world space. + * @param angle The angle in radians. Expects a `Float` + */ + rotateOnWorldAxis(axis: Vector3, angle: number): this; + + /** + * Rotates the object around _x_ axis in local space. + * @param rad The angle to rotate in radians. Expects a `Float` + */ + rotateX(angle: number): this; + + /** + * Rotates the object around _y_ axis in local space. + * @param rad The angle to rotate in radians. Expects a `Float` + */ + rotateY(angle: number): this; + + /** + * Rotates the object around _z_ axis in local space. + * @param rad The angle to rotate in radians. Expects a `Float` + */ + rotateZ(angle: number): this; + + /** + * Translate an object by distance along an axis in object space + * @remarks The axis is assumed to be normalized. + * @param axis A normalized vector in object space. + * @param distance The distance to translate. Expects a `Float` + */ + translateOnAxis(axis: Vector3, distance: number): this; + + /** + * Translates object along x axis in object space by {@link distance} units. + * @param distance Expects a `Float` + */ + translateX(distance: number): this; + + /** + * Translates object along _y_ axis in object space by {@link distance} units. + * @param distance Expects a `Float` + */ + translateY(distance: number): this; + + /** + * Translates object along _z_ axis in object space by {@link distance} units. + * @param distance Expects a `Float` + */ + translateZ(distance: number): this; + + /** + * Converts the vector from this object's local space to world space. + * @param vector A vector representing a position in this object's local space. + */ + localToWorld(vector: Vector3): Vector3; + + /** + * Converts the vector from world space to this object's local space. + * @param vector A vector representing a position in world space. + */ + worldToLocal(vector: Vector3): Vector3; + + /** + * Rotates the object to face a point in world space. + * @remarks This method does not support objects having non-uniformly-scaled parent(s). + * @param vector A vector representing a position in world space to look at. + */ + lookAt(vector: Vector3): void; + /** + * Rotates the object to face a point in world space. + * @remarks This method does not support objects having non-uniformly-scaled parent(s). + * @param x Expects a `Float` + * @param y Expects a `Float` + * @param z Expects a `Float` + */ + lookAt(x: number, y: number, z: number): void; + + /** + * Adds another {@link Object3D} as child of this {@link Object3D}. + * @remarks An arbitrary number of objects may be added + * Any current parent on an {@link object} passed in here will be removed, since an {@link Object3D} can have at most one parent. + * @see {@link attach} + * @see {@link THREE.Group | Group} for info on manually grouping objects. + * @param object + */ + add(...object: Object3D[]): this; + + /** + * Removes a {@link Object3D} as child of this {@link Object3D}. + * @remarks An arbitrary number of objects may be removed. + * @see {@link THREE.Group | Group} for info on manually grouping objects. + * @param object + */ + remove(...object: Object3D[]): this; + + /** + * Removes this object from its current parent. + */ + removeFromParent(): this; + + /** + * Removes all child objects. + */ + clear(): this; + + /** + * Adds a {@link Object3D} as a child of this, while maintaining the object's world transform. + * @remarks Note: This method does not support scene graphs having non-uniformly-scaled nodes(s). + * @see {@link add} + * @param object + */ + attach(object: Object3D): this; + + /** + * Searches through an object and its children, starting with the object itself, and returns the first with a matching id. + * @remarks Note that ids are assigned in chronological order: 1, 2, 3, ..., incrementing by one for each new object. + * @see {@link id} + * @param id Unique number of the object instance. Expects a `Integer` + */ + getObjectById(id: number): Object3D | undefined; + + /** + * Searches through an object and its children, starting with the object itself, and returns the first with a matching name. + * @remarks Note that for most objects the name is an empty string by default + * You will have to set it manually to make use of this method. + * @param name String to match to the children's Object3D.name property. + */ + getObjectByName(name: string): Object3D | undefined; + + /** + * Searches through an object and its children, starting with the object itself, + * and returns the first with a property that matches the value given. + * + * @param name - the property name to search for. + * @param value - value of the given property. + */ + getObjectByProperty(name: string, value: any): Object3D | undefined; + + /** + * Searches through an object and its children, starting with the object itself, + * and returns the first with a property that matches the value given. + * @param name The property name to search for. + * @param value Value of the given property. + * @param optionalTarget target to set the result. Otherwise a new Array is instantiated. If set, you must clear + * this array prior to each call (i.e., array.length = 0;). + */ + getObjectsByProperty(name: string, value: any, optionalTarget?: Object3D[]): Object3D[]; + + /** + * Returns a vector representing the position of the object in world space. + * @param target The result will be copied into this Vector3. + */ + getWorldPosition(target: Vector3): Vector3; + + /** + * Returns a quaternion representing the rotation of the object in world space. + * @param target The result will be copied into this Quaternion. + */ + getWorldQuaternion(target: Quaternion): Quaternion; + + /** + * Returns a vector of the scaling factors applied to the object for each axis in world space. + * @param target The result will be copied into this Vector3. + */ + getWorldScale(target: Vector3): Vector3; + + /** + * Returns a vector representing the direction of object's positive z-axis in world space. + * @param target The result will be copied into this Vector3. + */ + getWorldDirection(target: Vector3): Vector3; + + /** + * Abstract (empty) method to get intersections between a casted ray and this object + * @remarks Subclasses such as {@link THREE.Mesh | Mesh}, {@link THREE.Line | Line}, and {@link THREE.Points | Points} implement this method in order to use raycasting. + * @see {@link THREE.Raycaster | Raycaster} + * @param raycaster + * @param intersects + * @defaultValue `() => {}` + */ + raycast(raycaster: Raycaster, intersects: Intersection[]): void; + + /** + * Executes the callback on this object and all descendants. + * @remarks Note: Modifying the scene graph inside the callback is discouraged. + * @param callback A function with as first argument an {@link Object3D} object. + */ + traverse(callback: (object: Object3D) => any): void; + + /** + * Like traverse, but the callback will only be executed for visible objects + * @remarks Descendants of invisible objects are not traversed. + * Note: Modifying the scene graph inside the callback is discouraged. + * @param callback A function with as first argument an {@link Object3D} object. + */ + traverseVisible(callback: (object: Object3D) => any): void; + + /** + * Executes the callback on all ancestors. + * @remarks Note: Modifying the scene graph inside the callback is discouraged. + * @param callback A function with as first argument an {@link Object3D} object. + */ + traverseAncestors(callback: (object: Object3D) => any): void; + + /** + * Updates local transform. + */ + updateMatrix(): void; + + /** + * Updates the global transform of the object. + * And will update the object descendants if {@link matrixWorldNeedsUpdate | .matrixWorldNeedsUpdate} is set to true or if the {@link force} parameter is set to `true`. + * @param force A boolean that can be used to bypass {@link matrixWorldAutoUpdate | .matrixWorldAutoUpdate}, to recalculate the world matrix of the object and descendants on the current frame. + * Useful if you cannot wait for the renderer to update it on the next frame, assuming {@link matrixWorldAutoUpdate | .matrixWorldAutoUpdate} set to `true`. + */ + updateMatrixWorld(force?: boolean): void; + + /** + * Updates the global transform of the object. + * @param updateParents Recursively updates global transform of ancestors. + * @param updateChildren Recursively updates global transform of descendants. + */ + updateWorldMatrix(updateParents: boolean, updateChildren: boolean): void; + + /** + * Convert the object to three.js {@link https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 | JSON Object/Scene format}. + * @param meta Object containing metadata such as materials, textures or images for the object. + */ + toJSON(meta?: JSONMeta): Object3DJSON; + + /** + * Returns a clone of `this` object and optionally all descendants. + * @param recursive If true, descendants of the object are also cloned. Default `true` + */ + clone(recursive?: boolean): this; + + /** + * Copies the given object into this object. + * @remarks Event listeners and user-defined callbacks ({@link .onAfterRender} and {@link .onBeforeRender}) are not copied. + * @param object + * @param recursive If set to `true`, descendants of the object are copied next to the existing ones. If set to + * `false`, descendants are left unchanged. Default is `true`. + */ + copy(object: Object3D, recursive?: boolean): this; +} diff --git a/src-testing/src/core/Raycaster.d.ts b/src-testing/src/core/Raycaster.d.ts new file mode 100644 index 000000000..4b6d3746e --- /dev/null +++ b/src-testing/src/core/Raycaster.d.ts @@ -0,0 +1,208 @@ +import { Camera } from "../cameras/Camera.js"; +import { Ray } from "../math/Ray.js"; +import { Vector2 } from "../math/Vector2.js"; +import { Vector3 } from "../math/Vector3.js"; +import { XRTargetRaySpace } from "../renderers/webxr/WebXRController.js"; +import { Layers } from "./Layers.js"; +import { Object3D } from "./Object3D.js"; + +export interface Face { + a: number; + b: number; + c: number; + normal: Vector3; + materialIndex: number; +} + +export interface Intersection { + /** Distance between the origin of the ray and the intersection */ + distance: number; + distanceToRay?: number | undefined; + /** Point of intersection, in world coordinates */ + point: Vector3; + index?: number | undefined; + /** Intersected face */ + face?: Face | null | undefined; + /** Index of the intersected face */ + faceIndex?: number | null | undefined; + barycoord?: Vector3 | null; + /** The intersected object */ + object: TIntersected; + uv?: Vector2 | undefined; + uv1?: Vector2 | undefined; + normal?: Vector3; + /** The index number of the instance where the ray intersects the {@link THREE.InstancedMesh | InstancedMesh } */ + instanceId?: number | undefined; + pointOnLine?: Vector3; + batchId?: number; +} + +export interface RaycasterParameters { + Mesh: any; + Line: { threshold: number }; + Line2?: { threshold: number }; + LOD: any; + Points: { threshold: number }; + Sprite: any; +} + +/** + * This class is designed to assist with {@link https://en.wikipedia.org/wiki/Ray_casting | raycasting} + * @remarks + * Raycasting is used for mouse picking (working out what objects in the 3d space the mouse is over) amongst other things. + * @example + * ```typescript + * const raycaster = new THREE.Raycaster(); + * const pointer = new THREE.Vector2(); + * + * function onPointerMove(event) { + * // calculate pointer position in normalized device coordinates (-1 to +1) for both components + * pointer.x = (event.clientX / window.innerWidth) * 2 - 1; + * pointer.y = -(event.clientY / window.innerHeight) * 2 + 1; + * } + * + * function render() { + * // update the picking ray with the camera and pointer position + * raycaster.setFromCamera(pointer, camera); + * // calculate objects intersecting the picking ray + * const intersects = raycaster.intersectObjects(scene.children); + * for (let i = 0; i & lt; intersects.length; i++) { + * intersects[i].object.material.color.set(0xff0000); + * } + * renderer.render(scene, camera); + * } + * window.addEventListener('pointermove', onPointerMove); + * window.requestAnimationFrame(render); + * ``` + * @see Example: {@link https://threejs.org/examples/#webgl_interactive_cubes | Raycasting to a Mesh} + * @see Example: {@link https://threejs.org/examples/#webgl_interactive_cubes_ortho | Raycasting to a Mesh in using an OrthographicCamera} + * @see Example: {@link https://threejs.org/examples/#webgl_interactive_buffergeometry | Raycasting to a Mesh with BufferGeometry} + * @see Example: {@link https://threejs.org/examples/#webgl_instancing_raycast | Raycasting to a InstancedMesh} + * @see Example: {@link https://threejs.org/examples/#webgl_interactive_lines | Raycasting to a Line} + * @see Example: {@link https://threejs.org/examples/#webgl_interactive_raycasting_points | Raycasting to Points} + * @see Example: {@link https://threejs.org/examples/#webgl_geometry_terrain_raycast | Terrain raycasting} + * @see Example: {@link https://threejs.org/examples/#webgl_interactive_voxelpainter | Raycasting to paint voxels} + * @see Example: {@link https://threejs.org/examples/#webgl_raycaster_texture | Raycast to a Texture} + * @see {@link https://threejs.org/docs/index.html#api/en/core/Raycaster | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/Raycaster.js | Source} + */ +export class Raycaster { + /** + * This creates a new {@link Raycaster} object. + * @param origin The origin vector where the ray casts from. Default `new Vector3()` + * @param direction The direction vector that gives direction to the ray. Should be normalized. Default `new Vector3(0, 0, -1)` + * @param near All results returned are further away than near. Near can't be negative. Expects a `Float`. Default `0` + * @param far All results returned are closer than far. Far can't be lower than near. Expects a `Float`. Default `Infinity` + */ + constructor(origin?: Vector3, direction?: Vector3, near?: number, far?: number); + + /** + * The {@link THREE.RaycasterRay | Ray} used for the raycasting. + */ + ray: Ray; + + /** + * The near factor of the raycaster. This value indicates which objects can be discarded based on the distance. + * This value shouldn't be negative and should be smaller than the far property. + * @remarks Expects a `Float` + * @defaultValue `0` + */ + near: number; + + /** + * The far factor of the raycaster. This value indicates which objects can be discarded based on the distance. + * This value shouldn't be negative and should be larger than the near property. + * @remarks Expects a `Float` + * @defaultValue `Infinity` + */ + far: number; + + /** + * The camera to use when raycasting against view-dependent objects such as billboarded objects like {@link THREE.Sprites | Sprites}. + * This field can be set manually or is set when calling {@link setFromCamera}. + * @defaultValue `null` + */ + camera: Camera; + + /** + * Used by {@link Raycaster} to selectively ignore 3D objects when performing intersection tests. + * The following code example ensures that only 3D objects on layer `1` will be honored by the instance of Raycaster. + * ``` + * raycaster.layers.set( 1 ); + * object.layers.enable( 1 ); + * ``` + * @defaultValue `new THREE.Layers()` - See {@link THREE.Layers | Layers}. + */ + layers: Layers; + + /** + * An data object where threshold is the precision of the {@link Raycaster} when intersecting objects, in world units. + * @defaultValue `{ Mesh: {}, Line: { threshold: 1 }, LOD: {}, Points: { threshold: 1 }, Sprite: {} }` + */ + params: RaycasterParameters; + + /** + * Updates the ray with a new origin and direction + * @remarks + * Please note that this method only copies the values from the arguments. + * @param origin The origin vector where the ray casts from. + * @param direction The normalized direction vector that gives direction to the ray. + */ + set(origin: Vector3, direction: Vector3): void; + + /** + * Updates the ray with a new origin and direction. + * @param coords 2D coordinates of the mouse, in normalized device coordinates (NDC)---X and Y components should be between -1 and 1. + * @param camera camera from which the ray should originate + */ + setFromCamera(coords: Vector2, camera: Camera): void; + + /** + * Updates the ray with a new origin and direction. + * @param controller The controller to copy the position and direction from. + */ + setFromXRController(controller: XRTargetRaySpace): this; + + /** + * Checks all intersection between the ray and the object with or without the descendants + * @remarks Intersections are returned sorted by distance, closest first + * @remarks {@link Raycaster} delegates to the {@link Object3D.raycast | raycast} method of the passed object, when evaluating whether the ray intersects the object or not + * This allows {@link THREE.Mesh | meshes} to respond differently to ray casting than {@link THREE.Line | lines} and {@link THREE.Points | pointclouds}. + * **Note** that for meshes, faces must be pointed towards the origin of the {@link Raycaster.ray | ray} in order to be detected; + * intersections of the ray passing through the back of a face will not be detected + * To raycast against both faces of an object, you'll want to set the {@link Mesh.material | material}'s {@link Material.side | side} property to `THREE.DoubleSide`. + * @see {@link intersectObjects | .intersectObjects()}. + * @param object The object to check for intersection with the ray. + * @param recursive If true, it also checks all descendants. Otherwise it only checks intersection with the object. Default `true` + * @param optionalTarget Target to set the result. Otherwise a new {@link Array | Array} is instantiated. + * If set, you must clear this array prior to each call (i.e., array.length = 0;). Default `[]` + * @returns An array of intersections is returned. + */ + intersectObject( + object: Object3D, + recursive?: boolean, + optionalTarget?: Array>, + ): Array>; + + /** + * Checks all intersection between the ray and the objects with or without the descendants + * @remarks Intersections are returned sorted by distance, closest first + * @remarks Intersections are of the same form as those returned by {@link intersectObject | .intersectObject()}. + * @remarks {@link Raycaster} delegates to the {@link Object3D.raycast | raycast} method of the passed object, when evaluating whether the ray intersects the object or not + * This allows {@link THREE.Mesh | meshes} to respond differently to ray casting than {@link THREE.Line | lines} and {@link THREE.Points | pointclouds}. + * **Note** that for meshes, faces must be pointed towards the origin of the {@link Raycaster.ray | ray} in order to be detected; + * intersections of the ray passing through the back of a face will not be detected + * To raycast against both faces of an object, you'll want to set the {@link Mesh.material | material}'s {@link Material.side | side} property to `THREE.DoubleSide`. + * @see {@link intersectObject | .intersectObject()}. + * @param objects The objects to check for intersection with the ray. + * @param recursive If true, it also checks all descendants of the objects. Otherwise it only checks intersection with the objects. Default `true` + * @param optionalTarget Target to set the result. Otherwise a new {@link Array | Array} is instantiated. + * If set, you must clear this array prior to each call (i.e., array.length = 0;). Default `[]` + * @returns An array of intersections is returned. + */ + intersectObjects( + objects: Object3D[], + recursive?: boolean, + optionalTarget?: Array>, + ): Array>; +} diff --git a/src-testing/src/core/RenderTarget.d.ts b/src-testing/src/core/RenderTarget.d.ts new file mode 100644 index 000000000..2f20cabb5 --- /dev/null +++ b/src-testing/src/core/RenderTarget.d.ts @@ -0,0 +1,95 @@ +import { + MagnificationTextureFilter, + MinificationTextureFilter, + PixelFormatGPU, + TextureDataType, + Wrapping, +} from "../constants.js"; +import { Vector4 } from "../math/Vector4.js"; +import { DepthTexture } from "../textures/DepthTexture.js"; +import { Texture } from "../textures/Texture.js"; +import { EventDispatcher } from "./EventDispatcher.js"; + +export interface RenderTargetOptions { + wrapS?: Wrapping | undefined; + wrapT?: Wrapping | undefined; + magFilter?: MagnificationTextureFilter | undefined; + minFilter?: MinificationTextureFilter | undefined; + generateMipmaps?: boolean | undefined; // true + format?: number | undefined; // RGBAFormat + type?: TextureDataType | undefined; // UnsignedByteType + anisotropy?: number | undefined; // 1 + colorSpace?: string | undefined; + internalFormat?: PixelFormatGPU | null | undefined; // null + depthBuffer?: boolean | undefined; // true + stencilBuffer?: boolean | undefined; // false + resolveDepthBuffer?: boolean | undefined; // true + resolveStencilBuffer?: boolean | undefined; // true + depthTexture?: DepthTexture | null | undefined; // null + /** + * Defines the count of MSAA samples. Can only be used with WebGL 2. Default is **0**. + * @default 0 + */ + samples?: number | undefined; + count?: number | undefined; +} + +export class RenderTarget extends EventDispatcher<{ dispose: {} }> { + readonly isRenderTarget: true; + + width: number; + height: number; + depth: number; + + scissor: Vector4; + /** + * @default false + */ + scissorTest: boolean; + viewport: Vector4; + textures: TTexture[]; + + /** + * @default true + */ + depthBuffer: boolean; + + /** + * @default false + */ + stencilBuffer: boolean; + + /** + * Defines whether the depth buffer should be resolved when rendering into a multisampled render target. + * @default true + */ + resolveDepthBuffer: boolean; + + /** + * Defines whether the stencil buffer should be resolved when rendering into a multisampled render target. + * This property has no effect when {@link .resolveDepthBuffer} is set to `false`. + * @default true + */ + resolveStencilBuffer: boolean; + + /** + * @default null + */ + depthTexture: DepthTexture | null; + + /** + * Defines the count of MSAA samples. Can only be used with WebGL 2. Default is **0**. + * @default 0 + */ + samples: number; + + constructor(width?: number, height?: number, options?: RenderTargetOptions); + + get texture(): TTexture; + set texture(value: TTexture); + + setSize(width: number, height: number, depth?: number): void; + clone(): this; + copy(source: RenderTarget): this; + dispose(): void; +} diff --git a/src-testing/src/core/Uniform.d.ts b/src-testing/src/core/Uniform.d.ts new file mode 100644 index 000000000..851ae2bf9 --- /dev/null +++ b/src-testing/src/core/Uniform.d.ts @@ -0,0 +1,38 @@ +/** + * Uniforms are global GLSL variables. + * They are passed to shader programs. + * @example + * When declaring a uniform of a {@link THREE.ShaderMaterial | ShaderMaterial}, it is declared by value or by object. + * ```typescript + * uniforms: { + * time: { + * value: 1.0 + * }, + * resolution: new Uniform(new Vector2()) + * }; + * ``` + * @see Example: {@link https://threejs.org/examples/#webgl_nodes_materials_instance_uniform | WebGL2 / nodes / materials / instance / uniform} + * @see Example: {@link https://threejs.org/examples/#webgpu_instance_uniform| WebGPU / instance / uniform} + * @see {@link https://threejs.org/docs/index.html#api/en/core/Uniform | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/Uniform.js | Source} + */ +export class Uniform { + /** + * Create a new instance of {@link THREE.Uniform | Uniform} + * @param value An object containing the value to set up the uniform. It's type must be one of the Uniform Types described above. + */ + constructor(value: T); + + /** + * Current value of the uniform. + */ + value: T; + + /** + * Returns a clone of this uniform. + * @remarks + * If the uniform's {@link value} property is an {@link Object | Object} with a `clone()` method, this is used, + * otherwise the value is copied by assignment Array values are **shared** between cloned {@link THREE.UniformUniform | Uniform}s. + */ + clone(): Uniform; +} diff --git a/src-testing/src/core/UniformsGroup.d.ts b/src-testing/src/core/UniformsGroup.d.ts new file mode 100644 index 000000000..4fb30b2c1 --- /dev/null +++ b/src-testing/src/core/UniformsGroup.d.ts @@ -0,0 +1,33 @@ +import { Usage } from "../constants.js"; +import { EventDispatcher } from "./EventDispatcher.js"; +import { Uniform } from "./Uniform.js"; + +/** + * @see Example: {@link https://threejs.org/examples/#webgl2_ubo | WebGL2 / UBO} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/UniformsGroup.js | Source} + */ +export class UniformsGroup extends EventDispatcher<{ dispose: {} }> { + constructor(); + + readonly isUniformsGroup: true; + + id: number; + + usage: Usage; + + uniforms: Array; + + add(uniform: Uniform | Uniform[]): this; + + remove(uniform: Uniform | Uniform[]): this; + + setName(name: string): this; + + setUsage(value: Usage): this; + + dispose(): this; + + copy(source: UniformsGroup): this; + + clone(): UniformsGroup; +} diff --git a/src-testing/src/extras/Controls.d.ts b/src-testing/src/extras/Controls.d.ts new file mode 100644 index 000000000..6202a5c0c --- /dev/null +++ b/src-testing/src/extras/Controls.d.ts @@ -0,0 +1,54 @@ +import { EventDispatcher } from "../core/EventDispatcher.js"; +import { Object3D } from "../core/Object3D.js"; + +/** + * Abstract base class for controls. + */ +declare abstract class Controls extends EventDispatcher { + /** + * The 3D object that is managed by the controls. + */ + object: Object3D; + + /** + * The HTML element used for event listeners. If not provided via the constructor, {@link .connect} must be called + * after `domElement` has been set. + */ + domElement: HTMLElement | null; + + /** + * When set to `false`, the controls will not respond to user input. Default is `true`. + */ + enabled: boolean; + + /** + * Creates a new instance of {@link Controls}. + * @param object The object the controls should manage (usually the camera). + * @param domElement The HTML element used for event listeners. (optional) + */ + constructor(object: Object3D, domElement?: HTMLElement | null); + + /** + * Connects the controls to the DOM. This method has so called "side effects" since it adds the module's event + * listeners to the DOM. + */ + connect(): void; + + /** + * Disconnects the controls from the DOM. + */ + disconnect(): void; + + /** + * Call this method if you no longer want use to the controls. It frees all internal resources and removes all event + * listeners. + */ + dispose(): void; + + /** + * Controls should implement this method if they have to update their internal state per simulation step. + */ + update(delta: number): void; +} + +export { Controls }; diff --git a/src-testing/src/extras/DataUtils.d.ts b/src-testing/src/extras/DataUtils.d.ts new file mode 100644 index 000000000..fd678dbf4 --- /dev/null +++ b/src-testing/src/extras/DataUtils.d.ts @@ -0,0 +1,22 @@ +/** + * Returns a half precision floating point value from the given single precision floating point value. + * @param val A single precision floating point value. + * @see {@link https://threejs.org/docs/index.html#api/en/extras/DataUtils | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/DataUtils.js | Source} + */ +declare function toHalfFloat(val: number): number; + +/** + * Returns a single precision floating point value from the given half precision floating point value. + * @param val A half precision floating point value. + * @see {@link https://threejs.org/docs/index.html#api/en/extras/DataUtils | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/DataUtils.js | Source} + */ +declare function fromHalfFloat(val: number): number; + +declare const DataUtils: { + toHalfFloat: typeof toHalfFloat; + fromHalfFloat: typeof fromHalfFloat; +}; + +export { DataUtils, fromHalfFloat, toHalfFloat }; diff --git a/src-testing/src/extras/Earcut.d.ts b/src-testing/src/extras/Earcut.d.ts new file mode 100644 index 000000000..623b8ee82 --- /dev/null +++ b/src-testing/src/extras/Earcut.d.ts @@ -0,0 +1,15 @@ +/** + * An implementation of the {@link Earcut} polygon triangulation algorithm + * @remarks + * The code is a port of {@link https://github.com/mapbox/earcut | mapbox/earcut}. + * @see {@link https://threejs.org/docs/index.html#api/en/extras/Earcut | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/Earcut.js | Source} + */ +export const Earcut: { + /** + * Triangulates the given shape definition by returning an array of triangles + * @remarks + * A triangle is defined by three consecutive integers representing vertex indices. + */ + triangulate(data: number[], holeIndices?: number[], dim?: number): number[]; +}; diff --git a/src-testing/src/extras/ImageUtils.d.ts b/src-testing/src/extras/ImageUtils.d.ts new file mode 100644 index 000000000..798fc3e90 --- /dev/null +++ b/src-testing/src/extras/ImageUtils.d.ts @@ -0,0 +1,32 @@ +/** + * A class containing utility functions for images. + * @see {@link https://threejs.org/docs/index.html#api/en/extras/ImageUtils | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/ImageUtils.js | Source} + */ +declare class ImageUtils { + /** + * Returns a data URI containing a representation of the given image. + * @param image The image object. + */ + static getDataURL( + image: HTMLImageElement | HTMLCanvasElement | CanvasImageSource | ImageBitmap | ImageData, + ): string; + + /** + * Converts the given sRGB image data to linear color space. + * @param image + */ + static sRGBToLinear(image: HTMLImageElement | HTMLCanvasElement | ImageBitmap): HTMLCanvasElement; + + /** + * Converts the given sRGB image data to linear color space. + * @param image + */ + static sRGBToLinear(image: ImageData): { + data: ImageData["data"]; + width: ImageData["width"]; + height: ImageData["height"]; + }; +} + +export { ImageUtils }; diff --git a/src-testing/src/extras/PMREMGenerator.d.ts b/src-testing/src/extras/PMREMGenerator.d.ts new file mode 100644 index 000000000..3eb4a15e1 --- /dev/null +++ b/src-testing/src/extras/PMREMGenerator.d.ts @@ -0,0 +1,82 @@ +import { WebGLRenderer } from "../renderers/WebGLRenderer.js"; +import { WebGLRenderTarget } from "../renderers/WebGLRenderTarget.js"; +import { Scene } from "../scenes/Scene.js"; +import { CubeTexture } from "../textures/CubeTexture.js"; +import { Texture } from "../textures/Texture.js"; + +/** + * This class generates a Prefiltered, Mipmapped Radiance Environment Map (PMREM) from a cubeMap environment texture. + * @remarks + * This allows different levels of blur to be quickly accessed based on material roughness + * Unlike a traditional mipmap chain, it only goes down to the LOD_MIN level (above), and then creates extra even more filtered 'mips' at the same LOD_MIN resolution, + * associated with higher roughness levels + * In this way we maintain resolution to smoothly interpolate diffuse lighting while limiting sampling computation. + * @remarks + * Note: The minimum {@link THREE.MeshStandardMaterial | MeshStandardMaterial}'s roughness depends on the size of the provided texture + * If your render has small dimensions or the shiny parts have a lot of curvature, you may still be able to get away with a smaller texture size. + * + * | texture size | minimum roughness | + * |--------------|--------------------| + * | 16 | 0.21 | + * | 32 | 0.15 | + * | 64 | 0.11 | + * | 128 | 0.076 | + * | 256 | 0.054 | + * | 512 | 0.038 | + * | 1024 | 0.027 | + * + * @see {@link https://threejs.org/docs/index.html#api/en/extras/PMREMGenerator | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/PMREMGenerator.js | Source} + */ +export class PMREMGenerator { + /** + * This constructor creates a new PMREMGenerator. + * @param renderer + */ + constructor(renderer: WebGLRenderer); + + /** + * Generates a PMREM from a supplied Scene, which can be faster than using an image if networking bandwidth is low + * @remarks + * Optional near and far planes ensure the scene is rendered in its entirety (the cubeCamera is placed at the origin). + * @param scene The given scene. + * @param sigma Specifies a blur radius in radians to be applied to the scene before PMREM generation. Default `0`. + * @param near The near plane value. Default `0.1`. + * @param far The far plane value. Default `100`. + */ + fromScene(scene: Scene, sigma?: number, near?: number, far?: number): WebGLRenderTarget; + + /** + * Generates a PMREM from an equirectangular texture, which can be either LDR or HDR. The ideal input image size is + * 1k (1024 x 512), as this matches best with the 256 x 256 cubemap output. The smallest supported equirectangular + * image size is 64 x 32. + */ + fromEquirectangular(equirectangular: Texture, renderTarget?: WebGLRenderTarget | null): WebGLRenderTarget; + + /** + * Generates a PMREM from an cubemap texture, which can be either LDR or HDR. The ideal input cube size is + * 256 x 256, as this matches best with the 256 x 256 cubemap output. The smallest supported cube size is 16 x 16. + */ + fromCubemap(cubemap: CubeTexture, renderTarget?: WebGLRenderTarget | null): WebGLRenderTarget; + + /** + * Pre-compiles the cubemap shader + * @remarks + * You can get faster start-up by invoking this method during your texture's network fetch for increased concurrency. + */ + compileCubemapShader(): void; + + /** + * Pre-compiles the equirectangular shader + * @remarks + * You can get faster start-up by invoking this method during your texture's network fetch for increased concurrency. + */ + compileEquirectangularShader(): void; + + /** + * Frees the GPU-related resources allocated by this instance + * @remarks + * Call this method whenever this instance is no longer used in your app. + */ + dispose(): void; +} diff --git a/src-testing/src/extras/ShapeUtils.d.ts b/src-testing/src/extras/ShapeUtils.d.ts new file mode 100644 index 000000000..60fe8aaf9 --- /dev/null +++ b/src-testing/src/extras/ShapeUtils.d.ts @@ -0,0 +1,25 @@ +import { Vector2Like } from "../math/Vector2.js"; + +/** + * A class containing utility functions for shapes. + * @remarks Note that these are all linear functions so it is necessary to calculate separately for x, y (and z, w if present) components of a vector. + * @see {@link https://threejs.org/docs/index.html#api/en/extras/ShapeUtils | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/ShapeUtils.js | Source} + */ +export class ShapeUtils { + /** + * Calculate area of a ( 2D ) contour polygon. + */ + static area(contour: readonly Vector2Like[]): number; + + /** + * Note that this is a linear function so it is necessary to calculate separately for x, y components of a polygon. + * @remarks Used internally by {@link THREE.Path | Path}, {@link THREE.ExtrudeGeometry | ExtrudeGeometry} and {@link THREE.ShapeGeometry | ShapeGeometry}. + */ + static isClockWise(pts: readonly Vector2Like[]): boolean; + + /** + * Used internally by {@link THREE.ExtrudeGeometry | ExtrudeGeometry} and {@link THREE.ShapeGeometry | ShapeGeometry} to calculate faces in shapes with holes. + */ + static triangulateShape(contour: Vector2Like[], holes: Vector2Like[][]): number[][]; +} diff --git a/src-testing/src/extras/TextureUtils.d.ts b/src-testing/src/extras/TextureUtils.d.ts new file mode 100644 index 000000000..254458b43 --- /dev/null +++ b/src-testing/src/extras/TextureUtils.d.ts @@ -0,0 +1,42 @@ +import { CompressedPixelFormat, PixelFormat, TextureDataType } from "../constants.js"; +import { Texture } from "../textures/Texture.js"; + +/** + * Scales the texture as large as possible within its surface without cropping or stretching the texture. The method + * preserves the original aspect ratio of the texture. Akin to CSS `object-fit: contain`. + */ +declare function contain(texture: Texture, aspect: number): Texture; + +/** + * Scales the texture to the smallest possible size to fill the surface, leaving no empty space. The method preserves + * the original aspect ratio of the texture. Akin to CSS `object-fit: cover`. + */ +declare function cover(texture: Texture, aspect: number): Texture; + +/** + * Configures the texture to the default transformation. Akin to CSS `object-fit: fill`. + */ +declare function fill(texture: Texture): Texture; + +/** + * Given the width, height, format, and type of a texture. Determines how many bytes must be used to represent the + * texture. + */ +declare function getByteLength( + width: number, + height: number, + format: PixelFormat | CompressedPixelFormat, + type: TextureDataType, +): number; + +/** + * A class containing utility functions for textures. + */ +declare const TextureUtils: { + contain: typeof contain; + cover: typeof cover; + fill: typeof fill; + getByteLength: typeof getByteLength; +}; + +export { contain, cover, fill, getByteLength, TextureUtils }; diff --git a/src-testing/src/extras/core/Curve.d.ts b/src-testing/src/extras/core/Curve.d.ts new file mode 100644 index 000000000..9e3610903 --- /dev/null +++ b/src-testing/src/extras/core/Curve.d.ts @@ -0,0 +1,162 @@ +import { Vector2 } from "../../math/Vector2.js"; +import { Vector3 } from "../../math/Vector3.js"; + +export interface CurveJSON { + metadata: { version: number; type: string; generator: string }; + arcLengthDivisions: number; + type: string; +} + +/** + * An abstract base class for creating a {@link Curve} object that contains methods for interpolation + * @remarks + * For an array of Curves see {@link THREE.CurvePath | CurvePath}. + * @remarks + * This following curves inherit from THREE.Curve: + * + * **2D curves** + * - {@link THREE.ArcCurve} + * - {@link THREE.CubicBezierCurve} + * - {@link THREE.EllipseCurve} + * - {@link THREE.LineCurve} + * - {@link THREE.QuadraticBezierCurve} + * - {@link THREE.SplineCurve} + * + * **3D curves** + * - {@link THREE.CatmullRomCurve3} + * - {@link THREE.CubicBezierCurve3} + * - {@link THREE.LineCurve3} + * - {@link THREE.QuadraticBezierCurve3} + * + * @see {@link https://threejs.org/docs/index.html#api/en/extras/core/Curve | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/core/Curve.js | Source} + */ +export abstract class Curve { + protected constructor(); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `Curve` + */ + readonly type: string | "Curve"; + + /** + * This value determines the amount of divisions when calculating the cumulative segment lengths of a {@link Curve} + * via {@link .getLengths}. + * To ensure precision when using methods like {@link .getSpacedPoints}, it is recommended to increase {@link .arcLengthDivisions} if the {@link Curve} is very large. + * @defaultValue `200` + * @remarks Expects a `Integer` + */ + arcLengthDivisions: number; + + /** + * Returns a vector for a given position on the curve. + * @param t A position on the curve. Must be in the range `[ 0, 1 ]`. Expects a `Float` + * @param optionalTarget If specified, the result will be copied into this Vector, otherwise a new Vector will be created. Default `new T`. + */ + getPoint(t: number, optionalTarget?: TVector): TVector; + + /** + * Returns a vector for a given position on the {@link Curve} according to the arc length. + * @param u A position on the {@link Curve} according to the arc length. Must be in the range `[ 0, 1 ]`. Expects a `Float` + * @param optionalTarget If specified, the result will be copied into this Vector, otherwise a new Vector will be created. Default `new T`. + */ + getPointAt(u: number, optionalTarget?: TVector): TVector; + + /** + * Returns a set of divisions `+1` points using {@link .getPoint | getPoint(t)}. + * @param divisions Number of pieces to divide the {@link Curve} into. Expects a `Integer`. Default `5` + */ + getPoints(divisions?: number): TVector[]; + + /** + * Returns a set of divisions `+1` equi-spaced points using {@link .getPointAt | getPointAt(u)}. + * @param divisions Number of pieces to divide the {@link Curve} into. Expects a `Integer`. Default `5` + */ + getSpacedPoints(divisions?: number): TVector[]; + + /** + * Get total {@link Curve} arc length. + */ + getLength(): number; + + /** + * Get list of cumulative segment lengths. + * @param divisions Expects a `Integer` + */ + getLengths(divisions?: number): number[]; + + /** + * Update the cumulative segment distance cache + * @remarks + * The method must be called every time {@link Curve} parameters are changed + * If an updated {@link Curve} is part of a composed {@link Curve} like {@link THREE.CurvePath | CurvePath}, + * {@link .updateArcLengths}() must be called on the composed curve, too. + */ + updateArcLengths(): void; + + /** + * Given u in the range `[ 0, 1 ]`, + * @remarks + * `u` and `t` can then be used to give you points which are equidistant from the ends of the curve, using {@link .getPoint}. + * @param u Expects a `Float` + * @param distance Expects a `Float` + * @returns `t` also in the range `[ 0, 1 ]`. Expects a `Float`. + */ + getUtoTmapping(u: number, distance: number): number; + + /** + * Returns a unit vector tangent at t + * @remarks + * If the derived {@link Curve} does not implement its tangent derivation, two points a small delta apart will be used to find its gradient which seems to give a reasonable approximation. + * @param t A position on the curve. Must be in the range `[ 0, 1 ]`. Expects a `Float` + * @param optionalTarget If specified, the result will be copied into this Vector, otherwise a new Vector will be created. + */ + getTangent(t: number, optionalTarget?: TVector): TVector; + + /** + * Returns tangent at a point which is equidistant to the ends of the {@link Curve} from the point given in {@link .getTangent}. + * @param u A position on the {@link Curve} according to the arc length. Must be in the range `[ 0, 1 ]`. Expects a `Float` + * @param optionalTarget If specified, the result will be copied into this Vector, otherwise a new Vector will be created. + */ + getTangentAt(u: number, optionalTarget?: TVector): TVector; + + /** + * Generates the Frenet Frames + * @remarks + * Requires a {@link Curve} definition in 3D space + * Used in geometries like {@link THREE.TubeGeometry | TubeGeometry} or {@link THREE.ExtrudeGeometry | ExtrudeGeometry}. + * @param segments Expects a `Integer` + * @param closed + */ + computeFrenetFrames( + segments: number, + closed?: boolean, + ): { + tangents: Vector3[]; + normals: Vector3[]; + binormals: Vector3[]; + }; + + /** + * Creates a clone of this instance. + */ + clone(): this; + /** + * Copies another {@link Curve} object to this instance. + * @param source + */ + copy(source: Curve): this; + + /** + * Returns a JSON object representation of this instance. + */ + toJSON(): CurveJSON; + + /** + * Copies the data from the given JSON object to this instance. + * @param json + */ + fromJSON(json: CurveJSON): this; +} diff --git a/src-testing/src/extras/core/CurvePath.d.ts b/src-testing/src/extras/core/CurvePath.d.ts new file mode 100644 index 000000000..3a8577fd1 --- /dev/null +++ b/src-testing/src/extras/core/CurvePath.d.ts @@ -0,0 +1,77 @@ +import { Vector2 } from "../../math/Vector2.js"; +import { Vector3 } from "../../math/Vector3.js"; +import { Curve, CurveJSON } from "./Curve.js"; + +export interface CurvePathJSON extends CurveJSON { + autoClose: boolean; + curves: CurveJSON[]; +} + +/** + * Curved Path - a curve path is simply a array of connected curves, but retains the api of a curve. + * @remarks + * A {@link CurvePath} is simply an array of connected curves, but retains the api of a curve. + * @see {@link https://threejs.org/docs/index.html#api/en/extras/core/CurvePath | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/core/CurvePath.js | Source} + */ +export class CurvePath extends Curve { + /** + * The constructor take no parameters. + */ + constructor(); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `CurvePath` + */ + override readonly type: string | "CurvePath"; + + /** + * The array of {@link Curve | Curves}. + * @defaultValue `[]` + */ + curves: Array>; + + /** + * Whether or not to automatically close the path. + * @defaultValue false + */ + autoClose: boolean; + + /** + * Add a curve to the {@link .curves} array. + * @param curve + */ + add(curve: Curve): void; + /** + * Adds a {@link LineCurve | lineCurve} to close the path. + */ + closePath(): this; + + getPoint(t: number, optionalTarget?: TVector): TVector; + + /** + * Get list of cumulative curve lengths of the curves in the {@link .curves} array. + */ + getCurveLengths(): number[]; + + /** + * Returns an array of points representing a sequence of curves + * @remarks + * The `division` parameter defines the number of pieces each curve is divided into + * However, for optimization and quality purposes, the actual sampling resolution for each curve depends on its type + * For example, for a {@link THREE.LineCurve | LineCurve}, the returned number of points is always just 2. + * @param divisions Number of pieces to divide the curve into. Expects a `Integer`. Default `12` + */ + override getPoints(divisions?: number): TVector[]; + + /** + * Returns a set of divisions `+1` equi-spaced points using {@link .getPointAt | getPointAt(u)}. + * @param divisions Number of pieces to divide the curve into. Expects a `Integer`. Default `40` + */ + override getSpacedPoints(divisions?: number): TVector[]; + + toJSON(): CurvePathJSON; + fromJSON(json: CurvePathJSON): this; +} diff --git a/src-testing/src/extras/core/Interpolations.d.ts b/src-testing/src/extras/core/Interpolations.d.ts new file mode 100644 index 000000000..9f5ed3784 --- /dev/null +++ b/src-testing/src/extras/core/Interpolations.d.ts @@ -0,0 +1,36 @@ +/** + * Used internally by {@link THREE.SplineCurve | SplineCurve}. + * @param t Interpolation weight. Expects a `Float` + * @param p0 Expects a `Float` + * @param p1 Expects a `Float` + * @param p2 Expects a `Float` + * @param p3 P0, p1, p2, the points defining the spline curve. Expects a `Float` + * @see {@link https://threejs.org/docs/index.html#api/en/extras/core/Interpolations | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/core/Interpolations.js | Source} + */ +declare function CatmullRom(t: number, p0: number, p1: number, p2: number, p3: number): number; + +/** + * Used internally by {@link THREE.QuadraticBezierCurve3 | QuadraticBezierCurve3} and {@link THREE.QuadraticBezierCurve | QuadraticBezierCurve}. + * @param t Interpolation weight. Expects a `Float` + * @param p0 Expects a `Float` + * @param p1 Expects a `Float` + * @param p2 P0, p1, the starting, control and end points defining the curve. Expects a `Float` + * @see {@link https://threejs.org/docs/index.html#api/en/extras/core/Interpolations | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/core/Interpolations.js | Source} + */ +declare function QuadraticBezier(t: number, p0: number, p1: number, p2: number): number; + +/** + * Used internally by {@link THREE.CubicBezierCurve3 | CubicBezierCurve3} and {@link THREE.CubicBezierCurve | CubicBezierCurve}. + * @param t Interpolation weight. Expects a `Float` + * @param p0 Expects a `Float` + * @param p1 Expects a `Float` + * @param p2 Expects a `Float` + * @param p3 P0, p1, p2, the starting, control(twice) and end points defining the curve. Expects a `Float` + * @see {@link https://threejs.org/docs/index.html#api/en/extras/core/Interpolations | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/core/Interpolations.js | Source} + */ +declare function CubicBezier(t: number, p0: number, p1: number, p2: number, p3: number): number; + +export { CatmullRom, CubicBezier, QuadraticBezier }; diff --git a/src-testing/src/extras/core/Path.d.ts b/src-testing/src/extras/core/Path.d.ts new file mode 100644 index 000000000..28be15b9c --- /dev/null +++ b/src-testing/src/extras/core/Path.d.ts @@ -0,0 +1,166 @@ +import { Vector2, Vector2Tuple } from "../../math/Vector2.js"; +import { CurvePath, CurvePathJSON } from "./CurvePath.js"; + +export interface PathJSON extends CurvePathJSON { + currentPoint: Vector2Tuple; +} + +/** + * A 2D {@link Path} representation. + * @remarks + * The class provides methods for creating paths and contours of 2D shapes similar to the 2D Canvas API. + * @example + * ```typescript + * const {@link Path} = new THREE.Path(); + * path.lineTo(0, 0.8); + * path.quadraticCurveTo(0, 1, 0.2, 1); + * path.lineTo(1, 1); + * const points = path.getPoints(); + * const geometry = new THREE.BufferGeometry().setFromPoints(points); + * const material = new THREE.LineBasicMaterial({ + * color: 0xffffff + * }); + * const line = new THREE.Line(geometry, material); + * scene.add(line); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/extras/core/Path | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/core/Path.js | Source} + */ +export class Path extends CurvePath { + /** + * Creates a {@link Path} from the points + * @remarks + * The first point defines the offset, then successive points are added to the {@link CurvePath.curves | curves} array as {@link LineCurve | LineCurves}. + * If no points are specified, an empty {@link Path} is created and the {@link .currentPoint} is set to the origin. + * @param points Array of {@link Vector2 | Vector2s}. + */ + constructor(points?: Vector2[]); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `Path` + */ + override readonly type: string | "Path"; + + /** + * The current offset of the path. Any new {@link THREE.Curve | Curve} added will start here. + * @defaultValue `new THREE.Vector2()` + */ + currentPoint: Vector2; + + /** + * Adds an absolutely positioned {@link THREE.EllipseCurve | EllipseCurve} to the path. + * @param x Expects a `Float` + * @param y X, The absolute center of the arc. Expects a `Float` + * @param radius The radius of the arc. Expects a `Float` + * @param startAngle The start angle in radians. Expects a `Float` + * @param endAngle The end angle in radians. Expects a `Float` + * @param clockwise Sweep the arc clockwise. Default `false` + */ + absarc(aX: number, aY: number, aRadius: number, aStartAngle: number, aEndAngle: number, aClockwise?: boolean): this; + + /** + * Adds an absolutely positioned {@link THREE.EllipseCurve | EllipseCurve} to the path. + * @param x Expects a `Float` + * @param y X, The absolute center of the ellipse. Expects a `Float` + * @param xRadius The radius of the ellipse in the x axis. Expects a `Float` + * @param yRadius The radius of the ellipse in the y axis. Expects a `Float` + * @param startAngle The start angle in radians. Expects a `Float` + * @param endAngle The end angle in radians. Expects a `Float` + * @param clockwise Sweep the ellipse clockwise. Default `false` + * @param rotation The rotation angle of the ellipse in radians, counterclockwise from the positive X axis. Optional, Expects a `Float`. Default `0` + */ + absellipse( + aX: number, + aY: number, + xRadius: number, + yRadius: number, + aStartAngle: number, + aEndAngle: number, + aClockwise?: boolean, + aRotation?: number, + ): this; + + /** + * Adds an {@link THREE.EllipseCurve | EllipseCurve} to the path, positioned relative to {@link .currentPoint}. + * @param x Expects a `Float` + * @param y X, The center of the arc offset from the last call. Expects a `Float` + * @param radius The radius of the arc. Expects a `Float` + * @param startAngle The start angle in radians. Expects a `Float` + * @param endAngle The end angle in radians. Expects a `Float` + * @param clockwise Sweep the arc clockwise. Default `false` + */ + arc(aX: number, aY: number, aRadius: number, aStartAngle: number, aEndAngle: number, aClockwise?: boolean): this; + + /** + * This creates a bezier curve from {@link .currentPoint} with (cp1X, cp1Y) and (cp2X, cp2Y) as control points and updates {@link .currentPoint} to x and y. + * @param cp1X Expects a `Float` + * @param cp1Y Expects a `Float` + * @param cp2X Expects a `Float` + * @param cp2Y Expects a `Float` + * @param x Expects a `Float` + * @param y Expects a `Float` + */ + bezierCurveTo(aCP1x: number, aCP1y: number, aCP2x: number, aCP2y: number, aX: number, aY: number): this; + + /** + * Adds an {@link THREE.EllipseCurve | EllipseCurve} to the path, positioned relative to {@link .currentPoint}. + * @param x Expects a `Float` + * @param y X, The center of the ellipse offset from the last call. Expects a `Float` + * @param xRadius The radius of the ellipse in the x axis. Expects a `Float` + * @param yRadius The radius of the ellipse in the y axis. Expects a `Float` + * @param startAngle The start angle in radians. Expects a `Float` + * @param endAngle The end angle in radians. Expects a `Float` + * @param clockwise Sweep the ellipse clockwise. Default `false` + * @param rotation The rotation angle of the ellipse in radians, counterclockwise from the positive X axis. Optional, Expects a `Float`. Default `0` + */ + ellipse( + aX: number, + aY: number, + xRadius: number, + yRadius: number, + aStartAngle: number, + aEndAngle: number, + aClockwise?: boolean, + aRotation?: number, + ): this; + + /** + * Connects a {@link THREE.LineCurve | LineCurve} from {@link .currentPoint} to x, y onto the path. + * @param x Expects a `Float` + * @param y Expects a `Float` + */ + lineTo(x: number, y: number): this; + + /** + * Move the {@link .currentPoint} to x, y. + * @param x Expects a `Float` + * @param y Expects a `Float` + */ + moveTo(x: number, y: number): this; + + /** + * Creates a quadratic curve from {@link .currentPoint} with cpX and cpY as control point and updates {@link .currentPoint} to x and y. + * @param cpX Expects a `Float` + * @param cpY Expects a `Float` + * @param x Expects a `Float` + * @param y Expects a `Float` + */ + quadraticCurveTo(aCPx: number, aCPy: number, aX: number, aY: number): this; + + /** + * Points are added to the {@link CurvePath.curves | curves} array as {@link THREE.LineCurve | LineCurves}. + * @param vector2s + */ + setFromPoints(vectors: Vector2[]): this; + + /** + * Connects a new {@link THREE.SplineCurve | SplineCurve} onto the path. + * @param points An array of {@link Vector2 | Vector2's} + */ + splineThru(pts: Vector2[]): this; + + toJSON(): PathJSON; + fromJSON(json: PathJSON): this; +} diff --git a/src-testing/src/extras/core/Shape.d.ts b/src-testing/src/extras/core/Shape.d.ts new file mode 100644 index 000000000..84e5ff37f --- /dev/null +++ b/src-testing/src/extras/core/Shape.d.ts @@ -0,0 +1,86 @@ +import { Vector2 } from "../../math/Vector2.js"; +import { Path, PathJSON } from "./Path.js"; + +export interface ShapeJSON extends PathJSON { + uuid: string; + holes: PathJSON[]; +} + +/** + * Defines an arbitrary 2d {@link Shape} plane using paths with optional holes + * @remarks + * It can be used with {@link THREE.ExtrudeGeometry | ExtrudeGeometry}, {@link THREE.ShapeGeometry | ShapeGeometry}, to get points, or to get triangulated faces. + * @example + * ```typescript + * const heartShape = new THREE.Shape(); + * heartShape.moveTo(25, 25); + * heartShape.bezierCurveTo(25, 25, 20, 0, 0, 0); + * heartShape.bezierCurveTo(-30, 0, -30, 35, -30, 35); + * heartShape.bezierCurveTo(-30, 55, -10, 77, 25, 95); + * heartShape.bezierCurveTo(60, 77, 80, 55, 80, 35); + * heartShape.bezierCurveTo(80, 35, 80, 0, 50, 0); + * heartShape.bezierCurveTo(35, 0, 25, 25, 25, 25); + * const extrudeSettings = { + * depth: 8, + * bevelEnabled: true, + * bevelSegments: 2, + * steps: 2, + * bevelSize: 1, + * bevelThickness: 1 + * }; + * const geometry = new THREE.ExtrudeGeometry(heartShape, extrudeSettings); + * const mesh = new THREE.Mesh(geometry, new THREE.MeshPhongMaterial()); + * ``` + * @see Example: {@link https://threejs.org/examples/#webgl_geometry_shapes | geometry / shapes } + * @see Example: {@link https://threejs.org/examples/#webgl_geometry_extrude_shapes | geometry / extrude / shapes } + * @see Example: {@link https://threejs.org/examples/#webgl_geometry_extrude_shapes2 | geometry / extrude / shapes2 } + * @see {@link https://threejs.org/docs/index.html#api/en/extras/core/Shape | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/core/Shape.js | Source} + */ +export class Shape extends Path { + /** + * Creates a {@link Shape} from the points + * @remarks + * The first point defines the offset, then successive points are added to the {@link CurvePath.curves | curves} array as {@link THREE.LineCurve | LineCurves}. + * If no points are specified, an empty {@link Shape} is created and the {@link .currentPoint} is set to the origin. + * @param points Array of {@link Vector2 | Vector2s}. + */ + constructor(points?: Vector2[]); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `Shape` + */ + override readonly type: string | "Shape"; + + /** + * {@link http://en.wikipedia.org/wiki/Universally_unique_identifier | UUID} of this object instance. + * @remarks This gets automatically assigned and shouldn't be edited. + */ + uuid: string; + + /** + * An array of {@link Path | paths} that define the holes in the shape. + * @defaultValue `[]` + */ + holes: Path[]; + + /** + * Call {@link THREE.Curve.getPoints | getPoints} on the {@link Shape} and the {@link holes} array + * @param divisions The fineness of the result. Expects a `Integer` + */ + extractPoints(divisions: number): { + shape: Vector2[]; + holes: Vector2[][]; + }; + + /** + * Get an array of {@link Vector2 | Vector2's} that represent the holes in the shape. + * @param divisions The fineness of the result. Expects a `Integer` + */ + getPointsHoles(divisions: number): Vector2[][]; + + toJSON(): ShapeJSON; + fromJSON(json: ShapeJSON): this; +} diff --git a/src-testing/src/extras/core/ShapePath.d.ts b/src-testing/src/extras/core/ShapePath.d.ts new file mode 100644 index 000000000..0fcd88312 --- /dev/null +++ b/src-testing/src/extras/core/ShapePath.d.ts @@ -0,0 +1,98 @@ +import { Color } from "../../math/Color.js"; +import { Vector2 } from "../../math/Vector2.js"; +import { Path } from "./Path.js"; +import { Shape } from "./Shape.js"; + +/** + * This class is used to convert a series of shapes to an array of {@link THREE.Path | Path's}, + * for example an SVG shape to a path. + * @see {@link https://threejs.org/docs/index.html#api/en/extras/core/ShapePath | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/core/ShapePath.js | Source} + */ +export class ShapePath { + /** + * Creates a new {@link ShapePath} + * @remarks + * Unlike a {@link THREE.Path | Path}, no points are passed in as the {@link ShapePath} is designed to be generated after creation. + */ + constructor(); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `ShapePath` + */ + readonly type: "ShapePath"; + + /** + * Array of {@link THREE.Path | Path's}s. + * @defaultValue `[]` + */ + subPaths: Path[]; + + /** + * The current {@link THREE.Path | Path} that is being generated. + * @defaultValue `null` + */ + readonly currentPath: Path | null; + + /** + * {@link THREE.Color | Color} of the shape, by default set to white _(0xffffff)_. + * @defaultValue `new THREE.Color()` + */ + color: Color; + + /** + * Starts a new {@link THREE.Path | Path} and calls {@link THREE.Path.moveTo | Path.moveTo}( x, y ) on that {@link THREE.Path | Path} + * @remarks + * Also points {@link ShapePath.currentPath | currentPath} to that {@link THREE.Path | Path}. + * @param x Expects a `Float` + * @param y Expects a `Float` + */ + moveTo(x: number, y: number): this; + + /** + * This creates a line from the {@link ShapePath.currentPath | currentPath}'s offset to X and Y and updates the offset to X and Y. + * @param x Expects a `Float` + * @param y Expects a `Float` + */ + lineTo(x: number, y: number): this; + + /** + * This creates a quadratic curve from the {@link ShapePath.currentPath | currentPath}'s + * offset to _x_ and _y_ with _cpX_ and _cpY_ as control point and updates the {@link ShapePath.currentPath | currentPath}'s offset to _x_ and _y_. + * @param cpX Expects a `Float` + * @param cpY Expects a `Float` + * @param x Expects a `Float` + * @param y Expects a `Float` + */ + quadraticCurveTo(aCPx: number, aCPy: number, aX: number, aY: number): this; + + /** + * This creates a bezier curve from the {@link ShapePath.currentPath | currentPath}'s + * offset to _x_ and _y_ with _cp1X_, _cp1Y_ and _cp2X_, _cp2Y_ as control points and + * updates the {@link ShapePath.currentPath | currentPath}'s offset to _x_ and _y_. + * @param cp1X Expects a `Float` + * @param cp1Y Expects a `Float` + * @param cp2X Expects a `Float` + * @param cp2Y Expects a `Float` + * @param x Expects a `Float` + * @param y Expects a `Float` + */ + bezierCurveTo(aCP1x: number, aCP1y: number, aCP2x: number, aCP2y: number, aX: number, aY: number): this; + + /** + * Connects a new {@link THREE.SplineCurve | SplineCurve} onto the {@link ShapePath.currentPath | currentPath}. + * @param points An array of {@link THREE.Vector2 | Vector2}s + */ + splineThru(pts: Vector2[]): this; + + /** + * Converts the {@link ShapePath.subPaths | subPaths} array into an array of Shapes + * @remarks + * By default solid shapes are defined clockwise (CW) and holes are defined counterclockwise (CCW) + * If isCCW is set to true, then those are flipped. + * @param isCCW Changes how solids and holes are generated + */ + toShapes(isCCW: boolean): Shape[]; +} diff --git a/src-testing/src/extras/curves/ArcCurve.d.ts b/src-testing/src/extras/curves/ArcCurve.d.ts new file mode 100644 index 000000000..0932f7ffb --- /dev/null +++ b/src-testing/src/extras/curves/ArcCurve.d.ts @@ -0,0 +1,41 @@ +import { EllipseCurve } from "./EllipseCurve.js"; + +/** + * Alias for {@link THREE.EllipseCurve | EllipseCurve}. + * @see {@link https://threejs.org/docs/index.html#api/en/extras/curves/ArcCurve | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/curves/ArcCurve.js | Source} + */ +export class ArcCurve extends EllipseCurve { + /** + * This constructor creates a new {@link ArcCurve}. + * @param aX The X center of the ellipse. Expects a `Float`. Default is `0`. + * @param aY The Y center of the ellipse. Expects a `Float`. Default is `0`. + * @param xRadius The radius of the ellipse in the x direction. Expects a `Float`. Default is `1`. + * @param yRadius The radius of the ellipse in the y direction. Expects a `Float`. Default is `1`. + * @param aStartAngle The start angle of the curve in radians starting from the positive X axis. Default is `0`. + * @param aEndAngle The end angle of the curve in radians starting from the positive X axis. Default is `2 x Math.PI`. + * @param aClockwise Whether the ellipse is drawn clockwise. Default is `false`. + */ + constructor( + aX?: number, + aY?: number, + aRadius?: number, + aStartAngle?: number, + aEndAngle?: number, + aClockwise?: boolean, + ); + + /** + * Read-only flag to check if a given object is of type {@link ArcCurve}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isArcCurve = true; + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `ArcCurve` + */ + override readonly type: string | "ArcCurve"; +} diff --git a/src-testing/src/extras/curves/CatmullRomCurve3.d.ts b/src-testing/src/extras/curves/CatmullRomCurve3.d.ts new file mode 100644 index 000000000..55088e412 --- /dev/null +++ b/src-testing/src/extras/curves/CatmullRomCurve3.d.ts @@ -0,0 +1,77 @@ +import { Vector3 } from "../../math/Vector3.js"; +import { Curve } from "../core/Curve.js"; + +export type CurveType = "centripetal" | "chordal" | "catmullrom"; + +/** + * Create a smooth **3D** spline curve from a series of points using the {@link https://en.wikipedia.org/wiki/Centripetal_Catmull-Rom_spline | Catmull-Rom} algorithm. + * @example + * ```typescript + * //Create a closed wavey loop + * const curve = new THREE.CatmullRomCurve3([ + * new THREE.Vector3(-10, 0, 10), + * new THREE.Vector3(-5, 5, 5), + * new THREE.Vector3(0, 0, 0), + * new THREE.Vector3(5, -5, 5), + * new THREE.Vector3(10, 0, 10)]); + * const points = curve.getPoints(50); + * const geometry = new THREE.BufferGeometry().setFromPoints(points); + * const material = new THREE.LineBasicMaterial({ + * color: 0xff0000 + * }); + * // Create the final object to add to the scene + * const curveObject = new THREE.Line(geometry, material); + * ``` + * @see Example: {@link https://threejs.org/examples/#webgl_geometry_extrude_splines | WebGL / geometry / extrude / splines} + * @see {@link https://threejs.org/docs/index.html#api/en/extras/curves/CatmullRomCurve3 | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/curves/CatmullRomCurve3.js | Source} + */ +export class CatmullRomCurve3 extends Curve { + /** + * This constructor creates a new {@link CatmullRomCurve3}. + * @param points An array of {@link THREE.Vector3 | Vector3} points + * @param closed Whether the curve is closed. Default `false` + * @param curveType Type of the curve. Default `centripetal` + * @param tension Tension of the curve. Expects a `Float`. Default `0.5` + */ + constructor(points?: Vector3[], closed?: boolean, curveType?: CurveType, tension?: number); + + /** + * Read-only flag to check if a given object is of type {@link CatmullRomCurve3}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isCatmullRomCurve3 = true; + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `CatmullRomCurve3` + */ + override readonly type: string | "CatmullRomCurve3"; + + /** + * The curve will loop back onto itself when this is true. + * @defaultValue `false` + */ + closed: boolean; + + /** + * The array of {@link THREE.Vector3 | Vector3} points that define the curve. + * @remarks It needs at least two entries. + * @defaultValue `[]` + */ + points: Vector3[]; + + /** + * Possible values are `centripetal`, `chordal` and `catmullrom`. + * @defaultValue `centripetal` + */ + curveType: CurveType; + + /** + * When {@link .curveType} is `catmullrom`, defines catmullrom's tension. + * @remarks Expects a `Float` + */ + tension: number; +} diff --git a/src-testing/src/extras/curves/CubicBezierCurve.d.ts b/src-testing/src/extras/curves/CubicBezierCurve.d.ts new file mode 100644 index 000000000..ae4518312 --- /dev/null +++ b/src-testing/src/extras/curves/CubicBezierCurve.d.ts @@ -0,0 +1,72 @@ +import { Vector2 } from "../../math/Vector2.js"; +import { Curve } from "../core/Curve.js"; + +/** + * Create a smooth **2D** {@link http://en.wikipedia.org/wiki/B%C3%A9zier_curve#mediaviewer/File:Bezier_curve.svg | cubic bezier curve}, + * defined by a start point, endpoint and two control points. + * @example + * ```typescript + * const curve = new THREE.CubicBezierCurve( + * new THREE.Vector2(-10, 0), + * new THREE.Vector2(-5, 15), + * new THREE.Vector2(20, 15), + * new THREE.Vector2(10, 0)); + * const points = curve.getPoints(50); + * const geometry = new THREE.BufferGeometry().setFromPoints(points); + * const material = new THREE.LineBasicMaterial({ + * color: 0xff0000 + * }); + * // Create the final object to add to the scene + * const curveObject = new THREE.Line(geometry, material); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/extras/curves/CubicBezierCurve | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/curves/CubicBezierCurve.js | Source} + */ +export class CubicBezierCurve extends Curve { + /** + * This constructor creates a new {@link CubicBezierCurve}. + * @param v0 The starting point. Default is `new THREE.Vector2()`. + * @param v1 The first control point. Default is `new THREE.Vector2()`. + * @param v2 The second control point. Default is `new THREE.Vector2()`. + * @param v3 The ending point. Default is `new THREE.Vector2()`. + */ + constructor(v0?: Vector2, v1?: Vector2, v2?: Vector2, v3?: Vector2); + + /** + * Read-only flag to check if a given object is of type {@link CubicBezierCurve}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isCubicBezierCurve = true; + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `CubicBezierCurve` + */ + override readonly type: string | "CubicBezierCurve"; + + /** + * The starting point. + * @defaultValue `new THREE.Vector2()` + */ + v0: Vector2; + + /** + * The first control point. + * @defaultValue `new THREE.Vector2()` + */ + v1: Vector2; + + /** + * The second control point. + * @defaultValue `new THREE.Vector2()` + */ + v2: Vector2; + + /** + * The ending point. + * @defaultValue `new THREE.Vector2()` + */ + v3: Vector2; +} diff --git a/src-testing/src/extras/curves/CubicBezierCurve3.d.ts b/src-testing/src/extras/curves/CubicBezierCurve3.d.ts new file mode 100644 index 000000000..ad8edb356 --- /dev/null +++ b/src-testing/src/extras/curves/CubicBezierCurve3.d.ts @@ -0,0 +1,72 @@ +import { Vector3 } from "../../math/Vector3.js"; +import { Curve } from "../core/Curve.js"; + +/** + * Create a smooth **3D** {@link http://en.wikipedia.org/wiki/B%C3%A9zier_curve#mediaviewer/File:Bezier_curve.svg | cubic bezier curve}, + * defined by a start point, endpoint and two control points. + * @example + * ```typescript + * const curve = new THREE.CubicBezierCurve( + * new THREE.Vector2(-10, 0), + * new THREE.Vector2(-5, 15), + * new THREE.Vector2(20, 15), + * new THREE.Vector2(10, 0)); + * const points = curve.getPoints(50); + * const geometry = new THREE.BufferGeometry().setFromPoints(points); + * const material = new THREE.LineBasicMaterial({ + * color: 0xff0000 + * }); + * // Create the final object to add to the scene + * const curveObject = new THREE.Line(geometry, material); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/extras/curves/CubicBezierCurve | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/curves/CubicBezierCurve.js | Source} + */ +export class CubicBezierCurve3 extends Curve { + /** + * This constructor creates a new {@link CubicBezierCurve3}. + * @param v0 The starting point. Default is `new THREE.Vector3()`. + * @param v1 The first control point. Default is `new THREE.Vector3()`. + * @param v2 The second control point. Default is `new THREE.Vector3()`. + * @param v3 The ending point. Default is `new THREE.Vector3()`. + */ + constructor(v0?: Vector3, v1?: Vector3, v2?: Vector3, v3?: Vector3); + + /** + * Read-only flag to check if a given object is of type {@link CubicBezierCurve3}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isCubicBezierCurve3 = true; + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `CubicBezierCurve3` + */ + override readonly type: string | "CubicBezierCurve3"; + + /** + * The starting point. + * @defaultValue `new THREE.Vector3()`. + */ + v0: Vector3; + + /** + * The first control point. + * @defaultValue `new THREE.Vector3()`. + */ + v1: Vector3; + + /** + * The second control point. + * @defaultValue `new THREE.Vector3()`. + */ + v2: Vector3; + + /** + * The ending point. + * @defaultValue `new THREE.Vector3()`. + */ + v3: Vector3; +} diff --git a/src-testing/src/extras/curves/Curves.d.ts b/src-testing/src/extras/curves/Curves.d.ts new file mode 100644 index 000000000..996021d72 --- /dev/null +++ b/src-testing/src/extras/curves/Curves.d.ts @@ -0,0 +1,10 @@ +export * from "./ArcCurve.js"; +export * from "./CatmullRomCurve3.js"; +export * from "./CubicBezierCurve.js"; +export * from "./CubicBezierCurve3.js"; +export * from "./EllipseCurve.js"; +export * from "./LineCurve.js"; +export * from "./LineCurve3.js"; +export * from "./QuadraticBezierCurve.js"; +export * from "./QuadraticBezierCurve3.js"; +export * from "./SplineCurve.js"; diff --git a/src-testing/src/extras/curves/EllipseCurve.d.ts b/src-testing/src/extras/curves/EllipseCurve.d.ts new file mode 100644 index 000000000..4d15ca8c2 --- /dev/null +++ b/src-testing/src/extras/curves/EllipseCurve.d.ts @@ -0,0 +1,115 @@ +import { Vector2 } from "../../math/Vector2.js"; +import { Curve } from "../core/Curve.js"; + +/** + * Creates a 2d curve in the shape of an ellipse + * @remarks + * Setting the {@link xRadius} equal to the {@link yRadius} will result in a circle. + * @example + * ```typescript + * const curve = new THREE.EllipseCurve( + * 0, 0, // ax, aY + * 10, 10, // xRadius, yRadius + * 0, 2 * Math.PI, // aStartAngle, aEndAngle + * false, // aClockwise + * 0 // aRotation + * ); + * const points = curve.getPoints(50); + * const geometry = new THREE.BufferGeometry().setFromPoints(points); + * const material = new THREE.LineBasicMaterial({ color: 0xff0000 }); + * // Create the final object to add to the scene + * const ellipse = new THREE.Line(geometry, material); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/extras/curves/EllipseCurve | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/curves/EllipseCurve.js | Source} + */ +export class EllipseCurve extends Curve { + /** + * This constructor creates a new {@link EllipseCurve}. + * @param aX The X center of the ellipse. Expects a `Float`. Default is `0`. + * @param aY The Y center of the ellipse. Expects a `Float`. Default is `0`. + * @param xRadius The radius of the ellipse in the x direction. Expects a `Float`. Default is `1`. + * @param yRadius The radius of the ellipse in the y direction. Expects a `Float`. Default is `1`. + * @param aStartAngle The start angle of the curve in radians starting from the positive X axis. Default is `0`. + * @param aEndAngle The end angle of the curve in radians starting from the positive X axis. Default is `2 x Math.PI`. + * @param aClockwise Whether the ellipse is drawn clockwise. Default is `false`. + * @param aRotation The rotation angle of the ellipse in radians, counterclockwise from the positive X axis. Default is `0`. + */ + constructor( + aX?: number, + aY?: number, + xRadius?: number, + yRadius?: number, + aStartAngle?: number, + aEndAngle?: number, + aClockwise?: boolean, + aRotation?: number, + ); + + /** + * Read-only flag to check if a given object is of type {@link EllipseCurve}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isEllipseCurve = true; + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `EllipseCurve` + */ + override readonly type: string | "EllipseCurve"; + + /** + * The X center of the ellipse. + * @remarks Expects a `Float` + * @defaultValue `0` + */ + aX: number; + + /** + * The Y center of the ellipse. + * @remarks Expects a `Float` + * @defaultValue `0` + */ + aY: number; + + /** + * The radius of the ellipse in the x direction. + * @defaultValue `1` + */ + xRadius: number; + + /** + * The radius of the ellipse in the y direction. + * @defaultValue `1` + */ + yRadius: number; + + /** + * The start angle of the curve in radians starting from the middle right side. + * @remarks Expects a `Float` + * @defaultValue `0` + */ + aStartAngle: number; + + /** + * The end angle of the curve in radians starting from the middle right side. + * @remarks Expects a `Float` + * @defaultValue `2 * Math.PI` + */ + aEndAngle: number; + + /** + * Whether the ellipse is drawn clockwise. + * @defaultValue `false`` + */ + aClockwise: boolean; + + /** + * The rotation angle of the ellipse in radians, counterclockwise from the positive X axis (optional). + * @remarks Expects a `Float` + * @defaultValue `0` + */ + aRotation: number; +} diff --git a/src-testing/src/extras/curves/LineCurve.d.ts b/src-testing/src/extras/curves/LineCurve.d.ts new file mode 100644 index 000000000..3bcb000d3 --- /dev/null +++ b/src-testing/src/extras/curves/LineCurve.d.ts @@ -0,0 +1,42 @@ +import { Vector2 } from "../../math/Vector2.js"; +import { Curve } from "../core/Curve.js"; + +/** + * A curve representing a **2D** line segment. + * @see {@link https://threejs.org/docs/index.html#api/en/extras/curves/LineCurve | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/curves/LineCurve.js | Source} + */ +export class LineCurve extends Curve { + /** + * This constructor creates a new {@link LineCurve}. + * @param v1 The start point. Default is `new THREE.Vector2()`. + * @param v2 The end point. Default is `new THREE.Vector2()`. + */ + constructor(v1?: Vector2, v2?: Vector2); + + /** + * Read-only flag to check if a given object is of type {@link LineCurve}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isLineCurve = true; + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `LineCurve` + */ + override readonly type: string | "LineCurve"; + + /** + * The start point. + * @defaultValue `new THREE.Vector2()` + */ + v1: Vector2; + + /** + * The end point + * @defaultValue `new THREE.Vector2()` + */ + v2: Vector2; +} diff --git a/src-testing/src/extras/curves/LineCurve3.d.ts b/src-testing/src/extras/curves/LineCurve3.d.ts new file mode 100644 index 000000000..c7ae7c301 --- /dev/null +++ b/src-testing/src/extras/curves/LineCurve3.d.ts @@ -0,0 +1,42 @@ +import { Vector3 } from "../../math/Vector3.js"; +import { Curve } from "../core/Curve.js"; + +/** + * A curve representing a **3D** line segment. + * @see {@link https://threejs.org/docs/index.html#api/en/extras/curves/LineCurve3 | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/curves/LineCurve3.js | Source} + */ +export class LineCurve3 extends Curve { + /** + * This constructor creates a new {@link LineCurve3}. + * @param v1 The start point. Default is `new THREE.Vector3()`. + * @param v2 The end point. Default is `new THREE.Vector3()`. + */ + constructor(v1?: Vector3, v2?: Vector3); + + /** + * Read-only flag to check if a given object is of type {@link LineCurve3}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isLineCurve3 = true; + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `LineCurve3` + */ + override readonly type: string | "LineCurve3"; + + /** + * The start point. + * @defaultValue `new THREE.Vector3()`. + */ + v1: Vector3; + + /** + * The end point. + * @defaultValue `new THREE.Vector3()`. + */ + v2: Vector3; +} diff --git a/src-testing/src/extras/curves/QuadraticBezierCurve.d.ts b/src-testing/src/extras/curves/QuadraticBezierCurve.d.ts new file mode 100644 index 000000000..8ae4c3213 --- /dev/null +++ b/src-testing/src/extras/curves/QuadraticBezierCurve.d.ts @@ -0,0 +1,64 @@ +import { Vector2 } from "../../math/Vector2.js"; +import { Curve } from "../core/Curve.js"; + +/** + * Create a smooth **2D** {@link http://en.wikipedia.org/wiki/B%C3%A9zier_curve#mediaviewer/File:B%C3%A9zier_2_big.gif | quadratic bezier curve}, + * defined by a start point, end point and a single control point. + * @example + * ```typescript + * const curve = new THREE.QuadraticBezierCurve( + * new THREE.Vector2(-10, 0), + * new THREE.Vector2(20, 15), + * new THREE.Vector2(10, 0)); + * const points = curve.getPoints(50); + * const geometry = new THREE.BufferGeometry().setFromPoints(points); + * const material = new THREE.LineBasicMaterial({ + * color: 0xff0000 + * }); + * // Create the final object to add to the scene + * const curveObject = new THREE.Line(geometry, material); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/extras/curves/QuadraticBezierCurve | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/curves/QuadraticBezierCurve.js | Source} + */ +export class QuadraticBezierCurve extends Curve { + /** + * This constructor creates a new {@link QuadraticBezierCurve}. + * @param v0 The start point. Default is `new THREE.Vector2()`. + * @param v1 The control point. Default is `new THREE.Vector2()`. + * @param v2 The end point. Default is `new THREE.Vector2()`. + */ + constructor(v0?: Vector2, v1?: Vector2, v2?: Vector2); + + /** + * Read-only flag to check if a given object is of type {@link LineCurve3}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isQuadraticBezierCurve = true; + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `QuadraticBezierCurve` + */ + override readonly type: string | "QuadraticBezierCurve"; + + /** + * The start point. + * @defaultValue `new THREE.Vector2()` + */ + v0: Vector2; + + /** + * The control point. + * @defaultValue `new THREE.Vector2()` + */ + v1: Vector2; + + /** + * The end point. + * @defaultValue `new THREE.Vector2()` + */ + v2: Vector2; +} diff --git a/src-testing/src/extras/curves/QuadraticBezierCurve3.d.ts b/src-testing/src/extras/curves/QuadraticBezierCurve3.d.ts new file mode 100644 index 000000000..3964af820 --- /dev/null +++ b/src-testing/src/extras/curves/QuadraticBezierCurve3.d.ts @@ -0,0 +1,64 @@ +import { Vector3 } from "../../math/Vector3.js"; +import { Curve } from "../core/Curve.js"; + +/** + * Create a smooth **3D** {@link http://en.wikipedia.org/wiki/B%C3%A9zier_curve#mediaviewer/File:B%C3%A9zier_2_big.gif | quadratic bezier curve}, + * defined by a start point, end point and a single control point. + * @example + * ```typescript + * const curve = new THREE.QuadraticBezierCurve3( + * new THREE.Vector3(-10, 0, 0), + * new THREE.Vector3(20, 15, 0), + * new THREE.Vector3(10, 0, 0)); + * const points = curve.getPoints(50); + * const geometry = new THREE.BufferGeometry().setFromPoints(points); + * const material = new THREE.LineBasicMaterial({ + * color: 0xff0000 + * }); + * // Create the final object to add to the scene + * const curveObject = new THREE.Line(geometry, material); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/extras/curves/QuadraticBezierCurve3 | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/curves/QuadraticBezierCurve3.js | Source} + */ +export class QuadraticBezierCurve3 extends Curve { + /** + * This constructor creates a new {@link QuadraticBezierCurve}. + * @param v0 The start point. Default is `new THREE.Vector3()`. + * @param v1 The control point. Default is `new THREE.Vector3()`. + * @param v2 The end point. Default is `new THREE.Vector3()`. + */ + constructor(v0?: Vector3, v1?: Vector3, v2?: Vector3); + + /** + * Read-only flag to check if a given object is of type {@link QuadraticBezierCurve3}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isQuadraticBezierCurve3 = true; + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `QuadraticBezierCurve3` + */ + override readonly type: string | "QuadraticBezierCurve3"; + + /** + * The start point. + * @defaultValue `new THREE.Vector3()` + */ + v0: Vector3; + + /** + * The control point. + * @defaultValue `new THREE.Vector3()` + */ + v1: Vector3; + + /** + * The end point. + * @defaultValue `new THREE.Vector3()` + */ + v2: Vector3; +} diff --git a/src-testing/src/extras/curves/SplineCurve.d.ts b/src-testing/src/extras/curves/SplineCurve.d.ts new file mode 100644 index 000000000..c3c56210a --- /dev/null +++ b/src-testing/src/extras/curves/SplineCurve.d.ts @@ -0,0 +1,52 @@ +import { Vector2 } from "../../math/Vector2.js"; +import { Curve } from "../core/Curve.js"; + +/** + * Create a smooth **2D** spline curve from a series of points. + * @example + * ```typescript + * // Create a sine-like wave + * const curve = new THREE.SplineCurve([ + * new THREE.Vector2(-10, 0), + * new THREE.Vector2(-5, 5), + * new THREE.Vector2(0, 0), + * new THREE.Vector2(5, -5), + * new THREE.Vector2(10, 0)]); + * const points = curve.getPoints(50); + * const geometry = new THREE.BufferGeometry().setFromPoints(points); + * const material = new THREE.LineBasicMaterial({ + * color: 0xff0000 + * }); + * // Create the final object to add to the scene + * const splineObject = new THREE.Line(geometry, material); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/extras/curves/SplineCurve | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/curves/SplineCurve.js | Source} + */ +export class SplineCurve extends Curve { + /** + * This constructor creates a new {@link SplineCurve}. + * @param points An array of {@link THREE.Vector2 | Vector2} points that define the curve. Default `[]` + */ + constructor(points?: Vector2[]); + + /** + * Read-only flag to check if a given object is of type {@link SplineCurve}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isSplineCurve = true; + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `SplineCurve` + */ + override readonly type: string | "SplineCurve"; + + /** + * The array of {@link THREE.Vector2 | Vector2} points that define the curve. + * @defaultValue `[]` + */ + points: Vector2[]; +} diff --git a/src-testing/src/geometries/BoxGeometry.d.ts b/src-testing/src/geometries/BoxGeometry.d.ts new file mode 100644 index 000000000..7a756ae56 --- /dev/null +++ b/src-testing/src/geometries/BoxGeometry.d.ts @@ -0,0 +1,59 @@ +import { BufferGeometry } from "../core/BufferGeometry.js"; + +/** + * {@link BoxGeometry} is a geometry class for a rectangular cuboid with a given 'width', 'height', and 'depth' + * @remarks On creation, the cuboid is centred on the origin, with each edge parallel to one of the axes. + * @example + * ```typescript + * const geometry = new THREE.BoxGeometry(1, 1, 1); + * const material = new THREE.MeshBasicMaterial({ + * color: 0x00ff00 + * }); + * const cube = new THREE.Mesh(geometry, material); + * scene.add(cube); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/geometries/BoxGeometry | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/BoxGeometry.js | Source} + */ +export class BoxGeometry extends BufferGeometry { + /** + * Create a new instance of {@link BoxGeometry} + * @param width Width; that is, the length of the edges parallel to the X axis. Optional; Expects a `Float`. Default `1` + * @param height Height; that is, the length of the edges parallel to the Y axis. Optional; Expects a `Float`. Default `1` + * @param depth Depth; that is, the length of the edges parallel to the Z axis. Optional; Expects a `Float`. Default `1` + * @param widthSegments Number of segmented rectangular faces along the width of the sides. Optional; Expects a `Integer`. Default `1` + * @param heightSegments Number of segmented rectangular faces along the height of the sides. Optional; Expects a `Integer`. Default `1` + * @param depthSegments Number of segmented rectangular faces along the depth of the sides. Optional; Expects a `Integer`. Default `1` + */ + constructor( + width?: number, + height?: number, + depth?: number, + widthSegments?: number, + heightSegments?: number, + depthSegments?: number, + ); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `BoxGeometry` + */ + override readonly type: string | "BoxGeometry"; + + /** + * An object with a property for each of the constructor parameters. + * @remarks Any modification after instantiation does not change the geometry. + */ + readonly parameters: { + readonly width: number; + readonly height: number; + readonly depth: number; + readonly widthSegments: number; + readonly heightSegments: number; + readonly depthSegments: number; + }; + + /** @internal */ + static fromJSON(data: {}): BoxGeometry; +} diff --git a/src-testing/src/geometries/CapsuleGeometry.d.ts b/src-testing/src/geometries/CapsuleGeometry.d.ts new file mode 100644 index 000000000..b20616035 --- /dev/null +++ b/src-testing/src/geometries/CapsuleGeometry.d.ts @@ -0,0 +1,48 @@ +import { BufferGeometry } from "../core/BufferGeometry.js"; + +/** + * {@link CapsuleGeometry} is a geometry class for a capsule with given radii and height + * @remarks It is constructed using a lathe. + * @example + * ```typescript + * const geometry = new THREE.CapsuleGeometry(1, 1, 4, 8); + * const material = new THREE.MeshBasicMaterial({ + * color: 0x00ff00 + * }); + * const capsule = new THREE.Mesh(geometry, material); + * scene.add(capsule); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/geometries/CapsuleGeometry | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/CapsuleGeometry.js | Source} + */ +export class CapsuleGeometry extends BufferGeometry { + /** + * Create a new instance of {@link CapsuleGeometry} + * @param radius Radius of the capsule. Expects a `Float`. Default `1` + * @param length Length of the middle section. Expects a `Float`. Default `1` + * @param capSegments Number of curve segments used to build the caps. Expects a `Integer`. Default `4` + * @param radialSegments Number of segmented faces around the circumference of the capsule. Expects a `Integer`. Default `8` + */ + constructor(radius?: number, length?: number, capSegments?: number, radialSegments?: number); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `CapsuleGeometry` + */ + override readonly type: string | "CapsuleGeometry"; + + /** + * An object with a property for each of the constructor parameters. + * @remarks Any modification after instantiation does not change the geometry. + */ + readonly parameters: { + readonly radius: number; + readonly length: number; + readonly capSegments: number; + readonly radialSegments: number; + }; + + /** @internal */ + static fromJSON(data: {}): CapsuleGeometry; +} diff --git a/src-testing/src/geometries/CircleGeometry.d.ts b/src-testing/src/geometries/CircleGeometry.d.ts new file mode 100644 index 000000000..b512e4866 --- /dev/null +++ b/src-testing/src/geometries/CircleGeometry.d.ts @@ -0,0 +1,51 @@ +import { BufferGeometry } from "../core/BufferGeometry.js"; + +/** + * {@link CircleGeometry} is a simple shape of Euclidean geometry + * @remarks + * It is constructed from a number of triangular segments that are oriented around a central point and extend as far out as a given radius + * It is built counter-clockwise from a start angle and a given central angle + * It can also be used to create regular polygons, where the number of segments determines the number of sides. + * @example + * ```typescript + * const geometry = new THREE.CircleGeometry(5, 32); + * const material = new THREE.MeshBasicMaterial({ + * color: 0xffff00 + * }); + * const circle = new THREE.Mesh(geometry, material); + * scene.add(circle); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/geometries/CircleGeometry | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/CircleGeometry.js | Source} + */ +export class CircleGeometry extends BufferGeometry { + /** + * Create a new instance of {@link CircleGeometry} + * @param radius Radius of the circle. Expects a `Float`. Default `1` + * @param segments Number of segments (triangles). Expects a `Integer`. Minimum `3`. Default `32` + * @param thetaStart Start angle for first segment. Expects a `Float`. Default `0`, _(three o'clock position)_. + * @param thetaLength The central angle, often called theta, of the circular sector. Expects a `Float`. Default `Math.PI * 2`, _which makes for a complete circle_. + */ + constructor(radius?: number, segments?: number, thetaStart?: number, thetaLength?: number); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `CircleGeometry` + */ + override readonly type: string | "CircleGeometry"; + + /** + * An object with a property for each of the constructor parameters. + * @remarks Any modification after instantiation does not change the geometry. + */ + readonly parameters: { + readonly radius: number; + readonly segments: number; + readonly thetaStart: number; + readonly thetaLength: number; + }; + + /** @internal */ + static fromJSON(data: {}): CircleGeometry; +} diff --git a/src-testing/src/geometries/ConeGeometry.d.ts b/src-testing/src/geometries/ConeGeometry.d.ts new file mode 100644 index 000000000..683376429 --- /dev/null +++ b/src-testing/src/geometries/ConeGeometry.d.ts @@ -0,0 +1,64 @@ +import { CylinderGeometry } from "./CylinderGeometry.js"; + +/** + * A class for generating cone geometries. + * @example + * ```typescript + * const geometry = new THREE.ConeGeometry(5, 20, 32); + * const material = new THREE.MeshBasicMaterial({ + * color: 0xffff00 + * }); + * const cone = new THREE.Mesh(geometry, material); + * scene.add(cone); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/geometries/ConeGeometry | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/ConeGeometry.js | Source} + */ +export class ConeGeometry extends CylinderGeometry { + /** + * Create a new instance of {@link ConeGeometry} + * @param radius Radius of the cone base. Expects a `Float`. Default `1` + * @param height Height of the cone. Expects a `Float`. Default `1` + * @param radialSegments Number of segmented faces around the circumference of the cone. Expects a `Integer`. Default `32` + * @param heightSegments Number of rows of faces along the height of the cone. Expects a `Integer`. Default `1` + * @param openEnded A Boolean indicating whether the base of the cone is open or capped. Default `false`, _meaning capped_. + * @param thetaStart Start angle for first segment. Expects a `Float`. Default `0`, _(three o'clock position)_. + * @param thetaLength The central angle, often called theta, of the circular sector. Expects a `Float`. Default `Math.PI * 2`, _which makes for a complete cone_. + */ + constructor( + radius?: number, + height?: number, + radialSegments?: number, + heightSegments?: number, + openEnded?: boolean, + thetaStart?: number, + thetaLength?: number, + ); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `ConeGeometry` + */ + override readonly type: string | "ConeGeometry"; + + /** + * An object with a property for each of the constructor parameters. + * @remarks {@link radiusTop} and {@link radiusBottom} are from base {@link THREE.CylinderGeometry} class. + * @remarks Any modification after instantiation does not change the geometry. + */ + override readonly parameters: { + readonly radius: number; + readonly radiusTop: number; + readonly radiusBottom: number; + readonly height: number; + readonly radialSegments: number; + readonly heightSegments: number; + readonly openEnded: boolean; + readonly thetaStart: number; + readonly thetaLength: number; + }; + + /** @internal */ + static fromJSON(data: {}): ConeGeometry; +} diff --git a/src-testing/src/geometries/CylinderGeometry.d.ts b/src-testing/src/geometries/CylinderGeometry.d.ts new file mode 100644 index 000000000..90f1b06f3 --- /dev/null +++ b/src-testing/src/geometries/CylinderGeometry.d.ts @@ -0,0 +1,64 @@ +import { BufferGeometry } from "../core/BufferGeometry.js"; + +/** + * A class for generating cylinder geometries. + * @example + * ```typescript + * const geometry = new THREE.CylinderGeometry(5, 5, 20, 32); + * const material = new THREE.MeshBasicMaterial({ + * color: 0xffff00 + * }); + * const cylinder = new THREE.Mesh(geometry, material); + * scene.add(cylinder); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/geometries/CylinderGeometry | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/CylinderGeometry.js | Source} + */ +export class CylinderGeometry extends BufferGeometry { + /** + * Create a new instance of {@link CylinderGeometry} + * @param radiusTop Radius of the cylinder at the top. Default `1` + * @param radiusBottom Radius of the cylinder at the bottom. Default `1` + * @param height Height of the cylinder. Default `1` + * @param radialSegments Number of segmented faces around the circumference of the cylinder. Default `32` + * @param heightSegments Number of rows of faces along the height of the cylinder. Expects a `Integer`. Default `1` + * @param openEnded A Boolean indicating whether the ends of the cylinder are open or capped. Default `false`, _meaning capped_. + * @param thetaStart Start angle for first segment. Default `0`, _(three o'clock position)_. + * @param thetaLength The central angle, often called theta, of the circular sector. Default `Math.PI * 2`, _which makes for a complete cylinder. + */ + constructor( + radiusTop?: number, + radiusBottom?: number, + height?: number, + radialSegments?: number, + heightSegments?: number, + openEnded?: boolean, + thetaStart?: number, + thetaLength?: number, + ); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `CylinderGeometry` + */ + override readonly type: string | "CylinderGeometry"; + + /** + * An object with a property for each of the constructor parameters. + * @remarks Any modification after instantiation does not change the geometry. + */ + readonly parameters: { + readonly radiusTop: number; + readonly radiusBottom: number; + readonly height: number; + readonly radialSegments: number; + readonly heightSegments: number; + readonly openEnded: boolean; + readonly thetaStart: number; + readonly thetaLength: number; + }; + + /** @internal */ + static fromJSON(data: any): CylinderGeometry; +} diff --git a/src-testing/src/geometries/DodecahedronGeometry.d.ts b/src-testing/src/geometries/DodecahedronGeometry.d.ts new file mode 100644 index 000000000..e79e5a895 --- /dev/null +++ b/src-testing/src/geometries/DodecahedronGeometry.d.ts @@ -0,0 +1,25 @@ +import { PolyhedronGeometry } from "./PolyhedronGeometry.js"; + +/** + * A class for generating a dodecahedron geometries. + * @see {@link https://threejs.org/docs/index.html#api/en/geometries/DodecahedronGeometry | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/DodecahedronGeometry.js | Source} + */ +export class DodecahedronGeometry extends PolyhedronGeometry { + /** + * Create a new instance of {@link DodecahedronGeometry} + * @param radius Radius of the dodecahedron. Expects a `Float`. Default `1` + * @param detail Setting this to a value greater than 0 adds vertices making it no longer a dodecahedron. Expects a `Integer`. Default `0` + */ + constructor(radius?: number, detail?: number); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `DodecahedronGeometry` + */ + override readonly type: string | "DodecahedronGeometry"; + + /** @internal */ + static fromJSON(data: {}): DodecahedronGeometry; +} diff --git a/src-testing/src/geometries/EdgesGeometry.d.ts b/src-testing/src/geometries/EdgesGeometry.d.ts new file mode 100644 index 000000000..b901b10d7 --- /dev/null +++ b/src-testing/src/geometries/EdgesGeometry.d.ts @@ -0,0 +1,41 @@ +import { BufferGeometry } from "../core/BufferGeometry.js"; + +/** + * This can be used as a helper object to view the edges of a {@link THREE.BufferGeometry | geometry}. + * @example + * ```typescript + * const geometry = new THREE.BoxGeometry(100, 100, 100); + * const edges = new THREE.EdgesGeometry(geometry); + * const line = new THREE.LineSegments(edges, new THREE.LineBasicMaterial({ + * color: 0xffffff + * })); + * scene.add(line); + * ``` + * @see Example: {@link https://threejs.org/examples/#webgl_helpers | helpers} + * @see {@link https://threejs.org/docs/index.html#api/en/geometries/EdgesGeometry | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/EdgesGeometry.js | Source} + */ +export class EdgesGeometry extends BufferGeometry { + /** + * Create a new instance of {@link EdgesGeometry} + * @param geometry Any geometry object. Default `null`. + * @param thresholdAngle An edge is only rendered if the angle (in degrees) between the face normals of the adjoining faces exceeds this value. Expects a `Integer`. Default `1` _degree_. + */ + constructor(geometry?: TBufferGeometry | null, thresholdAngle?: number); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `EdgesGeometry` + */ + override readonly type: string | "EdgesGeometry"; + + /** + * An object with a property for each of the constructor parameters. + * @remarks Any modification after instantiation does not change the geometry. + */ + readonly parameters: { + readonly geometry: TBufferGeometry | null; + readonly thresholdAngle: number; + }; +} diff --git a/src-testing/src/geometries/ExtrudeGeometry.d.ts b/src-testing/src/geometries/ExtrudeGeometry.d.ts new file mode 100644 index 000000000..d872b7c21 --- /dev/null +++ b/src-testing/src/geometries/ExtrudeGeometry.d.ts @@ -0,0 +1,152 @@ +import { BufferGeometry } from "../core/BufferGeometry.js"; +import { Curve } from "../extras/core/Curve.js"; +import { Shape } from "../extras/core/Shape.js"; +import { Vector2 } from "../math/Vector2.js"; +import { Vector3 } from "../math/Vector3.js"; + +export interface ExtrudeGeometryOptions { + /** + * Number of points on the curves. + * Expects a `Integer`. + * @defaultValue `12` + */ + curveSegments?: number | undefined; + + /** + * Number of points used for subdividing segments along the depth of the extruded spline. + * @defaultValue `1` + */ + steps?: number | undefined; + + /** + * Depth to extrude the shape. + * @defaultValue `1` + */ + depth?: number | undefined; + + /** + * Turn on bevel. Applying beveling to the shape. + * @defaultValue `true` + */ + bevelEnabled?: boolean | undefined; + + /** + * How deep into the original shape the bevel goes. + * Expects a `Float`. + * @defaultValue `0.2` + */ + bevelThickness?: number | undefined; + + /** + * Distance from the shape outline that the bevel extends + * Expects a `Float`. + * @defaultValue `bevelThickness - 0.1` + */ + bevelSize?: number | undefined; + + /** + * Distance from the shape outline that the bevel starts. + * Expects a `Float`. + * @defaultValue `0` + */ + bevelOffset?: number | undefined; + + /** + * Number of bevel layers/segments. + * Expects a `Integer`. + * @defaultValue `3` + */ + bevelSegments?: number | undefined; + + /** + * A 3D spline path along which the shape should be extruded. + * @remarks Bevels not supported for path extrusion. + */ + extrudePath?: Curve | undefined; + + /** + * A object that provides UV generator functions. + */ + UVGenerator?: UVGenerator | undefined; +} + +export interface UVGenerator { + generateTopUV( + geometry: ExtrudeGeometry, + vertices: number[], + indexA: number, + indexB: number, + indexC: number, + ): Vector2[]; + generateSideWallUV( + geometry: ExtrudeGeometry, + vertices: number[], + indexA: number, + indexB: number, + indexC: number, + indexD: number, + ): Vector2[]; +} + +/** + * Creates extruded geometry from a path shape. + * @remarks This object extrudes a 2D shape to a 3D geometry. + * @remarks When creating a Mesh with this geometry, if you'd like to have a separate material used for its face and its extruded sides, you can use an array of materials + * @remarks The first material will be applied to the face; the second material will be applied to the sides. + * @example + * ```typescript + * const length = 12, width = 8; + * const shape = new THREE.Shape(); + * shape.moveTo(0, 0); + * shape.lineTo(0, width); + * shape.lineTo(length, width); + * shape.lineTo(length, 0); + * shape.lineTo(0, 0); + * const extrudeSettings = { + * steps: 2, + * depth: 16, + * bevelEnabled: true, + * bevelThickness: 1, + * bevelSize: 1, + * bevelOffset: 0, + * bevelSegments: 1 + * }; + * const geometry = new THREE.ExtrudeGeometry(shape, extrudeSettings); + * const material = new THREE.MeshBasicMaterial({ + * color: 0x00ff00 + * }); + * const mesh = new THREE.Mesh(geometry, material); + * scene.add(mesh); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/geometries/ExtrudeGeometry | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/ExtrudeGeometry.js | Source} + */ +export class ExtrudeGeometry extends BufferGeometry { + /** + * Create a new instance of {@link ExtrudeGeometry} + * @param shapes Shape or an array of shapes. Default `new Shape([new Vector2(0.5, 0.5), new Vector2(-0.5, 0.5), new Vector2(-0.5, -0.5), new Vector2(0.5, -0.5)])`. + * @param options Object that can contain the following parameters. @see {@link ExtrudeGeometryOptions} for defaults. + */ + constructor(shapes?: Shape | Shape[], options?: ExtrudeGeometryOptions); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `ExtrudeGeometry` + */ + override readonly type: string | "ExtrudeGeometry"; + + /** + * An object with a property for each of the constructor parameters. + * @remarks Any modification after instantiation does not change the geometry. + */ + readonly parameters: { + readonly shapes: Shape | Shape[]; + readonly options: ExtrudeGeometryOptions; + }; + + addShape(shape: Shape): void; + + /** @internal */ + static fromJSON(data: {}, shapes: unknown): ExtrudeGeometry; +} diff --git a/src-testing/src/geometries/Geometries.d.ts b/src-testing/src/geometries/Geometries.d.ts new file mode 100644 index 000000000..b1be46c46 --- /dev/null +++ b/src-testing/src/geometries/Geometries.d.ts @@ -0,0 +1,21 @@ +export * from "./BoxGeometry.js"; +export * from "./CapsuleGeometry.js"; +export * from "./CircleGeometry.js"; +export * from "./ConeGeometry.js"; +export * from "./CylinderGeometry.js"; +export * from "./DodecahedronGeometry.js"; +export * from "./EdgesGeometry.js"; +export * from "./ExtrudeGeometry.js"; +export * from "./IcosahedronGeometry.js"; +export * from "./LatheGeometry.js"; +export * from "./OctahedronGeometry.js"; +export * from "./PlaneGeometry.js"; +export * from "./PolyhedronGeometry.js"; +export * from "./RingGeometry.js"; +export * from "./ShapeGeometry.js"; +export * from "./SphereGeometry.js"; +export * from "./TetrahedronGeometry.js"; +export * from "./TorusGeometry.js"; +export * from "./TorusKnotGeometry.js"; +export * from "./TubeGeometry.js"; +export * from "./WireframeGeometry.js"; diff --git a/src-testing/src/geometries/IcosahedronGeometry.d.ts b/src-testing/src/geometries/IcosahedronGeometry.d.ts new file mode 100644 index 000000000..4c05b54de --- /dev/null +++ b/src-testing/src/geometries/IcosahedronGeometry.d.ts @@ -0,0 +1,26 @@ +import { PolyhedronGeometry } from "./PolyhedronGeometry.js"; + +/** + * A class for generating an icosahedron geometry. + * @see {@link https://threejs.org/docs/index.html#api/en/geometries/IcosahedronGeometry | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/IcosahedronGeometry.js | Source} + */ +export class IcosahedronGeometry extends PolyhedronGeometry { + /** + * Create a new instance of {@link IcosahedronGeometry} + * @param radius Expects a `Float`. Default `1` + * @param detail Setting this to a value greater than 0 adds more vertices making it no longer an icosahedron. + * When detail is greater than 1, it's effectively a sphere. Expects a `Integer`. Default `0` + */ + constructor(radius?: number, detail?: number); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `IcosahedronGeometry` + */ + override readonly type: string | "IcosahedronGeometry"; + + /** @internal */ + static fromJSON(data: {}): IcosahedronGeometry; +} diff --git a/src-testing/src/geometries/LatheGeometry.d.ts b/src-testing/src/geometries/LatheGeometry.d.ts new file mode 100644 index 000000000..f4194e514 --- /dev/null +++ b/src-testing/src/geometries/LatheGeometry.d.ts @@ -0,0 +1,55 @@ +import { BufferGeometry } from "../core/BufferGeometry.js"; +import { Vector2 } from "../math/Vector2.js"; + +/** + * Creates meshes with axial symmetry like vases + * @remarks + * The lathe rotates around the Y axis. + * @example + * ```typescript + * const points = []; + * for (let i = 0; i & lt; 10; i++) { + * points.push(new THREE.Vector2(Math.sin(i * 0.2) * 10 + 5, (i - 5) * 2)); + * } + * const geometry = new THREE.LatheGeometry(points); + * const material = new THREE.MeshBasicMaterial({ + * color: 0xffff00 + * }); + * const lathe = new THREE.Mesh(geometry, material); + * scene.add(lathe); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/geometries/LatheGeometry | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/LatheGeometry.js | Source} + */ +export class LatheGeometry extends BufferGeometry { + /** + * This creates a {@link LatheGeometry} based on the parameters. + * @param points Array of Vector2s. The x-coordinate of each point must be greater than zero. + * Default `[new Vector2(0, -0.5), new Vector2(0.5, 0), new Vector2(0, 0.5)]` _which creates a simple diamond shape_. + * @param segments The number of circumference segments to generate. Expects a `Integer`. Default `12`. + * @param phiStart The starting angle in radians. Expects a `Float`. Default `0`. + * @param phiLength The radian (0 to 2*PI) range of the lathed section 2*PI is a closed lathe, less than 2PI is a portion. Expects a `Float`. Default `Math.PI * 2`. + */ + constructor(points?: Vector2[], segments?: number, phiStart?: number, phiLength?: number); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `LatheGeometry` + */ + override readonly type: string | "LatheGeometry"; + + /** + * An object with a property for each of the constructor parameters. + * @remarks Any modification after instantiation does not change the geometry. + */ + readonly parameters: { + readonly points: Vector2[]; + readonly segments: number; + readonly phiStart: number; + readonly phiLength: number; + }; + + /** @internal */ + static fromJSON(data: {}): LatheGeometry; +} diff --git a/src-testing/src/geometries/OctahedronGeometry.d.ts b/src-testing/src/geometries/OctahedronGeometry.d.ts new file mode 100644 index 000000000..09ba0b1e7 --- /dev/null +++ b/src-testing/src/geometries/OctahedronGeometry.d.ts @@ -0,0 +1,25 @@ +import { PolyhedronGeometry } from "./PolyhedronGeometry.js"; + +/** + * A class for generating an octahedron geometry. + * @see {@link https://threejs.org/docs/index.html#api/en/geometries/OctahedronGeometry | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/OctahedronGeometry.js | Source} + */ +export class OctahedronGeometry extends PolyhedronGeometry { + /** + * Create a new instance of {@link OctahedronGeometry} + * @param radius Radius of the octahedron. Expects a `Float`. Default `1` + * @param detail Setting this to a value greater than zero add vertices making it no longer an octahedron. Expects a `Integer`. Default `0` + */ + constructor(radius?: number, detail?: number); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `OctahedronGeometry` + */ + override readonly type: string | "OctahedronGeometry"; + + /** @internal */ + static fromJSON(data: {}): OctahedronGeometry; +} diff --git a/src-testing/src/geometries/PlaneGeometry.d.ts b/src-testing/src/geometries/PlaneGeometry.d.ts new file mode 100644 index 000000000..fda5f4908 --- /dev/null +++ b/src-testing/src/geometries/PlaneGeometry.d.ts @@ -0,0 +1,48 @@ +import { BufferGeometry } from "../core/BufferGeometry.js"; + +/** + * A class for generating plane geometries. + * @example + * ```typescript + * const geometry = new THREE.PlaneGeometry(1, 1); + * const material = new THREE.MeshBasicMaterial({ + * color: 0xffff00, + * side: THREE.DoubleSide + * }); + * const plane = new THREE.Mesh(geometry, material); + * scene.add(plane); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/geometries/PlaneGeometry | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/PlaneGeometry.js | Source} + */ +export class PlaneGeometry extends BufferGeometry { + /** + * Create a new instance of {@link PlaneGeometry} + * @param width Width along the X axis. Expects a `Float`. Default `1` + * @param height Height along the Y axis. Expects a `Float`. Default `1` + * @param widthSegments Number of segmented faces along the width of the sides. Expects a `Integer`. Default `1` + * @param heightSegments Number of segmented faces along the height of the sides. Expects a `Integer`. Default `1` + */ + constructor(width?: number, height?: number, widthSegments?: number, heightSegments?: number); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `PlaneGeometry` + */ + override readonly type: string | "PlaneGeometry"; + + /** + * An object with a property for each of the constructor parameters. + * @remarks Any modification after instantiation does not change the geometry. + */ + readonly parameters: { + readonly width: number; + readonly height: number; + readonly widthSegments: number; + readonly heightSegments: number; + }; + + /** @internal */ + static fromJSON(data: {}): PlaneGeometry; +} diff --git a/src-testing/src/geometries/PolyhedronGeometry.d.ts b/src-testing/src/geometries/PolyhedronGeometry.d.ts new file mode 100644 index 000000000..f4c07772b --- /dev/null +++ b/src-testing/src/geometries/PolyhedronGeometry.d.ts @@ -0,0 +1,54 @@ +import { BufferGeometry } from "../core/BufferGeometry.js"; + +/** + * A polyhedron is a solid in three dimensions with flat faces + * @remarks + * This class will take an array of vertices, project them onto a sphere, and then divide them up to the desired level of detail + * This class is used by {@link THREE.DodecahedronGeometry | DodecahedronGeometry}, {@link THREE.IcosahedronGeometry | IcosahedronGeometry}, + * {@link THREE.OctahedronGeometry | OctahedronGeometry}, and {@link THREE.TetrahedronGeometry | TetrahedronGeometry} to generate their respective geometries. + * @example + * ```typescript + * const verticesOfCube = [-1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, ]; + * const indicesOfFaces = [ + * 2, 1, 0, 0, 3, 2, + * 0, 4, 7, 7, 3, 0, + * 0, 1, 5, 5, 4, 0, + * 1, 2, 6, 6, 5, 1, + * 2, 3, 7, 7, 6, 2, + * 4, 5, 6, 6, 7, 4]; + * const geometry = new THREE.PolyhedronGeometry(verticesOfCube, indicesOfFaces, 6, 2); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/geometries/PolyhedronGeometry | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/PolyhedronGeometry.js | Source} + */ +export class PolyhedronGeometry extends BufferGeometry { + /** + * Create a new instance of {@link PolyhedronGeometry} + * @param vertices Array of points of the form [1,1,1, -1,-1,-1, ... ]. Default `[]`. + * @param indices Array of indices that make up the faces of the form [0,1,2, 2,3,0, ... ]. Default `[]`. + * @param radius [page:The radius of the final shape Expects a `Float`. Default `1` + * @param detail [page:How many levels to subdivide the geometry. The more detail, the smoother the shape. Expects a `Integer`. Default `0` + */ + constructor(vertices?: number[], indices?: number[], radius?: number, detail?: number); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `PolyhedronGeometry` + */ + override readonly type: string | "PolyhedronGeometry"; + + /** + * An object with a property for each of the constructor parameters. + * @remarks Any modification after instantiation does not change the geometry. + */ + readonly parameters: { + readonly vertices: number[]; + readonly indices: number[]; + readonly radius: number; + readonly detail: number; + }; + + /** @internal */ + static fromJSON(data: {}): PolyhedronGeometry; +} diff --git a/src-testing/src/geometries/RingGeometry.d.ts b/src-testing/src/geometries/RingGeometry.d.ts new file mode 100644 index 000000000..2cbc63ef4 --- /dev/null +++ b/src-testing/src/geometries/RingGeometry.d.ts @@ -0,0 +1,59 @@ +import { BufferGeometry } from "../core/BufferGeometry.js"; + +/** + * A class for generating a two-dimensional ring geometry. + * @example + * ```typescript + * const geometry = new THREE.RingGeometry(1, 5, 32); + * const material = new THREE.MeshBasicMaterial({ + * color: 0xffff00, + * side: THREE.DoubleSide + * }); + * const mesh = new THREE.Mesh(geometry, material); + * scene.add(mesh); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/geometries/RingGeometry | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/RingGeometry.js | Source} + */ +export class RingGeometry extends BufferGeometry { + /** + * Create a new instance of {@link RingGeometry} + * @param innerRadius Expects a `Float`. Default `0.5`. + * @param outerRadius Expects a `Float`. Default `1`. + * @param thetaSegments Number of segments. A higher number means the ring will be more round. Minimum is 3. Expects a `Integer`. Default `32`. + * @param phiSegments Number of segments per ring segment. Minimum is `1`. Expects a `Integer`. Default `1`. + * @param thetaStart Starting angle. Expects a `Float`. Default `0`. + * @param thetaLength Central angle. Expects a `Float`. Default `Math.PI * 2`. + */ + constructor( + innerRadius?: number, + outerRadius?: number, + thetaSegments?: number, + phiSegments?: number, + thetaStart?: number, + thetaLength?: number, + ); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `RingGeometry` + */ + override readonly type: string | "RingGeometry"; + + /** + * An object with a property for each of the constructor parameters. + * @remarks Any modification after instantiation does not change the geometry. + */ + readonly parameters: { + readonly innerRadius: number; + readonly outerRadius: number; + readonly thetaSegments: number; + readonly phiSegments: number; + readonly thetaStart: number; + readonly thetaLength: number; + }; + + /** @internal */ + static fromJSON(data: {}): RingGeometry; +} diff --git a/src-testing/src/geometries/ShapeGeometry.d.ts b/src-testing/src/geometries/ShapeGeometry.d.ts new file mode 100644 index 000000000..a3089a645 --- /dev/null +++ b/src-testing/src/geometries/ShapeGeometry.d.ts @@ -0,0 +1,53 @@ +import { BufferGeometry } from "../core/BufferGeometry.js"; +import { Shape } from "../extras/core/Shape.js"; + +/** + * Creates an one-sided polygonal geometry from one or more path shapes. + * @example + * ```typescript + * const x = 0, y = 0; + * const heartShape = new THREE.Shape(); + * heartShape.moveTo(x + 5, y + 5); + * heartShape.bezierCurveTo(x + 5, y + 5, x + 4, y, x, y); + * heartShape.bezierCurveTo(x - 6, y, x - 6, y + 7, x - 6, y + 7); + * heartShape.bezierCurveTo(x - 6, y + 11, x - 3, y + 15.4, x + 5, y + 19); + * heartShape.bezierCurveTo(x + 12, y + 15.4, x + 16, y + 11, x + 16, y + 7); + * heartShape.bezierCurveTo(x + 16, y + 7, x + 16, y, x + 10, y); + * heartShape.bezierCurveTo(x + 7, y, x + 5, y + 5, x + 5, y + 5); + * const geometry = new THREE.ShapeGeometry(heartShape); + * const material = new THREE.MeshBasicMaterial({ + * color: 0x00ff00 + * }); + * const mesh = new THREE.Mesh(geometry, material); + * scene.add(mesh); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/geometries/ShapeGeometry | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/ShapeGeometry.js | Source} + */ +export class ShapeGeometry extends BufferGeometry { + /** + * Create a new instance of {@link ShapeGeometry} + * @param shapes Array of shapes or a single {@link THREE.Shape | Shape}. Default `new Shape([new Vector2(0, 0.5), new Vector2(-0.5, -0.5), new Vector2(0.5, -0.5)])`, _a single triangle shape_. + * @param curveSegments Number of segments per shape. Expects a `Integer`. Default `12` + */ + constructor(shapes?: Shape | Shape[], curveSegments?: number); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `ShapeGeometry` + */ + override readonly type: string | "ShapeGeometry"; + + /** + * An object with a property for each of the constructor parameters. + * @remarks Any modification after instantiation does not change the geometry. + */ + readonly parameters: { + readonly shapes: Shape | Shape[]; + readonly curveSegments: number; + }; + + /** @internal */ + static fromJSON(data: {}): ShapeGeometry; +} diff --git a/src-testing/src/geometries/SphereGeometry.d.ts b/src-testing/src/geometries/SphereGeometry.d.ts new file mode 100644 index 000000000..b597bb26c --- /dev/null +++ b/src-testing/src/geometries/SphereGeometry.d.ts @@ -0,0 +1,67 @@ +import { BufferGeometry } from "../core/BufferGeometry.js"; + +/** + * A class for generating sphere geometries. + * @example + * ```typescript + * const geometry = new THREE.SphereGeometry(15, 32, 16); + * const material = new THREE.MeshBasicMaterial({ + * color: 0xffff00 + * }); + * const sphere = new THREE.Mesh(geometry, material); + * scene.add(sphere); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/geometries/SphereGeometry | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/SphereGeometry.js | Source} + */ +export class SphereGeometry extends BufferGeometry { + /** + * Create a new instance of {@link SphereGeometry} + * @remarks + * The geometry is created by sweeping and calculating vertexes + * around the **Y** axis (horizontal sweep) and the **Z** axis (vertical sweep) + * Thus, incomplete spheres (akin to `'sphere slices'`) can be created + * through the use of different values of {@link phiStart}, {@link phiLength}, {@link thetaStart} and {@link thetaLength}, + * in order to define the points in which we start (or end) calculating those vertices. + * @param radius Sphere radius. Expects a `Float`. Default `1` + * @param widthSegments Number of horizontal segments. Minimum value is 3, and the Expects a `Integer`. Default `32` + * @param heightSegments Number of vertical segments. Minimum value is 2, and the Expects a `Integer`. Default `16` + * @param phiStart Specify horizontal starting angle. Expects a `Float`. Default `0` + * @param phiLength Specify horizontal sweep angle size. Expects a `Float`. Default `Math.PI * 2` + * @param thetaStart Specify vertical starting angle. Expects a `Float`. Default `0` + * @param thetaLength Specify vertical sweep angle size. Expects a `Float`. Default `Math.PI` + */ + constructor( + radius?: number, + widthSegments?: number, + heightSegments?: number, + phiStart?: number, + phiLength?: number, + thetaStart?: number, + thetaLength?: number, + ); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `SphereGeometry` + */ + override readonly type: string | "SphereGeometry"; + + /** + * An object with a property for each of the constructor parameters. + * @remarks Any modification after instantiation does not change the geometry. + */ + readonly parameters: { + readonly radius: number; + readonly widthSegments: number; + readonly heightSegments: number; + readonly phiStart: number; + readonly phiLength: number; + readonly thetaStart: number; + readonly thetaLength: number; + }; + + /** @internal */ + static fromJSON(data: {}): SphereGeometry; +} diff --git a/src-testing/src/geometries/TetrahedronGeometry.d.ts b/src-testing/src/geometries/TetrahedronGeometry.d.ts new file mode 100644 index 000000000..2dd0fe5b6 --- /dev/null +++ b/src-testing/src/geometries/TetrahedronGeometry.d.ts @@ -0,0 +1,25 @@ +import { PolyhedronGeometry } from "./PolyhedronGeometry.js"; + +/** + * A class for generating a tetrahedron geometries. + * @see {@link https://threejs.org/docs/index.html#api/en/geometries/TetrahedronGeometry | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/TetrahedronGeometry.js | Source} + */ +export class TetrahedronGeometry extends PolyhedronGeometry { + /** + * Create a new instance of {@link TetrahedronGeometry} + * @param radius Radius of the tetrahedron. Expects a `Float`. Default `1` + * @param detail Setting this to a value greater than 0 adds vertices making it no longer a tetrahedron. Expects a `Integer`. Default `0` + */ + constructor(radius?: number, detail?: number); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `TetrahedronGeometry` + */ + override readonly type: string | "TetrahedronGeometry"; + + /** @internal */ + static fromJSON(data: {}): TetrahedronGeometry; +} diff --git a/src-testing/src/geometries/TorusGeometry.d.ts b/src-testing/src/geometries/TorusGeometry.d.ts new file mode 100644 index 000000000..47a70ceea --- /dev/null +++ b/src-testing/src/geometries/TorusGeometry.d.ts @@ -0,0 +1,49 @@ +import { BufferGeometry } from "../core/BufferGeometry.js"; + +/** + * A class for generating torus geometries. + * @example + * ```typescript + * const geometry = new THREE.TorusGeometry(10, 3, 16, 100); + * const material = new THREE.MeshBasicMaterial({ + * color: 0xffff00 + * }); + * const torus = new THREE.Mesh(geometry, material); + * scene.add(torus); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/geometries/TorusGeometry | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/TorusGeometry.js | Source} + */ +export class TorusGeometry extends BufferGeometry { + /** + * Create a new instance of {@link TorusGeometry} + * @param radius Radius of the torus, from the center of the torus to the center of the tube. Expects a `Float`. Default `1`. + * @param tube Radius of the tube. Expects a `Float`. Default `0.4`. + * @param radialSegments Expects a `Integer`.Default is `12`. + * @param tubularSegments Expects a `Integer`. Default `48`. + * @param arc Central angle. Expects a `Float`. Default `Math.PI * 2` + */ + constructor(radius?: number, tube?: number, radialSegments?: number, tubularSegments?: number, arc?: number); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `TorusGeometry` + */ + override readonly type: string | "TorusGeometry"; + + /** + * An object with a property for each of the constructor parameters. + * @remarks Any modification after instantiation does not change the geometry. + */ + readonly parameters: { + readonly radius: number; + readonly tube: number; + readonly radialSegments: number; + readonly tubularSegments: number; + readonly arc: number; + }; + + /** @internal */ + static fromJSON(data: any): TorusGeometry; +} diff --git a/src-testing/src/geometries/TorusKnotGeometry.d.ts b/src-testing/src/geometries/TorusKnotGeometry.d.ts new file mode 100644 index 000000000..103b6916e --- /dev/null +++ b/src-testing/src/geometries/TorusKnotGeometry.d.ts @@ -0,0 +1,59 @@ +import { BufferGeometry } from "../core/BufferGeometry.js"; + +/** + * Creates a torus knot, the particular shape of which is defined by a pair of coprime integers, p and q + * If p and q are not coprime, the result will be a torus link. + * @example + * ```typescript + * const geometry = new THREE.TorusKnotGeometry(10, 3, 100, 16); + * const material = new THREE.MeshBasicMaterial({ + * color: 0xffff00 + * }); + * const torusKnot = new THREE.Mesh(geometry, material); + * scene.add(torusKnot); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/geometries/TorusKnotGeometry | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/TorusKnotGeometry.js | Source} + */ +export class TorusKnotGeometry extends BufferGeometry { + /** + * Create a new instance of {@link TorusKnotGeometry} + * @param radius Radius of the torus.. Default `1`. + * @param tube Expects a `Float`. Default `0.4`. + * @param tubularSegments Expects a `Integer`. Default `64`. + * @param radialSegments Expects a `Integer`. Default `8`. + * @param p This value determines, how many times the geometry winds around its axis of rotational symmetry. Expects a `Integer`. Default `2`. + * @param q This value determines, how many times the geometry winds around a circle in the interior of the torus. Expects a `Integer`. Default `3`. + */ + constructor( + radius?: number, + tube?: number, + tubularSegments?: number, + radialSegments?: number, + p?: number, + q?: number, + ); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `TorusKnotGeometry` + */ + override readonly type: string | "TorusKnotGeometry"; + + /** + * An object with a property for each of the constructor parameters. + * @remarks Any modification after instantiation does not change the geometry. + */ + readonly parameters: { + readonly radius: number; + readonly tube: number; + readonly tubularSegments: number; + readonly radialSegments: number; + readonly p: number; + readonly q: number; + }; + + /** @internal */ + static fromJSON(data: {}): TorusKnotGeometry; +} diff --git a/src-testing/src/geometries/TubeGeometry.d.ts b/src-testing/src/geometries/TubeGeometry.d.ts new file mode 100644 index 000000000..37e7129ad --- /dev/null +++ b/src-testing/src/geometries/TubeGeometry.d.ts @@ -0,0 +1,86 @@ +import { BufferGeometry } from "../core/BufferGeometry.js"; +import { Curve } from "../extras/core/Curve.js"; +import { Vector3 } from "../math/Vector3.js"; + +/** + * Creates a tube that extrudes along a 3d curve. + * @example + * ```typescript + * class CustomSinCurve extends THREE.Curve { + * constructor(scale = 1) { + * super(); + * this.scale = scale; + * } + * getPoint(t, optionalTarget = new THREE.Vector3()) { + * const tx = t * 3 - 1.5; + * const ty = Math.sin(2 * Math.PI * t); + * const tz = 0; + * return optionalTarget.set(tx, ty, tz).multiplyScalar(this.scale); + * } + * } + * const path = new CustomSinCurve(10); + * const geometry = new THREE.TubeGeometry(path, 20, 2, 8, false); + * const material = new THREE.MeshBasicMaterial({ + * color: 0x00ff00 + * }); + * const mesh = new THREE.Mesh(geometry, material); + * scene.add(mesh); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/geometries/TubeGeometry | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/TubeGeometry.js | Source} + */ +export class TubeGeometry extends BufferGeometry { + /** + * Create a new instance of {@link TubeGeometry} + * @param path A 3D path that inherits from the {@link THREE.Curve | Curve} base class. + * Default {@link THREE.QuadraticBezierCurve3 | new THREE.QuadraticBezierCurve3(new Vector3(-1, -1, 0 ), new Vector3(-1, 1, 0), new Vector3(1, 1, 0))}. + * @param tubularSegments The number of segments that make up the tube. Expects a `Integer`. Default `64`. + * @param radius The radius of the tube. Expects a `Float`. Default `1`. + * @param radialSegments The number of segments that make up the cross-section. Expects a `Integer`. Default `8`. + * @param closed Is the tube open or closed. Default `false`. + */ + constructor( + path?: Curve, + tubularSegments?: number, + radius?: number, + radialSegments?: number, + closed?: boolean, + ); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `TubeGeometry` + */ + override readonly type: string | "TubeGeometry"; + + /** + * An object with a property for each of the constructor parameters. + * @remarks Any modification after instantiation does not change the geometry. + */ + readonly parameters: { + readonly path: Curve; + readonly tubularSegments: number; + readonly radius: number; + readonly radialSegments: number; + readonly closed: boolean; + }; + + /** + * An array of {@link THREE.Vector3 | Vector3} tangents + */ + tangents: Vector3[]; + + /** + * An array of {@link THREE.Vector3 | Vector3} normals + */ + normals: Vector3[]; + + /** + * An array of {@link THREE.Vector3 | Vector3} binormals + */ + binormals: Vector3[]; + + /** @internal */ + static fromJSON(data: {}): TubeGeometry; +} diff --git a/src-testing/src/geometries/WireframeGeometry.d.ts b/src-testing/src/geometries/WireframeGeometry.d.ts new file mode 100644 index 000000000..6263316a6 --- /dev/null +++ b/src-testing/src/geometries/WireframeGeometry.d.ts @@ -0,0 +1,40 @@ +import { BufferGeometry } from "../core/BufferGeometry.js"; + +/** + * This can be used as a helper object to view a {@link BufferGeometry | geometry} as a wireframe. + * @example + * ```typescript + * const geometry = new THREE.SphereGeometry(100, 100, 100); + * const wireframe = new THREE.WireframeGeometry(geometry); + * const line = new THREE.LineSegments(wireframe); + * line.material.depthTest = false; + * line.material.opacity = 0.25; + * line.material.transparent = true; + * scene.add(line); + * ``` + * @see Example: {@link https://threejs.org/examples/#webgl_helpers | helpers} + * @see {@link https://threejs.org/docs/index.html#api/en/geometries/WireframeGeometry | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/WireframeGeometry.js | Source} + */ +export class WireframeGeometry extends BufferGeometry { + /** + * Create a new instance of {@link WireframeGeometry} + * @param geometry Any geometry object. Default `null`. + */ + constructor(geometry?: TBufferGeometry); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `WireframeGeometry` + */ + override readonly type: string | "WireframeGeometry"; + + /** + * An object with a property for each of the constructor parameters. + * @remarks Any modification after instantiation does not change the geometry. + */ + readonly parameters: { + readonly geometry: TBufferGeometry; + }; +} diff --git a/src-testing/src/helpers/ArrowHelper.d.ts b/src-testing/src/helpers/ArrowHelper.d.ts new file mode 100644 index 000000000..94896123c --- /dev/null +++ b/src-testing/src/helpers/ArrowHelper.d.ts @@ -0,0 +1,93 @@ +import { Object3D } from "../core/Object3D.js"; +import { ColorRepresentation } from "../math/Color.js"; +import { Vector3 } from "../math/Vector3.js"; +import { Line } from "../objects/Line.js"; +import { Mesh } from "../objects/Mesh.js"; + +/** + * An 3D arrow object for visualizing directions. + * @example + * ```typescript + * const dir = new THREE.Vector3(1, 2, 0); + * //normalize the direction vector (convert to vector of length 1) + * dir.normalize(); + * const origin = new THREE.Vector3(0, 0, 0); + * const length = 1; + * const hex = 0xffff00; + * const {@link ArrowHelper} = new THREE.ArrowHelper(dir, origin, length, hex); + * scene.add(arrowHelper); + * ``` + * @see Example: {@link https://threejs.org/examples/#webgl_shadowmesh | WebGL / shadowmesh} + * @see {@link https://threejs.org/docs/index.html#api/en/helpers/ArrowHelper | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/helpers/ArrowHelper.js | Source} + */ +export class ArrowHelper extends Object3D { + /** + * Create a new instance of {@link ArrowHelper} + * @param dir Direction from origin. Must be a unit vector. Default `new THREE.Vector3(0, 0, 1)` + * @param origin Point at which the arrow starts. Default `new THREE.Vector3(0, 0, 0)` + * @param length Length of the arrow. Default `1` + * @param hex Hexadecimal value to define color. Default `0xffff00` + * @param headLength The length of the head of the arrow. Default `0.2 * length` + * @param headWidth The width of the head of the arrow. Default `0.2 * headLength` + */ + constructor( + dir?: Vector3, + origin?: Vector3, + length?: number, + color?: ColorRepresentation, + headLength?: number, + headWidth?: number, + ); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @override + * @defaultValue `ArrowHelper` + */ + override readonly type: string | "ArrowHelper"; + + /** + * Contains the line part of the arrowHelper. + */ + line: Line; + + /** + * Contains the cone part of the arrowHelper. + */ + cone: Mesh; + + /** + * Sets the color of the arrowHelper. + * @param color The desired color. + */ + setColor(color: ColorRepresentation): void; + + /** + * @param dir The desired direction. Must be a unit vector. + */ + setDirection(dir: Vector3): void; + + /** + * Sets the length of the arrowhelper. + * @param length The desired length. + * @param headLength The length of the head of the arrow. Default `0.2 * length` + * @param headWidth The width of the head of the arrow. Default `0.2 * headLength` + */ + setLength(length: number, headLength?: number, headWidth?: number): void; + + /** + * Copy the given object into this object + * @remarks Note: event listeners and user-defined callbacks ({@link onAfterRender | .onAfterRender} and {@link onBeforeRender | .onBeforeRender}) are not copied. + * @param source + */ + override copy(source: this): this; + + /** + * Frees the GPU-related resources allocated by this instance + * @remarks + * Call this method whenever this instance is no longer used in your app. + */ + dispose(): void; +} diff --git a/src-testing/src/helpers/AxesHelper.d.ts b/src-testing/src/helpers/AxesHelper.d.ts new file mode 100644 index 000000000..c0633c102 --- /dev/null +++ b/src-testing/src/helpers/AxesHelper.d.ts @@ -0,0 +1,50 @@ +import { ColorRepresentation } from "../math/Color.js"; +import { LineSegments } from "../objects/LineSegments.js"; + +/** + * An axis object to visualize the 3 axes in a simple way. + * @remarks + * The X axis is red + * The Y axis is green + * The Z axis is blue. + * @example + * ```typescript + * const {@link AxesHelper} = new THREE.AxesHelper(5); + * scene.add(axesHelper); + * ``` + * @see Example: {@link https://threejs.org/examples/#webgl_buffergeometry_compression | WebGL / buffergeometry / compression} + * @see Example: {@link https://threejs.org/examples/#webgl_geometry_convex | WebGL / geometry / convex} + * @see Example: {@link https://threejs.org/examples/#webgl_loader_nrrd | WebGL / loader / nrrd} + * @see {@link https://threejs.org/docs/index.html#api/en/helpers/AxesHelper | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/helpers/AxesHelper.js | Source} + */ +export class AxesHelper extends LineSegments { + /** + * Create a new instance of {@link AxesHelper} + * @param size Size of the lines representing the axes. Default `1` + */ + constructor(size?: number); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @override + * @defaultValue `AxesHelper` + */ + override readonly type: string | "AxesHelper"; + + /** + * Sets the axes colors to {@link Color | xAxisColor}, {@link Color | yAxisColor}, {@link Color | zAxisColor}. + * @param xAxisColor + * @param yAxisColor + * @param zAxisColor + */ + setColors(xAxisColor: ColorRepresentation, yAxisColor: ColorRepresentation, zAxisColor: ColorRepresentation): this; + + /** + * Frees the GPU-related resources allocated by this instance + * @remarks + * Call this method whenever this instance is no longer used in your app. + */ + dispose(): void; +} diff --git a/src-testing/src/helpers/Box3Helper.d.ts b/src-testing/src/helpers/Box3Helper.d.ts new file mode 100644 index 000000000..78e1c6f82 --- /dev/null +++ b/src-testing/src/helpers/Box3Helper.d.ts @@ -0,0 +1,44 @@ +import { Box3 } from "../math/Box3.js"; +import { ColorRepresentation } from "../math/Color.js"; +import { LineSegments } from "../objects/LineSegments.js"; + +/** + * Helper object to visualize a {@link THREE.Box3 | Box3}. + * @example + * ```typescript + * const box = new THREE.Box3(); + * box.setFromCenterAndSize(new THREE.Vector3(1, 1, 1), new THREE.Vector3(2, 1, 3)); + * const helper = new THREE.Box3Helper(box, 0xffff00); + * scene.add(helper); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/helpers/Box3Helper | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/helpers/Box3Helper.js | Source} + */ +export class Box3Helper extends LineSegments { + /** + * Creates a new wireframe box that represents the passed Box3. + * @param box The Box3 to show. + * @param color The box's color. Default `0xffff00` + */ + constructor(box: Box3, color?: ColorRepresentation); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @override + * @defaultValue `Box3Helper` + */ + override readonly type: string | "Box3Helper"; + + /** + * The Box3 being visualized. + */ + box: Box3; + + /** + * Frees the GPU-related resources allocated by this instance + * @remarks + * Call this method whenever this instance is no longer used in your app. + */ + dispose(): void; +} diff --git a/src-testing/src/helpers/BoxHelper.d.ts b/src-testing/src/helpers/BoxHelper.d.ts new file mode 100644 index 000000000..d049a5b72 --- /dev/null +++ b/src-testing/src/helpers/BoxHelper.d.ts @@ -0,0 +1,64 @@ +import { BufferGeometry } from "../core/BufferGeometry.js"; +import { Object3D } from "../core/Object3D.js"; +import { LineBasicMaterial } from "../materials/LineBasicMaterial.js"; +import { ColorRepresentation } from "../math/Color.js"; +import { LineSegments } from "../objects/LineSegments.js"; + +/** + * Helper object to graphically show the world-axis-aligned bounding box around an object + * @remarks + * The actual bounding box is handled with {@link THREE.Box3 | Box3}, this is just a visual helper for debugging + * It can be automatically resized with the {@link THREE.BoxHelper.update | BoxHelper.update} method when the object it's created from is transformed + * Note that the object must have a {@link THREE.BufferGeometry | BufferGeometry} for this to work, so it won't work with {@link Sprite | Sprites}. + * @example + * ```typescript + * const sphere = new THREE.SphereGeometry(); + * const object = new THREE.Mesh(sphere, new THREE.MeshBasicMaterial(0xff0000)); + * const box = new THREE.BoxHelper(object, 0xffff00); + * scene.add(box); + * ``` + * @see Example: {@link https://threejs.org/examples/#webgl_helpers | WebGL / helpers} + * @see Example: {@link https://threejs.org/examples/#webgl_loader_nrrd | WebGL / loader / nrrd} + * @see Example: {@link https://threejs.org/examples/#webgl_buffergeometry_drawrange | WebGL / buffergeometry / drawrange} + * @see {@link https://threejs.org/docs/index.html#api/en/helpers/BoxHelper | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/helpers/BoxHelper.js | Source} + */ +export class BoxHelper extends LineSegments { + /** + * Creates a new wireframe box that bounds the passed object + * @remarks + * Internally this uses {@link THREE.Box3.setFromObject | Box3.setFromObject} to calculate the dimensions + * Note that this includes any children. + * @param object The object3D to show the world-axis-aligned bounding box. + * @param color Hexadecimal value that defines the box's color. Default `0xffff00` + */ + constructor(object: Object3D, color?: ColorRepresentation); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @override + * @defaultValue `BoxHelper` + */ + override readonly type: string | "BoxHelper"; + + /** + * Updates the helper's geometry to match the dimensions of the object, including any children + * @remarks + * See {@link THREE.Box3.setFromObject | Box3.setFromObject}. + */ + update(object?: Object3D): void; + + /** + * Updates the wireframe box for the passed object. + * @param object {@link THREE.Object3D | Object3D} to create the helper of. + */ + setFromObject(object: Object3D): this; + + /** + * Frees the GPU-related resources allocated by this instance + * @remarks + * Call this method whenever this instance is no longer used in your app. + */ + dispose(): void; +} diff --git a/src-testing/src/helpers/CameraHelper.d.ts b/src-testing/src/helpers/CameraHelper.d.ts new file mode 100644 index 000000000..469dcaa0d --- /dev/null +++ b/src-testing/src/helpers/CameraHelper.d.ts @@ -0,0 +1,80 @@ +import { Camera } from "../cameras/Camera.js"; +import { Color } from "../math/Color.js"; +import { Matrix4 } from "../math/Matrix4.js"; +import { LineSegments } from "../objects/LineSegments.js"; + +/** + * This helps with visualizing what a camera contains in its frustum + * @remarks + * It visualizes the frustum of a camera using a {@link THREE.LineSegments | LineSegments}. + * @remarks {@link CameraHelper} must be a child of the scene. + * @example + * ```typescript + * const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); + * const helper = new THREE.CameraHelper(camera); + * scene.add(helper); + * ``` + * @see Example: {@link https://threejs.org/examples/#webgl_camera | WebGL / camera} + * @see Example: {@link https://threejs.org/examples/#webgl_geometry_extrude_splines | WebGL / extrude / splines} + * @see {@link https://threejs.org/docs/index.html#api/en/helpers/CameraHelper | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/helpers/CameraHelper.js | Source} + */ +export class CameraHelper extends LineSegments { + /** + * This create a new {@link CameraHelper} for the specified camera. + * @param camera The camera to visualize. + */ + constructor(camera: Camera); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @override + * @defaultValue `CameraHelper` + */ + override readonly type: string | "CameraHelper"; + + /** + * The camera being visualized. + */ + camera: Camera; + + /** + * This contains the points used to visualize the camera. + */ + pointMap: { [id: string]: number[] }; + + /** + * Reference to the {@link THREE.Camera.matrixWorld | camera.matrixWorld}. + */ + matrix: Matrix4; + + /** + * Is set to `false`, as the helper is using the {@link THREE.Camera.matrixWorld | camera.matrixWorld}. + * @see {@link THREE.Object3D.matrixAutoUpdate | Object3D.matrixAutoUpdate}. + * @defaultValue `false`. + */ + override matrixAutoUpdate: boolean; + + /** + * Defines the colors of the helper. + * @param frustum + * @param cone + * @param up + * @param target + * @param cross + */ + setColors(frustum: Color, cone: Color, up: Color, target: Color, cross: Color): this; + + /** + * Updates the helper based on the projectionMatrix of the camera. + */ + update(): void; + + /** + * Frees the GPU-related resources allocated by this instance + * @remarks + * Call this method whenever this instance is no longer used in your app. + */ + dispose(): void; +} diff --git a/src-testing/src/helpers/DirectionalLightHelper.d.ts b/src-testing/src/helpers/DirectionalLightHelper.d.ts new file mode 100644 index 000000000..729eccedd --- /dev/null +++ b/src-testing/src/helpers/DirectionalLightHelper.d.ts @@ -0,0 +1,81 @@ +import { Object3D } from "../core/Object3D.js"; +import { DirectionalLight } from "../lights/DirectionalLight.js"; +import { ColorRepresentation } from "../math/Color.js"; +import { Matrix4 } from "../math/Matrix4.js"; +import { Line } from "../objects/Line.js"; + +/** + * Helper object to assist with visualizing a {@link THREE.DirectionalLight | DirectionalLight}'s effect on the scene + * @remarks + * This consists of plane and a line representing the light's position and direction. + * @example + * ```typescript + * const light = new THREE.DirectionalLight(0xFFFFFF); + * scene.add(light); + * + * const helper = new THREE.DirectionalLightHelper(light, 5); + * scene.add(helper); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/helpers/DirectionalLightHelper | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/helpers/DirectionalLightHelper.js | Source} + */ +export class DirectionalLightHelper extends Object3D { + /** + * Create a new instance of {@link DirectionalLightHelper} + * @param light The light to be visualized. + * @param size Dimensions of the plane. Default `1` + * @param color If this is not the set the helper will take the color of the light. Default `light.color` + */ + constructor(light: DirectionalLight, size?: number, color?: ColorRepresentation); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @override + * @defaultValue `DirectionalLightHelper` + */ + override readonly type: string | "DirectionalLightHelper"; + + /** + * Contains the line mesh showing the location of the directional light. + */ + lightPlane: Line; + + /** + * Reference to the {@link THREE.DirectionalLight | directionalLight} being visualized. + */ + light: DirectionalLight; + + /** + * Reference to the {@link THREE.DirectionalLight.matrixWorld | light.matrixWorld}. + */ + matrix: Matrix4; + + /** + * Is set to `false`, as the helper is using the {@link THREE.DirectionalLight.matrixWorld | light.matrixWorld}. + * @see {@link THREE.Object3D.matrixAutoUpdate | Object3D.matrixAutoUpdate}. + * @defaultValue `false`. + */ + override matrixAutoUpdate: boolean; + + /** + * The color parameter passed in the constructor. + * @remarks If this is changed, the helper's color will update the next time {@link update} is called. + * @defaultValue `undefined` + */ + color: ColorRepresentation | undefined; + + targetLine: Line; // TODO: Double check if this need to be exposed or not. + + /** + * Updates the helper to match the position and direction of the {@link light | DirectionalLight} being visualized. + */ + update(): void; + + /** + * Frees the GPU-related resources allocated by this instance + * @remarks + * Call this method whenever this instance is no longer used in your app. + */ + dispose(): void; +} diff --git a/src-testing/src/helpers/GridHelper.d.ts b/src-testing/src/helpers/GridHelper.d.ts new file mode 100644 index 000000000..0b786b992 --- /dev/null +++ b/src-testing/src/helpers/GridHelper.d.ts @@ -0,0 +1,47 @@ +import { BufferGeometry } from "../core/BufferGeometry.js"; +import { LineBasicMaterial } from "../materials/LineBasicMaterial.js"; +import { ColorRepresentation } from "../math/Color.js"; +import { LineSegments } from "../objects/LineSegments.js"; + +/** + * The {@link GridHelper} is an object to define grids + * @remarks + * Grids are two-dimensional arrays of lines. + * @example + * ```typescript + * const size = 10; + * const divisions = 10; + * const {@link GridHelper} = new THREE.GridHelper(size, divisions); + * scene.add(gridHelper); + * ``` + * @see Example: {@link https://threejs.org/examples/#webgl_helpers | WebGL / helpers} + * @see {@link https://threejs.org/docs/index.html#api/en/helpers/GridHelper | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/helpers/GridHelper.js | Source} + */ +export class GridHelper extends LineSegments { + /** + * Creates a new {@link GridHelper} of size 'size' and divided into 'divisions' segments per side + * @remarks + * Colors are optional. + * @param size The size of the grid. Default `10` + * @param divisions The number of divisions across the grid. Default `10` + * @param colorCenterLine The color of the centerline. This can be a {@link THREE.Color | Color}, a hexadecimal value and an CSS-Color name. Default `0x444444` + * @param colorGrid The color of the lines of the grid. This can be a {@link THREE.Color | Color}, a hexadecimal value and an CSS-Color name. Default `0x888888` + */ + constructor(size?: number, divisions?: number, color1?: ColorRepresentation, color2?: ColorRepresentation); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @override + * @defaultValue `GridHelper` + */ + override readonly type: string | "GridHelper"; + + /** + * Frees the GPU-related resources allocated by this instance + * @remarks + * Call this method whenever this instance is no longer used in your app. + */ + dispose(): void; +} diff --git a/src-testing/src/helpers/HemisphereLightHelper.d.ts b/src-testing/src/helpers/HemisphereLightHelper.d.ts new file mode 100644 index 000000000..80366b63b --- /dev/null +++ b/src-testing/src/helpers/HemisphereLightHelper.d.ts @@ -0,0 +1,72 @@ +import { Object3D } from "../core/Object3D.js"; +import { HemisphereLight } from "../lights/HemisphereLight.js"; +import { MeshBasicMaterial } from "../materials/MeshBasicMaterial.js"; +import { ColorRepresentation } from "../math/Color.js"; +import { Matrix4 } from "../math/Matrix4.js"; + +/** + * Creates a visual aid consisting of a spherical {@link THREE.Mesh | Mesh} for a {@link THREE.HemisphereLight | HemisphereLight}. + * @example + * ```typescript + * const light = new THREE.HemisphereLight(0xffffbb, 0x080820, 1); + * const helper = new THREE.HemisphereLightHelper(light, 5); + * scene.add(helper); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/helpers/HemisphereLightHelper | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/helpers/HemisphereLightHelper.js | Source} + */ +export class HemisphereLightHelper extends Object3D { + /** + * Create a new instance of {@link HemisphereLightHelper} + * @param light The light being visualized. + * @param size Thr sphere size + * @param color If this is not the set the helper will take the color of the light. + */ + constructor(light: HemisphereLight, size: number, color?: ColorRepresentation); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @override + * @defaultValue `HemisphereLightHelper` + */ + override readonly type: string | "HemisphereLightHelper"; + + /** + * Reference to the HemisphereLight being visualized. + */ + light: HemisphereLight; + + /** + * Reference to the {@link THREE.HemisphereLight.matrixWorld | light.matrixWorld}. + */ + matrix: Matrix4; + + /** + * Is set to `false`, as the helper is using the {@link THREE.HemisphereLight.matrixWorld | light.matrixWorld}. + * @see {@link THREE.Object3D.matrixAutoUpdate | Object3D.matrixAutoUpdate}. + * @defaultValue `false`. + */ + override matrixAutoUpdate: boolean; + + material: MeshBasicMaterial; // TODO: Double check if this need to be exposed or not. + + /** + * The color parameter passed in the constructor. + * @remarks If this is changed, the helper's color will update the next time {@link update} is called. + * @defaultValue `undefined` + */ + color: ColorRepresentation | undefined; + + /** + * Updates the helper to match the position and direction of the {@link .light | HemisphereLight}. + */ + update(): void; + + /** + * Frees the GPU-related resources allocated by this instance + * @remarks + * Call this method whenever this instance is no longer used in your app. + */ + dispose(): void; +} diff --git a/src-testing/src/helpers/PlaneHelper.d.ts b/src-testing/src/helpers/PlaneHelper.d.ts new file mode 100644 index 000000000..43c9821cb --- /dev/null +++ b/src-testing/src/helpers/PlaneHelper.d.ts @@ -0,0 +1,50 @@ +import { Plane } from "../math/Plane.js"; +import { LineSegments } from "../objects/LineSegments.js"; + +/** + * Helper object to visualize a {@link THREE.Plane | Plane}. + * @example + * ```typescript + * const plane = new THREE.Plane(new THREE.Vector3(1, 1, 0.2), 3); + * const helper = new THREE.PlaneHelper(plane, 1, 0xffff00); + * scene.add(helper); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/helpers/PlaneHelper | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/helpers/PlaneHelper.js | Source} + */ +export class PlaneHelper extends LineSegments { + /** + * Creates a new wireframe representation of the passed plane. + * @param plane The plane to visualize. + * @param size Side length of plane helper. Expects a `Float`. Default `1` + * @param hex Color. Default `0xffff00` + */ + constructor(plane: Plane, size?: number, hex?: number); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @override + * @defaultValue `PlaneHelper` + */ + override readonly type: string | "PlaneHelper"; + + /** + * The {@link Plane | plane} being visualized. + */ + plane: Plane; + + /** + * The side lengths of plane helper. + * @remarks Expects a `Float` + * @defaultValue `1` + */ + size: number; + + /** + * Frees the GPU-related resources allocated by this instance + * @remarks + * Call this method whenever this instance is no longer used in your app. + */ + dispose(): void; +} diff --git a/src-testing/src/helpers/PointLightHelper.d.ts b/src-testing/src/helpers/PointLightHelper.d.ts new file mode 100644 index 000000000..7d61da5e3 --- /dev/null +++ b/src-testing/src/helpers/PointLightHelper.d.ts @@ -0,0 +1,73 @@ +import { Object3D } from "../core/Object3D.js"; +import { PointLight } from "../lights/PointLight.js"; +import { ColorRepresentation } from "../math/Color.js"; +import { Matrix4 } from "../math/Matrix4.js"; + +/** + * This displays a helper object consisting of a spherical {@link THREE.Mesh | Mesh} for visualizing a {@link THREE.PointLight | PointLight}. + * @example + * ```typescript + * const pointLight = new THREE.PointLight(0xff0000, 1, 100); + * pointLight.position.set(10, 10, 10); + * scene.add(pointLight); + * const sphereSize = 1; + * const {@link PointLightHelper} = new THREE.PointLightHelper(pointLight, sphereSize); + * scene.add(pointLightHelper); + * ``` + * @see Example: {@link https://threejs.org/examples/#webgl_helpers | WebGL / helpers} + * @see {@link https://threejs.org/docs/index.html#api/en/helpers/PointLightHelper | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/helpers/PointLightHelper.js | Source} + */ +export class PointLightHelper extends Object3D { + /** + * Create a new instance of {@link PointLightHelper} + * @param light The light to be visualized. + * @param sphereSize The size of the sphere helper. Expects a `Float`. Default `1` + * @param color If this is not the set the helper will take the color of the light. + */ + constructor(light: PointLight, sphereSize?: number, color?: ColorRepresentation); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @override + * @defaultValue `PointLightHelper` + */ + override readonly type: string | "PointLightHelper"; + + /** + * The {@link THREE.PointLight | PointLight} that is being visualized. + */ + light: PointLight; + + /** + * Reference to the {@link THREE.PointLight.matrixWorld | light.matrixWorld}. + */ + matrix: Matrix4; + + /** + * The color parameter passed in the constructor. + * @remarks If this is changed, the helper's color will update the next time {@link update} is called. + * @defaultValue `undefined` + */ + color: ColorRepresentation | undefined; + + /** + * Is set to `false`, as the helper is using the {@link THREE.PointLight.matrixWorld | light.matrixWorld}. + * @see {@link THREE.Object3D.matrixAutoUpdate | Object3D.matrixAutoUpdate}. + * @defaultValue `false`. + */ + override matrixAutoUpdate: boolean; + + /** + * Updates the helper to match the position of the {@link THREE..light | .light}. + */ + update(): void; + + /** + * Frees the GPU-related resources allocated by this instance + * @remarks + * Call this method whenever this instance is no longer used in your app. + */ + dispose(): void; +} diff --git a/src-testing/src/helpers/PolarGridHelper.d.ts b/src-testing/src/helpers/PolarGridHelper.d.ts new file mode 100644 index 000000000..994d71c94 --- /dev/null +++ b/src-testing/src/helpers/PolarGridHelper.d.ts @@ -0,0 +1,55 @@ +import { ColorRepresentation } from "../math/Color.js"; +import { LineSegments } from "../objects/LineSegments.js"; + +/** + * The {@link PolarGridHelper} is an object to define polar grids + * @remarks + * Grids are two-dimensional arrays of lines. + * @example + * ```typescript + * const radius = 10; + * const sectors = 16; + * const rings = 8; + * const divisions = 64; + * const helper = new THREE.PolarGridHelper(radius, sectors, rings, divisions); + * scene.add(helper); + * ``` + * @see Example: {@link https://threejs.org/examples/#webgl_helpers | WebGL / helpers} + * @see {@link https://threejs.org/docs/index.html#api/en/helpers/PolarGridHelper | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/helpers/PolarGridHelper.js | Source} + */ +export class PolarGridHelper extends LineSegments { + /** + * Creates a new {@link PolarGridHelper} of radius 'radius' with 'sectors' number of sectors and 'rings' number of rings, where each circle is smoothed into 'divisions' number of line segments. + * @remarks Colors are optional. + * @param radius The radius of the polar grid. This can be any positive number. Default `10`. + * @param sectors The number of sectors the grid will be divided into. This can be any positive integer. Default `16`. + * @param rings The number of rings. This can be any positive integer. Default `8`. + * @param divisions The number of line segments used for each circle. This can be any positive integer that is 3 or greater. Default `64`. + * @param color1 The first color used for grid elements. This can be a {@link THREE.Color | Color}, a hexadecimal value and an CSS-Color name. Default `0x444444`. + * @param color2 The second color used for grid elements. This can be a {@link THREE.Color | Color}, a hexadecimal value and an CSS-Color name. Default `0x888888`. + */ + constructor( + radius?: number, + radials?: number, + circles?: number, + divisions?: number, + color1?: ColorRepresentation, + color2?: ColorRepresentation, + ); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @override + * @defaultValue `PolarGridHelper` + */ + override readonly type: string | "PolarGridHelper"; + + /** + * Frees the GPU-related resources allocated by this instance + * @remarks + * Call this method whenever this instance is no longer used in your app. + */ + dispose(): void; +} diff --git a/src-testing/src/helpers/SkeletonHelper.d.ts b/src-testing/src/helpers/SkeletonHelper.d.ts new file mode 100644 index 000000000..772ebf30e --- /dev/null +++ b/src-testing/src/helpers/SkeletonHelper.d.ts @@ -0,0 +1,78 @@ +import { Object3D } from "../core/Object3D.js"; +import { Matrix4 } from "../math/Matrix4.js"; +import { Bone } from "../objects/Bone.js"; +import { LineSegments } from "../objects/LineSegments.js"; +import { SkinnedMesh } from "../objects/SkinnedMesh.js"; + +/** + * A helper object to assist with visualizing a {@link Skeleton | Skeleton} + * @remarks + * The helper is rendered using a {@link LineBasicMaterial | LineBasicMaterial}. + * @example + * ```typescript + * const helper = new THREE.SkeletonHelper(skinnedMesh); + * scene.add(helper); + * ``` + * @see Example: {@link https://threejs.org/examples/#webgl_animation_skinning_blending | WebGL / animation / skinning / blending} + * @see Example: {@link https://threejs.org/examples/#webgl_animation_skinning_morph | WebGL / animation / skinning / morph} + * @see Example: {@link https://threejs.org/examples/#webgl_loader_bvh | WebGL / loader / bvh } + * @see {@link https://threejs.org/docs/index.html#api/en/helpers/SkeletonHelper | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/helpers/SkeletonHelper.js | Source} + */ +export class SkeletonHelper extends LineSegments { + /** + * Create a new instance of {@link SkeletonHelper} + * @param object Usually an instance of {@link THREE.SkinnedMesh | SkinnedMesh}. + * However, any instance of {@link THREE.Object3D | Object3D} can be used if it represents a hierarchy of {@link Bone | Bone}s (via {@link THREE.Object3D.children | Object3D.children}). + */ + constructor(object: SkinnedMesh | Object3D); + + /** + * Read-only flag to check if a given object is of type {@link SkeletonHelper}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isSkeletonHelper = true; + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @override + * @defaultValue `SkeletonHelper` + */ + override readonly type: string | "SkeletonHelper"; + + /** + * The list of bones that the helper renders as {@link Line | Lines}. + */ + bones: Bone[]; + + /** + * The object passed in the constructor. + */ + root: SkinnedMesh | Object3D; + + /** + * Reference to the {@link THREE.Object3D.matrixWorld | root.matrixWorld}. + */ + matrix: Matrix4; + + /** + * Is set to `false`, as the helper is using the {@link THREE.Object3D.matrixWorld | root.matrixWorld}. + * @see {@link THREE.Object3D.matrixAutoUpdate | Object3D.matrixAutoUpdate}. + * @defaultValue `false`. + */ + override matrixAutoUpdate: boolean; + + /** + * Updates the helper. + */ + update(): void; + + /** + * Frees the GPU-related resources allocated by this instance + * @remarks + * Call this method whenever this instance is no longer used in your app. + */ + dispose(): void; +} diff --git a/src-testing/src/helpers/SpotLightHelper.d.ts b/src-testing/src/helpers/SpotLightHelper.d.ts new file mode 100644 index 000000000..f620ed990 --- /dev/null +++ b/src-testing/src/helpers/SpotLightHelper.d.ts @@ -0,0 +1,77 @@ +import { Object3D } from "../core/Object3D.js"; +import { Light } from "../lights/Light.js"; +import { ColorRepresentation } from "../math/Color.js"; +import { Matrix4 } from "../math/Matrix4.js"; +import { LineSegments } from "../objects/LineSegments.js"; + +/** + * This displays a cone shaped helper object for a {@link THREE.SpotLight | SpotLight}. + * @example + * ```typescript + * const spotLight = new THREE.SpotLight(0xffffff); + * spotLight.position.set(10, 10, 10); + * scene.add(spotLight); + * const {@link SpotLightHelper} = new THREE.SpotLightHelper(spotLight); + * scene.add(spotLightHelper); + * ``` + * @see Example: {@link https://threejs.org/examples/#webgl_lights_spotlights | WebGL/ lights / spotlights } + * @see {@link https://threejs.org/docs/index.html#api/en/helpers/SpotLightHelper | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/helpers/SpotLightHelper.js | Source} + */ +export class SpotLightHelper extends Object3D { + /** + * Create a new instance of {@link SpotLightHelper} + * @param light The {@link THREE.SpotLight | SpotLight} to be visualized. + * @param color If this is not the set the helper will take the color of the light. Default `light.color` + */ + constructor(light: Light, color?: ColorRepresentation); + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @override + * @defaultValue `SpotLightHelper` + */ + override readonly type: string | "SpotLightHelper"; + + /** + * {@link THREE.LineSegments | LineSegments} used to visualize the light. + */ + cone: LineSegments; + + /** + * Reference to the {@link THREE.SpotLight | SpotLight} being visualized. + */ + light: Light; + + /** + * Reference to the spotLight's {@link Object3D.matrixWorld | matrixWorld}. + */ + matrix: Matrix4; + + /** + * The color parameter passed in the constructor. + * If this is changed, the helper's color will update the next time {@link SpotLightHelper.update | update} is called. + * @defaultValue `undefined` + */ + color: ColorRepresentation | undefined; + + /** + * Is set to `false`, as the helper is using the {@link THREE.Light.matrixWorld | light.matrixWorld}. + * @see {@link THREE.Object3D.matrixAutoUpdate | Object3D.matrixAutoUpdate}. + * @defaultValue `false`. + */ + override matrixAutoUpdate: boolean; + + /** + * Updates the light helper. + */ + update(): void; + + /** + * Frees the GPU-related resources allocated by this instance + * @remarks + * Call this method whenever this instance is no longer used in your app. + */ + dispose(): void; +} diff --git a/src-testing/src/lights/AmbientLight.d.ts b/src-testing/src/lights/AmbientLight.d.ts new file mode 100644 index 000000000..7000a37e7 --- /dev/null +++ b/src-testing/src/lights/AmbientLight.d.ts @@ -0,0 +1,36 @@ +import { ColorRepresentation } from "../math/Color.js"; +import { Light } from "./Light.js"; + +/** + * This light globally illuminates all objects in the scene equally. + * @remarks This light cannot be used to cast shadows as it does not have a direction. + * @example + * ```typescript + * const light = new THREE.AmbientLight(0x404040); // soft white light + * scene.add(light); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/lights/AmbientLight | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/lights/AmbientLight.js | Source} + */ +export class AmbientLight extends Light { + /** + * Creates a new {@link AmbientLight}. + * @param color Numeric value of the RGB component of the color. Default `0xffffff` + * @param intensity Numeric value of the light's strength/intensity. Expects a `Float`. Default `1` + */ + constructor(color?: ColorRepresentation, intensity?: number); + + /** + * Read-only flag to check if a given object is of type {@link AmbientLight}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isAmbientLight: true; + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `AmbientLight` + */ + override readonly type: string | "AmbientLight"; +} diff --git a/src-testing/src/lights/DirectionalLight.d.ts b/src-testing/src/lights/DirectionalLight.d.ts new file mode 100644 index 000000000..3d43b7d89 --- /dev/null +++ b/src-testing/src/lights/DirectionalLight.d.ts @@ -0,0 +1,103 @@ +import { Object3D } from "../core/Object3D.js"; +import { ColorRepresentation } from "../math/Color.js"; +import { Vector3 } from "../math/Vector3.js"; +import { DirectionalLightShadow } from "./DirectionalLightShadow.js"; +import { Light } from "./Light.js"; + +/** + * A light that gets emitted in a specific direction + * @remarks + * This light will behave as though it is infinitely far away and the rays produced from it are all parallel + * The common use case for this is to simulate daylight; the sun is far enough away that its position can be considered to be infinite, and all light rays coming from it are parallel. + * A common point of confusion for directional lights is that setting the rotation has no effect + * @remarks + * This is because three.js's {@link DirectionalLight} is the equivalent to what is often called a 'Target Direct Light' in other applications. + * This means that its direction is calculated as pointing from the light's {@link THREE.Object3D.position | position} to the {@link THREE.DirectionalLight.target | target}'s + * position (as opposed to a 'Free Direct Light' that just has a rotation component). + * See the {@link THREE.DirectionalLight.target | target} property below for details on updating the target. + * @example + * ```typescript + * // White directional light at half intensity shining from the top. + * const {@link DirectionalLight} = new THREE.DirectionalLight(0xffffff, 0.5); + * scene.add(directionalLight); + * ``` + * @see Example: {@link https://threejs.org/examples/#misc_controls_fly | controls / fly } + * @see Example: {@link https://threejs.org/examples/#webgl_effects_parallaxbarrier | effects / parallaxbarrier } + * @see Example: {@link https://threejs.org/examples/#webgl_effects_stereo | effects / stereo } + * @see Example: {@link https://threejs.org/examples/#webgl_geometry_extrude_splines | geometry / extrude / splines } + * @see Example: {@link https://threejs.org/examples/#webgl_materials_bumpmap | materials / bumpmap } + * @see {@link https://threejs.org/docs/index.html#api/en/lights/DirectionalLight | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/lights/DirectionalLight.js | Source} + */ +export class DirectionalLight extends Light { + /** + * Creates a new {@link DirectionalLight}. + * @param color Hexadecimal color of the light. Default `0xffffff` _(white)_. + * @param intensity Numeric value of the light's strength/intensity. Expects a `Float`. Default `1` + */ + constructor(color?: ColorRepresentation, intensity?: number); + + /** + * Read-only flag to check if a given object is of type {@link DirectionalLight}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isDirectionalLight: true; + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `DirectionalLight` + */ + override readonly type: string | "DirectionalLight"; + + /** + * Whether the object gets rendered into shadow map. + * @remarks + * If set to `true` light will cast dynamic shadows. + * **Warning**: This is expensive and requires tweaking to get shadows looking right. + * @see {@link THREE.DirectionalLightShadow | DirectionalLightShadow} for details. + * @defaultValue `false` + */ + override castShadow: boolean; + + /** + * This is set equal to {@link THREE.Object3D.DEFAULT_UP}, so that the light shines from the top down. + * @defaultValue {@link Object3D.DEFAULT_UP} _(0, 1, 0)_ + */ + override readonly position: Vector3; + + /** + * A {@link THREE.DirectionalLightShadow | DirectionalLightShadow} used to calculate shadows for this light. + * @defaultValue `new THREE.DirectionalLightShadow()` + */ + shadow: DirectionalLightShadow; + + /** + * The {@link DirectionalLight} points from its {@link DirectionalLight.position | position} to target.position. + * @remarks **Note**: For the target's position to be changed to anything other than the default, + * it must be added to the {@link THREE.Scene | scene} using + * ```typescript + * Scene.add( light.target ); + * ``` + * This is so that the target's {@link THREE.Object3D.matrixWorld | matrixWorld} gets automatically updated each frame. + * + * It is also possible to set the target to be another object in the scene (anything with a {@link THREE.Object3D.position | position} property), + * like so: + * ```typescript + * const targetObject = new THREE.Object3D(); + * scene.add(targetObject); + * light.target = targetObject; + * ``` + * The {@link DirectionalLight} will now track the target object. + * @defaultValue `new THREE.Object3D()` at _(0, 0, 0)_ + */ + target: Object3D; + + /** + * Frees the GPU-related resources allocated by this instance + * @remarks + * Call this method whenever this instance is no longer used in your app. + */ + dispose(): void; +} diff --git a/src-testing/src/lights/DirectionalLightShadow.d.ts b/src-testing/src/lights/DirectionalLightShadow.d.ts new file mode 100644 index 000000000..805e4fa0b --- /dev/null +++ b/src-testing/src/lights/DirectionalLightShadow.d.ts @@ -0,0 +1,73 @@ +import { OrthographicCamera } from "../cameras/OrthographicCamera.js"; +import { LightShadow } from "./LightShadow.js"; + +/** + * This is used internally by {@link DirectionalLight | DirectionalLights} for calculating shadows. + * Unlike the other shadow classes, this uses an {@link THREE.OrthographicCamera | OrthographicCamera} to calculate the shadows, + * rather than a {@link THREE.PerspectiveCamera | PerspectiveCamera} + * @remarks + * This is because light rays from a {@link THREE.DirectionalLight | DirectionalLight} are parallel. + * @example + * ```typescript + * //Create a WebGLRenderer and turn on shadows in the renderer + * const renderer = new THREE.WebGLRenderer(); + * renderer.shadowMap.enabled = true; + * renderer.shadowMap.type = THREE.PCFSoftShadowMap; // default THREE.PCFShadowMap + * //Create a DirectionalLight and turn on shadows for the light + * const light = new THREE.DirectionalLight(0xffffff, 1); + * light.position.set(0, 1, 0); //default; light shining from top + * light.castShadow = true; // default false + * scene.add(light); + * //Set up shadow properties for the light + * light.shadow.mapSize.width = 512; // default + * light.shadow.mapSize.height = 512; // default + * light.shadow.camera.near = 0.5; // default + * light.shadow.camera.far = 500; // default + * //Create a sphere that cast shadows (but does not receive them) + * const sphereGeometry = new THREE.SphereGeometry(5, 32, 32); + * const sphereMaterial = new THREE.MeshStandardMaterial({ + * color: 0xff0000 + * }); + * const sphere = new THREE.Mesh(sphereGeometry, sphereMaterial); + * sphere.castShadow = true; //default is false + * sphere.receiveShadow = false; //default + * scene.add(sphere); + * //Create a plane that receives shadows (but does not cast them) + * const planeGeometry = new THREE.PlaneGeometry(20, 20, 32, 32); + * const planeMaterial = new THREE.MeshStandardMaterial({ + * color: 0x00ff00 + * }) + * const plane = new THREE.Mesh(planeGeometry, planeMaterial); + * plane.receiveShadow = true; + * scene.add(plane); + * //Create a helper for the shadow camera (optional) + * const helper = new THREE.CameraHelper(light.shadow.camera); + * scene.add(helper); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/lights/shadows/DirectionalLightShadow | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/lights/DirectionalLightShadow.js | Source} + */ +export class DirectionalLightShadow extends LightShadow { + /** + * Create a new instance of {@link DirectionalLightShadow} + */ + constructor(); + + /** + * Read-only flag to check if a given object is of type {@link DirectionalLightShadow}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isDirectionalLightShadow: true; + + /** + * The light's view of the world. + * @remarks This is used to generate a depth map of the scene; objects behind other objects from the light's perspective will be in shadow. + * @defaultValue is an {@link THREE.OrthographicCamera | OrthographicCamera} with + * {@link OrthographicCamera.left | left} and {@link OrthographicCamera.bottom | bottom} set to -5, + * {@link OrthographicCamera.right | right} and {@link OrthographicCamera.top | top} set to 5, + * the {@link OrthographicCamera.near | near} clipping plane at 0.5 and + * the {@link OrthographicCamera.far | far} clipping plane at 500. + */ + camera: OrthographicCamera; +} diff --git a/src-testing/src/lights/HemisphereLight.d.ts b/src-testing/src/lights/HemisphereLight.d.ts new file mode 100644 index 000000000..1a796dfc8 --- /dev/null +++ b/src-testing/src/lights/HemisphereLight.d.ts @@ -0,0 +1,61 @@ +import { Color, ColorRepresentation } from "../math/Color.js"; +import { Vector3 } from "../math/Vector3.js"; +import { Light } from "./Light.js"; + +/** + * A light source positioned directly above the scene, with color fading from the sky color to the ground color. + * @remarks This light cannot be used to cast shadows. + * @example + * ```typescript + * const light = new THREE.HemisphereLight(0xffffbb, 0x080820, 1); + * scene.add(light); + * ``` + * @see Example: {@link https://threejs.org/examples/#webgl_animation_skinning_blending | animation / skinning / blending } + * @see Example: {@link https://threejs.org/examples/#webgl_lights_hemisphere | lights / hemisphere } + * @see Example: {@link https://threejs.org/examples/#misc_controls_pointerlock | controls / pointerlock } + * @see Example: {@link https://threejs.org/examples/#webgl_loader_collada_kinematics | loader / collada / kinematics } + * @see Example: {@link https://threejs.org/examples/#webgl_loader_stl | loader / stl } + * @see {@link https://threejs.org/docs/index.html#api/en/lights/HemisphereLight | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/lights/HemisphereLight.js | Source} + */ +export class HemisphereLight extends Light { + /** + * Creates a new {@link HemisphereLight}. + * @param skyColor Hexadecimal color of the sky. Expects a `Integer`. Default `0xffffff` _(white)_. + * @param groundColor Hexadecimal color of the ground. Expects a `Integer`. Default `0xffffff` _(white)_. + * @param intensity Numeric value of the light's strength/intensity. Expects a `Float`. Default `1`. + */ + constructor(skyColor?: ColorRepresentation, groundColor?: ColorRepresentation, intensity?: number); + + /** + * Read-only flag to check if a given object is of type {@link HemisphereLight}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isHemisphereLight: true; + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `HemisphereLight` + */ + override readonly type: string | "HemisphereLight"; + + /** + * This is set equal to {@link THREE.Object3D.DEFAULT_UP}, so that the light shines from the top down. + * @defaultValue {@link Object3D.DEFAULT_UP} _(0, 1, 0)_ + */ + override readonly position: Vector3; + + /** + * The light's sky color, as passed in the constructor. + * @defaultValue `new THREE.Color()` set to white _(0xffffff)_. + */ + override color: Color; + + /** + * The light's ground color, as passed in the constructor. + * @defaultValue `new THREE.Color()` set to white _(0xffffff)_. + */ + groundColor: Color; +} diff --git a/src-testing/src/lights/Light.d.ts b/src-testing/src/lights/Light.d.ts new file mode 100644 index 000000000..3ae757e3b --- /dev/null +++ b/src-testing/src/lights/Light.d.ts @@ -0,0 +1,82 @@ +import { JSONMeta, Object3D, Object3DJSON } from "../core/Object3D.js"; +import { Color, ColorRepresentation } from "../math/Color.js"; +import { LightShadow, LightShadowJSON } from "./LightShadow.js"; + +export interface LightJSON extends Object3DJSON { + color: number; + intensity: number; + + groundColor?: number; + + distance?: number; + angle?: number; + decay?: number; + penumbra?: number; + + shadow?: LightShadowJSON; + target?: string; +} + +/** + * Abstract base class for lights. + * @remarks All other light types inherit the properties and methods described here. + */ +export abstract class Light extends Object3D { + /** + * Creates a new {@link Light} + * @remarks + * **Note** that this is not intended to be called directly (use one of derived classes instead). + * @param color Hexadecimal color of the light. Default `0xffffff` _(white)_. + * @param intensity Numeric value of the light's strength/intensity. Expects a `Float`. Default `1`. + */ + constructor(color?: ColorRepresentation, intensity?: number); + + /** + * Read-only flag to check if a given object is of type {@link HemisphereLight}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isLight: true; + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `Light` + */ + override readonly type: string | "Light"; + + /** + * Color of the light. \ + * @defaultValue `new THREE.Color(0xffffff)` _(white)_. + */ + color: Color; + + /** + * The light's intensity, or strength. + * The units of intensity depend on the type of light. + * @defaultValue `1` + */ + intensity: number; + + /** + * A {@link THREE.LightShadow | LightShadow} used to calculate shadows for this light. + * @remarks Available only on Light's that support shadows. + */ + shadow: TShadowSupport; + + /** + * Copies value of all the properties from the {@link Light | source} to this instance. + * @param source + * @param recursive + */ + copy(source: this, recursive?: boolean): this; + + /** + * Frees the GPU-related resources allocated by this instance + * @remarks + * Call this method whenever this instance is no longer used in your app. + */ + dispose(): void; + + toJSON(meta?: JSONMeta): LightJSON; +} diff --git a/src-testing/src/lights/LightProbe.d.ts b/src-testing/src/lights/LightProbe.d.ts new file mode 100644 index 000000000..a63ffdc57 --- /dev/null +++ b/src-testing/src/lights/LightProbe.d.ts @@ -0,0 +1,47 @@ +import { SphericalHarmonics3 } from "../math/SphericalHarmonics3.js"; +import { Light } from "./Light.js"; + +/** + * Light probes are an alternative way of adding light to a 3D scene. + * @remarks + * Unlike classical light sources (e.g + * directional, point or spot lights), light probes do not emit light + * Instead they store information about light passing through 3D space + * During rendering, the light that hits a 3D object is approximated by using the data from the light probe. + * Light probes are usually created from (radiance) environment maps + * The class {@link THREE.LightProbeGenerator | LightProbeGenerator} can be used to create light probes from + * instances of {@link THREE.CubeTexture | CubeTexture} or {@link THREE.WebGLCubeRenderTarget | WebGLCubeRenderTarget} + * However, light estimation data could also be provided in other forms e.g + * by WebXR + * This enables the rendering of augmented reality content that reacts to real world lighting. + * The current probe implementation in three.js supports so-called diffuse light probes + * This type of light probe is functionally equivalent to an irradiance environment map. + * @see Example: {@link https://threejs.org/examples/#webgl_lightprobe | WebGL / light probe } + * @see Example: {@link https://threejs.org/examples/#webgl_lightprobe_cubecamera | WebGL / light probe / cube camera } + * @see {@link https://threejs.org/docs/index.html#api/en/lights/LightProbe | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/lights/LightProbe.js | Source} + */ +export class LightProbe extends Light { + /** + * Creates a new LightProbe. + * @param sh An instance of {@link THREE.SphericalHarmonics3 | SphericalHarmonics3}. Default `new THREE.SphericalHarmonics3()``. + * @param intensity Numeric value of the light probe's intensity. Expects a `Float`. Default `1`. + */ + constructor(sh?: SphericalHarmonics3, intensity?: number); + + /** + * Read-only flag to check if a given object is of type {@link DirectionalLight}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isLightProbe: true; + + /** + * A light probe uses spherical harmonics to encode lighting information. + * @defaultValue `new THREE.SphericalHarmonics3()` + */ + sh: SphericalHarmonics3; + + /** @internal */ + fromJSON(json: {}): LightProbe; +} diff --git a/src-testing/src/lights/LightShadow.d.ts b/src-testing/src/lights/LightShadow.d.ts new file mode 100644 index 000000000..53c163c3e --- /dev/null +++ b/src-testing/src/lights/LightShadow.d.ts @@ -0,0 +1,169 @@ +import { Camera } from "../cameras/Camera.js"; +import { Object3DJSONObject } from "../core/Object3D.js"; +import { Frustum } from "../math/Frustum.js"; +import { Matrix4 } from "../math/Matrix4.js"; +import { Vector2, Vector2Tuple } from "../math/Vector2.js"; +import { Vector4 } from "../math/Vector4.js"; +import { WebGLRenderTarget } from "../renderers/WebGLRenderTarget.js"; +import { Light } from "./Light.js"; + +export interface LightShadowJSON { + intensity?: number; + bias?: number; + normalBias?: number; + radius?: number; + mapSize?: Vector2Tuple; + + camera: Omit; +} + +/** + * Serves as a base class for the other shadow classes. + * @see {@link https://threejs.org/docs/index.html#api/en/lights/shadows/LightShadow | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/lights/LightShadow.js | Source} + */ +export class LightShadow { + /** + * Create a new instance of {@link LightShadow} + * @param camera The light's view of the world. + */ + constructor(camera: TCamera); + + /** + * The light's view of the world. + * @remark This is used to generate a depth map of the scene; objects behind other objects from the light's perspective will be in shadow. + */ + camera: TCamera; + + /** + * The intensity of the shadow. The default is `1`. Valid values are in the range `[0, 1]`. + */ + intensity: number; + + /** + * Shadow map bias, how much to add or subtract from the normalized depth when deciding whether a surface is in shadow. + * @remark The Very tiny adjustments here (in the order of 0.0001) may help reduce artifacts in shadows. + * @remarks Expects a `Float` + * @defaultValue `0` + */ + bias: number; + + /** + * Defines how much the position used to query the shadow map is offset along the object normal. + * @remark The Increasing this value can be used to reduce shadow acne especially in large scenes where light shines onto geometry at a shallow angle. + * @remark The cost is that shadows may appear distorted. + * @remarks Expects a `Float` + * @defaultValue `0` + */ + normalBias: number; + + /** + * Setting this to values greater than 1 will blur the edges of the shadow.toi + * @remark High values will cause unwanted banding effects in the shadows - a greater {@link LightShadow.mapSize | mapSize + * will allow for a higher value to be used here before these effects become visible. + * @remark If {@link THREE.WebGLRenderer.shadowMap.type | WebGLRenderer.shadowMap.type} is set to {@link Renderer | PCFSoftShadowMap}, + * radius has no effect and it is recommended to increase softness by decreasing {@link LightShadow.mapSize | mapSize} instead. + * @remark Note that this has no effect if the {@link THREE.WebGLRenderer.shadowMap | WebGLRenderer.shadowMap}.{@link THREE.WebGLShadowMap.type | type} + * is set to {@link THREE.BasicShadowMap | BasicShadowMap}. + * @remarks Expects a `Float` + * @defaultValue `1` + */ + radius: number; + + /** + * The amount of samples to use when blurring a VSM shadow map. + * @remarks Expects a `Integer` + * @defaultValue `8` + */ + blurSamples: number; + + /** + * A {@link THREE.Vector2 | Vector2} defining the width and height of the shadow map. + * @remarks Higher values give better quality shadows at the cost of computation time. + * @remarks Values must be powers of 2, up to the {@link THREE.WebGLRenderer.capabilities | WebGLRenderer.capabilities}.maxTextureSize for a given device, + * although the width and height don't have to be the same (so, for example, (512, 1024) is valid). + * @defaultValue `new THREE.Vector2(512, 512)` + */ + mapSize: Vector2; + + /** + * The depth map generated using the internal camera; a location beyond a pixel's depth is in shadow. Computed internally during rendering. + * @defaultValue null + */ + map: WebGLRenderTarget | null; + + /** + * The distribution map generated using the internal camera; an occlusion is calculated based on the distribution of depths. Computed internally during rendering. + * @defaultValue null + */ + mapPass: WebGLRenderTarget | null; + + /** + * Model to shadow camera space, to compute location and depth in shadow map. + * Stored in a {@link Matrix4 | Matrix4}. + * @remarks This is computed internally during rendering. + * @defaultValue new THREE.Matrix4() + */ + matrix: Matrix4; + + /** + * Enables automatic updates of the light's shadow. If you do not require dynamic lighting / shadows, you may set this to `false`. + * @defaultValue `true` + */ + autoUpdate: boolean; + + /** + * When set to `true`, shadow maps will be updated in the next `render` call. + * If you have set {@link autoUpdate} to `false`, you will need to set this property to `true` and then make a render call to update the light's shadow. + * @defaultValue `false` + */ + needsUpdate: boolean; + + /** + * Used internally by the renderer to get the number of viewports that need to be rendered for this shadow. + */ + getViewportCount(): number; + + /** + * Copies value of all the properties from the {@link {@link LightShadow} | source} to this Light. + * @param source + */ + copy(source: LightShadow): this; + + /** + * Creates a new {@link LightShadow} with the same properties as this one. + */ + clone(recursive?: boolean): this; + + /** + * Serialize this LightShadow. + */ + toJSON(): LightShadowJSON; + + /** + * Gets the shadow cameras frustum + * @remarks + * Used internally by the renderer to cull objects. + */ + getFrustum(): Frustum; + + /** + * Update the matrices for the camera and shadow, used internally by the renderer. + * @param light The light for which the shadow is being rendered. + */ + updateMatrices(light: Light): void; + + getViewport(viewportIndex: number): Vector4; + + /** + * Used internally by the renderer to extend the shadow map to contain all viewports + */ + getFrameExtents(): Vector2; + + /** + * Frees the GPU-related resources allocated by this instance + * @remarks + * Call this method whenever this instance is no longer used in your app. + */ + dispose(): void; +} diff --git a/src-testing/src/lights/PointLight.d.ts b/src-testing/src/lights/PointLight.d.ts new file mode 100644 index 000000000..c13044e12 --- /dev/null +++ b/src-testing/src/lights/PointLight.d.ts @@ -0,0 +1,102 @@ +import { ColorRepresentation } from "../math/Color.js"; +import { Light } from "./Light.js"; +import { PointLightShadow } from "./PointLightShadow.js"; + +/** + * A light that gets emitted from a single point in all directions + * @remarks + * A common use case for this is to replicate the light emitted from a bare lightbulb. + * @example + * ```typescript + * const light = new THREE.PointLight(0xff0000, 1, 100); + * light.position.set(50, 50, 50); + * scene.add(light); + * ``` + * @see Example: {@link https://threejs.org/examples/#webgl_lights_pointlights | lights / pointlights } + * @see Example: {@link https://threejs.org/examples/#webgl_effects_anaglyph | effects / anaglyph } + * @see Example: {@link https://threejs.org/examples/#webgl_geometry_text | geometry / text } + * @see Example: {@link https://threejs.org/examples/#webgl_lensflares | lensflares } + * @see {@link https://threejs.org/docs/index.html#api/en/lights/PointLight | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/lights/PointLight.js | Source} + */ +export class PointLight extends Light { + /** + * Creates a new PointLight. + * @param color Hexadecimal color of the light. Default is 0xffffff (white). Expects a `Integer` + * @param intensity Numeric value of the light's strength/intensity. Expects a `Float`. Default `1` + * @param distance Maximum range of the light. Default is 0 (no limit). + * @param decay The amount the light dims along the distance of the light. Expects a `Float`. Default `2` + */ + constructor(color?: ColorRepresentation, intensity?: number, distance?: number, decay?: number); + + /** + * Read-only flag to check if a given object is of type {@link PointLight}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isPointLight: true; + + /** + * @default 'PointLight' + */ + type: string; + + /** + * The light's intensity. + * + * When **{@link WebGLRenderer.useLegacyLights | legacy lighting mode} is disabled** — intensity is the luminous intensity of the light measured in candela (cd). + * @remarks Changing the intensity will also change the light's power. + * @remarks Expects a `Float` + * @defaultValue `1` + */ + intensity: number; + + /** + * When **Default mode** — When distance is zero, light does not attenuate. When distance is non-zero, + * light will attenuate linearly from maximum intensity at the light's position down to zero at this distance from the light. + * + * When **{@link WebGLRenderer.useLegacyLights | legacy lighting mode} is disabled** — When distance is zero, + * light will attenuate according to inverse-square law to infinite distance. + * When distance is non-zero, light will attenuate according to inverse-square law until near the distance cutoff, + * where it will then attenuate quickly and smoothly to 0. Inherently, cutoffs are not physically correct. + * + * @defaultValue `0.0` + * @remarks Expects a `Float` + */ + distance: number; + + /** + * If set to `true` light will cast dynamic shadows. + * **Warning**: This is expensive and requires tweaking to get shadows looking right. + * @see {@link THREE.PointLightShadow | PointLightShadow} for details. + * @defaultValue `false` + */ + castShadow: boolean; + + /** + * The amount the light dims along the distance of the light. + * In context of physically-correct rendering the default value should not be changed. + * @remarks Expects a `Float` + * @defaultValue `2` + */ + decay: number; + + /** + * A {@link THREE.PointLightShadow | PointLightShadow} used to calculate shadows for this light. + * The lightShadow's {@link LightShadow.camera | camera} is set to + * a {@link THREE.PerspectiveCamera | PerspectiveCamera} with {@link PerspectiveCamera.fov | fov} of 90, + * {@link PerspectiveCamera.aspect | aspect} of 1, + * {@link PerspectiveCamera.near | near} clipping plane at 0.5 + * and {@link PerspectiveCamera.far | far} clipping plane at 500. + * @defaultValue new THREE.PointLightShadow() + */ + shadow: PointLightShadow; + + /** + * The light's power. + * When **{@link WebGLRenderer.useLegacyLights | legacy lighting mode} is disabled** — power is the luminous power of the light measured in lumens (lm). + * @remarks Changing the power will also change the light's intensity. + * @remarks Expects a `Float` + */ + power: number; +} diff --git a/src-testing/src/lights/PointLightShadow.d.ts b/src-testing/src/lights/PointLightShadow.d.ts new file mode 100644 index 000000000..1d0e7e4af --- /dev/null +++ b/src-testing/src/lights/PointLightShadow.d.ts @@ -0,0 +1,22 @@ +import { PerspectiveCamera } from "../cameras/PerspectiveCamera.js"; +import { Light } from "./Light.js"; +import { LightShadow } from "./LightShadow.js"; + +/** + * Shadow for {@link THREE.PointLight | PointLight} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/lights/PointLightShadow.js | Source} + */ +export class PointLightShadow extends LightShadow { + /** + * Read-only flag to check if a given object is of type {@link PointLightShadow}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isPointLightShadow = true; + + /** + * Update the matrices for the camera and shadow, used internally by the renderer. + * @param light The light for which the shadow is being rendered. + */ + override updateMatrices(light: Light, viewportIndex?: number): void; +} diff --git a/src-testing/src/lights/RectAreaLight.d.ts b/src-testing/src/lights/RectAreaLight.d.ts new file mode 100644 index 000000000..2861e9794 --- /dev/null +++ b/src-testing/src/lights/RectAreaLight.d.ts @@ -0,0 +1,82 @@ +import { ColorRepresentation } from "../math/Color.js"; +import { Light } from "./Light.js"; + +/** + * {@link RectAreaLight} emits light uniformly across the face a rectangular plane + * @remarks + * This light type can be used to simulate light sources such as bright windows or strip lighting. + * Important Notes: + * - There is no shadow support. + * - Only {@link MeshStandardMaterial | MeshStandardMaterial} and {@link MeshPhysicalMaterial | MeshPhysicalMaterial} are supported. + * - You have to include {@link https://threejs.org/examples/jsm/lights/RectAreaLightUniformsLib.js | RectAreaLightUniformsLib} into your scene and call `init()`. + * @example + * ```typescript + * const width = 10; + * const height = 10; + * const intensity = 1; + * const rectLight = new THREE.RectAreaLight(0xffffff, intensity, width, height); + * rectLight.position.set(5, 5, 0); + * rectLight.lookAt(0, 0, 0); + * scene.add(rectLight) + * const rectLightHelper = new RectAreaLightHelper(rectLight); + * rectLight.add(rectLightHelper); + * ``` + * @see Example: {@link https://threejs.org/examples/#webgl_lights_rectarealight | WebGL / {@link RectAreaLight} } + * @see {@link https://threejs.org/docs/index.html#api/en/lights/RectAreaLight | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/lights/RectAreaLight.js | Source} + */ +export class RectAreaLight extends Light { + /** + * Creates a new {@link RectAreaLight}. + * @param color Hexadecimal color of the light. Default `0xffffff` _(white)_. + * @param intensity The light's intensity, or brightness. Expects a `Float`. Default `1` + * @param width Width of the light. Expects a `Float`. Default `10` + * @param height Height of the light. Expects a `Float`. Default `10` + */ + constructor(color?: ColorRepresentation, intensity?: number, width?: number, height?: number); + + /** + * Read-only flag to check if a given object is of type {@link RectAreaLight}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isRectAreaLight: true; + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `RectAreaLight` + */ + override readonly type: string | "RectAreaLight"; + + /** + * The width of the light. + * @remarks Expects a `Float` + * @defaultValue `10` + */ + width: number; + + /** + * The height of the light. + * @remarks Expects a `Float` + * @defaultValue `10` + */ + height: number; + + /** + * The light's intensity. + * @remarks Changing the intensity will also change the light's power. + * When **{@link WebGLRenderer.useLegacyLights | legacy lighting mode} is disabled** — intensity is the luminance (brightness) of the light measured in nits (cd/m^2). + * @remarks Expects a `Float` + * @defaultValue `1` + */ + intensity: number; + + /** + * The light's power. + * @remarks Changing the power will also change the light's intensity. + * When **{@link WebGLRenderer.useLegacyLights | legacy lighting mode} is disabled** — power is the luminous power of the light measured in lumens (lm). + * @remarks Expects a `Float` + */ + power: number; +} diff --git a/src-testing/src/lights/SpotLight.d.ts b/src-testing/src/lights/SpotLight.d.ts new file mode 100644 index 000000000..7f42488a8 --- /dev/null +++ b/src-testing/src/lights/SpotLight.d.ts @@ -0,0 +1,164 @@ +import { Object3D } from "../core/Object3D.js"; +import { ColorRepresentation } from "../math/Color.js"; +import { Vector3 } from "../math/Vector3.js"; +import { Texture } from "../textures/Texture.js"; +import { Light } from "./Light.js"; +import { SpotLightShadow } from "./SpotLightShadow.js"; + +/** + * This light gets emitted from a single point in one direction, along a cone that increases in size the further from the light it gets. + * @example + * ```typescript + * // white {@link SpotLight} shining from the side, modulated by a texture, casting a shadow + * const {@link SpotLight} = new THREE.SpotLight(0xffffff); + * spotLight.position.set(100, 1000, 100); + * spotLight.map = new THREE.TextureLoader().load(url); + * spotLight.castShadow = true; + * spotLight.shadow.mapSize.width = 1024; + * spotLight.shadow.mapSize.height = 1024; + * spotLight.shadow.camera.near = 500; + * spotLight.shadow.camera.far = 4000; + * spotLight.shadow.camera.fov = 30; + * scene.add(spotLight); + * ``` + * @see Example: {@link https://threejs.org/examples/#webgl_lights_spotlight | lights / {@link SpotLight} } + * @see Example: {@link https://threejs.org/examples/#webgl_lights_spotlights | lights / spotlights } + * @see {@link https://threejs.org/docs/index.html#api/en/lights/SpotLight | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/lights/SpotLight.js | Source} + */ +export class SpotLight extends Light { + /** + * Creates a new SpotLight. + * @param color Hexadecimal color of the light. Default `0xffffff` _(white)_. + * @param intensity Numeric value of the light's strength/intensity. Expects a `Float`. Default `1`. + * @param distance Maximum range of the light. Default is 0 (no limit). Expects a `Float`. + * @param angle Maximum angle of light dispersion from its direction whose upper bound is Math.PI/2. + * @param penumbra Percent of the {@link SpotLight} cone that is attenuated due to penumbra. Takes values between zero and 1. Expects a `Float`. Default `0`. + * @param decay The amount the light dims along the distance of the light. Expects a `Float`. Default `2`. + */ + constructor( + color?: ColorRepresentation, + intensity?: number, + distance?: number, + angle?: number, + penumbra?: number, + decay?: number, + ); + + /** + * Read-only flag to check if a given object is of type {@link SpotLight}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isSpotLight: true; + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @defaultValue `SpotLight` + */ + override readonly type: string | "SpotLight"; + + /** + * This is set equal to {@link THREE.Object3D.DEFAULT_UP | Object3D.DEFAULT_UP} (0, 1, 0), so that the light shines from the top down. + * @defaultValue `{@link Object3D.DEFAULT_UP}` + */ + readonly position: Vector3; + + /** + * The {@link SpotLight} points from its {@link SpotLight.position | position} to target.position. + * @remarks + * **Note**: For the target's position to be changed to anything other than the default, + * it must be added to the {@link Scene | scene} using + * + * ```typescript + * scene.add( light.target ); + * ``` + * + * This is so that the target's {@link Object3D.matrixWorld | matrixWorld} gets automatically updated each frame. + * It is also possible to set the target to be another object in the scene (anything with a {@link THREE.Object3D.position | position} property), like so: + * ```typescript + * const targetObject = new THREE.Object3D(); + * scene.add(targetObject); + * light.target = targetObject; + * ``` + * The {@link SpotLight} will now track the target object. + * @defaultValue `new THREE.Object3D()` _The default position of the target is *(0, 0, 0)*._ + */ + target: Object3D; + + /** + * If set to `true` light will cast dynamic shadows. + * @remarks **Warning**: This is expensive and requires tweaking to get shadows looking right. the {@link THREE.SpotLightShadow | SpotLightShadow} for details. + * @defaultValue `false` + */ + override castShadow: boolean; + + /** + * The light's intensity. + * @remarks Changing the intensity will also change the light's power. + * When **{@link WebGLRenderer.useLegacyLights | legacy lighting mode} is disabled** — intensity is the luminous intensity of the light measured in candela (cd). + * @remarks Expects a `Float` + * @defaultValue `1` + */ + intensity: number; + + /** + * When **Default mode** — When distance is zero, light does not attenuate. When distance is non-zero, + * light will attenuate linearly from maximum intensity at the light's position down to zero at this distance from the light. + * + * When **{@link WebGLRenderer.useLegacyLights | legacy lighting mode} is disabled** — When distance is zero, + * light will attenuate according to inverse-square law to infinite distance. + * When distance is non-zero, light will attenuate according to inverse-square law until near the distance cutoff, + * where it will then attenuate quickly and smoothly to `0`. Inherently, cutoffs are not physically correct. + * @remarks Expects a `Float` + * @defaultValue `0.0` + */ + distance: number; + + /** + * Maximum extent of the spotlight, in radians, from its direction. + * @remarks Should be no more than `Math.PI/2`. + * @remarks Expects a `Float` + * @defaultValue `Math.PI / 3` + */ + angle: number; + + /** + * The amount the light dims along the distance of the light. + * In context of physically-correct rendering the default value should not be changed. + * @remarks Expects a `Float` + * @defaultValue `2` + */ + decay: number; + + /** + * A {@link THREE.SpotLightShadow | SpotLightShadow} used to calculate shadows for this light. + * @defaultValue `new THREE.SpotLightShadow()` + */ + shadow: SpotLightShadow; + + /** + * The light's power. + * @remarks Changing the power will also change the light's intensity. + * When **{@link WebGLRenderer.useLegacyLights | legacy lighting mode} is disabled** — power is the luminous power of the light measured in lumens (lm). + * @remarks Expects a `Float` + */ + power: number; + + /** + * Percent of the {@link SpotLight} cone that is attenuated due to penumbra. + * @remarks Takes values between zero and 1. + * @remarks Expects a `Float` + * @defaultValue `0.0` + */ + penumbra: number; + + /** + * A {@link THREE.Texture | Texture} used to modulate the color of the light. + * The spot light color is mixed with the _RGB_ value of this texture, with a ratio corresponding to its alpha value. + * The cookie-like masking effect is reproduced using pixel values (0, 0, 0, 1-cookie_value). + * @remarks **Warning**: {@link SpotLight.map} is disabled if {@link SpotLight.castShadow} is `false`. + */ + map: Texture | null; +} diff --git a/src-testing/src/lights/SpotLightShadow.d.ts b/src-testing/src/lights/SpotLightShadow.d.ts new file mode 100644 index 000000000..77f075c44 --- /dev/null +++ b/src-testing/src/lights/SpotLightShadow.d.ts @@ -0,0 +1,72 @@ +import { PerspectiveCamera } from "../cameras/PerspectiveCamera.js"; +import { LightShadow } from "./LightShadow.js"; + +/** + * This is used internally by {@link SpotLight | SpotLights} for calculating shadows. + * @example + * ```typescript + * //Create a WebGLRenderer and turn on shadows in the renderer + * const renderer = new THREE.WebGLRenderer(); + * renderer.shadowMap.enabled = true; + * renderer.shadowMap.type = THREE.PCFSoftShadowMap; // default THREE.PCFShadowMap + * //Create a SpotLight and turn on shadows for the light + * const light = new THREE.SpotLight(0xffffff); + * light.castShadow = true; // default false + * scene.add(light); + * //Set up shadow properties for the light + * light.shadow.mapSize.width = 512; // default + * light.shadow.mapSize.height = 512; // default + * light.shadow.camera.near = 0.5; // default + * light.shadow.camera.far = 500; // default + * light.shadow.focus = 1; // default + * //Create a sphere that cast shadows (but does not receive them) + * const sphereGeometry = new THREE.SphereGeometry(5, 32, 32); + * const sphereMaterial = new THREE.MeshStandardMaterial({ + * color: 0xff0000 + * }); + * const sphere = new THREE.Mesh(sphereGeometry, sphereMaterial); + * sphere.castShadow = true; //default is false + * sphere.receiveShadow = false; //default + * scene.add(sphere); + * //Create a plane that receives shadows (but does not cast them) + * const planeGeometry = new THREE.PlaneGeometry(20, 20, 32, 32); + * const planeMaterial = new THREE.MeshStandardMaterial({ + * color: 0x00ff00 + * }) + * const plane = new THREE.Mesh(planeGeometry, planeMaterial); + * plane.receiveShadow = true; + * scene.add(plane); + * //Create a helper for the shadow camera (optional) + * const helper = new THREE.CameraHelper(light.shadow.camera); + * scene.add(helper); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/lights/shadows/SpotLightShadow | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/lights/SpotLightShadow.js | Source} + */ +export class SpotLightShadow extends LightShadow { + /** + * Read-only flag to check if a given object is of type {@link SpotLightShadow}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isSpotLightShadow: true; + + /** + * The light's view of the world. + * @remarks This is used to generate a depth map of the scene; objects behind other objects from the light's perspective will be in shadow. + * @remarks + * The {@link THREE.PerspectiveCamera.fov | fov} will track the {@link THREE.SpotLight.angle | angle} property + * of the owning {@link SpotLight | SpotLight} via the {@link SpotLightShadow.update | update} method. + * Similarly, the {@link THREE.PerspectiveCamera.aspect | aspect} property will track the aspect of the {@link LightShadow.mapSize | mapSize}. + * If the {@link SpotLight.distance | distance} property of the light is set, the {@link THREE.PerspectiveCamera.far | far} clipping plane will track that, otherwise it defaults to `500`. + * @defaultValue is a {@link THREE.PerspectiveCamera | PerspectiveCamera} with {@link THREE.PerspectiveCamera.near | near} clipping plane at `0.5`. + */ + camera: PerspectiveCamera; + + /** + * Used to focus the shadow camera. + * @remarks The camera's field of view is set as a percentage of the spotlight's field-of-view. Range is `[0, 1]`. 0`. + * @defaultValue `1` + */ + focus: number; +} diff --git a/src-testing/src/lights/webgpu/IESSpotLight.d.ts b/src-testing/src/lights/webgpu/IESSpotLight.d.ts new file mode 100644 index 000000000..bf1b66006 --- /dev/null +++ b/src-testing/src/lights/webgpu/IESSpotLight.d.ts @@ -0,0 +1,6 @@ +import { Texture } from "../../textures/Texture.js"; +import { SpotLight } from "../SpotLight.js"; + +export default class IESSpotLight extends SpotLight { + iesMap: Texture | null; +} diff --git a/src-testing/src/loaders/AnimationLoader.d.ts b/src-testing/src/loaders/AnimationLoader.d.ts new file mode 100644 index 000000000..567f30f30 --- /dev/null +++ b/src-testing/src/loaders/AnimationLoader.d.ts @@ -0,0 +1,9 @@ +import { AnimationClip } from "../animation/AnimationClip.js"; +import { Loader } from "./Loader.js"; +import { LoadingManager } from "./LoadingManager.js"; + +export class AnimationLoader extends Loader { + constructor(manager?: LoadingManager); + + parse(json: readonly unknown[]): AnimationClip[]; +} diff --git a/src-testing/src/loaders/AudioLoader.d.ts b/src-testing/src/loaders/AudioLoader.d.ts new file mode 100644 index 000000000..0204bef47 --- /dev/null +++ b/src-testing/src/loaders/AudioLoader.d.ts @@ -0,0 +1,6 @@ +import { Loader } from "./Loader.js"; +import { LoadingManager } from "./LoadingManager.js"; + +export class AudioLoader extends Loader { + constructor(manager?: LoadingManager); +} diff --git a/src-testing/src/loaders/BufferGeometryLoader.d.ts b/src-testing/src/loaders/BufferGeometryLoader.d.ts new file mode 100644 index 000000000..0aa994011 --- /dev/null +++ b/src-testing/src/loaders/BufferGeometryLoader.d.ts @@ -0,0 +1,10 @@ +import { BufferGeometry } from "../core/BufferGeometry.js"; +import { InstancedBufferGeometry } from "../core/InstancedBufferGeometry.js"; +import { Loader } from "./Loader.js"; +import { LoadingManager } from "./LoadingManager.js"; + +export class BufferGeometryLoader extends Loader { + constructor(manager?: LoadingManager); + + parse(json: unknown): InstancedBufferGeometry | BufferGeometry; +} diff --git a/src-testing/src/loaders/Cache.d.ts b/src-testing/src/loaders/Cache.d.ts new file mode 100644 index 000000000..0742af8f5 --- /dev/null +++ b/src-testing/src/loaders/Cache.d.ts @@ -0,0 +1,21 @@ +declare const Cache: { + /** + * @default false + */ + enabled: boolean; + + /** + * @default {} + */ + files: any; + + add(key: string, file: any): void; + + get(key: string): any; + + remove(key: string): void; + + clear(): void; +}; + +export { Cache }; diff --git a/src-testing/src/loaders/CompressedTextureLoader.d.ts b/src-testing/src/loaders/CompressedTextureLoader.d.ts new file mode 100644 index 000000000..eeca01ded --- /dev/null +++ b/src-testing/src/loaders/CompressedTextureLoader.d.ts @@ -0,0 +1,14 @@ +import { CompressedTexture } from "../textures/CompressedTexture.js"; +import { Loader } from "./Loader.js"; +import { LoadingManager } from "./LoadingManager.js"; + +export class CompressedTextureLoader extends Loader { + constructor(manager?: LoadingManager); + + load( + url: string, + onLoad?: (data: CompressedTexture) => void, + onProgress?: (event: ProgressEvent) => void, + onError?: (err: unknown) => void, + ): CompressedTexture; +} diff --git a/src-testing/src/loaders/CubeTextureLoader.d.ts b/src-testing/src/loaders/CubeTextureLoader.d.ts new file mode 100644 index 000000000..f6cd285c4 --- /dev/null +++ b/src-testing/src/loaders/CubeTextureLoader.d.ts @@ -0,0 +1,14 @@ +import { CubeTexture } from "../textures/CubeTexture.js"; +import { Loader } from "./Loader.js"; +import { LoadingManager } from "./LoadingManager.js"; + +export class CubeTextureLoader extends Loader { + constructor(manager?: LoadingManager); + + load( + url: readonly string[], + onLoad?: (data: CubeTexture) => void, + onProgress?: (event: ProgressEvent) => void, + onError?: (err: unknown) => void, + ): CubeTexture; +} diff --git a/src-testing/src/loaders/DataTextureLoader.d.ts b/src-testing/src/loaders/DataTextureLoader.d.ts new file mode 100644 index 000000000..0cc8d7475 --- /dev/null +++ b/src-testing/src/loaders/DataTextureLoader.d.ts @@ -0,0 +1,14 @@ +import { DataTexture } from "../textures/DataTexture.js"; +import { Loader } from "./Loader.js"; +import { LoadingManager } from "./LoadingManager.js"; + +export class DataTextureLoader extends Loader { + constructor(manager?: LoadingManager); + + load( + url: string, + onLoad?: (data: DataTexture, texData: object) => void, + onProgress?: (event: ProgressEvent) => void, + onError?: (err: unknown) => void, + ): DataTexture; +} diff --git a/src-testing/src/loaders/FileLoader.d.ts b/src-testing/src/loaders/FileLoader.d.ts new file mode 100644 index 000000000..25ceba9cd --- /dev/null +++ b/src-testing/src/loaders/FileLoader.d.ts @@ -0,0 +1,19 @@ +import { Loader } from "./Loader.js"; +import { LoadingManager } from "./LoadingManager.js"; + +export class FileLoader extends Loader { + constructor(manager?: LoadingManager); + + load( + url: string, + onLoad?: (data: string | ArrayBuffer) => void, + onProgress?: (event: ProgressEvent) => void, + onError?: (err: unknown) => void, + ): void; + + mimeType: string | undefined; + responseType: string | undefined; + + setMimeType(mimeType: string): FileLoader; + setResponseType(responseType: string): FileLoader; +} diff --git a/src-testing/src/loaders/ImageBitmapLoader.d.ts b/src-testing/src/loaders/ImageBitmapLoader.d.ts new file mode 100644 index 000000000..f182d326a --- /dev/null +++ b/src-testing/src/loaders/ImageBitmapLoader.d.ts @@ -0,0 +1,22 @@ +import { Loader } from "./Loader.js"; +import { LoadingManager } from "./LoadingManager.js"; + +export class ImageBitmapLoader extends Loader { + constructor(manager?: LoadingManager); + + load( + url: string, + onLoad?: (data: ImageBitmap) => void, + onProgress?: (event: ProgressEvent) => void, + onError?: (err: unknown) => void, + ): void; + + /** + * @default { premultiplyAlpha: 'none' } + */ + options: undefined | object; + + readonly isImageBitmapLoader: true; + + setOptions(options: object): ImageBitmapLoader; +} diff --git a/src-testing/src/loaders/ImageLoader.d.ts b/src-testing/src/loaders/ImageLoader.d.ts new file mode 100644 index 000000000..2189198e4 --- /dev/null +++ b/src-testing/src/loaders/ImageLoader.d.ts @@ -0,0 +1,17 @@ +import { Loader } from "./Loader.js"; +import { LoadingManager } from "./LoadingManager.js"; + +/** + * A loader for loading an image. + * Unlike other loaders, this one emits events instead of using predefined callbacks. So if you're interested in getting notified when things happen, you need to add listeners to the object. + */ +export class ImageLoader extends Loader { + constructor(manager?: LoadingManager); + + load( + url: string, + onLoad?: (data: HTMLImageElement) => void, + onProgress?: (event: ProgressEvent) => void, + onError?: (err: unknown) => void, + ): HTMLImageElement; +} diff --git a/src-testing/src/loaders/Loader.d.ts b/src-testing/src/loaders/Loader.d.ts new file mode 100644 index 000000000..0f65e66f3 --- /dev/null +++ b/src-testing/src/loaders/Loader.d.ts @@ -0,0 +1,50 @@ +import { LoadingManager } from "./LoadingManager.js"; + +/** + * Base class for implementing loaders. + */ +export class Loader { + constructor(manager?: LoadingManager); + + /** + * @default 'anonymous' + */ + crossOrigin: string; + + /** + * @default false + */ + withCredentials: boolean; + + /** + * @default '' + */ + path: string; + + /** + * @default '' + */ + resourcePath: string; + manager: LoadingManager; + + /** + * @default {} + */ + requestHeader: { [header: string]: string }; + + load( + url: TUrl, + onLoad: (data: TData) => void, + onProgress?: (event: ProgressEvent) => void, + onError?: (err: unknown) => void, + ): void; + loadAsync(url: TUrl, onProgress?: (event: ProgressEvent) => void): Promise; + + setCrossOrigin(crossOrigin: string): this; + setWithCredentials(value: boolean): this; + setPath(path: string): this; + setResourcePath(resourcePath: string): this; + setRequestHeader(requestHeader: { [header: string]: string }): this; + + static DEFAULT_MATERIAL_NAME: string; +} diff --git a/src-testing/src/loaders/LoaderUtils.d.ts b/src-testing/src/loaders/LoaderUtils.d.ts new file mode 100644 index 000000000..2f00baeff --- /dev/null +++ b/src-testing/src/loaders/LoaderUtils.d.ts @@ -0,0 +1,10 @@ +export class LoaderUtils { + /** + * @deprecated decodeText() has been deprecated with r165 and will be removed with r175. Use TextDecoder instead. + */ + static decodeText(array: BufferSource): string; + + static extractUrlBase(url: string): string; + + static resolveURL(url: string, path: string): string; +} diff --git a/src-testing/src/loaders/LoadingManager.d.ts b/src-testing/src/loaders/LoadingManager.d.ts new file mode 100644 index 000000000..ab5b546cd --- /dev/null +++ b/src-testing/src/loaders/LoadingManager.d.ts @@ -0,0 +1,69 @@ +import { Loader } from "./Loader.js"; + +export const DefaultLoadingManager: LoadingManager; + +/** + * Handles and keeps track of loaded and pending data. + */ +export class LoadingManager { + constructor( + onLoad?: () => void, + onProgress?: (url: string, loaded: number, total: number) => void, + onError?: (url: string) => void, + ); + + /** + * Will be called when loading of an item starts. + * @param url The url of the item that started loading. + * @param loaded The number of items already loaded so far. + * @param total The total amount of items to be loaded. + */ + onStart?: ((url: string, loaded: number, total: number) => void) | undefined; + + /** + * Will be called when all items finish loading. + * The default is a function with empty body. + */ + onLoad: () => void; + + /** + * Will be called for each loaded item. + * The default is a function with empty body. + * @param url The url of the item just loaded. + * @param loaded The number of items already loaded so far. + * @param total The total amount of items to be loaded. + */ + onProgress: (url: string, loaded: number, total: number) => void; + + /** + * Will be called when item loading fails. + * The default is a function with empty body. + * @param url The url of the item that errored. + */ + onError: (url: string) => void; + + /** + * If provided, the callback will be passed each resource URL before a request is sent. + * The callback may return the original URL, or a new URL to override loading behavior. + * This behavior can be used to load assets from .ZIP files, drag-and-drop APIs, and Data URIs. + * @param callback URL modifier callback. Called with url argument, and must return resolvedURL. + */ + setURLModifier(callback?: (url: string) => string): this; + + /** + * Given a URL, uses the URL modifier callback (if any) and returns a resolved URL. + * If no URL modifier is set, returns the original URL. + * @param url the url to load + */ + resolveURL(url: string): string; + + itemStart(url: string): void; + itemEnd(url: string): void; + itemError(url: string): void; + + // handlers + + addHandler(regex: RegExp, loader: Loader): this; + removeHandler(regex: RegExp): this; + getHandler(file: string): Loader | null; +} diff --git a/src-testing/src/loaders/MaterialLoader.d.ts b/src-testing/src/loaders/MaterialLoader.d.ts new file mode 100644 index 000000000..742c22a04 --- /dev/null +++ b/src-testing/src/loaders/MaterialLoader.d.ts @@ -0,0 +1,21 @@ +import { Material } from "../materials/Material.js"; +import { Texture } from "../textures/Texture.js"; +import { Loader } from "./Loader.js"; +import { LoadingManager } from "./LoadingManager.js"; + +export class MaterialLoader extends Loader { + /** + * @default {} + */ + textures: { [key: string]: Texture }; + + constructor(manager?: LoadingManager); + + parse(json: unknown): Material; + + setTextures(textures: { [key: string]: Texture }): this; + + createMaterialFromType(type: string): Material; + + static createMaterialFromType(type: string): Material; +} diff --git a/src-testing/src/loaders/ObjectLoader.d.ts b/src-testing/src/loaders/ObjectLoader.d.ts new file mode 100644 index 000000000..306c75700 --- /dev/null +++ b/src-testing/src/loaders/ObjectLoader.d.ts @@ -0,0 +1,35 @@ +import { AnimationClip } from "../animation/AnimationClip.js"; +import { BufferGeometry } from "../core/BufferGeometry.js"; +import { InstancedBufferGeometry } from "../core/InstancedBufferGeometry.js"; +import { Object3D } from "../core/Object3D.js"; +import { Material } from "../materials/Material.js"; +import { Source } from "../textures/Source.js"; +import { Texture } from "../textures/Texture.js"; +import { Loader } from "./Loader.js"; +import { LoadingManager } from "./LoadingManager.js"; + +export class ObjectLoader extends Loader { + constructor(manager?: LoadingManager); + + load( + url: string, + onLoad?: (data: Object3D) => void, + onProgress?: (event: ProgressEvent) => void, + onError?: (err: unknown) => void, + ): void; + + parse(json: unknown, onLoad?: (object: Object3D) => void): Object3D; + parseAsync(json: unknown): Promise; + parseGeometries(json: unknown): { [key: string]: InstancedBufferGeometry | BufferGeometry }; + parseMaterials(json: unknown, textures: { [key: string]: Texture }): { [key: string]: Material }; + parseAnimations(json: unknown): { [key: string]: AnimationClip }; + parseImages(json: unknown, onLoad?: () => void): { [key: string]: Source }; + parseImagesAsync(json: unknown): Promise<{ [key: string]: Source }>; + parseTextures(json: unknown, images: { [key: string]: Source }): { [key: string]: Texture }; + parseObject( + data: unknown, + geometries: { [key: string]: InstancedBufferGeometry | BufferGeometry }, + materials: { [key: string]: Material }, + animations: { [key: string]: AnimationClip }, + ): Object3D; +} diff --git a/src-testing/src/loaders/TextureLoader.d.ts b/src-testing/src/loaders/TextureLoader.d.ts new file mode 100644 index 000000000..3cc07f5c3 --- /dev/null +++ b/src-testing/src/loaders/TextureLoader.d.ts @@ -0,0 +1,18 @@ +import { Texture } from "../textures/Texture.js"; +import { Loader } from "./Loader.js"; +import { LoadingManager } from "./LoadingManager.js"; + +/** + * Class for loading a texture. + * Unlike other loaders, this one emits events instead of using predefined callbacks. So if you're interested in getting notified when things happen, you need to add listeners to the object. + */ +export class TextureLoader extends Loader { + constructor(manager?: LoadingManager); + + load( + url: string, + onLoad?: (data: Texture) => void, + onProgress?: (event: ProgressEvent) => void, + onError?: (err: unknown) => void, + ): Texture; +} diff --git a/src-testing/src/loaders/nodes/NodeLoader.d.ts b/src-testing/src/loaders/nodes/NodeLoader.d.ts new file mode 100644 index 000000000..9083b2315 --- /dev/null +++ b/src-testing/src/loaders/nodes/NodeLoader.d.ts @@ -0,0 +1,21 @@ +import { Node } from "../../nodes/Nodes.js"; +import { Texture } from "../../textures/Texture.js"; +import { Loader } from "../Loader.js"; +import { LoadingManager } from "../LoadingManager.js"; + +export interface NodeLoaderResult { + [hash: string]: Node; +} + +export default class NodeLoader extends Loader { + textures: { [key: string]: Texture }; + nodes: { [type: string]: Node }; + + constructor(manager?: LoadingManager); + + parseNodes(json: unknown): NodeLoaderResult; + parse(json: unknown): Node; + setTextures(textures: { [key: string]: Texture }): this; + setNodes(value: { [type: string]: Node }): this; + createNodeFromType(type: string): Node; +} diff --git a/src-testing/src/loaders/nodes/NodeMaterialLoader.d.ts b/src-testing/src/loaders/nodes/NodeMaterialLoader.d.ts new file mode 100644 index 000000000..89dee9c6a --- /dev/null +++ b/src-testing/src/loaders/nodes/NodeMaterialLoader.d.ts @@ -0,0 +1,11 @@ +import NodeMaterial from "../../materials/nodes/NodeMaterial.js"; +import { MaterialLoader } from "../MaterialLoader.js"; +import { NodeLoaderResult } from "./NodeLoader.js"; + +export default class NodeMaterialLoader extends MaterialLoader { + nodes: NodeLoaderResult; + nodeMaterials: { [type: string]: NodeMaterial }; + + setNodes(value: NodeLoaderResult): this; + setNodeMaterials(value: { [type: string]: NodeMaterial }): this; +} diff --git a/src-testing/src/loaders/nodes/NodeObjectLoader.d.ts b/src-testing/src/loaders/nodes/NodeObjectLoader.d.ts new file mode 100644 index 000000000..0dbcef8a5 --- /dev/null +++ b/src-testing/src/loaders/nodes/NodeObjectLoader.d.ts @@ -0,0 +1,22 @@ +import { Material } from "../../materials/Material.js"; +import NodeMaterial from "../../materials/nodes/NodeMaterial.js"; +import { Node } from "../../nodes/Nodes.js"; +import { Texture } from "../../textures/Texture.js"; +import { LoadingManager } from "../LoadingManager.js"; +import { ObjectLoader } from "../ObjectLoader.js"; +import { NodeLoaderResult } from "./NodeLoader.js"; + +export default class NodeObjectLoader extends ObjectLoader { + nodes: { [type: string]: Node }; + nodeMaterials: { [type: string]: NodeMaterial }; + + constructor(manager?: LoadingManager); + + setNodes(value: { [type: string]: Node }): this; + + setNodeMaterials(value: { [type: string]: NodeMaterial }): this; + + parseNodes(json: unknown, textures: { [key: string]: Texture }): NodeLoaderResult; + + parseMaterials(json: unknown, textures: { [key: string]: Texture }): { [key: string]: Material }; +} diff --git a/src-testing/src/materials/LineBasicMaterial.d.ts b/src-testing/src/materials/LineBasicMaterial.d.ts new file mode 100644 index 000000000..7f8bac230 --- /dev/null +++ b/src-testing/src/materials/LineBasicMaterial.d.ts @@ -0,0 +1,55 @@ +import { Color, ColorRepresentation } from "../math/Color.js"; +import { Texture } from "../textures/Texture.js"; +import { Material, MaterialParameters } from "./Material.js"; + +export interface LineBasicMaterialParameters extends MaterialParameters { + color?: ColorRepresentation | undefined; + fog?: boolean | undefined; + linewidth?: number | undefined; + linecap?: string | undefined; + linejoin?: string | undefined; +} + +export class LineBasicMaterial extends Material { + constructor(parameters?: LineBasicMaterialParameters); + + /** + * Read-only flag to check if a given object is of type {@link LineBasicMaterial}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isLineBasicMaterial: true; + + /** + * @default 0xffffff + */ + color: Color; + + /** + * Whether the material is affected by fog. Default is true. + * @default true + */ + fog: boolean; + + /** + * @default 1 + */ + linewidth: number; + + /** + * @default 'round' + */ + linecap: string; + + /** + * @default 'round' + */ + linejoin: string; + + /** + * Sets the color of the lines using data from a {@link Texture}. + */ + map: Texture | null; + + setValues(parameters: LineBasicMaterialParameters): void; +} diff --git a/src-testing/src/materials/LineDashedMaterial.d.ts b/src-testing/src/materials/LineDashedMaterial.d.ts new file mode 100644 index 000000000..514bb3f93 --- /dev/null +++ b/src-testing/src/materials/LineDashedMaterial.d.ts @@ -0,0 +1,35 @@ +import { LineBasicMaterial, LineBasicMaterialParameters } from "./LineBasicMaterial.js"; + +export interface LineDashedMaterialParameters extends LineBasicMaterialParameters { + scale?: number | undefined; + dashSize?: number | undefined; + gapSize?: number | undefined; +} + +export class LineDashedMaterial extends LineBasicMaterial { + constructor(parameters?: LineDashedMaterialParameters); + + /** + * Read-only flag to check if a given object is of type {@link LineDashedMaterial}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isLineDashedMaterial: true; + + /** + * @default 1 + */ + scale: number; + + /** + * @default 1 + */ + dashSize: number; + + /** + * @default 1 + */ + gapSize: number; + + setValues(parameters: LineDashedMaterialParameters): void; +} diff --git a/src-testing/src/materials/Material.d.ts b/src-testing/src/materials/Material.d.ts new file mode 100644 index 000000000..731bcc89e --- /dev/null +++ b/src-testing/src/materials/Material.d.ts @@ -0,0 +1,629 @@ +import { Camera } from "../cameras/Camera.js"; +import { + Blending, + BlendingDstFactor, + BlendingEquation, + BlendingSrcFactor, + Combine, + DepthModes, + NormalMapTypes, + PixelFormat, + Side, + StencilFunc, + StencilOp, +} from "../constants.js"; +import { BufferGeometry } from "../core/BufferGeometry.js"; +import { EventDispatcher } from "../core/EventDispatcher.js"; +import { JSONMeta, Object3D } from "../core/Object3D.js"; +import { Color, ColorRepresentation } from "../math/Color.js"; +import { Plane } from "../math/Plane.js"; +import { Group } from "../objects/Group.js"; +import { WebGLProgramParametersWithUniforms } from "../renderers/webgl/WebGLPrograms.js"; +import { WebGLRenderer } from "../renderers/WebGLRenderer.js"; +import { Scene } from "../scenes/Scene.js"; +import { EulerTuple, SourceJSON, TextureJSON, Vector2Tuple } from "../Three.js"; + +export interface MaterialParameters { + alphaHash?: boolean | undefined; + alphaTest?: number | undefined; + alphaToCoverage?: boolean | undefined; + blendAlpha?: number | undefined; + blendColor?: ColorRepresentation | undefined; + blendDst?: BlendingDstFactor | undefined; + blendDstAlpha?: number | undefined; + blendEquation?: BlendingEquation | undefined; + blendEquationAlpha?: number | undefined; + blending?: Blending | undefined; + blendSrc?: BlendingSrcFactor | BlendingDstFactor | undefined; + blendSrcAlpha?: number | undefined; + clipIntersection?: boolean | undefined; + clippingPlanes?: Plane[] | undefined; + clipShadows?: boolean | undefined; + colorWrite?: boolean | undefined; + defines?: any; + depthFunc?: DepthModes | undefined; + depthTest?: boolean | undefined; + depthWrite?: boolean | undefined; + name?: string | undefined; + opacity?: number | undefined; + polygonOffset?: boolean | undefined; + polygonOffsetFactor?: number | undefined; + polygonOffsetUnits?: number | undefined; + precision?: "highp" | "mediump" | "lowp" | null | undefined; + premultipliedAlpha?: boolean | undefined; + forceSinglePass?: boolean | undefined; + dithering?: boolean | undefined; + side?: Side | undefined; + shadowSide?: Side | undefined; + toneMapped?: boolean | undefined; + transparent?: boolean | undefined; + vertexColors?: boolean | undefined; + visible?: boolean | undefined; + format?: PixelFormat | undefined; + stencilWrite?: boolean | undefined; + stencilFunc?: StencilFunc | undefined; + stencilRef?: number | undefined; + stencilWriteMask?: number | undefined; + stencilFuncMask?: number | undefined; + stencilFail?: StencilOp | undefined; + stencilZFail?: StencilOp | undefined; + stencilZPass?: StencilOp | undefined; + userData?: Record | undefined; +} + +export interface MaterialJSON { + metadata: { version: number; type: string; generator: string }; + + uuid: string; + type: string; + + name?: string; + + color?: number; + roughness?: number; + metalness?: number; + + sheen?: number; + sheenColor?: number; + sheenRoughness?: number; + emissive?: number; + emissiveIntensity?: number; + + specular?: number; + specularIntensity?: number; + specularColor?: number; + shininess?: number; + clearcoat?: number; + clearcoatRoughness?: number; + clearcoatMap?: string; + clearcoatRoughnessMap?: string; + clearcoatNormalMap?: string; + clearcoatNormalScale?: Vector2Tuple; + + dispersion?: number; + + iridescence?: number; + iridescenceIOR?: number; + iridescenceThicknessRange?: number; + iridescenceMap?: string; + iridescenceThicknessMap?: string; + + anisotropy?: number; + anisotropyRotation?: number; + anisotropyMap?: string; + + map?: string; + matcap?: string; + alphaMap?: string; + + lightMap?: string; + lightMapIntensity?: number; + + aoMap?: string; + aoMapIntensity?: number; + + bumpMap?: string; + bumpScale?: number; + + normalMap?: string; + normalMapType?: NormalMapTypes; + normalScale?: Vector2Tuple; + + displacementMap?: string; + displacementScale?: number; + displacementBias?: number; + + roughnessMap?: string; + metalnessMap?: string; + + emissiveMap?: string; + specularMap?: string; + specularIntensityMap?: string; + specularColorMap?: string; + + envMap?: string; + combine?: Combine; + + envMapRotation?: EulerTuple; + envMapIntensity?: number; + reflectivity?: number; + refractionRatio?: number; + + gradientMap?: string; + + transmission?: number; + transmissionMap?: string; + thickness?: number; + thicknessMap?: string; + attenuationDistance?: number; + attenuationColor?: number; + + size?: number; + shadowSide?: number; + sizeAttenuation?: boolean; + + blending?: Blending; + side?: Side; + vertexColors?: boolean; + + opacity?: number; + transparent?: boolean; + + blendSrc?: BlendingSrcFactor; + blendDst?: BlendingDstFactor; + blendEquation?: BlendingEquation; + blendSrcAlpha?: number | null; + blendDstAlpha?: number | null; + blendEquationAlpha?: number | null; + blendColor?: number; + blendAlpha?: number; + + depthFunc?: DepthModes; + depthTest?: boolean; + depthWrite?: boolean; + colorWrite?: boolean; + + stencilWriteMask?: number; + stencilFunc?: StencilFunc; + stencilRef?: number; + stencilFuncMask?: number; + stencilFail?: StencilOp; + stencilZFail?: StencilOp; + stencilZPass?: StencilOp; + stencilWrite?: boolean; + + rotation?: number; + + polygonOffset?: boolean; + polygonOffsetFactor?: number; + polygonOffsetUnits?: number; + + linewidth?: number; + dashSize?: number; + gapSize?: number; + scale?: number; + + dithering?: boolean; + + alphaTest?: number; + alphaHash?: boolean; + alphaToCoverage?: boolean; + premultipliedAlpha?: boolean; + forceSinglePass?: boolean; + + wireframe?: boolean; + wireframeLinewidth?: number; + wireframeLinecap?: string; + wireframeLinejoin?: string; + + flatShading?: boolean; + + visible?: boolean; + + toneMapped?: boolean; + + fog?: boolean; + + userData?: Record; + + textures?: Array>; + images?: SourceJSON[]; +} + +/** + * Materials describe the appearance of objects. They are defined in a (mostly) renderer-independent way, so you don't have to rewrite materials if you decide to use a different renderer. + */ +export class Material extends EventDispatcher<{ dispose: {} }> { + static get type(): string; + + get type(): string; + + constructor(); + + /** + * Read-only flag to check if a given object is of type {@link Material}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isMaterial: true; + + /** + * Enables alpha hashed transparency, an alternative to {@link .transparent} or {@link .alphaTest}. The material + * will not be rendered if opacity is lower than a random threshold. Randomization introduces some grain or noise, + * but approximates alpha blending without the associated problems of sorting. Using TAARenderPass can reduce the + * resulting noise. + */ + alphaHash: boolean; + + /** + * Enables alpha to coverage. Can only be used with MSAA-enabled rendering contexts (meaning when the renderer was + * created with *antialias* parameter set to `true`). Enabling this will smooth aliasing on clip plane edges and + * alphaTest-clipped edges. + * @default false + */ + alphaToCoverage: boolean; + + /** + * Represents the alpha value of the constant blend color. This property has only an effect when using custom + * blending with {@link ConstantAlphaFactor} or {@link OneMinusConstantAlphaFactor}. + * @default 0 + */ + blendAlpha: number; + + /** + * Represent the RGB values of the constant blend color. This property has only an effect when using custom + * blending with {@link ConstantColorFactor} or {@link OneMinusConstantColorFactor}. + * @default 0x000000 + */ + blendColor: Color; + + /** + * Blending destination. It's one of the blending mode constants defined in Three.js. Default is {@link OneMinusSrcAlphaFactor}. + * @default THREE.OneMinusSrcAlphaFactor + */ + blendDst: BlendingDstFactor; + + /** + * The tranparency of the .blendDst. Default is null. + * @default null + */ + blendDstAlpha: number | null; + + /** + * Blending equation to use when applying blending. It's one of the constants defined in Three.js. Default is {@link AddEquation}. + * @default THREE.AddEquation + */ + blendEquation: BlendingEquation; + + /** + * The tranparency of the .blendEquation. Default is null. + * @default null + */ + blendEquationAlpha: number | null; + + /** + * Which blending to use when displaying objects with this material. Default is {@link NormalBlending}. + * @default THREE.NormalBlending + */ + blending: Blending; + + /** + * Blending source. It's one of the blending mode constants defined in Three.js. Default is {@link SrcAlphaFactor}. + * @default THREE.SrcAlphaFactor + */ + blendSrc: BlendingSrcFactor | BlendingDstFactor; + + /** + * The tranparency of the .blendSrc. Default is null. + * @default null + */ + blendSrcAlpha: number | null; + + /** + * Changes the behavior of clipping planes so that only their intersection is clipped, rather than their union. Default is false. + * @default false + */ + clipIntersection: boolean; + + /** + * User-defined clipping planes specified as THREE.Plane objects in world space. + * These planes apply to the objects this material is attached to. + * Points in space whose signed distance to the plane is negative are clipped (not rendered). + * See the WebGL / clipping /intersection example. Default is null. + * @default null + */ + clippingPlanes: Plane[] | null; + + /** + * Defines whether to clip shadows according to the clipping planes specified on this material. Default is false. + * @default false + */ + clipShadows: boolean; + + /** + * Whether to render the material's color. This can be used in conjunction with a mesh's .renderOrder property to create invisible objects that occlude other objects. Default is true. + * @default true + */ + colorWrite: boolean; + + /** + * Custom defines to be injected into the shader. These are passed in form of an object literal, with key/value pairs. { MY_CUSTOM_DEFINE: '' , PI2: Math.PI * 2 }. + * The pairs are defined in both vertex and fragment shaders. Default is undefined. + * @default undefined + */ + defines: undefined | { [key: string]: any }; + + /** + * Which depth function to use. Default is {@link LessEqualDepth}. See the depth mode constants for all possible values. + * @default THREE.LessEqualDepth + */ + depthFunc: DepthModes; + + /** + * Whether to have depth test enabled when rendering this material. When the depth test is disabled, the depth write + * will also be implicitly disabled. + * @default true + */ + depthTest: boolean; + + /** + * Whether rendering this material has any effect on the depth buffer. Default is true. + * When drawing 2D overlays it can be useful to disable the depth writing in order to layer several things together without creating z-index artifacts. + * @default true + */ + depthWrite: boolean; + + /** + * Unique number of this material instance. + */ + id: number; + + /** + * Whether rendering this material has any effect on the stencil buffer. Default is *false*. + * @default false + */ + stencilWrite: boolean; + + /** + * The stencil comparison function to use. Default is {@link AlwaysStencilFunc}. See stencil operation constants for all possible values. + * @default THREE.AlwaysStencilFunc + */ + stencilFunc: StencilFunc; + + /** + * The value to use when performing stencil comparisons or stencil operations. Default is *0*. + * @default 0 + */ + stencilRef: number; + + /** + * The bit mask to use when writing to the stencil buffer. Default is *0xFF*. + * @default 0xff + */ + stencilWriteMask: number; + + /** + * The bit mask to use when comparing against the stencil buffer. Default is *0xFF*. + * @default 0xff + */ + stencilFuncMask: number; + + /** + * Which stencil operation to perform when the comparison function returns false. Default is {@link KeepStencilOp}. See the stencil operation constants for all possible values. + * @default THREE.KeepStencilOp + */ + stencilFail: StencilOp; + + /** + * Which stencil operation to perform when the comparison function returns true but the depth test fails. + * Default is {@link KeepStencilOp}. + * See the stencil operation constants for all possible values. + * @default THREE.KeepStencilOp + */ + stencilZFail: StencilOp; + + /** + * Which stencil operation to perform when the comparison function returns true and the depth test passes. + * Default is {@link KeepStencilOp}. + * See the stencil operation constants for all possible values. + * @default THREE.KeepStencilOp + */ + stencilZPass: StencilOp; + + /** + * Material name. Default is an empty string. + * @default '' + */ + name: string; + + /** + * Opacity. Default is 1. + * @default 1 + */ + opacity: number; + + /** + * Whether to use polygon offset. Default is false. This corresponds to the POLYGON_OFFSET_FILL WebGL feature. + * @default false + */ + polygonOffset: boolean; + + /** + * Sets the polygon offset factor. Default is 0. + * @default 0 + */ + polygonOffsetFactor: number; + + /** + * Sets the polygon offset units. Default is 0. + * @default 0 + */ + polygonOffsetUnits: number; + + /** + * Override the renderer's default precision for this material. Can be "highp", "mediump" or "lowp". Defaults is null. + * @default null + */ + precision: "highp" | "mediump" | "lowp" | null; + + /** + * Whether to premultiply the alpha (transparency) value. See WebGL / Materials / Transparency for an example of the difference. Default is false. + * @default false + */ + premultipliedAlpha: boolean; + + /** + * @default false + */ + forceSinglePass: boolean; + + /** + * Whether to apply dithering to the color to remove the appearance of banding. Default is false. + * @default false + */ + dithering: boolean; + + /** + * Defines which of the face sides will be rendered - front, back or both. + * Default is {@link THREE.FrontSide}. Other options are {@link THREE.BackSide} and {@link THREE.DoubleSide}. + * + * @default {@link THREE.FrontSide} + */ + side: Side; + + /** + * Defines which of the face sides will cast shadows. Default is *null*. + * If *null*, the value is opposite that of side, above. + * @default null + */ + shadowSide: Side | null; + + /** + * Defines whether this material is tone mapped according to the renderer's + * {@link WebGLRenderer.toneMapping toneMapping} setting. It is ignored when rendering to a render target or using + * post processing. + * @default true + */ + toneMapped: boolean; + + /** + * Defines whether this material is transparent. This has an effect on rendering as transparent objects need special treatment and are rendered after non-transparent objects. + * When set to true, the extent to which the material is transparent is controlled by setting it's .opacity property. + * @default false + */ + transparent: boolean; + + /** + * UUID of this material instance. This gets automatically assigned, so this shouldn't be edited. + */ + uuid: string; + + /** + * Defines whether vertex coloring is used. Default is false. + * @default false + */ + vertexColors: boolean; + + /** + * Defines whether this material is visible. Default is true. + * @default true + */ + visible: boolean; + + /** + * An object that can be used to store custom data about the Material. It should not hold references to functions as these will not be cloned. + * @default {} + */ + userData: Record; + + /** + * This starts at 0 and counts how many times .needsUpdate is set to true. + * @default 0 + */ + version: number; + + /** + * Gets the alpha value to be used when running an alpha test. Default is 0. + * @default 0 + */ + get alphaTest(): number; + + /** + * Sets the alpha value to be used when running an alpha test. Default is 0. + * @default 0 + */ + set alphaTest(value: number); + + /** + * An optional callback that is executed immediately before the material is used to render a 3D object. + * Unlike properties, the callback is not supported by {@link .clone()}, {@link .copy()} and {@link .toJSON()}. + * This callback is only supported in `WebGLRenderer` (not `WebGPURenderer`). + */ + onBeforeRender( + renderer: WebGLRenderer, + scene: Scene, + camera: Camera, + geometry: BufferGeometry, + object: Object3D, + group: Group, + ): void; + + /** + * An optional callback that is executed immediately before the shader program is compiled. + * This function is called with the shader source code as a parameter. + * Useful for the modification of built-in materials. + * Unlike properties, the callback is not supported by {@link .clone()}, {@link .copy()} and {@link .toJSON()}. + * This callback is only supported in `WebGLRenderer` (not `WebGPURenderer`). + * @param parameters WebGL program parameters + * @param renderer WebGLRenderer context that is initializing the material + */ + onBeforeCompile(parameters: WebGLProgramParametersWithUniforms, renderer: WebGLRenderer): void; + + /** + * In case onBeforeCompile is used, this callback can be used to identify values of settings used in onBeforeCompile, so three.js can reuse a cached shader or recompile the shader as needed. + */ + customProgramCacheKey(): string; + + /** + * Sets the properties based on the values. + * @param values A container with parameters. + */ + setValues(values: MaterialParameters): void; + + /** + * Convert the material to three.js JSON format. + * @param meta Object containing metadata such as textures or images for the material. + */ + toJSON(meta?: JSONMeta): MaterialJSON; + + /** + * Return a new material with the same parameters as this material. + */ + clone(): this; + + /** + * Copy the parameters from the passed material into this material. + * @param material + */ + copy(material: Material): this; + + /** + * Frees the GPU-related resources allocated by this instance. Call this method whenever this instance is no longer + * used in your app. + * + * Material textures must be disposed of by the dispose() method of {@link Texture}. + */ + dispose(): void; + + /** + * Specifies that the material needs to be updated, WebGL wise. Set it to true if you made changes that need to be reflected in WebGL. + * This property is automatically set to true when instancing a new material. + * @default false + */ + set needsUpdate(value: boolean); + + /** + * @deprecated onBuild() has been removed. + */ + onBuild(object: Object3D, parameters: WebGLProgramParametersWithUniforms, renderer: WebGLRenderer): void; +} diff --git a/src-testing/src/materials/Materials.d.ts b/src-testing/src/materials/Materials.d.ts new file mode 100644 index 000000000..dbca5e5b7 --- /dev/null +++ b/src-testing/src/materials/Materials.d.ts @@ -0,0 +1,18 @@ +export * from "./LineBasicMaterial.js"; +export * from "./LineDashedMaterial.js"; +export * from "./Material.js"; +export * from "./MeshBasicMaterial.js"; +export * from "./MeshDepthMaterial.js"; +export * from "./MeshDistanceMaterial.js"; +export * from "./MeshLambertMaterial.js"; +export * from "./MeshMatcapMaterial.js"; +export * from "./MeshNormalMaterial.js"; +export * from "./MeshPhongMaterial.js"; +export * from "./MeshPhysicalMaterial.js"; +export * from "./MeshStandardMaterial.js"; +export * from "./MeshToonMaterial.js"; +export * from "./PointsMaterial.js"; +export * from "./RawShaderMaterial.js"; +export * from "./ShaderMaterial.js"; +export * from "./ShadowMaterial.js"; +export * from "./SpriteMaterial.js"; diff --git a/src-testing/src/materials/MeshBasicMaterial.d.ts b/src-testing/src/materials/MeshBasicMaterial.d.ts new file mode 100644 index 000000000..37ca083d7 --- /dev/null +++ b/src-testing/src/materials/MeshBasicMaterial.d.ts @@ -0,0 +1,134 @@ +import { Combine } from "../constants.js"; +import { Color, ColorRepresentation } from "../math/Color.js"; +import { Euler } from "../math/Euler.js"; +import { Texture } from "../textures/Texture.js"; +import { Material, MaterialParameters } from "./Material.js"; + +/** + * parameters is an object with one or more properties defining the material's appearance. + */ +export interface MeshBasicMaterialParameters extends MaterialParameters { + color?: ColorRepresentation | undefined; + opacity?: number | undefined; + map?: Texture | null | undefined; + lightMap?: Texture | null; + lightMapIntensity?: number | undefined; + aoMap?: Texture | null | undefined; + aoMapIntensity?: number | undefined; + specularMap?: Texture | null | undefined; + alphaMap?: Texture | null | undefined; + fog?: boolean | undefined; + envMap?: Texture | null | undefined; + envMapRotation?: Euler | undefined; + combine?: Combine | undefined; + reflectivity?: number | undefined; + refractionRatio?: number | undefined; + wireframe?: boolean | undefined; + wireframeLinewidth?: number | undefined; + wireframeLinecap?: string | undefined; + wireframeLinejoin?: string | undefined; +} + +export class MeshBasicMaterial extends Material { + constructor(parameters?: MeshBasicMaterialParameters); + + /** + * Read-only flag to check if a given object is of type {@link MeshBasicMaterial}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isMeshBasicMaterial: true; + + /** + * @default new THREE.Color( 0xffffff ) + */ + color: Color; + + /** + * @default null + */ + map: Texture | null; + + /** + * @default null + */ + lightMap: Texture | null; + + /** + * @default 1 + */ + lightMapIntensity: number; + + /** + * @default null + */ + aoMap: Texture | null; + + /** + * @default 1 + */ + aoMapIntensity: number; + + /** + * @default null + */ + specularMap: Texture | null; + + /** + * @default null + */ + alphaMap: Texture | null; + + /** + * @default null + */ + envMap: Texture | null; + + /** + * The rotation of the environment map in radians. Default is `(0,0,0)`. + */ + envMapRotation: Euler; + + /** + * @default THREE.MultiplyOperation + */ + combine: Combine; + + /** + * @default 1 + */ + reflectivity: number; + + /** + * @default 0.98 + */ + refractionRatio: number; + + /** + * @default false + */ + wireframe: boolean; + + /** + * @default 1 + */ + wireframeLinewidth: number; + + /** + * @default 'round' + */ + wireframeLinecap: string; + + /** + * @default 'round' + */ + wireframeLinejoin: string; + + /** + * Whether the material is affected by fog. Default is true. + * @default fog + */ + fog: boolean; + + setValues(parameters: MeshBasicMaterialParameters): void; +} diff --git a/src-testing/src/materials/MeshDepthMaterial.d.ts b/src-testing/src/materials/MeshDepthMaterial.d.ts new file mode 100644 index 000000000..dcdcd18b6 --- /dev/null +++ b/src-testing/src/materials/MeshDepthMaterial.d.ts @@ -0,0 +1,71 @@ +import { DepthPackingStrategies } from "../constants.js"; +import { Texture } from "../textures/Texture.js"; +import { Material, MaterialParameters } from "./Material.js"; + +export interface MeshDepthMaterialParameters extends MaterialParameters { + map?: Texture | null | undefined; + alphaMap?: Texture | null | undefined; + depthPacking?: DepthPackingStrategies | undefined; + displacementMap?: Texture | null | undefined; + displacementScale?: number | undefined; + displacementBias?: number | undefined; + wireframe?: boolean | undefined; + wireframeLinewidth?: number | undefined; +} + +export class MeshDepthMaterial extends Material { + constructor(parameters?: MeshDepthMaterialParameters); + /** + * Read-only flag to check if a given object is of type {@link MeshDepthMaterial}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isMeshDepthMaterial: true; + + /** + * @default null + */ + map: Texture | null; + + /** + * @default null + */ + alphaMap: Texture | null; + + /** + * @default THREE.BasicDepthPacking + */ + depthPacking: DepthPackingStrategies; + + /** + * @default null + */ + displacementMap: Texture | null; + + /** + * @default 1 + */ + displacementScale: number; + + /** + * @default 0 + */ + displacementBias: number; + + /** + * @default false + */ + wireframe: boolean; + + /** + * @default 1 + */ + wireframeLinewidth: number; + + /** + * @default false + */ + fog: boolean; + + setValues(parameters: MeshDepthMaterialParameters): void; +} diff --git a/src-testing/src/materials/MeshDistanceMaterial.d.ts b/src-testing/src/materials/MeshDistanceMaterial.d.ts new file mode 100644 index 000000000..4e6a8754b --- /dev/null +++ b/src-testing/src/materials/MeshDistanceMaterial.d.ts @@ -0,0 +1,57 @@ +import { Vector3 } from "../math/Vector3.js"; +import { Texture } from "../textures/Texture.js"; +import { Material, MaterialParameters } from "./Material.js"; + +export interface MeshDistanceMaterialParameters extends MaterialParameters { + map?: Texture | null | undefined; + alphaMap?: Texture | null | undefined; + displacementMap?: Texture | null | undefined; + displacementScale?: number | undefined; + displacementBias?: number | undefined; + farDistance?: number | undefined; + nearDistance?: number | undefined; + referencePosition?: Vector3 | undefined; +} + +export class MeshDistanceMaterial extends Material { + constructor(parameters?: MeshDistanceMaterialParameters); + + /** + * Read-only flag to check if a given object is of type {@link MeshDistanceMaterial}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isMeshDistanceMaterial: true; + + /** + * @default null + */ + map: Texture | null; + + /** + * @default null + */ + alphaMap: Texture | null; + + /** + * @default null + */ + displacementMap: Texture | null; + + /** + * @default 1 + */ + displacementScale: number; + + /** + * @default 0 + */ + displacementBias: number; + + /** + * @default false + */ + fog: boolean; + + setValues(parameters: MeshDistanceMaterialParameters): void; +} diff --git a/src-testing/src/materials/MeshLambertMaterial.d.ts b/src-testing/src/materials/MeshLambertMaterial.d.ts new file mode 100644 index 000000000..868fbbbe0 --- /dev/null +++ b/src-testing/src/materials/MeshLambertMaterial.d.ts @@ -0,0 +1,199 @@ +import { Combine, NormalMapTypes } from "../constants.js"; +import { Color, ColorRepresentation } from "../math/Color.js"; +import { Euler } from "../math/Euler.js"; +import { Vector2 } from "../math/Vector2.js"; +import { Texture } from "../textures/Texture.js"; +import { Material, MaterialParameters } from "./Material.js"; + +export interface MeshLambertMaterialParameters extends MaterialParameters { + bumpMap?: Texture | undefined; + bumpScale?: number | undefined; + color?: ColorRepresentation | undefined; + displacementMap?: Texture | undefined; + displacementScale?: number | undefined; + displacementBias?: number | undefined; + emissive?: ColorRepresentation | undefined; + emissiveIntensity?: number | undefined; + emissiveMap?: Texture | null | undefined; + flatShading?: boolean | undefined; + map?: Texture | null | undefined; + lightMap?: Texture | null | undefined; + lightMapIntensity?: number | undefined; + normalMap?: Texture | undefined; + normalScale?: Vector2 | undefined; + aoMap?: Texture | null | undefined; + aoMapIntensity?: number | undefined; + specularMap?: Texture | null | undefined; + alphaMap?: Texture | null | undefined; + envMap?: Texture | null | undefined; + envMapRotation?: Euler | undefined; + combine?: Combine | undefined; + reflectivity?: number | undefined; + refractionRatio?: number | undefined; + wireframe?: boolean | undefined; + wireframeLinewidth?: number | undefined; + wireframeLinecap?: string | undefined; + wireframeLinejoin?: string | undefined; + fog?: boolean | undefined; +} + +export class MeshLambertMaterial extends Material { + constructor(parameters?: MeshLambertMaterialParameters); + + /** + * Read-only flag to check if a given object is of type {@link MeshLambertMaterial}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isMeshLambertMaterial: true; + + /** + * @default new THREE.Color( 0xffffff ) + */ + color: Color; + + /** + * @default null + */ + bumpMap: Texture | null; + + /** + * @default 1 + */ + bumpScale: number; + + /** + * @default null + */ + displacementMap: Texture | null; + + /** + * @default 1 + */ + displacementScale: number; + + /** + * @default 0 + */ + displacementBias: number; + + /** + * @default new THREE.Color( 0x000000 ) + */ + emissive: Color; + + /** + * @default 1 + */ + emissiveIntensity: number; + + /** + * @default null + */ + emissiveMap: Texture | null; + + /** + * @default false + */ + flatShading: boolean; + + /** + * @default null + */ + map: Texture | null; + + /** + * @default null + */ + lightMap: Texture | null; + + /** + * @default 1 + */ + lightMapIntensity: number; + + /** + * @default null + */ + normalMap: Texture | null; + + normalMapType: NormalMapTypes; + + /** + * @default new THREE.Vector2( 1, 1 ) + */ + normalScale: Vector2; + + /** + * @default null + */ + aoMap: Texture | null; + + /** + * @default 1 + */ + aoMapIntensity: number; + + /** + * @default null + */ + specularMap: Texture | null; + + /** + * @default null + */ + alphaMap: Texture | null; + + /** + * @default null + */ + envMap: Texture | null; + + /** + * The rotation of the environment map in radians. Default is `(0,0,0)`. + */ + envMapRotation: Euler; + + /** + * @default THREE.MultiplyOperation + */ + combine: Combine; + + /** + * @default 1 + */ + reflectivity: number; + + /** + * @default 0.98 + */ + refractionRatio: number; + + /** + * @default false + */ + wireframe: boolean; + + /** + * @default 1 + */ + wireframeLinewidth: number; + + /** + * @default 'round' + */ + wireframeLinecap: string; + + /** + * @default 'round' + */ + wireframeLinejoin: string; + + /** + * Whether the material is affected by fog. Default is true. + * @default fog + */ + fog: boolean; + + setValues(parameters: MeshLambertMaterialParameters): void; +} diff --git a/src-testing/src/materials/MeshMatcapMaterial.d.ts b/src-testing/src/materials/MeshMatcapMaterial.d.ts new file mode 100644 index 000000000..7f7334d4b --- /dev/null +++ b/src-testing/src/materials/MeshMatcapMaterial.d.ts @@ -0,0 +1,112 @@ +import { NormalMapTypes } from "../constants.js"; +import { Color, ColorRepresentation } from "../math/Color.js"; +import { Vector2 } from "../math/Vector2.js"; +import { Texture } from "../textures/Texture.js"; +import { Material, MaterialParameters } from "./Material.js"; + +export interface MeshMatcapMaterialParameters extends MaterialParameters { + color?: ColorRepresentation | undefined; + matcap?: Texture | null | undefined; + map?: Texture | null | undefined; + bumpMap?: Texture | null | undefined; + bumpScale?: number | undefined; + normalMap?: Texture | null | undefined; + normalMapType?: NormalMapTypes | undefined; + normalScale?: Vector2 | undefined; + displacementMap?: Texture | null | undefined; + displacementScale?: number | undefined; + displacementBias?: number | undefined; + alphaMap?: Texture | null | undefined; + fog?: boolean | undefined; + flatShading?: boolean | undefined; +} + +export class MeshMatcapMaterial extends Material { + constructor(parameters?: MeshMatcapMaterialParameters); + + /** + * Read-only flag to check if a given object is of type {@link MeshMatcapMaterial}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isMeshMatcapMaterial: true; + + /** + * @default { 'MATCAP': '' } + */ + defines: { [key: string]: any }; + + /** + * @default new THREE.Color( 0xffffff ) + */ + color: Color; + + /** + * @default null + */ + matcap: Texture | null; + + /** + * @default null + */ + map: Texture | null; + + /** + * @default null + */ + bumpMap: Texture | null; + + /** + * @default 1 + */ + bumpScale: number; + + /** + * @default null + */ + normalMap: Texture | null; + + /** + * @default THREE.TangentSpaceNormalMap + */ + normalMapType: NormalMapTypes; + + /** + * @default new Vector2( 1, 1 ) + */ + normalScale: Vector2; + + /** + * @default null + */ + displacementMap: Texture | null; + + /** + * @default 1 + */ + displacementScale: number; + + /** + * @default 0 + */ + displacementBias: number; + + /** + * @default null + */ + alphaMap: Texture | null; + + /** + * Define whether the material is rendered with flat shading. Default is false. + * @default false + */ + flatShading: boolean; + + /** + * Whether the material is affected by fog. Default is true. + * @default fog + */ + fog: boolean; + + setValues(parameters: MeshMatcapMaterialParameters): void; +} diff --git a/src-testing/src/materials/MeshNormalMaterial.d.ts b/src-testing/src/materials/MeshNormalMaterial.d.ts new file mode 100644 index 000000000..715ada4e6 --- /dev/null +++ b/src-testing/src/materials/MeshNormalMaterial.d.ts @@ -0,0 +1,88 @@ +import { NormalMapTypes } from "../constants.js"; +import { Vector2 } from "../math/Vector2.js"; +import { Texture } from "../textures/Texture.js"; +import { Material, MaterialParameters } from "./Material.js"; + +export interface MeshNormalMaterialParameters extends MaterialParameters { + bumpMap?: Texture | null | undefined; + bumpScale?: number | undefined; + normalMap?: Texture | null | undefined; + normalMapType?: NormalMapTypes | undefined; + normalScale?: Vector2 | undefined; + displacementMap?: Texture | null | undefined; + displacementScale?: number | undefined; + displacementBias?: number | undefined; + wireframe?: boolean | undefined; + wireframeLinewidth?: number | undefined; + + flatShading?: boolean | undefined; +} + +export class MeshNormalMaterial extends Material { + constructor(parameters?: MeshNormalMaterialParameters); + + /** + * Read-only flag to check if a given object is of type {@link MeshNormalMaterial}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isMeshNormalMaterial: true; + + /** + * @default null + */ + bumpMap: Texture | null; + + /** + * @default 1 + */ + bumpScale: number; + + /** + * @default null + */ + normalMap: Texture | null; + + /** + * @default THREE.TangentSpaceNormalMap + */ + normalMapType: NormalMapTypes; + + /** + * @default new THREE.Vector2( 1, 1 ) + */ + normalScale: Vector2; + + /** + * @default null + */ + displacementMap: Texture | null; + + /** + * @default 1 + */ + displacementScale: number; + + /** + * @default 0 + */ + displacementBias: number; + + /** + * @default false + */ + wireframe: boolean; + + /** + * @default 1 + */ + wireframeLinewidth: number; + + /** + * Define whether the material is rendered with flat shading. Default is false. + * @default false + */ + flatShading: boolean; + + setValues(parameters: MeshNormalMaterialParameters): void; +} diff --git a/src-testing/src/materials/MeshPhongMaterial.d.ts b/src-testing/src/materials/MeshPhongMaterial.d.ts new file mode 100644 index 000000000..2b002524b --- /dev/null +++ b/src-testing/src/materials/MeshPhongMaterial.d.ts @@ -0,0 +1,223 @@ +import { Combine, NormalMapTypes } from "../constants.js"; +import { Color, ColorRepresentation } from "../math/Color.js"; +import { Euler } from "../math/Euler.js"; +import { Vector2 } from "../math/Vector2.js"; +import { Texture } from "../textures/Texture.js"; +import { Material, MaterialParameters } from "./Material.js"; + +export interface MeshPhongMaterialParameters extends MaterialParameters { + /** geometry color in hexadecimal. Default is 0xffffff. */ + color?: ColorRepresentation | undefined; + specular?: ColorRepresentation | undefined; + shininess?: number | undefined; + opacity?: number | undefined; + map?: Texture | null | undefined; + lightMap?: Texture | null | undefined; + lightMapIntensity?: number | undefined; + aoMap?: Texture | null | undefined; + aoMapIntensity?: number | undefined; + emissive?: ColorRepresentation | undefined; + emissiveIntensity?: number | undefined; + emissiveMap?: Texture | null | undefined; + bumpMap?: Texture | null | undefined; + bumpScale?: number | undefined; + normalMap?: Texture | null | undefined; + normalMapType?: NormalMapTypes | undefined; + normalScale?: Vector2 | undefined; + displacementMap?: Texture | null | undefined; + displacementScale?: number | undefined; + displacementBias?: number | undefined; + specularMap?: Texture | null | undefined; + alphaMap?: Texture | null | undefined; + envMap?: Texture | null | undefined; + envMapRotation?: Euler | undefined; + combine?: Combine | undefined; + reflectivity?: number | undefined; + refractionRatio?: number | undefined; + wireframe?: boolean | undefined; + wireframeLinewidth?: number | undefined; + wireframeLinecap?: string | undefined; + wireframeLinejoin?: string | undefined; + fog?: boolean | undefined; + flatShading?: boolean | undefined; +} + +export class MeshPhongMaterial extends Material { + constructor(parameters?: MeshPhongMaterialParameters); + + /** + * Read-only flag to check if a given object is of type {@link MeshPhongMaterial}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isMeshPhongMaterial: true; + + /** + * @default new THREE.Color( 0xffffff ) + */ + color: Color; + + /** + * @default new THREE.Color( 0x111111 ) + */ + specular: Color; + + /** + * @default 30 + */ + shininess: number; + + /** + * @default null + */ + map: Texture | null; + + /** + * @default null + */ + lightMap: Texture | null; + + /** + * @default null + */ + lightMapIntensity: number; + + /** + * @default null + */ + aoMap: Texture | null; + + /** + * @default null + */ + aoMapIntensity: number; + + /** + * @default new THREE.Color( 0x000000 ) + */ + emissive: Color; + + /** + * @default 1 + */ + emissiveIntensity: number; + + /** + * @default null + */ + emissiveMap: Texture | null; + + /** + * @default null + */ + bumpMap: Texture | null; + + /** + * @default 1 + */ + bumpScale: number; + + /** + * @default null + */ + normalMap: Texture | null; + + /** + * @default THREE.TangentSpaceNormalMap + */ + normalMapType: NormalMapTypes; + + /** + * @default new Vector2( 1, 1 ) + */ + normalScale: Vector2; + + /** + * @default null + */ + displacementMap: Texture | null; + + /** + * @default 1 + */ + displacementScale: number; + + /** + * @default 0 + */ + displacementBias: number; + + /** + * @default null + */ + specularMap: Texture | null; + + /** + * @default null + */ + alphaMap: Texture | null; + + /** + * @default null + */ + envMap: Texture | null; + + /** + * The rotation of the environment map in radians. Default is `(0,0,0)`. + */ + envMapRotation: Euler; + + /** + * @default THREE.MultiplyOperation + */ + combine: Combine; + + /** + * @default 1 + */ + reflectivity: number; + + /** + * @default 0.98 + */ + refractionRatio: number; + + /** + * @default false + */ + wireframe: boolean; + + /** + * @default 1 + */ + wireframeLinewidth: number; + + /** + * @default 'round' + */ + wireframeLinecap: string; + + /** + * @default 'round' + */ + wireframeLinejoin: string; + + /** + * Define whether the material is rendered with flat shading. Default is false. + * @default false + */ + flatShading: boolean; + + /** + * @deprecated Use {@link MeshStandardMaterial THREE.MeshStandardMaterial} instead. + */ + metal: boolean; + + /** + * Whether the material is affected by fog. Default is true. + * @default fog + */ + fog: boolean; + + setValues(parameters: MeshPhongMaterialParameters): void; +} diff --git a/src-testing/src/materials/MeshPhysicalMaterial.d.ts b/src-testing/src/materials/MeshPhysicalMaterial.d.ts new file mode 100644 index 000000000..f201ad662 --- /dev/null +++ b/src-testing/src/materials/MeshPhysicalMaterial.d.ts @@ -0,0 +1,231 @@ +import { Color, ColorRepresentation } from "../math/Color.js"; +import { Vector2 } from "../math/Vector2.js"; +import { Texture } from "../textures/Texture.js"; +import { MeshStandardMaterial, MeshStandardMaterialParameters } from "./MeshStandardMaterial.js"; + +export interface MeshPhysicalMaterialParameters extends MeshStandardMaterialParameters { + anisotropyRotation?: number | undefined; + anisotropyMap?: Texture | null | undefined; + + clearcoatMap?: Texture | null | undefined; + clearcoatRoughness?: number | undefined; + clearcoatRoughnessMap?: Texture | null | undefined; + clearcoatNormalScale?: Vector2 | undefined; + clearcoatNormalMap?: Texture | null | undefined; + + ior?: number | undefined; + + reflectivity?: number | undefined; + + iridescenceMap?: Texture | null | undefined; + iridescenceIOR?: number | undefined; + iridescenceThicknessRange?: [number, number] | undefined; + iridescenceThicknessMap?: Texture | null | undefined; + + sheenColor?: ColorRepresentation | undefined; + sheenColorMap?: Texture | null | undefined; + sheenRoughness?: number | undefined; + sheenRoughnessMap?: Texture | null | undefined; + + transmissionMap?: Texture | null | undefined; + + thickness?: number | undefined; + thicknessMap?: Texture | null | undefined; + attenuationDistance?: number | undefined; + attenuationColor?: ColorRepresentation | undefined; + + specularIntensity?: number | undefined; + specularIntensityMap?: Texture | null | undefined; + specularColor?: ColorRepresentation | undefined; + specularColorMap?: Texture | null | undefined; + + anisotropy?: number | undefined; + clearcoat?: number | undefined; + iridescence?: number | undefined; + dispersion?: number | undefined; + sheen?: number | undefined; + transmission?: number | undefined; +} + +export class MeshPhysicalMaterial extends MeshStandardMaterial { + constructor(parameters?: MeshPhysicalMaterialParameters); + + /** + * Read-only flag to check if a given object is of type {@link MeshPhysicalMaterial}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isMeshPhysicalMaterial: true; + + /** + * @default { 'STANDARD': '', 'PHYSICAL': '' } + */ + defines: { [key: string]: any }; + + /** + * @default 0 + */ + anisotropyRotation?: number; + + /** + * @default null + */ + anisotropyMap?: Texture | null; + + /** + * @default null + */ + clearcoatMap: Texture | null; + + /** + * @default 0 + */ + clearcoatRoughness: number; + + /** + * @default null + */ + clearcoatRoughnessMap: Texture | null; + + /** + * @default new THREE.Vector2( 1, 1 ) + */ + clearcoatNormalScale: Vector2; + + /** + * @default null + */ + clearcoatNormalMap: Texture | null; + + /** + * @default 1.5 + */ + ior: number; + + /** + * @default 0.5 + */ + get reflectivity(): number; + set reflectivity(reflectivity: number); + + /** + * @default null + */ + iridescenceMap: Texture | null; + + /** + * @default 1.3 + */ + iridescenceIOR: number; + + /** + * @default [100, 400] + */ + iridescenceThicknessRange: [number, number]; + + /** + * @default null + */ + iridescenceThicknessMap: Texture | null; + + /** + * @default Color( 0x000000 ) + */ + sheenColor: Color; + + /** + * @default null + */ + sheenColorMap: Texture | null; + + /** + * @default 1.0 + */ + sheenRoughness: number; + + /** + * @default null + */ + sheenRoughnessMap: Texture | null; + + /** + * @default null + */ + transmissionMap: Texture | null; + + /** + * @default 0.01 + */ + thickness: number; + + /** + * @default null + */ + thicknessMap: Texture | null; + + /** + * @default 0.0 + */ + attenuationDistance: number; + + /** + * @default Color( 1, 1, 1 ) + */ + attenuationColor: Color; + + /** + * @default 1.0 + */ + specularIntensity: number; + + /** + * @default null + */ + specularIntensityMap: Texture | null; + + /** + * @default Color(1, 1, 1) + */ + specularColor: Color; + + /** + * @default null + */ + specularColorMap: Texture | null; + + /** + * @default 0 + */ + get anisotropy(): number; + set anisotropy(value: number); + + /** + * @default 0 + */ + get clearcoat(): number; + set clearcoat(value: number); + + /** + * @default 0 + */ + get iridescence(): number; + set iridescence(value: number); + + /** + * @default 0 + */ + get dispersion(): number; + set dispersion(value: number); + + /** + * @default 0.0 + */ + get sheen(): number; + set sheen(value: number); + + /** + * @default 0 + */ + get transmission(): number; + set transmission(value: number); +} diff --git a/src-testing/src/materials/MeshStandardMaterial.d.ts b/src-testing/src/materials/MeshStandardMaterial.d.ts new file mode 100644 index 000000000..b4493a1d7 --- /dev/null +++ b/src-testing/src/materials/MeshStandardMaterial.d.ts @@ -0,0 +1,213 @@ +import { NormalMapTypes } from "../constants.js"; +import { Color, ColorRepresentation } from "../math/Color.js"; +import { Euler } from "../math/Euler.js"; +import { Vector2 } from "../math/Vector2.js"; +import { Texture } from "../textures/Texture.js"; +import { Material, MaterialParameters } from "./Material.js"; + +export interface MeshStandardMaterialParameters extends MaterialParameters { + color?: ColorRepresentation | undefined; + roughness?: number | undefined; + metalness?: number | undefined; + map?: Texture | null | undefined; + lightMap?: Texture | null | undefined; + lightMapIntensity?: number | undefined; + aoMap?: Texture | null | undefined; + aoMapIntensity?: number | undefined; + emissive?: ColorRepresentation | undefined; + emissiveIntensity?: number | undefined; + emissiveMap?: Texture | null | undefined; + bumpMap?: Texture | null | undefined; + bumpScale?: number | undefined; + normalMap?: Texture | null | undefined; + normalMapType?: NormalMapTypes | undefined; + normalScale?: Vector2 | undefined; + displacementMap?: Texture | null | undefined; + displacementScale?: number | undefined; + displacementBias?: number | undefined; + roughnessMap?: Texture | null | undefined; + metalnessMap?: Texture | null | undefined; + alphaMap?: Texture | null | undefined; + envMap?: Texture | null | undefined; + envMapRotation?: Euler | undefined; + envMapIntensity?: number | undefined; + wireframe?: boolean | undefined; + wireframeLinewidth?: number | undefined; + fog?: boolean | undefined; + flatShading?: boolean | undefined; +} + +export class MeshStandardMaterial extends Material { + constructor(parameters?: MeshStandardMaterialParameters); + + /** + * Read-only flag to check if a given object is of type {@link MeshStandardMaterial}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isMeshStandardMaterial: true; + + /** + * @default { 'STANDARD': '' } + */ + defines: { [key: string]: any }; + + /** + * @default new THREE.Color( 0xffffff ) + */ + color: Color; + + /** + * @default 1 + */ + roughness: number; + + /** + * @default 0 + */ + metalness: number; + + /** + * @default null + */ + map: Texture | null; + + /** + * @default null + */ + lightMap: Texture | null; + + /** + * @default 1 + */ + lightMapIntensity: number; + + /** + * @default null + */ + aoMap: Texture | null; + + /** + * @default 1 + */ + aoMapIntensity: number; + + /** + * @default new THREE.Color( 0x000000 ) + */ + emissive: Color; + + /** + * @default 1 + */ + emissiveIntensity: number; + + /** + * @default null + */ + emissiveMap: Texture | null; + + /** + * @default null + */ + bumpMap: Texture | null; + + /** + * @default 1 + */ + bumpScale: number; + + /** + * @default null + */ + normalMap: Texture | null; + + /** + * @default THREE.TangentSpaceNormalMap + */ + normalMapType: NormalMapTypes; + + /** + * @default new THREE.Vector2( 1, 1 ) + */ + normalScale: Vector2; + + /** + * @default null + */ + displacementMap: Texture | null; + + /** + * @default 1 + */ + displacementScale: number; + + /** + * @default 0 + */ + displacementBias: number; + + /** + * @default null + */ + roughnessMap: Texture | null; + + /** + * @default null + */ + metalnessMap: Texture | null; + + /** + * @default null + */ + alphaMap: Texture | null; + + /** + * @default null + */ + envMap: Texture | null; + + /** + * The rotation of the environment map in radians. Default is `(0,0,0)`. + */ + envMapRotation: Euler; + + /** + * @default 1 + */ + envMapIntensity: number; + + /** + * @default false + */ + wireframe: boolean; + + /** + * @default 1 + */ + wireframeLinewidth: number; + + /** + * @default 'round' + */ + wireframeLinecap: string; + + /** + * @default 'round' + */ + wireframeLinejoin: string; + + /** + * Define whether the material is rendered with flat shading. Default is false. + * @default false + */ + flatShading: boolean; + + /** + * Whether the material is affected by fog. Default is true. + * @default fog + */ + fog: boolean; + + setValues(parameters: MeshStandardMaterialParameters): void; +} diff --git a/src-testing/src/materials/MeshToonMaterial.d.ts b/src-testing/src/materials/MeshToonMaterial.d.ts new file mode 100644 index 000000000..14c71b27a --- /dev/null +++ b/src-testing/src/materials/MeshToonMaterial.d.ts @@ -0,0 +1,173 @@ +import { NormalMapTypes } from "../constants.js"; +import { Color, ColorRepresentation } from "../math/Color.js"; +import { Vector2 } from "../math/Vector2.js"; +import { Texture } from "../textures/Texture.js"; +import { Material, MaterialParameters } from "./Material.js"; + +export interface MeshToonMaterialParameters extends MaterialParameters { + /** geometry color in hexadecimal. Default is 0xffffff. */ + color?: ColorRepresentation | undefined; + opacity?: number | undefined; + gradientMap?: Texture | null | undefined; + map?: Texture | null | undefined; + lightMap?: Texture | null | undefined; + lightMapIntensity?: number | undefined; + aoMap?: Texture | null | undefined; + aoMapIntensity?: number | undefined; + emissive?: ColorRepresentation | undefined; + emissiveIntensity?: number | undefined; + emissiveMap?: Texture | null | undefined; + bumpMap?: Texture | null | undefined; + bumpScale?: number | undefined; + normalMap?: Texture | null | undefined; + normalMapType?: NormalMapTypes | undefined; + normalScale?: Vector2 | undefined; + displacementMap?: Texture | null | undefined; + displacementScale?: number | undefined; + displacementBias?: number | undefined; + alphaMap?: Texture | null | undefined; + wireframe?: boolean | undefined; + wireframeLinewidth?: number | undefined; + wireframeLinecap?: string | undefined; + wireframeLinejoin?: string | undefined; + fog?: boolean | undefined; +} + +export class MeshToonMaterial extends Material { + constructor(parameters?: MeshToonMaterialParameters); + + /** + * Read-only flag to check if a given object is of type {@link MeshToonMaterial}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isMeshToonMaterial: true; + + /** + * @default { 'TOON': '' } + */ + defines: { [key: string]: any }; + + /** + * @default new THREE.Color( 0xffffff ) + */ + color: Color; + + /** + * @default null + */ + gradientMap: Texture | null; + + /** + * @default null + */ + map: Texture | null; + + /** + * @default null + */ + lightMap: Texture | null; + + /** + * @default 1 + */ + lightMapIntensity: number; + + /** + * @default null + */ + aoMap: Texture | null; + + /** + * @default 1 + */ + aoMapIntensity: number; + + /** + * @default new THREE.Color( 0x000000 ) + */ + emissive: Color; + + /** + * @default 1 + */ + emissiveIntensity: number; + + /** + * @default null + */ + emissiveMap: Texture | null; + + /** + * @default null + */ + bumpMap: Texture | null; + + /** + * @default 1 + */ + bumpScale: number; + + /** + * @default null + */ + normalMap: Texture | null; + + /** + * @default THREE.TangentSpaceNormalMap + */ + normalMapType: NormalMapTypes; + + /** + * @default new THREE.Vector2( 1, 1 ) + */ + normalScale: Vector2; + + /** + * @default null + */ + displacementMap: Texture | null; + + /** + * @default 1 + */ + displacementScale: number; + + /** + * @default 0 + */ + displacementBias: number; + + /** + * @default null + */ + alphaMap: Texture | null; + + /** + * @default false + */ + wireframe: boolean; + + /** + * @default 1 + */ + wireframeLinewidth: number; + + /** + * @default 'round' + */ + wireframeLinecap: string; + + /** + * @default 'round' + */ + wireframeLinejoin: string; + + /** + * Whether the material is affected by fog. Default is true. + * @default fog + */ + fog: boolean; + + setValues(parameters: MeshToonMaterialParameters): void; +} diff --git a/src-testing/src/materials/PointsMaterial.d.ts b/src-testing/src/materials/PointsMaterial.d.ts new file mode 100644 index 000000000..a47a0817b --- /dev/null +++ b/src-testing/src/materials/PointsMaterial.d.ts @@ -0,0 +1,56 @@ +import { Color, ColorRepresentation } from "../math/Color.js"; +import { Texture } from "../textures/Texture.js"; +import { Material, MaterialParameters } from "./Material.js"; + +export interface PointsMaterialParameters extends MaterialParameters { + color?: ColorRepresentation | undefined; + map?: Texture | null | undefined; + alphaMap?: Texture | null | undefined; + size?: number | undefined; + sizeAttenuation?: boolean | undefined; + fog?: boolean | undefined; +} + +export class PointsMaterial extends Material { + constructor(parameters?: PointsMaterialParameters); + + /** + * Read-only flag to check if a given object is of type {@link PointsMaterial}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isPointsMaterial: true; + + /** + * @default new THREE.Color( 0xffffff ) + */ + color: Color; + + /** + * @default null + */ + map: Texture | null; + + /** + * @default null + */ + alphaMap: Texture | null; + + /** + * @default 1 + */ + size: number; + + /** + * @default true + */ + sizeAttenuation: boolean; + + /** + * Whether the material is affected by fog. Default is true. + * @default fog + */ + fog: boolean; + + setValues(parameters: PointsMaterialParameters): void; +} diff --git a/src-testing/src/materials/RawShaderMaterial.d.ts b/src-testing/src/materials/RawShaderMaterial.d.ts new file mode 100644 index 000000000..6ff6b67f0 --- /dev/null +++ b/src-testing/src/materials/RawShaderMaterial.d.ts @@ -0,0 +1,12 @@ +import { ShaderMaterial, ShaderMaterialParameters } from "./ShaderMaterial.js"; + +export class RawShaderMaterial extends ShaderMaterial { + constructor(parameters?: ShaderMaterialParameters); + + /** + * Read-only flag to check if a given object is of type {@link RawShaderMaterial}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isRawShaderMaterial: true; +} diff --git a/src-testing/src/materials/ShaderMaterial.d.ts b/src-testing/src/materials/ShaderMaterial.d.ts new file mode 100644 index 000000000..53e07a821 --- /dev/null +++ b/src-testing/src/materials/ShaderMaterial.d.ts @@ -0,0 +1,162 @@ +import { GLSLVersion } from "../constants.js"; +import { JSONMeta } from "../core/Object3D.js"; +import { UniformsGroup } from "../core/UniformsGroup.js"; +import { Matrix3, Matrix3Tuple } from "../math/Matrix3.js"; +import { Matrix4, Matrix4Tuple } from "../math/Matrix4.js"; +import { Vector2Tuple } from "../math/Vector2.js"; +import { Vector3Tuple } from "../math/Vector3.js"; +import { Vector4Tuple } from "../math/Vector4.js"; +import { IUniform } from "../renderers/shaders/UniformsLib.js"; +import { Material, MaterialJSON, MaterialParameters } from "./Material.js"; + +export interface ShaderMaterialParameters extends MaterialParameters { + uniforms?: { [uniform: string]: IUniform } | undefined; + uniformsGroups?: UniformsGroup[] | undefined; + vertexShader?: string | undefined; + fragmentShader?: string | undefined; + linewidth?: number | undefined; + wireframe?: boolean | undefined; + wireframeLinewidth?: number | undefined; + lights?: boolean | undefined; + clipping?: boolean | undefined; + fog?: boolean | undefined; + extensions?: + | { + clipCullDistance?: boolean | undefined; + multiDraw?: boolean | undefined; + } + | undefined; + glslVersion?: GLSLVersion | undefined; +} + +export type ShaderMaterialUniformJSON = { + type: "t"; + value: string; +} | { + type: "c"; + value: number; +} | { + type: "v2"; + value: Vector2Tuple; +} | { + type: "v3"; + value: Vector3Tuple; +} | { + type: "v4"; + value: Vector4Tuple; +} | { + type: "m3"; + value: Matrix3Tuple; +} | { + type: "m4"; + value: Matrix4Tuple; +} | { + value: unknown; +}; + +export interface ShaderMaterialJSON extends MaterialJSON { + glslVersion: number | null; + uniforms: Record; + + defines?: Record; + + vertexShader: string; + ragmentShader: string; + + lights: boolean; + clipping: boolean; + + extensions?: Record; +} + +export class ShaderMaterial extends Material { + constructor(parameters?: ShaderMaterialParameters); + + /** + * Read-only flag to check if a given object is of type {@link ShaderMaterial}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isShaderMaterial: true; + + /** + * @default {} + */ + defines: { [key: string]: any }; + + /** + * @default {} + */ + uniforms: { [uniform: string]: IUniform }; + + uniformsGroups: UniformsGroup[]; + + vertexShader: string; + + fragmentShader: string; + + /** + * @default 1 + */ + linewidth: number; + + /** + * @default false + */ + wireframe: boolean; + + /** + * @default 1 + */ + wireframeLinewidth: number; + + /** + * @default false + */ + fog: boolean; + + /** + * @default false + */ + lights: boolean; + + /** + * @default false + */ + clipping: boolean; + + /** + * @default { + * clipCullDistance: false, + * multiDraw: false + * } + */ + extensions: { + clipCullDistance: boolean; + multiDraw: boolean; + }; + + /** + * @default { 'color': [ 1, 1, 1 ], 'uv': [ 0, 0 ], 'uv1': [ 0, 0 ] } + */ + defaultAttributeValues: any; + + /** + * @default undefined + */ + index0AttributeName: string | undefined; + + /** + * @default false + */ + uniformsNeedUpdate: boolean; + + /** + * @default null + */ + glslVersion: GLSLVersion | null; + + setValues(parameters: ShaderMaterialParameters): void; + + toJSON(meta?: JSONMeta): ShaderMaterialJSON; +} diff --git a/src-testing/src/materials/ShadowMaterial.d.ts b/src-testing/src/materials/ShadowMaterial.d.ts new file mode 100644 index 000000000..fc7a7ae06 --- /dev/null +++ b/src-testing/src/materials/ShadowMaterial.d.ts @@ -0,0 +1,34 @@ +import { Color, ColorRepresentation } from "../math/Color.js"; +import { Material, MaterialParameters } from "./Material.js"; + +export interface ShadowMaterialParameters extends MaterialParameters { + color?: ColorRepresentation | undefined; + fog?: boolean | undefined; +} + +export class ShadowMaterial extends Material { + constructor(parameters?: ShadowMaterialParameters); + + /** + * Read-only flag to check if a given object is of type {@link ShadowMaterial}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isShadowMaterial: true; + + /** + * @default new THREE.Color( 0x000000 ) + */ + color: Color; + + /** + * @default true + */ + transparent: boolean; + + /** + * Whether the material is affected by fog. Default is true. + * @default fog + */ + fog: boolean; +} diff --git a/src-testing/src/materials/SpriteMaterial.d.ts b/src-testing/src/materials/SpriteMaterial.d.ts new file mode 100644 index 000000000..4fa5db8a0 --- /dev/null +++ b/src-testing/src/materials/SpriteMaterial.d.ts @@ -0,0 +1,61 @@ +import { Color, ColorRepresentation } from "../math/Color.js"; +import { Texture } from "../textures/Texture.js"; +import { Material, MaterialParameters } from "./Material.js"; + +export interface SpriteMaterialParameters extends MaterialParameters { + color?: ColorRepresentation | undefined; + map?: Texture | null | undefined; + alphaMap?: Texture | null | undefined; + rotation?: number | undefined; + sizeAttenuation?: boolean | undefined; + fog?: boolean | undefined; +} + +export class SpriteMaterial extends Material { + constructor(parameters?: SpriteMaterialParameters); + /** + * Read-only flag to check if a given object is of type {@link SpriteMaterial}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isSpriteMaterial: true; + + /** + * @default new THREE.Color( 0xffffff ) + */ + color: Color; + + /** + * @default null + */ + map: Texture | null; + + /** + * @default null + */ + alphaMap: Texture | null; + + /** + * @default 0 + */ + rotation: number; + + /** + * @default true + */ + sizeAttenuation: boolean; + + /** + * @default true + */ + transparent: boolean; + + /** + * Whether the material is affected by fog. Default is true. + * @default fog + */ + fog: boolean; + + setValues(parameters: SpriteMaterialParameters): void; + copy(source: SpriteMaterial): this; +} diff --git a/src-testing/src/materials/nodes/InstancedPointsNodeMaterial.d.ts b/src-testing/src/materials/nodes/InstancedPointsNodeMaterial.d.ts new file mode 100644 index 000000000..9784e7f52 --- /dev/null +++ b/src-testing/src/materials/nodes/InstancedPointsNodeMaterial.d.ts @@ -0,0 +1,33 @@ +import { Color } from "../../math/Color.js"; +import Node from "../../nodes/core/Node.js"; +import { Texture } from "../../textures/Texture.js"; +import { PointsMaterialParameters } from "../PointsMaterial.js"; +import NodeMaterial, { NodeMaterialParameters } from "./NodeMaterial.js"; + +export interface InstancedPointsNodeMaterialParameters extends NodeMaterialParameters, PointsMaterialParameters { + useAlphaToCoverage?: boolean | undefined; + useColor?: boolean | undefined; + pointWidth?: number | undefined; + pointColorNode?: Node | null | undefined; + pointWidthNode?: Node | null | undefined; +} + +declare class InstancedPointsNodeMaterial extends NodeMaterial { + useAlphaToCoverage: boolean; + useColor: boolean | undefined; + pointWidth: number; + pointColorNode: Node | null; + pointWidthNode: Node | null; + + // Properties from LineDashedMaterial + readonly isPointsMaterial: true; + color: Color; + map: Texture | null; + alphaMap: Texture | null; + size: number; + sizeAttenuation: boolean; + + constructor(params?: InstancedPointsNodeMaterialParameters); +} + +export default InstancedPointsNodeMaterial; diff --git a/src-testing/src/materials/nodes/Line2NodeMaterial.d.ts b/src-testing/src/materials/nodes/Line2NodeMaterial.d.ts new file mode 100644 index 000000000..13c65ffd6 --- /dev/null +++ b/src-testing/src/materials/nodes/Line2NodeMaterial.d.ts @@ -0,0 +1,53 @@ +import { Color } from "../../math/Color.js"; +import Node from "../../nodes/core/Node.js"; +import { Texture } from "../../textures/Texture.js"; +import { LineDashedMaterialParameters } from "../LineDashedMaterial.js"; +import NodeMaterial, { NodeMaterialParameters } from "./NodeMaterial.js"; + +export interface Line2NodeMaterialParameters extends NodeMaterialParameters, LineDashedMaterialParameters { + dashed?: boolean | undefined; +} + +export default class Line2NodeMaterial extends NodeMaterial { + lights: boolean; + + // Properties from LineDashedMaterial + readonly isLineDashedMaterial: true; + scale: number; + dashSize: number; + gapSize: number; + + // Properties from LineBasicMaterial + readonly isLineBasicMaterial: true; + color: Color; + fog: boolean; + linewidth: number; + linecap: string; + linejoin: string; + map: Texture | null; + + useAlphaToCoverage: boolean; + useColor: boolean; + useDash: boolean; + useWorldUnits: boolean; + + dashOffset: number; + lineWidth: number; + + lineColorNode: Node | null; + + offsetNode: Node | null; + dashScaleNode: Node | null; + dashSizeNode: Node | null; + gapSizeNode: Node | null; + + constructor(parameters?: Line2NodeMaterialParameters); + + setupShaders(): void; + + get worldUnits(): boolean; + set worldUnits(value: boolean); + + get dashed(): boolean; + set dashed(value: boolean); +} diff --git a/src-testing/src/materials/nodes/LineBasicNodeMaterial.d.ts b/src-testing/src/materials/nodes/LineBasicNodeMaterial.d.ts new file mode 100644 index 000000000..84b8db897 --- /dev/null +++ b/src-testing/src/materials/nodes/LineBasicNodeMaterial.d.ts @@ -0,0 +1,22 @@ +import { Color } from "../../math/Color.js"; +import { Texture } from "../../textures/Texture.js"; +import { LineBasicMaterialParameters } from "../LineBasicMaterial.js"; +import NodeMaterial, { NodeMaterialParameters } from "./NodeMaterial.js"; + +export interface LineBasicNodeMaterialParameters extends NodeMaterialParameters, LineBasicMaterialParameters { +} + +export default class LineBasicNodeMaterial extends NodeMaterial { + readonly isLineBasicNodeMaterial: true; + + // Properties from LineBasicMaterial + readonly isLineBasicMaterial: true; + color: Color; + fog: boolean; + linewidth: number; + linecap: string; + linejoin: string; + map: Texture | null; + + constructor(parameters?: LineBasicNodeMaterialParameters); +} diff --git a/src-testing/src/materials/nodes/LineDashedNodeMaterial.d.ts b/src-testing/src/materials/nodes/LineDashedNodeMaterial.d.ts new file mode 100644 index 000000000..10715e2cd --- /dev/null +++ b/src-testing/src/materials/nodes/LineDashedNodeMaterial.d.ts @@ -0,0 +1,29 @@ +import Node from "../../nodes/core/Node.js"; +import { LineDashedMaterialParameters } from "../LineDashedMaterial.js"; +import NodeMaterial, { NodeMaterialParameters } from "./NodeMaterial.js"; + +export interface LineDashedNodeMaterialParameters extends NodeMaterialParameters, LineDashedMaterialParameters { + offsetNode?: Node | null | undefined; + dashScaleNode?: Node | null | undefined; + dashSizeNode?: Node | null | undefined; + gapSizeNode?: Node | null | undefined; +} + +declare class LineDashedNodeMaterial extends NodeMaterial { + readonly isLineDashedNodeMaterial: true; + + offsetNode: Node | null; + dashScaleNode: Node | null; + dashSizeNode: Node | null; + gapSizeNode: Node | null; + + // Properties from LineDashedMaterial + readonly isLineDashedMaterial: true; + scale: number; + dashSize: number; + gapSize: number; + + constructor(parameters?: LineDashedMaterialParameters); +} + +export default LineDashedNodeMaterial; diff --git a/src-testing/src/materials/nodes/MeshBasicNodeMaterial.d.ts b/src-testing/src/materials/nodes/MeshBasicNodeMaterial.d.ts new file mode 100644 index 000000000..515fa5f67 --- /dev/null +++ b/src-testing/src/materials/nodes/MeshBasicNodeMaterial.d.ts @@ -0,0 +1,36 @@ +import { Combine } from "../../constants.js"; +import { Color } from "../../math/Color.js"; +import { Euler } from "../../math/Euler.js"; +import { Texture } from "../../textures/Texture.js"; +import { MeshBasicMaterialParameters } from "../MeshBasicMaterial.js"; +import NodeMaterial, { NodeMaterialParameters } from "./NodeMaterial.js"; + +export interface MeshBasicNodeMaterialParameters extends NodeMaterialParameters, MeshBasicMaterialParameters { +} + +export default class MeshBasicNodeMaterial extends NodeMaterial { + readonly isMeshBasicNodeMaterial: true; + + // Properties from MeshBasicMaterial + readonly isMeshBasicMaterial: true; + color: Color; + map: Texture | null; + lightMap: Texture | null; + lightMapIntensity: number; + aoMap: Texture | null; + aoMapIntensity: number; + specularMap: Texture | null; + alphaMap: Texture | null; + envMap: Texture | null; + envMapRotation: Euler; + combine: Combine; + reflectivity: number; + refractionRatio: number; + wireframe: boolean; + wireframeLinewidth: number; + wireframeLinecap: string; + wireframeLinejoin: string; + fog: boolean; + + constructor(parameters?: MeshBasicNodeMaterialParameters); +} diff --git a/src-testing/src/materials/nodes/MeshLambertNodeMaterial.d.ts b/src-testing/src/materials/nodes/MeshLambertNodeMaterial.d.ts new file mode 100644 index 000000000..aedda10a7 --- /dev/null +++ b/src-testing/src/materials/nodes/MeshLambertNodeMaterial.d.ts @@ -0,0 +1,49 @@ +import { Combine, NormalMapTypes } from "../../constants.js"; +import { Color } from "../../math/Color.js"; +import { Euler } from "../../math/Euler.js"; +import { Vector2 } from "../../math/Vector2.js"; +import { Texture } from "../../textures/Texture.js"; +import { MeshLambertMaterialParameters } from "../MeshLambertMaterial.js"; +import NodeMaterial, { NodeMaterialParameters } from "./NodeMaterial.js"; + +export interface MeshLambertNodeMaterialParameters extends NodeMaterialParameters, MeshLambertMaterialParameters {} + +declare class MeshLambertNodeMaterial extends NodeMaterial { + readonly isMeshLambertNodeMaterial: true; + + // Properties from MeshLambertMaterial + readonly isMeshLambertMaterial: true; + color: Color; + bumpMap: Texture | null; + bumpScale: number; + displacementMap: Texture | null; + displacementScale: number; + displacementBias: number; + emissive: Color; + emissiveIntensity: number; + emissiveMap: Texture | null; + flatShading: boolean; + map: Texture | null; + lightMap: Texture | null; + lightMapIntensity: number; + normalMap: Texture | null; + normalMapType: NormalMapTypes; + normalScale: Vector2; + aoMap: Texture | null; + aoMapIntensity: number; + specularMap: Texture | null; + alphaMap: Texture | null; + envMap: Texture | null; + envMapRotation: Euler; + combine: Combine; + reflectivity: number; + refractionRatio: number; + wireframe: boolean; + wireframeLinewidth: number; + wireframeLinecap: string; + wireframeLinejoin: string; + + constructor(parameters?: MeshLambertNodeMaterialParameters); +} + +export default MeshLambertNodeMaterial; diff --git a/src-testing/src/materials/nodes/MeshMatcapNodeMaterial.d.ts b/src-testing/src/materials/nodes/MeshMatcapNodeMaterial.d.ts new file mode 100644 index 000000000..cc0d2f9a0 --- /dev/null +++ b/src-testing/src/materials/nodes/MeshMatcapNodeMaterial.d.ts @@ -0,0 +1,32 @@ +import { NormalMapTypes } from "../../constants.js"; +import { Color } from "../../math/Color.js"; +import { Vector2 } from "../../math/Vector2.js"; +import { Texture } from "../../textures/Texture.js"; +import { MeshMatcapMaterialParameters } from "../MeshMatcapMaterial.js"; +import NodeMaterial, { NodeMaterialParameters } from "./NodeMaterial.js"; + +export interface MeshMatcapNodeMaterialParameters extends NodeMaterialParameters, MeshMatcapMaterialParameters { +} + +export default class MeshMatcapNodeMaterial extends NodeMaterial { + readonly isMeshMatcapNodeMaterial: true; + + // Properties from MeshMatcapMaterial + readonly isMeshMatcapMaterial: true; + color: Color; + matcap: Texture | null; + map: Texture | null; + bumpMap: Texture | null; + bumpScale: number; + normalMap: Texture | null; + normalMapType: NormalMapTypes; + normalScale: Vector2; + displacementMap: Texture | null; + displacementScale: number; + displacementBias: number; + alphaMap: Texture | null; + flatShading: boolean; + fog: boolean; + + constructor(parameters?: MeshMatcapNodeMaterialParameters); +} diff --git a/src-testing/src/materials/nodes/MeshNormalNodeMaterial.d.ts b/src-testing/src/materials/nodes/MeshNormalNodeMaterial.d.ts new file mode 100644 index 000000000..761998bac --- /dev/null +++ b/src-testing/src/materials/nodes/MeshNormalNodeMaterial.d.ts @@ -0,0 +1,28 @@ +import { NormalMapTypes } from "../../constants.js"; +import { Vector2 } from "../../math/Vector2.js"; +import { Texture } from "../../textures/Texture.js"; +import { MeshNormalMaterialParameters } from "../MeshNormalMaterial.js"; +import NodeMaterial, { NodeMaterialParameters } from "./NodeMaterial.js"; + +export interface MeshBasicNodeMaterialParameters extends NodeMaterialParameters, MeshNormalMaterialParameters { +} + +export default class MeshNormalNodeMaterial extends NodeMaterial { + readonly isMeshNormalNodeMaterial: true; + + // Properties from MeshNormalMaterial + readonly isMeshNormalMaterial: true; + bumpMap: Texture | null; + bumpScale: number; + normalMap: Texture | null; + normalMapType: NormalMapTypes; + normalScale: Vector2; + displacementMap: Texture | null; + displacementScale: number; + displacementBias: number; + wireframe: boolean; + wireframeLinewidth: number; + flatShading: boolean; + + constructor(parameters?: MeshBasicNodeMaterialParameters); +} diff --git a/src-testing/src/materials/nodes/MeshPhongNodeMaterial.d.ts b/src-testing/src/materials/nodes/MeshPhongNodeMaterial.d.ts new file mode 100644 index 000000000..3680e533c --- /dev/null +++ b/src-testing/src/materials/nodes/MeshPhongNodeMaterial.d.ts @@ -0,0 +1,56 @@ +import { Combine, NormalMapTypes } from "../../constants.js"; +import { Color } from "../../math/Color.js"; +import { Euler } from "../../math/Euler.js"; +import { Vector2 } from "../../math/Vector2.js"; +import Node from "../../nodes/core/Node.js"; +import { Texture } from "../../textures/Texture.js"; +import { MeshPhongMaterialParameters } from "../MeshPhongMaterial.js"; +import NodeMaterial, { NodeMaterialParameters } from "./NodeMaterial.js"; + +export interface MeshPhongNodeMaterialParameters extends NodeMaterialParameters, MeshPhongMaterialParameters { +} + +export default class MeshPhongNodeMaterial extends NodeMaterial { + readonly isMeshPhongNodeMaterial: true; + + shininessNode: Node | null; + specularNode: Node | null; + + // Properties from MeshPhongMaterial + readonly isMeshPhongMaterial: true; + color: Color; + specular: Color; + shininess: number; + map: Texture | null; + lightMap: Texture | null; + lightMapIntensity: number; + aoMap: Texture | null; + aoMapIntensity: number; + emissive: Color; + emissiveIntensity: number; + emissiveMap: Texture | null; + bumpMap: Texture | null; + bumpScale: number; + normalMap: Texture | null; + normalMapType: NormalMapTypes; + normalScale: Vector2; + displacementMap: Texture | null; + displacementScale: number; + displacementBias: number; + specularMap: Texture | null; + alphaMap: Texture | null; + envMap: Texture | null; + envMapRotation: Euler; + combine: Combine; + reflectivity: number; + refractionRatio: number; + wireframe: boolean; + wireframeLinewidth: number; + wireframeLinecap: string; + wireframeLinejoin: string; + flatShading: boolean; + metal: boolean; + fog: boolean; + + constructor(parameters?: MeshPhongNodeMaterialParameters); +} diff --git a/src-testing/src/materials/nodes/MeshPhysicalNodeMaterial.d.ts b/src-testing/src/materials/nodes/MeshPhysicalNodeMaterial.d.ts new file mode 100644 index 000000000..e7da3ee90 --- /dev/null +++ b/src-testing/src/materials/nodes/MeshPhysicalNodeMaterial.d.ts @@ -0,0 +1,93 @@ +import { Color } from "../../math/Color.js"; +import { Vector2 } from "../../math/Vector2.js"; +import Node from "../../nodes/core/Node.js"; +import { ShaderNodeObject } from "../../nodes/tsl/TSLCore.js"; +import { Texture } from "../../textures/Texture.js"; +import { MeshPhysicalMaterialParameters } from "../MeshPhysicalMaterial.js"; +import MeshStandardNodeMaterial, { MeshStandardNodeMaterialParameters } from "./MeshStandardNodeMaterial.js"; + +export interface MeshPhysicalNodeMaterialParameters + extends MeshStandardNodeMaterialParameters, MeshPhysicalMaterialParameters +{ +} + +export default class MeshPhysicalNodeMaterial extends MeshStandardNodeMaterial { + readonly isMeshPhysicalNodeMaterial: true; + + clearcoatNode: Node | null; + clearcoatRoughnessNode: Node | null; + clearcoatNormalNode: Node | null; + + sheenNode: Node | null; + sheenRoughnessNode: Node | null; + + iridescenceNode: Node | null; + iridescenceIORNode: Node | null; + iridescenceThicknessNode: Node | null; + + iorNode: Node | null; + + specularIntensityNode: Node | null; + specularColorNode: Node | null; + + transmissionNode: Node | null; + thicknessNode: Node | null; + attenuationDistanceNode: Node | null; + attenuationColorNode: Node | null; + dispersionNode: Node | null; + + anisotropyNode: Node | null; + + // Properties from MeshPhysicalMaterial + readonly isMeshPhysicalMaterial: true; + anisotropyRotation: number; + anisotropyMap: Texture | null; + clearcoatMap: Texture | null; + clearcoatRoughness: number; + clearcoatRoughnessMap: Texture | null; + clearcoatNormalScale: Vector2; + clearcoatNormalMap: Texture | null; + ior: number; + get reflectivity(): number; + set reflectivity(reflectivity: number); + iridescenceMap: Texture | null; + iridescenceIOR: number; + iridescenceThicknessRange: [number, number]; + iridescenceThicknessMap: Texture | null; + sheenColor: Color; + sheenColorMap: Texture | null; + sheenRoughness: number; + sheenRoughnessMap: Texture | null; + transmissionMap: Texture | null; + thickness: number; + thicknessMap: Texture | null; + attenuationDistance: number; + attenuationColor: Color; + specularIntensity: number; + specularIntensityMap: Texture | null; + specularColor: Color; + specularColorMap: Texture | null; + get anisotropy(): number; + set anisotropy(value: number); + get clearcoat(): number; + set clearcoat(value: number); + get iridescence(): number; + set iridescence(value: number); + get dispersion(): number; + set dispersion(value: number); + get sheen(): number; + set sheen(value: number); + get transmission(): number; + set transmission(value: number); + + constructor(parameters?: MeshPhysicalNodeMaterialParameters); + + get useClearcoat(): boolean; + get useIridescence(): boolean; + get useSheen(): boolean; + get useAnisotropy(): boolean; + get useTransmission(): boolean; + get useDispersion(): boolean; + + setupClearcoatNormal(): ShaderNodeObject; +} diff --git a/src-testing/src/materials/nodes/MeshSSSNodeMaterial.d.ts b/src-testing/src/materials/nodes/MeshSSSNodeMaterial.d.ts new file mode 100644 index 000000000..bccbec30c --- /dev/null +++ b/src-testing/src/materials/nodes/MeshSSSNodeMaterial.d.ts @@ -0,0 +1,16 @@ +import ConstNode from "../../nodes/core/ConstNode.js"; +import Node from "../../nodes/core/Node.js"; +import MeshPhysicalNodeMaterial, { MeshPhysicalNodeMaterialParameters } from "./MeshPhysicalNodeMaterial.js"; + +export default class MeshSSSNodeMaterial extends MeshPhysicalNodeMaterial { + thicknessColorNode: Node | null; + thicknessDistortionNode: ConstNode; + thicknessAmbientNode: ConstNode; + thicknessAttenuationNode: ConstNode; + thicknessPowerNode: ConstNode; + thicknessScaleNode: ConstNode; + + constructor(parameters?: MeshPhysicalNodeMaterialParameters); + + get useSSS(): boolean; +} diff --git a/src-testing/src/materials/nodes/MeshStandardNodeMaterial.d.ts b/src-testing/src/materials/nodes/MeshStandardNodeMaterial.d.ts new file mode 100644 index 000000000..9c3329042 --- /dev/null +++ b/src-testing/src/materials/nodes/MeshStandardNodeMaterial.d.ts @@ -0,0 +1,56 @@ +import { NormalMapTypes } from "../../constants.js"; +import { Color } from "../../math/Color.js"; +import { Euler } from "../../math/Euler.js"; +import { Vector2 } from "../../math/Vector2.js"; +import Node from "../../nodes/core/Node.js"; +import { Texture } from "../../textures/Texture.js"; +import { MeshStandardMaterialParameters } from "../MeshStandardMaterial.js"; +import NodeMaterial, { NodeMaterialParameters } from "./NodeMaterial.js"; + +export interface MeshStandardNodeMaterialParameters extends NodeMaterialParameters, MeshStandardMaterialParameters { +} + +export default class MeshStandardNodeMaterial extends NodeMaterial { + readonly isMeshStandardNodeMaterial: true; + + emissiveNode: Node | null; + + metalnessNode: Node | null; + roughnessNode: Node | null; + + // Properties from MeshStandardMaterial + readonly isMeshStandardMaterial: true; + color: Color; + roughness: number; + metalness: number; + map: Texture | null; + lightMap: Texture | null; + lightMapIntensity: number; + aoMap: Texture | null; + aoMapIntensity: number; + emissive: Color; + emissiveIntensity: number; + emissiveMap: Texture | null; + bumpMap: Texture | null; + bumpScale: number; + normalMap: Texture | null; + normalMapType: NormalMapTypes; + normalScale: Vector2; + displacementMap: Texture | null; + displacementScale: number; + displacementBias: number; + roughnessMap: Texture | null; + metalnessMap: Texture | null; + alphaMap: Texture | null; + envMap: Texture | null; + envMapRotation: Euler; + envMapIntensity: number; + wireframe: boolean; + wireframeLinewidth: number; + wireframeLinecap: string; + wireframeLinejoin: string; + flatShading: boolean; + fog: boolean; + + constructor(parameters?: MeshStandardNodeMaterialParameters); +} diff --git a/src-testing/src/materials/nodes/MeshToonNodeMaterial.d.ts b/src-testing/src/materials/nodes/MeshToonNodeMaterial.d.ts new file mode 100644 index 000000000..e1dee0fb3 --- /dev/null +++ b/src-testing/src/materials/nodes/MeshToonNodeMaterial.d.ts @@ -0,0 +1,42 @@ +import { NormalMapTypes } from "../../constants.js"; +import { Color } from "../../math/Color.js"; +import { Vector2 } from "../../math/Vector2.js"; +import { Texture } from "../../textures/Texture.js"; +import { MeshToonMaterialParameters } from "../MeshToonMaterial.js"; +import NodeMaterial, { NodeMaterialParameters } from "./NodeMaterial.js"; + +export interface MeshToonNodeMaterialParameters extends NodeMaterialParameters, MeshToonMaterialParameters { +} + +export default class MeshToonNodeMaterial extends NodeMaterial { + readonly isMeshToonNodeMaterial: true; + + // Properties from MeshToonMaterial + readonly isMeshToonMaterial: true; + color: Color; + gradientMap: Texture | null; + map: Texture | null; + lightMap: Texture | null; + lightMapIntensity: number; + aoMap: Texture | null; + aoMapIntensity: number; + emissive: Color; + emissiveIntensity: number; + emissiveMap: Texture | null; + bumpMap: Texture | null; + bumpScale: number; + normalMap: Texture | null; + normalMapType: NormalMapTypes; + normalScale: Vector2; + displacementMap: Texture | null; + displacementScale: number; + displacementBias: number; + alphaMap: Texture | null; + wireframe: boolean; + wireframeLinewidth: number; + wireframeLinecap: string; + wireframeLinejoin: string; + fog: boolean; + + constructor(parameters?: MeshToonNodeMaterialParameters); +} diff --git a/src-testing/src/materials/nodes/NodeMaterial.ts b/src-testing/src/materials/nodes/NodeMaterial.ts new file mode 100644 index 000000000..3c77c74e6 --- /dev/null +++ b/src-testing/src/materials/nodes/NodeMaterial.ts @@ -0,0 +1,535 @@ +import { Material } from '../Material.js'; +import { NormalBlending } from '../../constants.js'; + +import { getNodeChildren, getCacheKey } from '../../nodes/core/NodeUtils.js'; +import { attribute } from '../../nodes/core/AttributeNode.js'; +import { output, diffuseColor, emissive, varyingProperty } from '../../nodes/core/PropertyNode.js'; +import { + materialAlphaTest, + materialColor, + materialOpacity, + materialEmissive, + materialNormal, + materialLightMap, + materialAOMap, +} from '../../nodes/accessors/MaterialNode.js'; +import { modelViewProjection } from '../../nodes/accessors/ModelViewProjectionNode.js'; +import { normalLocal } from '../../nodes/accessors/Normal.js'; +import { instance } from '../../nodes/accessors/InstanceNode.js'; +import { batch } from '../../nodes/accessors/BatchNode.js'; +import { materialReference } from '../../nodes/accessors/MaterialReferenceNode.js'; +import { positionLocal, positionView } from '../../nodes/accessors/Position.js'; +import { skinningReference } from '../../nodes/accessors/SkinningNode.js'; +import { morphReference } from '../../nodes/accessors/MorphNode.js'; +import { mix } from '../../nodes/math/MathNode.js'; +import { float, vec3, vec4 } from '../../nodes/tsl/TSLBase.js'; +import AONode from '../../nodes/lighting/AONode.js'; +import { lightingContext } from '../../nodes/lighting/LightingContextNode.js'; +import IrradianceNode from '../../nodes/lighting/IrradianceNode.js'; +import { + depth, + perspectiveDepthToLogarithmicDepth, + viewZToOrthographicDepth, +} from '../../nodes/display/ViewportDepthNode.js'; +import { cameraFar, cameraNear } from '../../nodes/accessors/Camera.js'; +import { clipping, clippingAlpha } from '../../nodes/accessors/ClippingNode.js'; +import NodeMaterialObserver from './manager/NodeMaterialObserver.js'; + +class NodeMaterial extends Material { + static get type() { + return 'NodeMaterial'; + } + + constructor() { + super(); + + this.isNodeMaterial = true; + + this.type = this.constructor.type; + + this.forceSinglePass = false; + + this.fog = true; + this.lights = false; + + this.lightsNode = null; + this.envNode = null; + this.aoNode = null; + + this.colorNode = null; + this.normalNode = null; + this.opacityNode = null; + this.backdropNode = null; + this.backdropAlphaNode = null; + this.alphaTestNode = null; + + this.positionNode = null; + this.geometryNode = null; + + this.depthNode = null; + this.shadowNode = null; + this.shadowPositionNode = null; + + this.outputNode = null; + this.mrtNode = null; + + this.fragmentNode = null; + this.vertexNode = null; + } + + customProgramCacheKey() { + return this.type + getCacheKey(this); + } + + build(builder) { + this.setup(builder); + } + + setupObserver(builder) { + return new NodeMaterialObserver(builder); + } + + setup(builder) { + builder.context.setupNormal = () => this.setupNormal(builder); + + // < VERTEX STAGE > + + builder.addStack(); + + builder.stack.outputNode = this.vertexNode || this.setupPosition(builder); + + if (this.geometryNode !== null) { + builder.stack.outputNode = builder.stack.outputNode.bypass(this.geometryNode); + } + + builder.addFlow('vertex', builder.removeStack()); + + // < FRAGMENT STAGE > + + builder.addStack(); + + let resultNode; + + const clippingNode = this.setupClipping(builder); + + if (this.depthWrite === true) this.setupDepth(builder); + + if (this.fragmentNode === null) { + this.setupDiffuseColor(builder); + this.setupVariants(builder); + + const outgoingLightNode = this.setupLighting(builder); + + if (clippingNode !== null) builder.stack.add(clippingNode); + + // force unsigned floats - useful for RenderTargets + + const basicOutput = vec4(outgoingLightNode, diffuseColor.a).max(0); + + resultNode = this.setupOutput(builder, basicOutput); + + // OUTPUT NODE + + output.assign(resultNode); + + // + + if (this.outputNode !== null) resultNode = this.outputNode; + + // MRT + + const renderTarget = builder.renderer.getRenderTarget(); + + if (renderTarget !== null) { + const mrt = builder.renderer.getMRT(); + const materialMRT = this.mrtNode; + + if (mrt !== null) { + resultNode = mrt; + + if (materialMRT !== null) { + resultNode = mrt.merge(materialMRT); + } + } else if (materialMRT !== null) { + resultNode = materialMRT; + } + } + } else { + let fragmentNode = this.fragmentNode; + + if (fragmentNode.isOutputStructNode !== true) { + fragmentNode = vec4(fragmentNode); + } + + resultNode = this.setupOutput(builder, fragmentNode); + } + + builder.stack.outputNode = resultNode; + + builder.addFlow('fragment', builder.removeStack()); + + // < MONITOR > + + builder.monitor = this.setupObserver(builder); + } + + setupClipping(builder) { + if (builder.clippingContext === null) return null; + + const { globalClippingCount, localClippingCount } = builder.clippingContext; + + let result = null; + + if (globalClippingCount || localClippingCount) { + const samples = builder.renderer.samples; + + if (this.alphaToCoverage && samples > 1) { + // to be added to flow when the color/alpha value has been determined + result = clippingAlpha(); + } else { + builder.stack.add(clipping()); + } + } + + return result; + } + + setupDepth(builder) { + const { renderer, camera } = builder; + + // Depth + + let depthNode = this.depthNode; + + if (depthNode === null) { + const mrt = renderer.getMRT(); + + if (mrt && mrt.has('depth')) { + depthNode = mrt.get('depth'); + } else if (renderer.logarithmicDepthBuffer === true) { + if (camera.isPerspectiveCamera) { + depthNode = perspectiveDepthToLogarithmicDepth(modelViewProjection().w, cameraNear, cameraFar); + } else { + depthNode = viewZToOrthographicDepth(positionView.z, cameraNear, cameraFar); + } + } + } + + if (depthNode !== null) { + depth.assign(depthNode).append(); + } + } + + setupPosition(builder) { + const { object } = builder; + const geometry = object.geometry; + + builder.addStack(); + + // Vertex + + if (geometry.morphAttributes.position || geometry.morphAttributes.normal || geometry.morphAttributes.color) { + morphReference(object).append(); + } + + if (object.isSkinnedMesh === true) { + skinningReference(object).append(); + } + + if (this.displacementMap) { + const displacementMap = materialReference('displacementMap', 'texture'); + const displacementScale = materialReference('displacementScale', 'float'); + const displacementBias = materialReference('displacementBias', 'float'); + + positionLocal.addAssign( + normalLocal.normalize().mul(displacementMap.x.mul(displacementScale).add(displacementBias)), + ); + } + + if (object.isBatchedMesh) { + batch(object).append(); + } + + if (object.instanceMatrix && object.instanceMatrix.isInstancedBufferAttribute === true) { + instance(object).append(); + } + + if (this.positionNode !== null) { + positionLocal.assign(this.positionNode); + } + + const mvp = modelViewProjection(); + + builder.context.vertex = builder.removeStack(); + builder.context.mvp = mvp; + + return mvp; + } + + setupDiffuseColor({ object, geometry }) { + let colorNode = this.colorNode ? vec4(this.colorNode) : materialColor; + + // VERTEX COLORS + + if (this.vertexColors === true && geometry.hasAttribute('color')) { + colorNode = vec4(colorNode.xyz.mul(attribute('color', 'vec3')), colorNode.a); + } + + // Instanced colors + + if (object.instanceColor) { + const instanceColor = varyingProperty('vec3', 'vInstanceColor'); + + colorNode = instanceColor.mul(colorNode); + } + + if (object.isBatchedMesh && object._colorsTexture) { + const batchColor = varyingProperty('vec3', 'vBatchColor'); + + colorNode = batchColor.mul(colorNode); + } + + // COLOR + + diffuseColor.assign(colorNode); + + // OPACITY + + const opacityNode = this.opacityNode ? float(this.opacityNode) : materialOpacity; + diffuseColor.a.assign(diffuseColor.a.mul(opacityNode)); + + // ALPHA TEST + + if (this.alphaTestNode !== null || this.alphaTest > 0) { + const alphaTestNode = this.alphaTestNode !== null ? float(this.alphaTestNode) : materialAlphaTest; + + diffuseColor.a.lessThanEqual(alphaTestNode).discard(); + } + + if (this.transparent === false && this.blending === NormalBlending && this.alphaToCoverage === false) { + diffuseColor.a.assign(1.0); + } + } + + setupVariants(/*builder*/) { + // Interface function. + } + + setupOutgoingLight() { + return this.lights === true ? vec3(0) : diffuseColor.rgb; + } + + setupNormal() { + return this.normalNode ? vec3(this.normalNode) : materialNormal; + } + + setupEnvironment(/*builder*/) { + let node = null; + + if (this.envNode) { + node = this.envNode; + } else if (this.envMap) { + node = this.envMap.isCubeTexture + ? materialReference('envMap', 'cubeTexture') + : materialReference('envMap', 'texture'); + } + + return node; + } + + setupLightMap(builder) { + let node = null; + + if (builder.material.lightMap) { + node = new IrradianceNode(materialLightMap); + } + + return node; + } + + setupLights(builder) { + const materialLightsNode = []; + + // + + const envNode = this.setupEnvironment(builder); + + if (envNode && envNode.isLightingNode) { + materialLightsNode.push(envNode); + } + + const lightMapNode = this.setupLightMap(builder); + + if (lightMapNode && lightMapNode.isLightingNode) { + materialLightsNode.push(lightMapNode); + } + + if (this.aoNode !== null || builder.material.aoMap) { + const aoNode = this.aoNode !== null ? this.aoNode : materialAOMap; + + materialLightsNode.push(new AONode(aoNode)); + } + + let lightsN = this.lightsNode || builder.lightsNode; + + if (materialLightsNode.length > 0) { + lightsN = builder.renderer.lighting.createNode([...lightsN.getLights(), ...materialLightsNode]); + } + + return lightsN; + } + + setupLightingModel(/*builder*/) { + // Interface function. + } + + setupLighting(builder) { + const { material } = builder; + const { backdropNode, backdropAlphaNode, emissiveNode } = this; + + // OUTGOING LIGHT + + const lights = this.lights === true || this.lightsNode !== null; + + const lightsNode = lights ? this.setupLights(builder) : null; + + let outgoingLightNode = this.setupOutgoingLight(builder); + + if (lightsNode && lightsNode.getScope().hasLights) { + const lightingModel = this.setupLightingModel(builder); + + outgoingLightNode = lightingContext(lightsNode, lightingModel, backdropNode, backdropAlphaNode); + } else if (backdropNode !== null) { + outgoingLightNode = vec3( + backdropAlphaNode !== null ? mix(outgoingLightNode, backdropNode, backdropAlphaNode) : backdropNode, + ); + } + + // EMISSIVE + + if ( + (emissiveNode && emissiveNode.isNode === true) || + (material.emissive && material.emissive.isColor === true) + ) { + emissive.assign(vec3(emissiveNode ? emissiveNode : materialEmissive)); + + outgoingLightNode = outgoingLightNode.add(emissive); + } + + return outgoingLightNode; + } + + setupOutput(builder, outputNode) { + // FOG + + if (this.fog === true) { + const fogNode = builder.fogNode; + + if (fogNode) outputNode = vec4(fogNode.mix(outputNode.rgb, fogNode.colorNode), outputNode.a); + } + + return outputNode; + } + + setDefaultValues(material) { + // This approach is to reuse the native refreshUniforms* + // and turn available the use of features like transmission and environment in core + + for (const property in material) { + const value = material[property]; + + if (this[property] === undefined) { + this[property] = value; + + if (value && value.clone) this[property] = value.clone(); + } + } + + const descriptors = Object.getOwnPropertyDescriptors(material.constructor.prototype); + + for (const key in descriptors) { + if ( + Object.getOwnPropertyDescriptor(this.constructor.prototype, key) === undefined && + descriptors[key].get !== undefined + ) { + Object.defineProperty(this.constructor.prototype, key, descriptors[key]); + } + } + } + + toJSON(meta) { + const isRoot = meta === undefined || typeof meta === 'string'; + + if (isRoot) { + meta = { + textures: {}, + images: {}, + nodes: {}, + }; + } + + const data = Material.prototype.toJSON.call(this, meta); + const nodeChildren = getNodeChildren(this); + + data.inputNodes = {}; + + for (const { property, childNode } of nodeChildren) { + data.inputNodes[property] = childNode.toJSON(meta).uuid; + } + + // TODO: Copied from Object3D.toJSON + + function extractFromCache(cache) { + const values = []; + + for (const key in cache) { + const data = cache[key]; + delete data.metadata; + values.push(data); + } + + return values; + } + + if (isRoot) { + const textures = extractFromCache(meta.textures); + const images = extractFromCache(meta.images); + const nodes = extractFromCache(meta.nodes); + + if (textures.length > 0) data.textures = textures; + if (images.length > 0) data.images = images; + if (nodes.length > 0) data.nodes = nodes; + } + + return data; + } + + copy(source) { + this.lightsNode = source.lightsNode; + this.envNode = source.envNode; + + this.colorNode = source.colorNode; + this.normalNode = source.normalNode; + this.opacityNode = source.opacityNode; + this.backdropNode = source.backdropNode; + this.backdropAlphaNode = source.backdropAlphaNode; + this.alphaTestNode = source.alphaTestNode; + + this.positionNode = source.positionNode; + this.geometryNode = source.geometryNode; + + this.depthNode = source.depthNode; + this.shadowNode = source.shadowNode; + this.shadowPositionNode = source.shadowPositionNode; + + this.outputNode = source.outputNode; + this.mrtNode = source.mrtNode; + + this.fragmentNode = source.fragmentNode; + this.vertexNode = source.vertexNode; + + return super.copy(source); + } +} + +export default NodeMaterial; diff --git a/src-testing/src/materials/nodes/NodeMaterials.d.ts b/src-testing/src/materials/nodes/NodeMaterials.d.ts new file mode 100644 index 000000000..395273cd9 --- /dev/null +++ b/src-testing/src/materials/nodes/NodeMaterials.d.ts @@ -0,0 +1,18 @@ +export { default as InstancedPointsNodeMaterial } from "./InstancedPointsNodeMaterial.js"; +export { default as Line2NodeMaterial } from "./Line2NodeMaterial.js"; +export { default as LineBasicNodeMaterial } from "./LineBasicNodeMaterial.js"; +export { default as LineDashedNodeMaterial } from "./LineDashedNodeMaterial.js"; +export { default as MeshBasicNodeMaterial } from "./MeshBasicNodeMaterial.js"; +export { default as MeshLambertNodeMaterial } from "./MeshLambertNodeMaterial.js"; +export { default as MeshMatcapNodeMaterial } from "./MeshMatcapNodeMaterial.js"; +export { default as MeshNormalNodeMaterial } from "./MeshNormalNodeMaterial.js"; +export { default as MeshPhongNodeMaterial } from "./MeshPhongNodeMaterial.js"; +export { default as MeshPhysicalNodeMaterial } from "./MeshPhysicalNodeMaterial.js"; +export { default as MeshSSSNodeMaterial } from "./MeshSSSNodeMaterial.js"; +export { default as MeshStandardNodeMaterial } from "./MeshStandardNodeMaterial.js"; +export { default as MeshToonNodeMaterial } from "./MeshToonNodeMaterial.js"; +export { default as NodeMaterial } from "./NodeMaterial.js"; +export { default as PointsNodeMaterial } from "./PointsNodeMaterial.js"; +export { default as ShadowNodeMaterial } from "./ShadowNodeMaterial.js"; +export { default as SpriteNodeMaterial } from "./SpriteNodeMaterial.js"; +export { default as VolumeNodeMaterial } from "./VolumeNodeMaterial.js"; diff --git a/src-testing/src/materials/nodes/PointsNodeMaterial.d.ts b/src-testing/src/materials/nodes/PointsNodeMaterial.d.ts new file mode 100644 index 000000000..836f55a6d --- /dev/null +++ b/src-testing/src/materials/nodes/PointsNodeMaterial.d.ts @@ -0,0 +1,21 @@ +import { Color } from "../../math/Color.js"; +import { Texture } from "../../textures/Texture.js"; +import { PointsMaterialParameters } from "../PointsMaterial.js"; +import NodeMaterial, { NodeMaterialParameters } from "./NodeMaterial.js"; + +export interface PointsNodeMaterialParameters extends NodeMaterialParameters, PointsMaterialParameters { +} + +export default class PointsNodeMaterial extends NodeMaterial { + readonly isPointsNodeMaterial: true; + + // Properties from PointsMaterial + readonly isPointsMaterial: true; + color: Color; + map: Texture | null; + alphaMap: Texture | null; + size: number; + sizeAttenuation: boolean; + + constructor(parameters?: PointsNodeMaterialParameters); +} diff --git a/src-testing/src/materials/nodes/ShadowNodeMaterial.d.ts b/src-testing/src/materials/nodes/ShadowNodeMaterial.d.ts new file mode 100644 index 000000000..c53d92437 --- /dev/null +++ b/src-testing/src/materials/nodes/ShadowNodeMaterial.d.ts @@ -0,0 +1,17 @@ +import { Color } from "../../math/Color.js"; +import { ShadowMaterialParameters } from "../ShadowMaterial.js"; +import NodeMaterial, { NodeMaterialParameters } from "./NodeMaterial.js"; + +export interface ShadowNodeMaterialParameters extends NodeMaterialParameters, ShadowMaterialParameters { +} + +export default class ShadowNodeMaterial extends NodeMaterial { + readonly isShadowNodeMaterial: true; + + // Properties from ShadowMaterial + readonly isShadowMaterial: true; + color: Color; + fog: boolean; + + constructor(parameters?: ShadowNodeMaterialParameters); +} diff --git a/src-testing/src/materials/nodes/SpriteNodeMaterial.d.ts b/src-testing/src/materials/nodes/SpriteNodeMaterial.d.ts new file mode 100644 index 000000000..e34845d78 --- /dev/null +++ b/src-testing/src/materials/nodes/SpriteNodeMaterial.d.ts @@ -0,0 +1,26 @@ +import { Color } from "../../math/Color.js"; +import Node from "../../nodes/core/Node.js"; +import { Texture } from "../../textures/Texture.js"; +import { SpriteMaterialParameters } from "../SpriteMaterial.js"; +import NodeMaterial, { NodeMaterialParameters } from "./NodeMaterial.js"; + +export interface SpriteNodeMaterialParameters extends NodeMaterialParameters, SpriteMaterialParameters { +} + +export default class SpriteNodeMaterial extends NodeMaterial { + isSpriteNodeMaterial: true; + + rotationNode: Node | null; + scaleNode: Node | null; + + // Properties from SpriteMaterial + readonly isSpriteMaterial: true; + color: Color; + map: Texture | null; + alphaMap: Texture | null; + rotation: number; + sizeAttenuation: boolean; + fog: boolean; + + constructor(parameters?: SpriteNodeMaterialParameters); +} diff --git a/src-testing/src/materials/nodes/VolumeNodeMaterial.d.ts b/src-testing/src/materials/nodes/VolumeNodeMaterial.d.ts new file mode 100644 index 000000000..4f2c6e260 --- /dev/null +++ b/src-testing/src/materials/nodes/VolumeNodeMaterial.d.ts @@ -0,0 +1,10 @@ +import Node from "../../nodes/core/Node.js"; +import NodeMaterial, { NodeMaterialParameters } from "./NodeMaterial.js"; + +export default class VolumeNodeMaterial extends NodeMaterial { + lights: boolean; + readonly isVolumeNodeMaterial: true; + testNode: Node | null; + + constructor(parameters?: NodeMaterialParameters); +} diff --git a/src-testing/src/materials/nodes/manager/NodeMaterialObserver.ts b/src-testing/src/materials/nodes/manager/NodeMaterialObserver.ts new file mode 100644 index 000000000..8ab1a6d67 --- /dev/null +++ b/src-testing/src/materials/nodes/manager/NodeMaterialObserver.ts @@ -0,0 +1,308 @@ +const refreshUniforms = [ + 'alphaMap', + 'alphaTest', + 'anisotropy', + 'anisotropyMap', + 'anisotropyRotation', + 'aoMap', + 'attenuationColor', + 'attenuationDistance', + 'bumpMap', + 'clearcoat', + 'clearcoatMap', + 'clearcoatNormalMap', + 'clearcoatNormalScale', + 'clearcoatRoughness', + 'color', + 'dispersion', + 'displacementMap', + 'emissive', + 'emissiveMap', + 'envMap', + 'gradientMap', + 'ior', + 'iridescence', + 'iridescenceIOR', + 'iridescenceMap', + 'iridescenceThicknessMap', + 'lightMap', + 'map', + 'matcap', + 'metalness', + 'metalnessMap', + 'normalMap', + 'normalScale', + 'opacity', + 'roughness', + 'roughnessMap', + 'sheen', + 'sheenColor', + 'sheenColorMap', + 'sheenRoughnessMap', + 'shininess', + 'specular', + 'specularColor', + 'specularColorMap', + 'specularIntensity', + 'specularIntensityMap', + 'specularMap', + 'thickness', + 'transmission', + 'transmissionMap', +]; + +class NodeMaterialObserver { + constructor(builder) { + this.renderObjects = new WeakMap(); + this.hasNode = this.containsNode(builder); + this.hasAnimation = builder.object.isSkinnedMesh === true; + this.refreshUniforms = refreshUniforms; + this.renderId = 0; + } + + firstInitialization(renderObject) { + const hasInitialized = this.renderObjects.has(renderObject); + + if (hasInitialized === false) { + this.getRenderObjectData(renderObject); + + return true; + } + + return false; + } + + getRenderObjectData(renderObject) { + let data = this.renderObjects.get(renderObject); + + if (data === undefined) { + const { geometry, material } = renderObject; + + data = { + material: this.getMaterialData(material), + geometry: { + attributes: this.getAttributesData(geometry.attributes), + indexVersion: geometry.index ? geometry.index.version : null, + drawRange: { start: geometry.drawRange.start, count: geometry.drawRange.count }, + }, + worldMatrix: renderObject.object.matrixWorld.clone(), + }; + + if (renderObject.object.center) { + data.center = renderObject.object.center.clone(); + } + + if (renderObject.object.morphTargetInfluences) { + data.morphTargetInfluences = renderObject.object.morphTargetInfluences.slice(); + } + + if (renderObject.bundle !== null) { + data.version = renderObject.bundle.version; + } + + this.renderObjects.set(renderObject, data); + } + + return data; + } + + getAttributesData(attributes) { + const attributesData = {}; + + for (const name in attributes) { + const attribute = attributes[name]; + + attributesData[name] = { + version: attribute.version, + }; + } + + return attributesData; + } + + containsNode(builder) { + const material = builder.material; + + for (const property in material) { + if (material[property] && material[property].isNode) return true; + } + + if (builder.renderer.nodes.modelViewMatrix !== null || builder.renderer.nodes.modelNormalViewMatrix !== null) + return true; + + return false; + } + + getMaterialData(material) { + const data = {}; + + for (const property of this.refreshUniforms) { + const value = material[property]; + + if (value === null || value === undefined) continue; + + if (typeof value === 'object' && value.clone !== undefined) { + if (value.isTexture === true) { + data[property] = { id: value.id, version: value.version }; + } else { + data[property] = value.clone(); + } + } else { + data[property] = value; + } + } + + return data; + } + + equals(renderObject) { + const { object, material, geometry } = renderObject; + + const renderObjectData = this.getRenderObjectData(renderObject); + + // world matrix + + if (renderObjectData.worldMatrix.equals(object.matrixWorld) !== true) { + renderObjectData.worldMatrix.copy(object.matrixWorld); + + return false; + } + + // material + + const materialData = renderObjectData.material; + + for (const property in materialData) { + const value = materialData[property]; + const mtlValue = material[property]; + + if (value.equals !== undefined) { + if (value.equals(mtlValue) === false) { + value.copy(mtlValue); + + return false; + } + } else if (mtlValue.isTexture === true) { + if (value.id !== mtlValue.id || value.version !== mtlValue.version) { + value.id = mtlValue.id; + value.version = mtlValue.version; + + return false; + } + } else if (value !== mtlValue) { + materialData[property] = mtlValue; + + return false; + } + } + + // geometry + + const storedGeometryData = renderObjectData.geometry; + const attributes = geometry.attributes; + const storedAttributes = storedGeometryData.attributes; + + const storedAttributeNames = Object.keys(storedAttributes); + const currentAttributeNames = Object.keys(attributes); + + if (storedAttributeNames.length !== currentAttributeNames.length) { + renderObjectData.geometry.attributes = this.getAttributesData(attributes); + return false; + } + + // Compare each attribute + for (const name of storedAttributeNames) { + const storedAttributeData = storedAttributes[name]; + const attribute = attributes[name]; + + if (attribute === undefined) { + // Attribute was removed + delete storedAttributes[name]; + return false; + } + + if (storedAttributeData.version !== attribute.version) { + storedAttributeData.version = attribute.version; + return false; + } + } + + // Check index + const index = geometry.index; + const storedIndexVersion = storedGeometryData.indexVersion; + const currentIndexVersion = index ? index.version : null; + + if (storedIndexVersion !== currentIndexVersion) { + storedGeometryData.indexVersion = currentIndexVersion; + return false; + } + + // Check drawRange + if ( + storedGeometryData.drawRange.start !== geometry.drawRange.start || + storedGeometryData.drawRange.count !== geometry.drawRange.count + ) { + storedGeometryData.drawRange.start = geometry.drawRange.start; + storedGeometryData.drawRange.count = geometry.drawRange.count; + return false; + } + + // morph targets + + if (renderObjectData.morphTargetInfluences) { + let morphChanged = false; + + for (let i = 0; i < renderObjectData.morphTargetInfluences.length; i++) { + if (renderObjectData.morphTargetInfluences[i] !== object.morphTargetInfluences[i]) { + morphChanged = true; + } + } + + if (morphChanged) return true; + } + + // center + + if (renderObjectData.center) { + if (renderObjectData.center.equals(object.center) === false) { + renderObjectData.center.copy(object.center); + + return true; + } + } + + // bundle + + if (renderObject.bundle !== null) { + renderObjectData.version = renderObject.bundle.version; + } + + return true; + } + + needsRefresh(renderObject, nodeFrame) { + if (this.hasNode || this.hasAnimation || this.firstInitialization(renderObject)) return true; + + const { renderId } = nodeFrame; + + if (this.renderId !== renderId) { + this.renderId = renderId; + + return true; + } + + const isStatic = renderObject.object.static === true; + const isBundle = + renderObject.bundle !== null && + renderObject.bundle.static === true && + this.getRenderObjectData(renderObject).version === renderObject.bundle.version; + + if (isStatic || isBundle) return false; + + const notEqual = this.equals(renderObject) !== true; + + return notEqual; + } +} + +export default NodeMaterialObserver; diff --git a/src-testing/src/math/Box2.d.ts b/src-testing/src/math/Box2.d.ts new file mode 100644 index 000000000..de05083d0 --- /dev/null +++ b/src-testing/src/math/Box2.d.ts @@ -0,0 +1,48 @@ +import { Vector2 } from "./Vector2.js"; + +// Math ////////////////////////////////////////////////////////////////////////////////// + +export class Box2 { + constructor(min?: Vector2, max?: Vector2); + + /** + * @default new THREE.Vector2( + Infinity, + Infinity ) + */ + min: Vector2; + + /** + * @default new THREE.Vector2( - Infinity, - Infinity ) + */ + max: Vector2; + + set(min: Vector2, max: Vector2): Box2; + setFromPoints(points: Vector2[]): Box2; + setFromCenterAndSize(center: Vector2, size: Vector2): Box2; + clone(): this; + copy(box: Box2): this; + makeEmpty(): Box2; + isEmpty(): boolean; + getCenter(target: Vector2): Vector2; + getSize(target: Vector2): Vector2; + expandByPoint(point: Vector2): Box2; + expandByVector(vector: Vector2): Box2; + expandByScalar(scalar: number): Box2; + containsPoint(point: Vector2): boolean; + containsBox(box: Box2): boolean; + getParameter(point: Vector2, target: Vector2): Vector2; + intersectsBox(box: Box2): boolean; + clampPoint(point: Vector2, target: Vector2): Vector2; + distanceToPoint(point: Vector2): number; + intersect(box: Box2): Box2; + union(box: Box2): Box2; + translate(offset: Vector2): Box2; + equals(box: Box2): boolean; + /** + * @deprecated Use {@link Box2#isEmpty .isEmpty()} instead. + */ + empty(): any; + /** + * @deprecated Use {@link Box2#intersectsBox .intersectsBox()} instead. + */ + isIntersectionBox(b: any): any; +} diff --git a/src-testing/src/math/Box3.d.ts b/src-testing/src/math/Box3.d.ts new file mode 100644 index 000000000..2e7b11bc9 --- /dev/null +++ b/src-testing/src/math/Box3.d.ts @@ -0,0 +1,66 @@ +import { BufferAttribute } from "../core/BufferAttribute.js"; +import { Object3D } from "../core/Object3D.js"; +import { Matrix4 } from "./Matrix4.js"; +import { Plane } from "./Plane.js"; +import { Sphere } from "./Sphere.js"; +import { Triangle } from "./Triangle.js"; +import { Vector3 } from "./Vector3.js"; + +export class Box3 { + constructor(min?: Vector3, max?: Vector3); + + /** + * @default new THREE.Vector3( + Infinity, + Infinity, + Infinity ) + */ + min: Vector3; + + /** + * @default new THREE.Vector3( - Infinity, - Infinity, - Infinity ) + */ + max: Vector3; + readonly isBox3: true; + + set(min: Vector3, max: Vector3): this; + setFromArray(array: ArrayLike): this; + setFromBufferAttribute(bufferAttribute: BufferAttribute): this; + setFromPoints(points: Vector3[]): this; + setFromCenterAndSize(center: Vector3, size: Vector3): this; + setFromObject(object: Object3D, precise?: boolean): this; + clone(): this; + copy(box: Box3): this; + makeEmpty(): this; + isEmpty(): boolean; + getCenter(target: Vector3): Vector3; + getSize(target: Vector3): Vector3; + expandByPoint(point: Vector3): this; + expandByVector(vector: Vector3): this; + expandByScalar(scalar: number): this; + expandByObject(object: Object3D, precise?: boolean): this; + containsPoint(point: Vector3): boolean; + containsBox(box: Box3): boolean; + getParameter(point: Vector3, target: Vector3): Vector3; + intersectsBox(box: Box3): boolean; + intersectsSphere(sphere: Sphere): boolean; + intersectsPlane(plane: Plane): boolean; + intersectsTriangle(triangle: Triangle): boolean; + clampPoint(point: Vector3, target: Vector3): Vector3; + distanceToPoint(point: Vector3): number; + getBoundingSphere(target: Sphere): Sphere; + intersect(box: Box3): this; + union(box: Box3): this; + applyMatrix4(matrix: Matrix4): this; + translate(offset: Vector3): this; + equals(box: Box3): boolean; + /** + * @deprecated Use {@link Box3#isEmpty .isEmpty()} instead. + */ + empty(): any; + /** + * @deprecated Use {@link Box3#intersectsBox .intersectsBox()} instead. + */ + isIntersectionBox(b: any): any; + /** + * @deprecated Use {@link Box3#intersectsSphere .intersectsSphere()} instead. + */ + isIntersectionSphere(s: any): any; +} diff --git a/src-testing/src/math/Color.d.ts b/src-testing/src/math/Color.d.ts new file mode 100644 index 000000000..a0e265f83 --- /dev/null +++ b/src-testing/src/math/Color.d.ts @@ -0,0 +1,375 @@ +import { Matrix3 } from "./Matrix3.js"; +import { Vector3 } from "./Vector3.js"; + +import { BufferAttribute } from "../core/BufferAttribute.js"; +import { InterleavedBufferAttribute } from "../core/InterleavedBufferAttribute.js"; + +export { SRGBToLinear } from "./ColorManagement.js"; + +declare const _colorKeywords: { + aliceblue: 0xf0f8ff; + antiquewhite: 0xfaebd7; + aqua: 0x00ffff; + aquamarine: 0x7fffd4; + azure: 0xf0ffff; + beige: 0xf5f5dc; + bisque: 0xffe4c4; + black: 0x000000; + blanchedalmond: 0xffebcd; + blue: 0x0000ff; + blueviolet: 0x8a2be2; + brown: 0xa52a2a; + burlywood: 0xdeb887; + cadetblue: 0x5f9ea0; + chartreuse: 0x7fff00; + chocolate: 0xd2691e; + coral: 0xff7f50; + cornflowerblue: 0x6495ed; + cornsilk: 0xfff8dc; + crimson: 0xdc143c; + cyan: 0x00ffff; + darkblue: 0x00008b; + darkcyan: 0x008b8b; + darkgoldenrod: 0xb8860b; + darkgray: 0xa9a9a9; + darkgreen: 0x006400; + darkgrey: 0xa9a9a9; + darkkhaki: 0xbdb76b; + darkmagenta: 0x8b008b; + darkolivegreen: 0x556b2f; + darkorange: 0xff8c00; + darkorchid: 0x9932cc; + darkred: 0x8b0000; + darksalmon: 0xe9967a; + darkseagreen: 0x8fbc8f; + darkslateblue: 0x483d8b; + darkslategray: 0x2f4f4f; + darkslategrey: 0x2f4f4f; + darkturquoise: 0x00ced1; + darkviolet: 0x9400d3; + deeppink: 0xff1493; + deepskyblue: 0x00bfff; + dimgray: 0x696969; + dimgrey: 0x696969; + dodgerblue: 0x1e90ff; + firebrick: 0xb22222; + floralwhite: 0xfffaf0; + forestgreen: 0x228b22; + fuchsia: 0xff00ff; + gainsboro: 0xdcdcdc; + ghostwhite: 0xf8f8ff; + gold: 0xffd700; + goldenrod: 0xdaa520; + gray: 0x808080; + green: 0x008000; + greenyellow: 0xadff2f; + grey: 0x808080; + honeydew: 0xf0fff0; + hotpink: 0xff69b4; + indianred: 0xcd5c5c; + indigo: 0x4b0082; + ivory: 0xfffff0; + khaki: 0xf0e68c; + lavender: 0xe6e6fa; + lavenderblush: 0xfff0f5; + lawngreen: 0x7cfc00; + lemonchiffon: 0xfffacd; + lightblue: 0xadd8e6; + lightcoral: 0xf08080; + lightcyan: 0xe0ffff; + lightgoldenrodyellow: 0xfafad2; + lightgray: 0xd3d3d3; + lightgreen: 0x90ee90; + lightgrey: 0xd3d3d3; + lightpink: 0xffb6c1; + lightsalmon: 0xffa07a; + lightseagreen: 0x20b2aa; + lightskyblue: 0x87cefa; + lightslategray: 0x778899; + lightslategrey: 0x778899; + lightsteelblue: 0xb0c4de; + lightyellow: 0xffffe0; + lime: 0x00ff00; + limegreen: 0x32cd32; + linen: 0xfaf0e6; + magenta: 0xff00ff; + maroon: 0x800000; + mediumaquamarine: 0x66cdaa; + mediumblue: 0x0000cd; + mediumorchid: 0xba55d3; + mediumpurple: 0x9370db; + mediumseagreen: 0x3cb371; + mediumslateblue: 0x7b68ee; + mediumspringgreen: 0x00fa9a; + mediumturquoise: 0x48d1cc; + mediumvioletred: 0xc71585; + midnightblue: 0x191970; + mintcream: 0xf5fffa; + mistyrose: 0xffe4e1; + moccasin: 0xffe4b5; + navajowhite: 0xffdead; + navy: 0x000080; + oldlace: 0xfdf5e6; + olive: 0x808000; + olivedrab: 0x6b8e23; + orange: 0xffa500; + orangered: 0xff4500; + orchid: 0xda70d6; + palegoldenrod: 0xeee8aa; + palegreen: 0x98fb98; + paleturquoise: 0xafeeee; + palevioletred: 0xdb7093; + papayawhip: 0xffefd5; + peachpuff: 0xffdab9; + peru: 0xcd853f; + pink: 0xffc0cb; + plum: 0xdda0dd; + powderblue: 0xb0e0e6; + purple: 0x800080; + rebeccapurple: 0x663399; + red: 0xff0000; + rosybrown: 0xbc8f8f; + royalblue: 0x4169e1; + saddlebrown: 0x8b4513; + salmon: 0xfa8072; + sandybrown: 0xf4a460; + seagreen: 0x2e8b57; + seashell: 0xfff5ee; + sienna: 0xa0522d; + silver: 0xc0c0c0; + skyblue: 0x87ceeb; + slateblue: 0x6a5acd; + slategray: 0x708090; + slategrey: 0x708090; + snow: 0xfffafa; + springgreen: 0x00ff7f; + steelblue: 0x4682b4; + tan: 0xd2b48c; + teal: 0x008080; + thistle: 0xd8bfd8; + tomato: 0xff6347; + turquoise: 0x40e0d0; + violet: 0xee82ee; + wheat: 0xf5deb3; + white: 0xffffff; + whitesmoke: 0xf5f5f5; + yellow: 0xffff00; + yellowgreen: 0x9acd32; +}; + +export type ColorRepresentation = Color | string | number; + +export interface HSL { + h: number; + s: number; + l: number; +} + +export interface RGB { + r: number; + g: number; + b: number; +} + +/** + * Class representing a color. + * + * A Color instance is represented by RGB components in the linear working color space, which defaults to + * `LinearSRGBColorSpace`. Inputs conventionally using `SRGBColorSpace` (such as hexadecimals and CSS strings) are + * converted to the working color space automatically. + * + * ``` + * // converted automatically from SRGBColorSpace to LinearSRGBColorSpace + * const color = new THREE.Color().setHex( 0x112233 ); + * ``` + * + * Source color spaces may be specified explicitly, to ensure correct conversions. + * + * ``` + * // assumed already LinearSRGBColorSpace; no conversion + * const color = new THREE.Color().setRGB( 0.5, 0.5, 0.5 ); + * + * // converted explicitly from SRGBColorSpace to LinearSRGBColorSpace + * const color = new THREE.Color().setRGB( 0.5, 0.5, 0.5, SRGBColorSpace ); + * ``` + * + * If THREE.ColorManagement is disabled, no conversions occur. For details, see Color management. + * + * Iterating through a Color instance will yield its components (r, g, b) in the corresponding order. + */ +export class Color { + constructor(color?: ColorRepresentation); + constructor(r: number, g: number, b: number); + + readonly isColor: true; + + /** + * Red channel value between `0.0` and `1.0`. Default is `1`. + * @default 1 + */ + r: number; + + /** + * Green channel value between `0.0` and `1.0`. Default is `1`. + * @default 1 + */ + g: number; + + /** + * Blue channel value between `0.0` and `1.0`. Default is `1`. + * @default 1 + */ + b: number; + + set(...args: [color: ColorRepresentation] | [r: number, g: number, b: number]): this; + + /** + * Sets this color's {@link r}, {@link g} and {@link b} components from the x, y, and z components of the specified + * {@link Vector3 | vector}. + */ + setFromVector3(vector: Vector3): this; + + setScalar(scalar: number): Color; + setHex(hex: number, colorSpace?: string): Color; + + /** + * Sets this color from RGB values. + * @param r Red channel value between 0 and 1. + * @param g Green channel value between 0 and 1. + * @param b Blue channel value between 0 and 1. + */ + setRGB(r: number, g: number, b: number, colorSpace?: string): Color; + + /** + * Sets this color from HSL values. + * Based on MochiKit implementation by Bob Ippolito. + * + * @param h Hue channel value between 0 and 1. + * @param s Saturation value channel between 0 and 1. + * @param l Value channel value between 0 and 1. + */ + setHSL(h: number, s: number, l: number, colorSpace?: string): Color; + + /** + * Sets this color from a CSS context style string. + * @param contextStyle Color in CSS context style format. + */ + setStyle(style: string, colorSpace?: string): Color; + + /** + * Sets this color from a color name. + * Faster than {@link Color#setStyle .setStyle()} method if you don't need the other CSS-style formats. + * @param style Color name in X11 format. + */ + setColorName(style: string, colorSpace?: string): Color; + + /** + * Clones this color. + */ + clone(): this; + + /** + * Copies given color. + * @param color Color to copy. + */ + copy(color: Color): this; + + /** + * Copies given color making conversion from `SRGBColorSpace` to `LinearSRGBColorSpace`. + * @param color Color to copy. + */ + copySRGBToLinear(color: Color): Color; + + /** + * Copies given color making conversion from `LinearSRGBColorSpace` to `SRGBColorSpace`. + * @param color Color to copy. + */ + copyLinearToSRGB(color: Color): Color; + + /** + * Converts this color from `SRGBColorSpace` to `LinearSRGBColorSpace`. + */ + convertSRGBToLinear(): Color; + + /** + * Converts this color from `LinearSRGBColorSpace` to `SRGBColorSpace`. + */ + convertLinearToSRGB(): Color; + + /** + * Returns the hexadecimal value of this color. + */ + getHex(colorSpace?: string): number; + + /** + * Returns the string formated hexadecimal value of this color. + */ + getHexString(colorSpace?: string): string; + + getHSL(target: HSL, colorSpace?: string): HSL; + + getRGB(target: RGB, colorSpace?: string): RGB; + + /** + * Returns the value of this color in CSS context style. + * Example: rgb(r, g, b) + */ + getStyle(colorSpace?: string): string; + + offsetHSL(h: number, s: number, l: number): this; + + add(color: Color): this; + addColors(color1: Color, color2: Color): this; + addScalar(s: number): this; + + /** + * Applies the transform {@link Matrix3 | m} to this color's RGB components. + */ + applyMatrix3(m: Matrix3): this; + + sub(color: Color): this; + multiply(color: Color): this; + multiplyScalar(s: number): this; + lerp(color: Color, alpha: number): this; + lerpColors(color1: Color, color2: Color, alpha: number): this; + lerpHSL(color: Color, alpha: number): this; + equals(color: Color): boolean; + + /** + * Sets this color's red, green and blue value from the provided array or array-like. + * @param array the source array or array-like. + * @param offset (optional) offset into the array-like. Default is 0. + */ + fromArray(array: number[] | ArrayLike, offset?: number): this; + + /** + * Returns an array [red, green, blue], or copies red, green and blue into the provided array. + * @param array (optional) array to store the color to. If this is not provided, a new array will be created. + * @param offset (optional) optional offset into the array. + * @return The created or provided array. + */ + toArray(array?: number[], offset?: number): number[]; + + /** + * Copies red, green and blue into the provided array-like. + * @param array array-like to store the color to. + * @param offset (optional) optional offset into the array-like. + * @return The provided array-like. + */ + toArray(xyz: ArrayLike, offset?: number): ArrayLike; + + /** + * This method defines the serialization result of Color. + * @return The color as a hexadecimal value. + */ + toJSON(): number; + + fromBufferAttribute(attribute: BufferAttribute | InterleavedBufferAttribute, index: number): this; + + [Symbol.iterator](): Generator; + + /** + * List of X11 color names. + */ + static NAMES: typeof _colorKeywords; +} diff --git a/src-testing/src/math/ColorManagement.d.ts b/src-testing/src/math/ColorManagement.d.ts new file mode 100644 index 000000000..eaa520d8c --- /dev/null +++ b/src-testing/src/math/ColorManagement.d.ts @@ -0,0 +1,49 @@ +import { ColorSpaceTransfer } from "../constants.js"; +import { Color } from "./Color.js"; +import { Matrix3 } from "./Matrix3.js"; +import { Vector3 } from "./Vector3.js"; + +export interface ColorSpaceDefinition { + primaries: [number, number, number, number, number, number]; + whitePoint: [number, number]; + transfer: ColorSpaceTransfer; + toXYZ: Matrix3; + fromXYZ: Matrix3; + luminanceCoefficients: [number, number, number]; + workingColorSpaceConfig?: { unpackColorSpace: string }; + outputColorSpaceConfig?: { drawingBufferColorSpace: string }; +} + +export interface ColorManagement { + /** + * @default true + */ + enabled: boolean; + + /** + * @default LinearSRGBColorSpace + */ + workingColorSpace: string; + + spaces: Record; + + convert: (color: Color, sourceColorSpace: string, targetColorSpace: string) => Color; + + fromWorkingColorSpace: (color: Color, targetColorSpace: string) => Color; + + toWorkingColorSpace: (color: Color, sourceColorSpace: string) => Color; + + getPrimaries: (colorSpace: string) => [number, number, number, number, number, number]; + + getTransfer: (colorSpace: string) => ColorSpaceTransfer; + + getLuminanceCoefficients: (target: Vector3, colorSpace?: string) => [number, number, number]; + + define: (colorSpaces: Record) => void; +} + +export const ColorManagement: ColorManagement; + +export function SRGBToLinear(c: number): number; + +export function LinearToSRGB(c: number): number; diff --git a/src-testing/src/math/Cylindrical.d.ts b/src-testing/src/math/Cylindrical.d.ts new file mode 100644 index 000000000..6764f8154 --- /dev/null +++ b/src-testing/src/math/Cylindrical.d.ts @@ -0,0 +1,26 @@ +import { Vector3 } from "./Vector3.js"; + +export class Cylindrical { + constructor(radius?: number, theta?: number, y?: number); + + /** + * @default 1 + */ + radius: number; + + /** + * @default 0 + */ + theta: number; + + /** + * @default 0 + */ + y: number; + + clone(): this; + copy(other: Cylindrical): this; + set(radius: number, theta: number, y: number): this; + setFromVector3(vec3: Vector3): this; + setFromCartesianCoords(x: number, y: number, z: number): this; +} diff --git a/src-testing/src/math/Euler.d.ts b/src-testing/src/math/Euler.d.ts new file mode 100644 index 000000000..81be13d82 --- /dev/null +++ b/src-testing/src/math/Euler.d.ts @@ -0,0 +1,50 @@ +import { Matrix4 } from "./Matrix4.js"; +import { Quaternion } from "./Quaternion.js"; +import { Vector3 } from "./Vector3.js"; + +export type EulerOrder = "XYZ" | "YXZ" | "ZXY" | "ZYX" | "YZX" | "XZY"; + +export type EulerTuple = [x: number, y: number, z: number, order?: EulerOrder]; + +export class Euler { + constructor(x?: number, y?: number, z?: number, order?: EulerOrder); + + /** + * @default 0 + */ + x: number; + + /** + * @default 0 + */ + y: number; + + /** + * @default 0 + */ + z: number; + + /** + * @default THREE.Euler.DEFAULT_ORDER + */ + order: EulerOrder; + readonly isEuler: true; + + _onChangeCallback: () => void; + + set(x: number, y: number, z: number, order?: EulerOrder): Euler; + clone(): this; + copy(euler: Euler): this; + setFromRotationMatrix(m: Matrix4, order?: EulerOrder, update?: boolean): Euler; + setFromQuaternion(q: Quaternion, order?: EulerOrder, update?: boolean): Euler; + setFromVector3(v: Vector3, order?: EulerOrder): Euler; + reorder(newOrder: EulerOrder): Euler; + equals(euler: Euler): boolean; + fromArray(array: EulerTuple): Euler; + toArray(array?: Partial, offset?: number): EulerTuple; + _onChange(callback: () => void): this; + + static DEFAULT_ORDER: "XYZ"; + + [Symbol.iterator](): Generator; +} diff --git a/src-testing/src/math/Frustum.d.ts b/src-testing/src/math/Frustum.d.ts new file mode 100644 index 000000000..364c8e926 --- /dev/null +++ b/src-testing/src/math/Frustum.d.ts @@ -0,0 +1,30 @@ +import { CoordinateSystem } from "../constants.js"; +import { Object3D } from "../core/Object3D.js"; +import { Sprite } from "../objects/Sprite.js"; +import { Box3 } from "./Box3.js"; +import { Matrix4 } from "./Matrix4.js"; +import { Plane } from "./Plane.js"; +import { Sphere } from "./Sphere.js"; +import { Vector3 } from "./Vector3.js"; + +/** + * Frustums are used to determine what is inside the camera's field of view. They help speed up the rendering process. + */ +export class Frustum { + constructor(p0?: Plane, p1?: Plane, p2?: Plane, p3?: Plane, p4?: Plane, p5?: Plane); + + /** + * Array of 6 vectors. + */ + planes: Plane[]; + + set(p0: Plane, p1: Plane, p2: Plane, p3: Plane, p4: Plane, p5: Plane): Frustum; + clone(): this; + copy(frustum: Frustum): this; + setFromProjectionMatrix(m: Matrix4, coordinateSystem?: CoordinateSystem): this; + intersectsObject(object: Object3D): boolean; + intersectsSprite(sprite: Sprite): boolean; + intersectsSphere(sphere: Sphere): boolean; + intersectsBox(box: Box3): boolean; + containsPoint(point: Vector3): boolean; +} diff --git a/src-testing/src/math/Interpolant.d.ts b/src-testing/src/math/Interpolant.d.ts new file mode 100644 index 000000000..9d2b1aced --- /dev/null +++ b/src-testing/src/math/Interpolant.d.ts @@ -0,0 +1,10 @@ +export abstract class Interpolant { + constructor(parameterPositions: any, sampleValues: any, sampleSize: number, resultBuffer?: any); + + parameterPositions: any; + sampleValues: any; + valueSize: number; + resultBuffer: any; + + evaluate(time: number): any; +} diff --git a/src-testing/src/math/Line3.d.ts b/src-testing/src/math/Line3.d.ts new file mode 100644 index 000000000..ab7e749bc --- /dev/null +++ b/src-testing/src/math/Line3.d.ts @@ -0,0 +1,29 @@ +import { Matrix4 } from "./Matrix4.js"; +import { Vector3 } from "./Vector3.js"; + +export class Line3 { + constructor(start?: Vector3, end?: Vector3); + + /** + * @default new THREE.Vector3() + */ + start: Vector3; + + /** + * @default new THREE.Vector3() + */ + end: Vector3; + + set(start?: Vector3, end?: Vector3): Line3; + clone(): this; + copy(line: Line3): this; + getCenter(target: Vector3): Vector3; + delta(target: Vector3): Vector3; + distanceSq(): number; + distance(): number; + at(t: number, target: Vector3): Vector3; + closestPointToPointParameter(point: Vector3, clampToLine?: boolean): number; + closestPointToPoint(point: Vector3, clampToLine: boolean, target: Vector3): Vector3; + applyMatrix4(matrix: Matrix4): Line3; + equals(line: Line3): boolean; +} diff --git a/src-testing/src/math/MathUtils.d.ts b/src-testing/src/math/MathUtils.d.ts new file mode 100644 index 000000000..48f10a3c3 --- /dev/null +++ b/src-testing/src/math/MathUtils.d.ts @@ -0,0 +1,137 @@ +import { Quaternion } from "./Quaternion.js"; + +/** + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/math/MathUtils.js|src/math/MathUtils.js} + */ + +export const DEG2RAD: number; + +export const RAD2DEG: number; + +export function generateUUID(): string; + +/** + * Clamps the x to be between a and b. + * + * @param value Value to be clamped. + * @param min Minimum value. + * @param max Maximum value. + */ +export function clamp(value: number, min: number, max: number): number; + +export function euclideanModulo(n: number, m: number): number; + +/** + * Linear mapping of x from range [a1, a2] to range [b1, b2]. + * + * @param x Value to be mapped. + * @param a1 Minimum value for range A. + * @param a2 Maximum value for range A. + * @param b1 Minimum value for range B. + * @param b2 Maximum value for range B. + */ +export function mapLinear(x: number, a1: number, a2: number, b1: number, b2: number): number; + +export function inverseLerp(x: number, y: number, t: number): number; + +/** + * Returns a value linearly interpolated from two known points based + * on the given interval - t = 0 will return x and t = 1 will return y. + * + * @param x Start point. + * @param y End point. + * @param t interpolation factor in the closed interval [0, 1] + */ +export function lerp(x: number, y: number, t: number): number; + +/** + * Smoothly interpolate a number from x toward y in a spring-like + * manner using the dt to maintain frame rate independent movement. + * + * @param x Current point. + * @param y Target point. + * @param lambda A higher lambda value will make the movement more sudden, and a lower value will make the movement more gradual. + * @param dt Delta time in seconds. + */ +export function damp(x: number, y: number, lambda: number, dt: number): number; + +/** + * Returns a value that alternates between 0 and length. + * + * @param x The value to pingpong. + * @param length The positive value the export function will pingpong to. Default is 1. + */ +export function pingpong(x: number, length?: number): number; + +export function smoothstep(x: number, min: number, max: number): number; + +export function smootherstep(x: number, min: number, max: number): number; + +/** + * Random integer from low to high interval. + */ +export function randInt(low: number, high: number): number; + +/** + * Random float from low to high interval. + */ +export function randFloat(low: number, high: number): number; + +/** + * Random float from - range / 2 to range / 2 interval. + */ +export function randFloatSpread(range: number): number; + +/** + * Deterministic pseudo-random float in the interval [ 0, 1 ]. + */ +export function seededRandom(seed?: number): number; + +export function degToRad(degrees: number): number; + +export function radToDeg(radians: number): number; + +export function isPowerOfTwo(value: number): boolean; + +export function ceilPowerOfTwo(value: number): number; + +export function floorPowerOfTwo(value: number): number; + +export function setQuaternionFromProperEuler(q: Quaternion, a: number, b: number, c: number, order: string): void; + +export function denormalize( + value: number, + array: Float32Array | Uint32Array | Uint16Array | Uint8Array | Int32Array | Int16Array | Int8Array, +): number; + +export function normalize( + value: number, + array: Float32Array | Uint32Array | Uint16Array | Uint8Array | Int32Array | Int16Array | Int8Array, +): number; + +export const MathUtils: { + DEG2RAD: typeof DEG2RAD; + RAD2DEG: typeof RAD2DEG; + generateUUID: typeof generateUUID; + clamp: typeof clamp; + euclideanModulo: typeof euclideanModulo; + mapLinear: typeof mapLinear; + inverseLerp: typeof inverseLerp; + lerp: typeof lerp; + damp: typeof damp; + pingpong: typeof pingpong; + smoothstep: typeof smoothstep; + smootherstep: typeof smootherstep; + randInt: typeof randInt; + randFloat: typeof randFloat; + randFloatSpread: typeof randFloatSpread; + seededRandom: typeof seededRandom; + degToRad: typeof degToRad; + radToDeg: typeof radToDeg; + isPowerOfTwo: typeof isPowerOfTwo; + ceilPowerOfTwo: typeof ceilPowerOfTwo; + floorPowerOfTwo: typeof floorPowerOfTwo; + setQuaternionFromProperEuler: typeof setQuaternionFromProperEuler; + normalize: typeof normalize; + denormalize: typeof denormalize; +}; diff --git a/src-testing/src/math/Matrix2.d.ts b/src-testing/src/math/Matrix2.d.ts new file mode 100644 index 000000000..40ed4c8aa --- /dev/null +++ b/src-testing/src/math/Matrix2.d.ts @@ -0,0 +1,53 @@ +export type Matrix2Tuple = [ + n11: number, + n12: number, + n21: number, + n22: number, +]; + +/** + * A class representing a 2x2 {@link https://en.wikipedia.org/wiki/Matrix_(mathematics) matrix}. + * + * @example + * const m = new Matrix2(); + */ +export class Matrix2 { + readonly isMatrix2: true; + + /** + * A {@link https://en.wikipedia.org/wiki/Row-_and_column-major_order column-major} list of matrix values. + */ + elements: Matrix2Tuple; + + /** + * Creates a 2x2 {@link https://en.wikipedia.org/wiki/Identity_matrix identity matrix}. + */ + constructor(); + + /** + * Creates a 2x2 matrix with the given arguments in row-major order. + */ + constructor(n11: number, n12: number, n21: number, n22: number); + + /** + * Resets this matrix to the 2x2 identity matrix: + */ + identity(): this; + + /** + * Sets the elements of this matrix based on an array in + * {@link https://en.wikipedia.org/wiki/Row-_and_column-major_order#Column-major_order column-major} format. + * + * @param array the array to read the elements from + * @param offset (optional) index of first element in the array. Default is `0`. + */ + fromArray(array: ArrayLike, offset?: number): this; + + /** + * Sets the 2x2 matrix values to the given + * {@link https://en.wikipedia.org/wiki/Row-_and_column-major_order row-major} sequence of values: + * [n11, n12, + * n21, n22] + */ + set(n11: number, n12: number, n21: number, n22: number): this; +} diff --git a/src-testing/src/math/Matrix3.d.ts b/src-testing/src/math/Matrix3.d.ts new file mode 100644 index 000000000..0b593fcb8 --- /dev/null +++ b/src-testing/src/math/Matrix3.d.ts @@ -0,0 +1,184 @@ +// https://threejs.org/docs/#api/en/math/Matrix3 + +import { Matrix4 } from "./Matrix4.js"; +import { Vector2 } from "./Vector2.js"; +import { Vector3 } from "./Vector3.js"; + +export type Matrix3Tuple = [ + n11: number, + n12: number, + n13: number, + n21: number, + n22: number, + n23: number, + n31: number, + n32: number, + n33: number, +]; + +export class Matrix3 { + readonly isMatrix3: true; + + /** + * Array with matrix values. + * @default [1, 0, 0, 0, 1, 0, 0, 0, 1] + */ + elements: Matrix3Tuple; + + /** + * Creates an identity matrix. + */ + constructor(); + /** + * Creates a 3x3 matrix with the given arguments in row-major order. + */ + constructor( + n11: number, + n12: number, + n13: number, + n21: number, + n22: number, + n23: number, + n31: number, + n32: number, + n33: number, + ); + + set( + n11: number, + n12: number, + n13: number, + n21: number, + n22: number, + n23: number, + n31: number, + n32: number, + n33: number, + ): Matrix3; + + identity(): this; + + copy(m: Matrix3): this; + + extractBasis(xAxis: Vector3, yAxis: Vector3, zAxis: Vector3): this; + + setFromMatrix4(m: Matrix4): Matrix3; + + /** + * Multiplies this matrix by m. + */ + multiply(m: Matrix3): this; + + premultiply(m: Matrix3): this; + + /** + * Sets this matrix to a x b. + */ + multiplyMatrices(a: Matrix3, b: Matrix3): this; + + multiplyScalar(s: number): this; + + determinant(): number; + + /** + * Inverts this matrix in place. + */ + invert(): this; + + /** + * Transposes this matrix in place. + */ + transpose(): this; + + getNormalMatrix(matrix4: Matrix4): this; + + /** + * Transposes this matrix into the supplied array r, and returns itself. + */ + transposeIntoArray(r: number[]): this; + + setUvTransform(tx: number, ty: number, sx: number, sy: number, rotation: number, cx: number, cy: number): this; + + scale(sx: number, sy: number): this; + + rotate(theta: number): this; + + translate(tx: number, ty: number): this; + + /** + * Sets this matrix as a 2D translation transform: + * + * ``` + * 1, 0, x, + * 0, 1, y, + * 0, 0, 1 + * ``` + * + * @param v the amount to translate. + */ + makeTranslation(v: Vector2): this; + /** + * Sets this matrix as a 2D translation transform: + * + * ``` + * 1, 0, x, + * 0, 1, y, + * 0, 0, 1 + * ``` + * + * @param x the amount to translate in the X axis. + * @param y the amount to translate in the Y axis. + */ + makeTranslation(x: number, y: number): this; + + /** + * Sets this matrix as a 2D rotational transformation by theta radians. The resulting matrix will be: + * + * ``` + * cos(θ) -sin(θ) 0 + * sin(θ) cos(θ) 0 + * 0 0 1 + * ``` + * + * @param theta Rotation angle in radians. Positive values rotate counterclockwise. + */ + makeRotation(theta: number): this; + + /** + * Sets this matrix as a 2D scale transform: + * + * ``` + * x, 0, 0, + * 0, y, 0, + * 0, 0, 1 + * ``` + * + * @param x the amount to scale in the X axis. + * @param y the amount to scale in the Y axis. + */ + makeScale(x: number, y: number): this; + + equals(matrix: Matrix3): boolean; + + /** + * Sets the values of this matrix from the provided array or array-like. + * @param array the source array or array-like. + * @param offset (optional) offset into the array-like. Default is 0. + */ + fromArray(array: ArrayLike, offset?: number): this; + + /** + * Writes the elements of this matrix to an array in + * {@link https://en.wikipedia.org/wiki/Row-_and_column-major_order#Column-major_order column-major} format. + */ + toArray(): Matrix3Tuple; + /** + * Writes the elements of this matrix to an array in + * {@link https://en.wikipedia.org/wiki/Row-_and_column-major_order#Column-major_order column-major} format. + * @param array array to store the resulting vector in. If not given a new array will be created. + * @param offset (optional) offset in the array at which to put the result. + */ + toArray>(array: TArray, offset?: number): TArray; + + clone(): this; +} diff --git a/src-testing/src/math/Matrix4.d.ts b/src-testing/src/math/Matrix4.d.ts new file mode 100644 index 000000000..9ef2a9ceb --- /dev/null +++ b/src-testing/src/math/Matrix4.d.ts @@ -0,0 +1,284 @@ +import { CoordinateSystem } from "../constants.js"; +import { Euler } from "./Euler.js"; +import { Matrix3 } from "./Matrix3.js"; +import { Quaternion } from "./Quaternion.js"; +import { Vector3 } from "./Vector3.js"; + +export type Matrix4Tuple = [ + n11: number, + n12: number, + n13: number, + n14: number, + n21: number, + n22: number, + n23: number, + n24: number, + n31: number, + n32: number, + n33: number, + n34: number, + n41: number, + n42: number, + n43: number, + n44: number, +]; + +/** + * A 4x4 Matrix. + * + * @example + * // Simple rig for rotating around 3 axes + * const m = new THREE.Matrix4(); + * const m1 = new THREE.Matrix4(); + * const m2 = new THREE.Matrix4(); + * const m3 = new THREE.Matrix4(); + * const alpha = 0; + * const beta = Math.PI; + * const gamma = Math.PI/2; + * m1.makeRotationX( alpha ); + * m2.makeRotationY( beta ); + * m3.makeRotationZ( gamma ); + * m.multiplyMatrices( m1, m2 ); + * m.multiply( m3 ); + */ +export class Matrix4 { + readonly isMatrix4: true; + + /** + * Array with matrix values. + * @default [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] + */ + elements: Matrix4Tuple; + + /** + * Creates an identity matrix. + */ + constructor(); + /** + * Creates a 4x4 matrix with the given arguments in row-major order. + */ + constructor( + n11: number, + n12: number, + n13: number, + n14: number, + n21: number, + n22: number, + n23: number, + n24: number, + n31: number, + n32: number, + n33: number, + n34: number, + n41: number, + n42: number, + n43: number, + n44: number, + ); + + /** + * Sets all fields of this matrix. + */ + set( + n11: number, + n12: number, + n13: number, + n14: number, + n21: number, + n22: number, + n23: number, + n24: number, + n31: number, + n32: number, + n33: number, + n34: number, + n41: number, + n42: number, + n43: number, + n44: number, + ): this; + + /** + * Resets this matrix to identity. + */ + identity(): this; + + clone(): Matrix4; + + copy(m: Matrix4): this; + + copyPosition(m: Matrix4): this; + + /** + * Set the upper 3x3 elements of this matrix to the values of the Matrix3 m. + */ + setFromMatrix3(m: Matrix3): this; + + extractBasis(xAxis: Vector3, yAxis: Vector3, zAxis: Vector3): this; + + makeBasis(xAxis: Vector3, yAxis: Vector3, zAxis: Vector3): this; + + /** + * Copies the rotation component of the supplied matrix m into this matrix rotation component. + */ + extractRotation(m: Matrix4): this; + + makeRotationFromEuler(euler: Euler): this; + + makeRotationFromQuaternion(q: Quaternion): this; + + /** + * Constructs a rotation matrix, looking from eye towards center with defined up vector. + */ + lookAt(eye: Vector3, target: Vector3, up: Vector3): this; + + /** + * Multiplies this matrix by m. + */ + multiply(m: Matrix4): this; + + premultiply(m: Matrix4): this; + + /** + * Sets this matrix to a x b. + */ + multiplyMatrices(a: Matrix4, b: Matrix4): this; + + /** + * Multiplies this matrix by s. + */ + multiplyScalar(s: number): this; + + /** + * Computes determinant of this matrix. + * Based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm + */ + determinant(): number; + + /** + * Transposes this matrix. + */ + transpose(): this; + + /** + * Sets the position component for this matrix from vector v. + */ + setPosition(v: Vector3): this; + setPosition(x: number, y: number, z: number): this; + + /** + * Inverts this matrix. + */ + invert(): this; + + /** + * Multiplies the columns of this matrix by vector v. + */ + scale(v: Vector3): this; + + getMaxScaleOnAxis(): number; + + /** + * Sets this matrix as translation transform. + */ + makeTranslation(v: Vector3): this; + makeTranslation(x: number, y: number, z: number): this; + + /** + * Sets this matrix as rotation transform around x axis by theta radians. + * + * @param theta Rotation angle in radians. + */ + makeRotationX(theta: number): this; + + /** + * Sets this matrix as rotation transform around y axis by theta radians. + * + * @param theta Rotation angle in radians. + */ + makeRotationY(theta: number): this; + + /** + * Sets this matrix as rotation transform around z axis by theta radians. + * + * @param theta Rotation angle in radians. + */ + makeRotationZ(theta: number): this; + + /** + * Sets this matrix as rotation transform around axis by angle radians. + * Based on http://www.gamedev.net/reference/articles/article1199.asp. + * + * @param axis Rotation axis. + * @param angle Rotation angle in radians. + */ + makeRotationAxis(axis: Vector3, angle: number): this; + + /** + * Sets this matrix as scale transform. + */ + makeScale(x: number, y: number, z: number): this; + + /** + * Sets this matrix as shear transform. + */ + makeShear(xy: number, xz: number, yx: number, yz: number, zx: number, zy: number): this; + + /** + * Sets this matrix to the transformation composed of translation, rotation and scale. + */ + compose(position: Vector3, quaternion: Quaternion, scale: Vector3): this; + + /** + * Decomposes this matrix into it's position, quaternion and scale components. + */ + decompose(position: Vector3, quaternion: Quaternion, scale: Vector3): this; + + /** + * Creates a perspective projection matrix. + */ + makePerspective( + left: number, + right: number, + top: number, + bottom: number, + near: number, + far: number, + coordinateSystem?: CoordinateSystem, + ): this; + + /** + * Creates an orthographic projection matrix. + */ + makeOrthographic( + left: number, + right: number, + top: number, + bottom: number, + near: number, + far: number, + coordinateSystem?: CoordinateSystem, + ): this; + + equals(matrix: Matrix4): boolean; + + /** + * Sets the values of this matrix from the provided array or array-like. + * @param array the source array or array-like. + * @param offset (optional) offset into the array-like. Default is 0. + */ + fromArray(array: ArrayLike, offset?: number): this; + + /** + * Writes the elements of this matrix to an array in + * {@link https://en.wikipedia.org/wiki/Row-_and_column-major_order#Column-major_order column-major} format. + */ + toArray(): Matrix4Tuple; + /** + * Writes the elements of this matrix to an array in + * {@link https://en.wikipedia.org/wiki/Row-_and_column-major_order#Column-major_order column-major} format. + * @param array array to store the resulting vector in. + * @param offset (optional) offset in the array at which to put the result. + */ + toArray>(array: TArray, offset?: number): TArray; +} diff --git a/src-testing/src/math/Plane.d.ts b/src-testing/src/math/Plane.d.ts new file mode 100644 index 000000000..59fa23912 --- /dev/null +++ b/src-testing/src/math/Plane.d.ts @@ -0,0 +1,47 @@ +import { Box3 } from "./Box3.js"; +import { Line3 } from "./Line3.js"; +import { Matrix3 } from "./Matrix3.js"; +import { Matrix4 } from "./Matrix4.js"; +import { Sphere } from "./Sphere.js"; +import { Vector3 } from "./Vector3.js"; + +export class Plane { + constructor(normal?: Vector3, constant?: number); + + /** + * @default new THREE.Vector3( 1, 0, 0 ) + */ + normal: Vector3; + + /** + * @default 0 + */ + constant: number; + + readonly isPlane: true; + + set(normal: Vector3, constant: number): Plane; + setComponents(x: number, y: number, z: number, w: number): Plane; + setFromNormalAndCoplanarPoint(normal: Vector3, point: Vector3): Plane; + setFromCoplanarPoints(a: Vector3, b: Vector3, c: Vector3): Plane; + clone(): this; + copy(plane: Plane): this; + normalize(): Plane; + negate(): Plane; + distanceToPoint(point: Vector3): number; + distanceToSphere(sphere: Sphere): number; + projectPoint(point: Vector3, target: Vector3): Vector3; + intersectLine(line: Line3, target: Vector3): Vector3 | null; + intersectsLine(line: Line3): boolean; + intersectsBox(box: Box3): boolean; + intersectsSphere(sphere: Sphere): boolean; + coplanarPoint(target: Vector3): Vector3; + applyMatrix4(matrix: Matrix4, optionalNormalMatrix?: Matrix3): Plane; + translate(offset: Vector3): Plane; + equals(plane: Plane): boolean; + + /** + * @deprecated Use {@link Plane#intersectsLine .intersectsLine()} instead. + */ + isIntersectionLine(l: any): any; +} diff --git a/src-testing/src/math/Quaternion.d.ts b/src-testing/src/math/Quaternion.d.ts new file mode 100644 index 000000000..7485b6956 --- /dev/null +++ b/src-testing/src/math/Quaternion.d.ts @@ -0,0 +1,189 @@ +import { BufferAttribute } from "../core/BufferAttribute.js"; +import { InterleavedBufferAttribute } from "../core/InterleavedBufferAttribute.js"; +import { Euler } from "./Euler.js"; +import { Matrix4 } from "./Matrix4.js"; +import { Vector3, Vector3Like } from "./Vector3.js"; + +export interface QuaternionLike { + readonly x: number; + readonly y: number; + readonly z: number; + readonly w: number; +} + +export type QuaternionTuple = [x: number, y: number, z: number, w: number]; + +/** + * Implementation of a quaternion. This is used for rotating things without incurring in the dreaded gimbal lock issue, amongst other advantages. + * + * @example + * const quaternion = new THREE.Quaternion(); + * quaternion.setFromAxisAngle( new THREE.Vector3( 0, 1, 0 ), Math.PI / 2 ); + * const vector = new THREE.Vector3( 1, 0, 0 ); + * vector.applyQuaternion( quaternion ); + */ +export class Quaternion { + /** + * @param x x coordinate + * @param y y coordinate + * @param z z coordinate + * @param w w coordinate + */ + constructor(x?: number, y?: number, z?: number, w?: number); + + /** + * @default 0 + */ + x: number; + + /** + * @default 0 + */ + y: number; + + /** + * @default 0 + */ + z: number; + + /** + * @default 1 + */ + w: number; + readonly isQuaternion: true; + + /** + * Sets values of this quaternion. + */ + set(x: number, y: number, z: number, w: number): this; + + /** + * Clones this quaternion. + */ + clone(): this; + + /** + * Copies values of q to this quaternion. + */ + copy(q: QuaternionLike): this; + + /** + * Sets this quaternion from rotation specified by Euler angles. + */ + setFromEuler(euler: Euler, update?: boolean): this; + + /** + * Sets this quaternion from rotation specified by axis and angle. + * Adapted from http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm. + * Axis have to be normalized, angle is in radians. + */ + setFromAxisAngle(axis: Vector3Like, angle: number): this; + + /** + * Sets this quaternion from rotation component of m. Adapted from http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm. + */ + setFromRotationMatrix(m: Matrix4): this; + setFromUnitVectors(vFrom: Vector3, vTo: Vector3Like): this; + angleTo(q: Quaternion): number; + rotateTowards(q: Quaternion, step: number): this; + + identity(): this; + + /** + * Inverts this quaternion. + */ + invert(): this; + + conjugate(): this; + dot(v: Quaternion): number; + lengthSq(): number; + + /** + * Computes length of this quaternion. + */ + length(): number; + + /** + * Normalizes this quaternion. + */ + normalize(): this; + + /** + * Multiplies this quaternion by b. + */ + multiply(q: Quaternion): this; + premultiply(q: Quaternion): this; + + /** + * Sets this quaternion to a x b + * Adapted from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm. + */ + multiplyQuaternions(a: Quaternion, b: Quaternion): this; + + slerp(qb: Quaternion, t: number): this; + slerpQuaternions(qa: Quaternion, qb: Quaternion, t: number): this; + equals(v: Quaternion): boolean; + + /** + * Sets this quaternion's x, y, z and w value from the provided array or array-like. + * @param array the source array or array-like. + * @param offset (optional) offset into the array. Default is 0. + */ + fromArray(array: number[] | ArrayLike, offset?: number): this; + + /** + * Returns an array [x, y, z, w], or copies x, y, z and w into the provided array. + * @param array (optional) array to store the quaternion to. If this is not provided, a new array will be created. + * @param offset (optional) optional offset into the array. + * @return The created or provided array. + */ + toArray(array?: number[], offset?: number): number[]; + toArray(array?: QuaternionTuple, offset?: 0): QuaternionTuple; + + /** + * Copies x, y, z and w into the provided array-like. + * @param array array-like to store the quaternion to. + * @param offset (optional) optional offset into the array. + * @return The provided array-like. + */ + toArray(array: ArrayLike, offset?: number): ArrayLike; + + /** + * This method defines the serialization result of Quaternion. + * @return The numerical elements of this quaternion in an array of format [x, y, z, w]. + */ + toJSON(): [number, number, number, number]; + + /** + * Sets x, y, z, w properties of this quaternion from the attribute. + * @param attribute the source attribute. + * @param index index in the attribute. + */ + fromBufferAttribute(attribute: BufferAttribute | InterleavedBufferAttribute, index: number): this; + + _onChange(callback: () => void): this; + _onChangeCallback: () => void; + + static slerpFlat( + dst: number[], + dstOffset: number, + src0: number[], + srcOffset: number, + src1: number[], + stcOffset1: number, + t: number, + ): void; + + static multiplyQuaternionsFlat( + dst: number[], + dstOffset: number, + src0: number[], + srcOffset: number, + src1: number[], + stcOffset1: number, + ): number[]; + + random(): this; + + [Symbol.iterator](): Generator; +} diff --git a/src-testing/src/math/Ray.d.ts b/src-testing/src/math/Ray.d.ts new file mode 100644 index 000000000..98b9fd70f --- /dev/null +++ b/src-testing/src/math/Ray.d.ts @@ -0,0 +1,60 @@ +import { Box3 } from "./Box3.js"; +import { Matrix4 } from "./Matrix4.js"; +import { Plane } from "./Plane.js"; +import { Sphere } from "./Sphere.js"; +import { Vector3 } from "./Vector3.js"; + +export class Ray { + constructor(origin?: Vector3, direction?: Vector3); + + /** + * @default new THREE.Vector3() + */ + origin: Vector3; + + /** + * @default new THREE.Vector3( 0, 0, - 1 ) + */ + direction: Vector3; + + set(origin: Vector3, direction: Vector3): Ray; + clone(): this; + copy(ray: Ray): this; + at(t: number, target: Vector3): Vector3; + lookAt(v: Vector3): Ray; + recast(t: number): Ray; + closestPointToPoint(point: Vector3, target: Vector3): Vector3; + distanceToPoint(point: Vector3): number; + distanceSqToPoint(point: Vector3): number; + distanceSqToSegment( + v0: Vector3, + v1: Vector3, + optionalPointOnRay?: Vector3, + optionalPointOnSegment?: Vector3, + ): number; + intersectSphere(sphere: Sphere, target: Vector3): Vector3 | null; + intersectsSphere(sphere: Sphere): boolean; + distanceToPlane(plane: Plane): number; + intersectPlane(plane: Plane, target: Vector3): Vector3 | null; + intersectsPlane(plane: Plane): boolean; + intersectBox(box: Box3, target: Vector3): Vector3 | null; + intersectsBox(box: Box3): boolean; + intersectTriangle(a: Vector3, b: Vector3, c: Vector3, backfaceCulling: boolean, target: Vector3): Vector3 | null; + applyMatrix4(matrix4: Matrix4): Ray; + equals(ray: Ray): boolean; + + /** + * @deprecated Use {@link Ray#intersectsBox .intersectsBox()} instead. + */ + isIntersectionBox(b: any): any; + + /** + * @deprecated Use {@link Ray#intersectsPlane .intersectsPlane()} instead. + */ + isIntersectionPlane(p: any): any; + + /** + * @deprecated Use {@link Ray#intersectsSphere .intersectsSphere()} instead. + */ + isIntersectionSphere(s: any): any; +} diff --git a/src-testing/src/math/Sphere.d.ts b/src-testing/src/math/Sphere.d.ts new file mode 100644 index 000000000..a423a6f97 --- /dev/null +++ b/src-testing/src/math/Sphere.d.ts @@ -0,0 +1,47 @@ +import { Box3 } from "./Box3.js"; +import { Matrix4 } from "./Matrix4.js"; +import { Plane } from "./Plane.js"; +import { Vector3 } from "./Vector3.js"; + +export class Sphere { + constructor(center?: Vector3, radius?: number); + + /** + * Read-only flag to check if a given object is of type {@link Sphere}. + */ + readonly isSphere: true; + + /** + * @default new Vector3() + */ + center: Vector3; + + /** + * @default 1 + */ + radius: number; + + set(center: Vector3, radius: number): Sphere; + setFromPoints(points: Vector3[], optionalCenter?: Vector3): Sphere; + clone(): this; + copy(sphere: Sphere): this; + expandByPoint(point: Vector3): this; + isEmpty(): boolean; + makeEmpty(): this; + containsPoint(point: Vector3): boolean; + distanceToPoint(point: Vector3): number; + intersectsSphere(sphere: Sphere): boolean; + intersectsBox(box: Box3): boolean; + intersectsPlane(plane: Plane): boolean; + clampPoint(point: Vector3, target: Vector3): Vector3; + getBoundingBox(target: Box3): Box3; + applyMatrix4(matrix: Matrix4): Sphere; + translate(offset: Vector3): Sphere; + equals(sphere: Sphere): boolean; + union(sphere: Sphere): this; + + /** + * @deprecated Use {@link Sphere#isEmpty .isEmpty()} instead. + */ + empty(): any; +} diff --git a/src-testing/src/math/Spherical.d.ts b/src-testing/src/math/Spherical.d.ts new file mode 100644 index 000000000..8d4815a17 --- /dev/null +++ b/src-testing/src/math/Spherical.d.ts @@ -0,0 +1,27 @@ +import { Vector3 } from "./Vector3.js"; + +export class Spherical { + constructor(radius?: number, phi?: number, theta?: number); + + /** + * @default 1 + */ + radius: number; + + /** + * @default 0 + */ + phi: number; + + /** + * @default 0 + */ + theta: number; + + set(radius: number, phi: number, theta: number): this; + clone(): this; + copy(other: Spherical): this; + makeSafe(): this; + setFromVector3(v: Vector3): this; + setFromCartesianCoords(x: number, y: number, z: number): this; +} diff --git a/src-testing/src/math/SphericalHarmonics3.d.ts b/src-testing/src/math/SphericalHarmonics3.d.ts new file mode 100644 index 000000000..5981a0b48 --- /dev/null +++ b/src-testing/src/math/SphericalHarmonics3.d.ts @@ -0,0 +1,50 @@ +import { Vector3 } from "./Vector3.js"; + +export class SphericalHarmonics3 { + constructor(); + + /** + * @default [new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3(), + * new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3()] + */ + coefficients: Vector3[]; + readonly isSphericalHarmonics3: true; + + set(coefficients: Vector3[]): SphericalHarmonics3; + zero(): SphericalHarmonics3; + add(sh: SphericalHarmonics3): SphericalHarmonics3; + addScaledSH(sh: SphericalHarmonics3, s: number): SphericalHarmonics3; + scale(s: number): SphericalHarmonics3; + lerp(sh: SphericalHarmonics3, alpha: number): SphericalHarmonics3; + equals(sh: SphericalHarmonics3): boolean; + copy(sh: SphericalHarmonics3): SphericalHarmonics3; + clone(): this; + + /** + * Sets the values of this spherical harmonics from the provided array or array-like. + * @param array the source array or array-like. + * @param offset (optional) offset into the array. Default is 0. + */ + fromArray(array: number[] | ArrayLike, offset?: number): this; + + /** + * Returns an array with the values of this spherical harmonics, or copies them into the provided array. + * @param array (optional) array to store the spherical harmonics to. If this is not provided, a new array will be created. + * @param offset (optional) optional offset into the array. + * @return The created or provided array. + */ + toArray(array?: number[], offset?: number): number[]; + + /** + * Returns an array with the values of this spherical harmonics, or copies them into the provided array-like. + * @param array array-like to store the spherical harmonics to. + * @param offset (optional) optional offset into the array-like. + * @return The provided array-like. + */ + toArray(array: ArrayLike, offset?: number): ArrayLike; + + getAt(normal: Vector3, target: Vector3): Vector3; + getIrradianceAt(normal: Vector3, target: Vector3): Vector3; + + static getBasisAt(normal: Vector3, shBasis: number[]): void; +} diff --git a/src-testing/src/math/Triangle.d.ts b/src-testing/src/math/Triangle.d.ts new file mode 100644 index 000000000..9f0e7935b --- /dev/null +++ b/src-testing/src/math/Triangle.d.ts @@ -0,0 +1,110 @@ +import { Box3 } from "./Box3.js"; +import { Plane } from "./Plane.js"; +import { Vector2 } from "./Vector2.js"; +import { Vector3 } from "./Vector3.js"; +import { Vector4 } from "./Vector4.js"; + +import { BufferAttribute } from "../core/BufferAttribute.js"; +import { InterleavedBufferAttribute } from "../core/InterleavedBufferAttribute.js"; + +export class Triangle { + constructor(a?: Vector3, b?: Vector3, c?: Vector3); + + /** + * @default new THREE.Vector3() + */ + a: Vector3; + + /** + * @default new THREE.Vector3() + */ + b: Vector3; + + /** + * @default new THREE.Vector3() + */ + c: Vector3; + + set(a: Vector3, b: Vector3, c: Vector3): Triangle; + setFromPointsAndIndices(points: Vector3[], i0: number, i1: number, i2: number): this; + setFromAttributeAndIndices( + attribute: BufferAttribute | InterleavedBufferAttribute, + i0: number, + i1: number, + i2: number, + ): this; + clone(): this; + copy(triangle: Triangle): this; + getArea(): number; + getMidpoint(target: Vector3): Vector3; + getNormal(target: Vector3): Vector3; + getPlane(target: Plane): Plane; + getBarycoord(point: Vector3, target: Vector3): Vector3 | null; + getInterpolation(point: Vector3, v1: Vector2, v2: Vector2, v3: Vector2, target: Vector2): Vector2 | null; + getInterpolation(point: Vector3, v1: Vector3, v2: Vector3, v3: Vector3, target: Vector3): Vector3 | null; + getInterpolation(point: Vector3, v1: Vector4, v2: Vector4, v3: Vector4, target: Vector4): Vector4 | null; + containsPoint(point: Vector3): boolean; + intersectsBox(box: Box3): boolean; + isFrontFacing(direction: Vector3): boolean; + closestPointToPoint(point: Vector3, target: Vector3): Vector3; + equals(triangle: Triangle): boolean; + + static getNormal(a: Vector3, b: Vector3, c: Vector3, target: Vector3): Vector3; + static getBarycoord(point: Vector3, a: Vector3, b: Vector3, c: Vector3, target: Vector3): Vector3 | null; + static containsPoint(point: Vector3, a: Vector3, b: Vector3, c: Vector3): boolean; + static getInterpolation( + point: Vector3, + p1: Vector3, + p2: Vector3, + p3: Vector3, + v1: Vector2, + v2: Vector2, + v3: Vector2, + target: Vector2, + ): Vector2 | null; + static getInterpolation( + point: Vector3, + p1: Vector3, + p2: Vector3, + p3: Vector3, + v1: Vector3, + v2: Vector3, + v3: Vector3, + target: Vector3, + ): Vector3 | null; + static getInterpolation( + point: Vector3, + p1: Vector3, + p2: Vector3, + p3: Vector3, + v1: Vector4, + v2: Vector4, + v3: Vector4, + target: Vector4, + ): Vector4 | null; + static getInterpolatedAttribute( + attr: BufferAttribute, + i1: number, + i2: number, + i3: number, + barycoord: Vector3, + target: Vector2, + ): Vector2; + static getInterpolatedAttribute( + attr: BufferAttribute, + i1: number, + i2: number, + i3: number, + barycoord: Vector3, + target: Vector3, + ): Vector3; + static getInterpolatedAttribute( + attr: BufferAttribute, + i1: number, + i2: number, + i3: number, + barycoord: Vector3, + target: Vector4, + ): Vector4; + static isFrontFacing(a: Vector3, b: Vector3, c: Vector3, direction: Vector3): boolean; +} diff --git a/src-testing/src/math/Vector2.d.ts b/src-testing/src/math/Vector2.d.ts new file mode 100644 index 000000000..fd2a84a1d --- /dev/null +++ b/src-testing/src/math/Vector2.d.ts @@ -0,0 +1,321 @@ +import { BufferAttribute } from "../core/BufferAttribute.js"; +import { Matrix3 } from "./Matrix3.js"; + +export type Vector2Tuple = [x: number, y: number]; + +export interface Vector2Like { + readonly x: number; + readonly y: number; +} + +/** + * 2D vector. + */ +export class Vector2 { + constructor(x?: number, y?: number); + + /** + * @default 0 + */ + x: number; + + /** + * @default 0 + */ + y: number; + width: number; + height: number; + readonly isVector2: true; + + /** + * Sets value of this vector. + */ + set(x: number, y: number): this; + + /** + * Sets the x and y values of this vector both equal to scalar. + */ + setScalar(scalar: number): this; + + /** + * Sets X component of this vector. + */ + setX(x: number): this; + + /** + * Sets Y component of this vector. + */ + setY(y: number): this; + + /** + * Sets a component of this vector. + */ + setComponent(index: number, value: number): this; + + /** + * Gets a component of this vector. + */ + getComponent(index: number): number; + + /** + * Returns a new Vector2 instance with the same `x` and `y` values. + */ + clone(): this; + + /** + * Copies value of v to this vector. + */ + copy(v: Vector2Like): this; + + /** + * Adds v to this vector. + */ + add(v: Vector2Like): this; + + /** + * Adds the scalar value s to this vector's x and y values. + */ + addScalar(s: number): this; + + /** + * Sets this vector to a + b. + */ + addVectors(a: Vector2Like, b: Vector2Like): this; + + /** + * Adds the multiple of v and s to this vector. + */ + addScaledVector(v: Vector2Like, s: number): this; + + /** + * Subtracts v from this vector. + */ + sub(v: Vector2Like): this; + + /** + * Subtracts s from this vector's x and y components. + */ + subScalar(s: number): this; + + /** + * Sets this vector to a - b. + */ + subVectors(a: Vector2Like, b: Vector2Like): this; + + /** + * Multiplies this vector by v. + */ + multiply(v: Vector2Like): this; + + /** + * Multiplies this vector by scalar s. + */ + multiplyScalar(scalar: number): this; + + /** + * Divides this vector by v. + */ + divide(v: Vector2Like): this; + + /** + * Divides this vector by scalar s. + * Set vector to ( 0, 0 ) if s == 0. + */ + divideScalar(s: number): this; + + /** + * Multiplies this vector (with an implicit 1 as the 3rd component) by m. + */ + applyMatrix3(m: Matrix3): this; + + /** + * If this vector's x or y value is greater than v's x or y value, replace that value with the corresponding min value. + */ + min(v: Vector2Like): this; + + /** + * If this vector's x or y value is less than v's x or y value, replace that value with the corresponding max value. + */ + max(v: Vector2Like): this; + + /** + * If this vector's x or y value is greater than the max vector's x or y value, it is replaced by the corresponding value. + * If this vector's x or y value is less than the min vector's x or y value, it is replaced by the corresponding value. + * @param min the minimum x and y values. + * @param max the maximum x and y values in the desired range. + */ + clamp(min: Vector2Like, max: Vector2Like): this; + + /** + * If this vector's x or y values are greater than the max value, they are replaced by the max value. + * If this vector's x or y values are less than the min value, they are replaced by the min value. + * @param min the minimum value the components will be clamped to. + * @param max the maximum value the components will be clamped to. + */ + clampScalar(min: number, max: number): this; + + /** + * If this vector's length is greater than the max value, it is replaced by the max value. + * If this vector's length is less than the min value, it is replaced by the min value. + * @param min the minimum value the length will be clamped to. + * @param max the maximum value the length will be clamped to. + */ + clampLength(min: number, max: number): this; + + /** + * The components of the vector are rounded down to the nearest integer value. + */ + floor(): this; + + /** + * The x and y components of the vector are rounded up to the nearest integer value. + */ + ceil(): this; + + /** + * The components of the vector are rounded to the nearest integer value. + */ + round(): this; + + /** + * The components of the vector are rounded towards zero (up if negative, down if positive) to an integer value. + */ + roundToZero(): this; + + /** + * Inverts this vector. + */ + negate(): this; + + /** + * Computes dot product of this vector and v. + */ + dot(v: Vector2Like): number; + + /** + * Computes cross product of this vector and v. + */ + cross(v: Vector2Like): number; + + /** + * Computes squared length of this vector. + */ + lengthSq(): number; + + /** + * Computes length of this vector. + */ + length(): number; + + /** + * Computes the Manhattan length of this vector. + * + * see {@link http://en.wikipedia.org/wiki/Taxicab_geometry|Wikipedia: Taxicab Geometry} + */ + manhattanLength(): number; + + /** + * Normalizes this vector. + */ + normalize(): this; + + /** + * computes the angle in radians with respect to the positive x-axis + */ + angle(): number; + + /** + * Returns the angle between this vector and vector {@link Vector2 | v} in radians. + */ + angleTo(v: Vector2): number; + + /** + * Computes distance of this vector to v. + */ + distanceTo(v: Vector2Like): number; + + /** + * Computes squared distance of this vector to v. + */ + distanceToSquared(v: Vector2Like): number; + + /** + * Computes the Manhattan length (distance) from this vector to the given vector v + * + * see {@link http://en.wikipedia.org/wiki/Taxicab_geometry|Wikipedia: Taxicab Geometry} + */ + manhattanDistanceTo(v: Vector2Like): number; + + /** + * Normalizes this vector and multiplies it by l. + */ + setLength(length: number): this; + + /** + * Linearly interpolates between this vector and v, where alpha is the distance along the line - alpha = 0 will be this vector, and alpha = 1 will be v. + * @param v vector to interpolate towards. + * @param alpha interpolation factor in the closed interval [0, 1]. + */ + lerp(v: Vector2Like, alpha: number): this; + + /** + * Sets this vector to be the vector linearly interpolated between v1 and v2 where alpha is the distance along the line connecting the two vectors - alpha = 0 will be v1, and alpha = 1 will be v2. + * @param v1 the starting vector. + * @param v2 vector to interpolate towards. + * @param alpha interpolation factor in the closed interval [0, 1]. + */ + lerpVectors(v1: Vector2Like, v2: Vector2Like, alpha: number): this; + + /** + * Checks for strict equality of this vector and v. + */ + equals(v: Vector2Like): boolean; + + /** + * Sets this vector's x and y value from the provided array or array-like. + * @param array the source array or array-like. + * @param offset (optional) offset into the array. Default is 0. + */ + fromArray(array: number[] | ArrayLike, offset?: number): this; + + /** + * Returns an array [x, y], or copies x and y into the provided array. + * @param array (optional) array to store the vector to. If this is not provided, a new array will be created. + * @param offset (optional) optional offset into the array. + * @return The created or provided array. + */ + toArray(array?: number[], offset?: number): number[]; + toArray(array?: Vector2Tuple, offset?: 0): Vector2Tuple; + + /** + * Copies x and y into the provided array-like. + * @param array array-like to store the vector to. + * @param offset (optional) optional offset into the array. + * @return The provided array-like. + */ + toArray(array: ArrayLike, offset?: number): ArrayLike; + + /** + * Sets this vector's x and y values from the attribute. + * @param attribute the source attribute. + * @param index index in the attribute. + */ + fromBufferAttribute(attribute: BufferAttribute, index: number): this; + + /** + * Rotates the vector around center by angle radians. + * @param center the point around which to rotate. + * @param angle the angle to rotate, in radians. + */ + rotateAround(center: Vector2Like, angle: number): this; + + /** + * Sets this vector's x and y from Math.random + */ + random(): this; + + /** + * Iterating through a Vector2 instance will yield its components (x, y) in the corresponding order. + */ + [Symbol.iterator](): Iterator; +} diff --git a/src-testing/src/math/Vector3.d.ts b/src-testing/src/math/Vector3.d.ts new file mode 100644 index 000000000..56e907ceb --- /dev/null +++ b/src-testing/src/math/Vector3.d.ts @@ -0,0 +1,301 @@ +import { Camera } from "../cameras/Camera.js"; +import { BufferAttribute } from "../core/BufferAttribute.js"; +import { InterleavedBufferAttribute } from "../core/InterleavedBufferAttribute.js"; +import { RGB } from "./Color.js"; +import { Cylindrical } from "./Cylindrical.js"; +import { Euler } from "./Euler.js"; +import { Matrix3 } from "./Matrix3.js"; +import { Matrix4 } from "./Matrix4.js"; +import { QuaternionLike } from "./Quaternion.js"; +import { Spherical } from "./Spherical.js"; + +export type Vector3Tuple = [number, number, number]; + +export interface Vector3Like { + readonly x: number; + readonly y: number; + readonly z: number; +} + +/** + * 3D vector. + * + * see {@link https://github.com/mrdoob/three.js/blob/master/src/math/Vector3.js} + * + * @example + * const a = new THREE.Vector3( 1, 0, 0 ); + * const b = new THREE.Vector3( 0, 1, 0 ); + * const c = new THREE.Vector3(); + * c.crossVectors( a, b ); + */ +export class Vector3 { + constructor(x?: number, y?: number, z?: number); + + /** + * @default 0 + */ + x: number; + + /** + * @default 0 + */ + y: number; + + /** + * @default 0 + */ + z: number; + readonly isVector3: true; + + /** + * Sets value of this vector. + */ + set(x: number, y: number, z: number): this; + + /** + * Sets all values of this vector. + */ + setScalar(scalar: number): this; + + /** + * Sets x value of this vector. + */ + setX(x: number): this; + + /** + * Sets y value of this vector. + */ + setY(y: number): this; + + /** + * Sets z value of this vector. + */ + setZ(z: number): this; + + setComponent(index: number, value: number): this; + + getComponent(index: number): number; + + /** + * Clones this vector. + */ + clone(): this; + + /** + * Copies value of v to this vector. + */ + copy(v: Vector3Like): this; + + /** + * Adds v to this vector. + */ + add(v: Vector3Like): this; + + addScalar(s: number): this; + + /** + * Sets this vector to a + b. + */ + addVectors(a: Vector3Like, b: Vector3Like): this; + + addScaledVector(v: Vector3, s: number): this; + + /** + * Subtracts v from this vector. + */ + sub(a: Vector3Like): this; + + subScalar(s: number): this; + + /** + * Sets this vector to a - b. + */ + subVectors(a: Vector3Like, b: Vector3Like): this; + + multiply(v: Vector3Like): this; + + /** + * Multiplies this vector by scalar s. + */ + multiplyScalar(s: number): this; + + multiplyVectors(a: Vector3Like, b: Vector3Like): this; + + applyEuler(euler: Euler): this; + + applyAxisAngle(axis: Vector3, angle: number): this; + + applyMatrix3(m: Matrix3): this; + + applyNormalMatrix(m: Matrix3): this; + + applyMatrix4(m: Matrix4): this; + + applyQuaternion(q: QuaternionLike): this; + + project(camera: Camera): this; + + unproject(camera: Camera): this; + + transformDirection(m: Matrix4): this; + + divide(v: Vector3Like): this; + + /** + * Divides this vector by scalar s. + * Set vector to ( 0, 0, 0 ) if s == 0. + */ + divideScalar(s: number): this; + + min(v: Vector3Like): this; + + max(v: Vector3Like): this; + + clamp(min: Vector3Like, max: Vector3Like): this; + + clampScalar(min: number, max: number): this; + + clampLength(min: number, max: number): this; + + floor(): this; + + ceil(): this; + + round(): this; + + roundToZero(): this; + + /** + * Inverts this vector. + */ + negate(): this; + + /** + * Computes dot product of this vector and v. + */ + dot(v: Vector3Like): number; + + /** + * Computes squared length of this vector. + */ + lengthSq(): number; + + /** + * Computes length of this vector. + */ + length(): number; + + /** + * Computes the Manhattan length of this vector. + * + * see {@link http://en.wikipedia.org/wiki/Taxicab_geometry|Wikipedia: Taxicab Geometry} + */ + manhattanLength(): number; + + /** + * Normalizes this vector. + */ + normalize(): this; + + /** + * Normalizes this vector and multiplies it by l. + */ + setLength(l: number): this; + lerp(v: Vector3Like, alpha: number): this; + + lerpVectors(v1: Vector3Like, v2: Vector3Like, alpha: number): this; + + /** + * Sets this vector to cross product of itself and v. + */ + cross(a: Vector3Like): this; + + /** + * Sets this vector to cross product of a and b. + */ + crossVectors(a: Vector3Like, b: Vector3Like): this; + projectOnVector(v: Vector3): this; + projectOnPlane(planeNormal: Vector3): this; + reflect(vector: Vector3Like): this; + angleTo(v: Vector3): number; + + /** + * Computes distance of this vector to v. + */ + distanceTo(v: Vector3Like): number; + + /** + * Computes squared distance of this vector to v. + */ + distanceToSquared(v: Vector3Like): number; + + /** + * Computes the Manhattan length (distance) from this vector to the given vector v + * + * see {@link http://en.wikipedia.org/wiki/Taxicab_geometry|Wikipedia: Taxicab Geometry} + */ + manhattanDistanceTo(v: Vector3Like): number; + + setFromSpherical(s: Spherical): this; + setFromSphericalCoords(r: number, phi: number, theta: number): this; + setFromCylindrical(s: Cylindrical): this; + setFromCylindricalCoords(radius: number, theta: number, y: number): this; + setFromMatrixPosition(m: Matrix4): this; + setFromMatrixScale(m: Matrix4): this; + setFromMatrixColumn(matrix: Matrix4, index: number): this; + setFromMatrix3Column(matrix: Matrix3, index: number): this; + + /** + * Sets this vector's {@link x}, {@link y} and {@link z} components from the x, y, and z components of the specified {@link Euler Euler Angle}. + */ + setFromEuler(e: Euler): this; + + /** + * Sets this vector's {@link x}, {@link y} and {@link z} components from the r, g, and b components of the specified + * {@link Color | color}. + */ + setFromColor(color: RGB): this; + + /** + * Checks for strict equality of this vector and v. + */ + equals(v: Vector3Like): boolean; + + /** + * Sets this vector's x, y and z value from the provided array or array-like. + * @param array the source array or array-like. + * @param offset (optional) offset into the array. Default is 0. + */ + fromArray(array: number[] | ArrayLike, offset?: number): this; + + /** + * Returns an array [x, y, z], or copies x, y and z into the provided array. + * @param array (optional) array to store the vector to. If this is not provided, a new array will be created. + * @param offset (optional) optional offset into the array. + * @return The created or provided array. + */ + toArray(array?: number[], offset?: number): number[]; + toArray(array?: Vector3Tuple, offset?: 0): Vector3Tuple; + + /** + * Copies x, y and z into the provided array-like. + * @param array array-like to store the vector to. + * @param offset (optional) optional offset into the array-like. + * @return The provided array-like. + */ + toArray(array: ArrayLike, offset?: number): ArrayLike; + + fromBufferAttribute(attribute: BufferAttribute | InterleavedBufferAttribute, index: number): this; + + /** + * Sets this vector's x, y and z from Math.random + */ + random(): this; + + randomDirection(): this; + + /** + * Iterating through a Vector3 instance will yield its components (x, y, z) in the corresponding order. + */ + [Symbol.iterator](): Iterator; +} diff --git a/src-testing/src/math/Vector4.d.ts b/src-testing/src/math/Vector4.d.ts new file mode 100644 index 000000000..88cf74ff2 --- /dev/null +++ b/src-testing/src/math/Vector4.d.ts @@ -0,0 +1,239 @@ +import { BufferAttribute } from "../core/BufferAttribute.js"; +import { Matrix4 } from "./Matrix4.js"; +import { QuaternionLike } from "./Quaternion.js"; + +export type Vector4Tuple = [number, number, number, number]; + +export interface Vector4Like { + readonly x: number; + readonly y: number; + readonly z: number; + readonly w: number; +} + +/** + * 4D vector. + */ +export class Vector4 { + constructor(x?: number, y?: number, z?: number, w?: number); + + /** + * @default 0 + */ + x: number; + + /** + * @default 0 + */ + y: number; + + /** + * @default 0 + */ + z: number; + + /** + * @default 0 + */ + w: number; + + width: number; + height: number; + readonly isVector4: true; + + /** + * Sets value of this vector. + */ + set(x: number, y: number, z: number, w: number): this; + + /** + * Sets all values of this vector. + */ + setScalar(scalar: number): this; + + /** + * Sets X component of this vector. + */ + setX(x: number): this; + + /** + * Sets Y component of this vector. + */ + setY(y: number): this; + + /** + * Sets Z component of this vector. + */ + setZ(z: number): this; + + /** + * Sets w component of this vector. + */ + setW(w: number): this; + + setComponent(index: number, value: number): this; + + getComponent(index: number): number; + + /** + * Clones this vector. + */ + clone(): this; + + /** + * Copies value of v to this vector. + */ + copy(v: Vector4Like): this; + + /** + * Adds v to this vector. + */ + add(v: Vector4Like): this; + + addScalar(scalar: number): this; + + /** + * Sets this vector to a + b. + */ + addVectors(a: Vector4Like, b: Vector4Like): this; + + addScaledVector(v: Vector4Like, s: number): this; + /** + * Subtracts v from this vector. + */ + sub(v: Vector4Like): this; + + subScalar(s: number): this; + + /** + * Sets this vector to a - b. + */ + subVectors(a: Vector4Like, b: Vector4Like): this; + + multiply(v: Vector4Like): this; + + /** + * Multiplies this vector by scalar s. + */ + multiplyScalar(s: number): this; + + applyMatrix4(m: Matrix4): this; + + /** + * Divides this vector by scalar s. + * Set vector to ( 0, 0, 0 ) if s == 0. + */ + divideScalar(s: number): this; + + /** + * http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm + * @param q is assumed to be normalized + */ + setAxisAngleFromQuaternion(q: QuaternionLike): this; + + /** + * http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/index.htm + * @param m assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) + */ + setAxisAngleFromRotationMatrix(m: Matrix4): this; + + /** + * Sets this vector to the position elements of the + * [transformation matrix]{@link https://en.wikipedia.org/wiki/Transformation_matrix} m. + */ + setFromMatrixPosition(m: Matrix4): this; + + min(v: Vector4Like): this; + max(v: Vector4Like): this; + clamp(min: Vector4Like, max: Vector4Like): this; + clampScalar(min: number, max: number): this; + floor(): this; + ceil(): this; + round(): this; + roundToZero(): this; + + /** + * Inverts this vector. + */ + negate(): this; + + /** + * Computes dot product of this vector and v. + */ + dot(v: Vector4Like): number; + + /** + * Computes squared length of this vector. + */ + lengthSq(): number; + + /** + * Computes length of this vector. + */ + length(): number; + + /** + * Computes the Manhattan length of this vector. + * + * see {@link http://en.wikipedia.org/wiki/Taxicab_geometry|Wikipedia: Taxicab Geometry} + */ + manhattanLength(): number; + + /** + * Normalizes this vector. + */ + normalize(): this; + + /** + * Normalizes this vector and multiplies it by l. + */ + setLength(length: number): this; + + /** + * Linearly interpolate between this vector and v with alpha factor. + */ + lerp(v: Vector4Like, alpha: number): this; + + lerpVectors(v1: Vector4Like, v2: Vector4Like, alpha: number): this; + + /** + * Checks for strict equality of this vector and v. + */ + equals(v: Vector4Like): boolean; + + /** + * Sets this vector's x, y, z and w value from the provided array or array-like. + * @param array the source array or array-like. + * @param offset (optional) offset into the array. Default is 0. + */ + fromArray(array: number[] | ArrayLike, offset?: number): this; + + /** + * Returns an array [x, y, z, w], or copies x, y, z and w into the provided array. + * @param array (optional) array to store the vector to. If this is not provided, a new array will be created. + * @param offset (optional) optional offset into the array. + * @return The created or provided array. + */ + toArray(array?: number[], offset?: number): number[]; + toArray(array?: Vector4Tuple, offset?: 0): Vector4Tuple; + + /** + * Copies x, y, z and w into the provided array-like. + * @param array array-like to store the vector to. + * @param offset (optional) optional offset into the array-like. + * @return The provided array-like. + */ + toArray(array: ArrayLike, offset?: number): ArrayLike; + + fromBufferAttribute(attribute: BufferAttribute, index: number): this; + + /** + * Sets this vector's x, y, z and w from Math.random + */ + random(): this; + + /** + * Iterating through a Vector4 instance will yield its components (x, y, z, w) in the corresponding order. + */ + [Symbol.iterator](): Iterator; +} diff --git a/src-testing/src/math/interpolants/CubicInterpolant.d.ts b/src-testing/src/math/interpolants/CubicInterpolant.d.ts new file mode 100644 index 000000000..282b98d7e --- /dev/null +++ b/src-testing/src/math/interpolants/CubicInterpolant.d.ts @@ -0,0 +1,7 @@ +import { Interpolant } from "../Interpolant.js"; + +export class CubicInterpolant extends Interpolant { + constructor(parameterPositions: any, samplesValues: any, sampleSize: number, resultBuffer?: any); + + interpolate_(i1: number, t0: number, t: number, t1: number): any; +} diff --git a/src-testing/src/math/interpolants/DiscreteInterpolant.d.ts b/src-testing/src/math/interpolants/DiscreteInterpolant.d.ts new file mode 100644 index 000000000..28bd458b8 --- /dev/null +++ b/src-testing/src/math/interpolants/DiscreteInterpolant.d.ts @@ -0,0 +1,7 @@ +import { Interpolant } from "../Interpolant.js"; + +export class DiscreteInterpolant extends Interpolant { + constructor(parameterPositions: any, samplesValues: any, sampleSize: number, resultBuffer?: any); + + interpolate_(i1: number, t0: number, t: number, t1: number): any; +} diff --git a/src-testing/src/math/interpolants/LinearInterpolant.d.ts b/src-testing/src/math/interpolants/LinearInterpolant.d.ts new file mode 100644 index 000000000..e6ff11c0b --- /dev/null +++ b/src-testing/src/math/interpolants/LinearInterpolant.d.ts @@ -0,0 +1,7 @@ +import { Interpolant } from "../Interpolant.js"; + +export class LinearInterpolant extends Interpolant { + constructor(parameterPositions: any, samplesValues: any, sampleSize: number, resultBuffer?: any); + + interpolate_(i1: number, t0: number, t: number, t1: number): any; +} diff --git a/src-testing/src/math/interpolants/QuaternionLinearInterpolant.d.ts b/src-testing/src/math/interpolants/QuaternionLinearInterpolant.d.ts new file mode 100644 index 000000000..dccb66976 --- /dev/null +++ b/src-testing/src/math/interpolants/QuaternionLinearInterpolant.d.ts @@ -0,0 +1,7 @@ +import { Interpolant } from "../Interpolant.js"; + +export class QuaternionLinearInterpolant extends Interpolant { + constructor(parameterPositions: any, samplesValues: any, sampleSize: number, resultBuffer?: any); + + interpolate_(i1: number, t0: number, t: number, t1: number): any; +} diff --git a/src-testing/src/nodes/Nodes.ts b/src-testing/src/nodes/Nodes.ts new file mode 100644 index 000000000..648eec734 --- /dev/null +++ b/src-testing/src/nodes/Nodes.ts @@ -0,0 +1,144 @@ +// constants +export * from './core/constants.js'; + +// core +export { default as AssignNode } from './core/AssignNode.js'; +export { default as AttributeNode } from './core/AttributeNode.js'; +export { default as BypassNode } from './core/BypassNode.js'; +export { default as CacheNode } from './core/CacheNode.js'; +export { default as ConstNode } from './core/ConstNode.js'; +export { default as ContextNode } from './core/ContextNode.js'; +export { default as IndexNode } from './core/IndexNode.js'; +export { default as LightingModel } from './core/LightingModel.js'; +export { default as Node } from './core/Node.js'; +export { default as VarNode } from './core/VarNode.js'; +export { default as NodeAttribute } from './core/NodeAttribute.js'; +export { default as NodeBuilder } from './core/NodeBuilder.js'; +export { default as NodeCache } from './core/NodeCache.js'; +export { default as NodeCode } from './core/NodeCode.js'; +export { default as NodeFrame } from './core/NodeFrame.js'; +export { default as NodeFunctionInput } from './core/NodeFunctionInput.js'; +export { default as NodeUniform } from './core/NodeUniform.js'; +export { default as NodeVar } from './core/NodeVar.js'; +export { default as NodeVarying } from './core/NodeVarying.js'; +export { default as ParameterNode } from './core/ParameterNode.js'; +export { default as PropertyNode } from './core/PropertyNode.js'; +export { default as StackNode } from './core/StackNode.js'; +export { default as TempNode } from './core/TempNode.js'; +export { default as UniformGroupNode } from './core/UniformGroupNode.js'; +export { default as UniformNode } from './core/UniformNode.js'; +export { default as VaryingNode } from './core/VaryingNode.js'; +export { default as OutputStructNode } from './core/OutputStructNode.js'; +export { default as MRTNode } from './core/MRTNode.js'; + +import * as NodeUtils from './core/NodeUtils.js'; +export { NodeUtils }; + +// utils +export { default as ArrayElementNode } from './utils/ArrayElementNode.js'; +export { default as ConvertNode } from './utils/ConvertNode.js'; +export { default as EquirectUVNode } from './utils/EquirectUVNode.js'; +export { default as FunctionOverloadingNode } from './utils/FunctionOverloadingNode.js'; +export { default as JoinNode } from './utils/JoinNode.js'; +export { default as LoopNode } from './utils/LoopNode.js'; +export { default as MatcapUVNode } from './utils/MatcapUVNode.js'; +export { default as MaxMipLevelNode } from './utils/MaxMipLevelNode.js'; +export { default as RemapNode } from './utils/RemapNode.js'; +export { default as RotateNode } from './utils/RotateNode.js'; +export { default as SetNode } from './utils/SetNode.js'; +export { default as SplitNode } from './utils/SplitNode.js'; +export { default as SpriteSheetUVNode } from './utils/SpriteSheetUVNode.js'; +export { default as StorageArrayElementNode } from './utils/StorageArrayElementNode.js'; +export { default as TriplanarTexturesNode } from './utils/TriplanarTexturesNode.js'; +export { default as ReflectorNode } from './utils/ReflectorNode.js'; +export { default as RTTNode } from './utils/RTTNode.js'; + +// accessors +export { default as UniformArrayNode } from './accessors/UniformArrayNode.js'; +export { default as BufferAttributeNode } from './accessors/BufferAttributeNode.js'; +export { default as BufferNode } from './accessors/BufferNode.js'; +export { default as VertexColorNode } from './accessors/VertexColorNode.js'; +export { default as CubeTextureNode } from './accessors/CubeTextureNode.js'; +export { default as InstanceNode } from './accessors/InstanceNode.js'; +export { default as BatchNode } from './accessors/BatchNode.js'; +export { default as MaterialNode } from './accessors/MaterialNode.js'; +export { default as MaterialReferenceNode } from './accessors/MaterialReferenceNode.js'; +export { default as RendererReferenceNode } from './accessors/RendererReferenceNode.js'; +export { default as MorphNode } from './accessors/MorphNode.js'; +export { default as ModelNode } from './accessors/ModelNode.js'; +export { default as ModelViewProjectionNode } from './accessors/ModelViewProjectionNode.js'; +export { default as Object3DNode } from './accessors/Object3DNode.js'; +export { default as PointUVNode } from './accessors/PointUVNode.js'; +export { default as ReferenceNode } from './accessors/ReferenceNode.js'; +export { default as SkinningNode } from './accessors/SkinningNode.js'; +export { default as SceneNode } from './accessors/SceneNode.js'; +export { default as StorageBufferNode } from './accessors/StorageBufferNode.js'; +export { default as TextureNode } from './accessors/TextureNode.js'; +export { default as TextureSizeNode } from './accessors/TextureSizeNode.js'; +export { default as StorageTextureNode } from './accessors/StorageTextureNode.js'; +export { default as Texture3DNode } from './accessors/Texture3DNode.js'; +export { default as UserDataNode } from './accessors/UserDataNode.js'; + +// display +export { default as BumpMapNode } from './display/BumpMapNode.js'; +export { default as ColorSpaceNode } from './display/ColorSpaceNode.js'; +export { default as FrontFacingNode } from './display/FrontFacingNode.js'; +export { default as NormalMapNode } from './display/NormalMapNode.js'; +export { default as PosterizeNode } from './display/PosterizeNode.js'; +export { default as ToneMappingNode } from './display/ToneMappingNode.js'; +export { default as ScreenNode } from './display/ScreenNode.js'; +export { default as ViewportTextureNode } from './display/ViewportTextureNode.js'; +export { default as ViewportSharedTextureNode } from './display/ViewportSharedTextureNode.js'; +export { default as ViewportDepthTextureNode } from './display/ViewportDepthTextureNode.js'; +export { default as ViewportDepthNode } from './display/ViewportDepthNode.js'; +export { default as RenderOutputNode } from './display/RenderOutputNode.js'; +export { default as PassNode } from './display/PassNode.js'; +export { default as ToonOutlinePassNode } from './display/ToonOutlinePassNode.js'; + +// code +export { default as ExpressionNode } from './code/ExpressionNode.js'; +export { default as CodeNode } from './code/CodeNode.js'; +export { default as FunctionCallNode } from './code/FunctionCallNode.js'; +export { default as FunctionNode } from './code/FunctionNode.js'; +export { default as ScriptableNode } from './code/ScriptableNode.js'; +export { default as ScriptableValueNode } from './code/ScriptableValueNode.js'; + +// fog +export { default as FogNode } from './fog/FogNode.js'; +export { default as FogRangeNode } from './fog/FogRangeNode.js'; +export { default as FogExp2Node } from './fog/FogExp2Node.js'; + +// geometry +export { default as RangeNode } from './geometry/RangeNode.js'; + +// gpgpu +export { default as ComputeNode } from './gpgpu/ComputeNode.js'; + +// lighting +export { default as PointLightNode } from './lighting/PointLightNode.js'; +export { default as DirectionalLightNode } from './lighting/DirectionalLightNode.js'; +export { default as RectAreaLightNode } from './lighting/RectAreaLightNode.js'; +export { default as SpotLightNode } from './lighting/SpotLightNode.js'; +export { default as IESSpotLightNode } from './lighting/IESSpotLightNode.js'; +export { default as AmbientLightNode } from './lighting/AmbientLightNode.js'; +export { default as LightsNode } from './lighting/LightsNode.js'; +export { default as LightingNode } from './lighting/LightingNode.js'; +export { default as LightingContextNode } from './lighting/LightingContextNode.js'; +export { default as HemisphereLightNode } from './lighting/HemisphereLightNode.js'; +export { default as LightProbeNode } from './lighting/LightProbeNode.js'; +export { default as EnvironmentNode } from './lighting/EnvironmentNode.js'; +export { default as BasicEnvironmentNode } from './lighting/BasicEnvironmentNode.js'; +export { default as IrradianceNode } from './lighting/IrradianceNode.js'; +export { default as AONode } from './lighting/AONode.js'; +export { default as AnalyticLightNode } from './lighting/AnalyticLightNode.js'; +export { default as ShadowNode } from './lighting/ShadowNode.js'; + +// pmrem +export { default as PMREMNode } from './pmrem/PMREMNode.js'; + +// parsers +export { default as GLSLNodeParser } from './parsers/GLSLNodeParser.js'; // @TODO: Move to jsm/renderers/webgl. + +// lighting models +export { default as PhongLightingModel } from './functions/PhongLightingModel.js'; +export { default as PhysicalLightingModel } from './functions/PhysicalLightingModel.js'; diff --git a/src-testing/src/nodes/TSL.d.ts b/src-testing/src/nodes/TSL.d.ts new file mode 100644 index 000000000..e3e3e439b --- /dev/null +++ b/src-testing/src/nodes/TSL.d.ts @@ -0,0 +1,156 @@ +// constants +export * from "./core/constants.js"; + +// core +export * from "./core/AssignNode.js"; +export * from "./core/AttributeNode.js"; +export * from "./core/BypassNode.js"; +export * from "./core/CacheNode.js"; +export * from "./core/ContextNode.js"; +export * from "./core/IndexNode.js"; +export * from "./core/MRTNode.js"; +export * from "./core/OutputStructNode.js"; +export * from "./core/ParameterNode.js"; +export * from "./core/PropertyNode.js"; +export * from "./core/StackNode.js"; +export * from "./core/UniformGroupNode.js"; +export * from "./core/UniformNode.js"; +export * from "./core/VaryingNode.js"; + +// math +export * from "./math/Hash.js"; +export * from "./math/MathUtils.js"; +export * from "./math/TriNoise3D.js"; + +// utils +export * from "./utils/EquirectUVNode.js"; +export * from "./utils/FunctionOverloadingNode.js"; +export * from "./utils/LoopNode.js"; +export * from "./utils/MatcapUVNode.js"; +export * from "./utils/MaxMipLevelNode.js"; +export * from "./utils/Oscillators.js"; +export * from "./utils/Packing.js"; +export * from "./utils/PostProcessingUtils.js"; +export * from "./utils/ReflectorNode.js"; +export * from "./utils/RemapNode.js"; +export * from "./utils/RotateNode.js"; +export * from "./utils/RTTNode.js"; +export * from "./utils/SpriteSheetUVNode.js"; +export * from "./utils/SpriteUtils.js"; +export * from "./utils/Timer.js"; +export * from "./utils/TriplanarTexturesNode.js"; +export * from "./utils/UVUtils.js"; +export * from "./utils/ViewportUtils.js"; + +// three.js shading language +export * from "./tsl/TSLBase.js"; + +// accessors +export * from "./accessors/AccessorsUtils.js"; +export * from "./accessors/BatchNode.js"; +export * from "./accessors/Bitangent.js"; +export * from "./accessors/BufferAttributeNode.js"; +export * from "./accessors/BufferNode.js"; +export * from "./accessors/Camera.js"; +export * from "./accessors/CubeTextureNode.js"; +export * from "./accessors/InstanceNode.js"; +export * from "./accessors/MaterialNode.js"; +export * from "./accessors/MaterialProperties.js"; +export * from "./accessors/MaterialReferenceNode.js"; +export * from "./accessors/ModelNode.js"; +export * from "./accessors/ModelViewProjectionNode.js"; +export * from "./accessors/MorphNode.js"; +export * from "./accessors/Normal.js"; +export * from "./accessors/Object3DNode.js"; +export * from "./accessors/PointUVNode.js"; +export * from "./accessors/Position.js"; +export * from "./accessors/ReferenceNode.js"; +export * from "./accessors/ReflectVector.js"; +export * from "./accessors/RendererReferenceNode.js"; +export * from "./accessors/SceneNode.js"; +export * from "./accessors/SkinningNode.js"; +export * from "./accessors/StorageBufferNode.js"; +export * from "./accessors/StorageTextureNode.js"; +export * from "./accessors/Tangent.js"; +export * from "./accessors/Texture3DNode.js"; +export * from "./accessors/TextureBicubic.js"; +export * from "./accessors/TextureNode.js"; +export * from "./accessors/TextureSizeNode.js"; +export * from "./accessors/UniformArrayNode.js"; +export * from "./accessors/UserDataNode.js"; +export * from "./accessors/UV.js"; +export * from "./accessors/VelocityNode.js"; +export * from "./accessors/VertexColorNode.js"; + +// display +export * from "./display/BlendMode.js"; +export * from "./display/BumpMapNode.js"; +export * from "./display/ColorAdjustment.js"; +export * from "./display/ColorSpaceNode.js"; +export * from "./display/FrontFacingNode.js"; +export * from "./display/NormalMapNode.js"; +export * from "./display/PosterizeNode.js"; +export * from "./display/RenderOutputNode.js"; +export * from "./display/ScreenNode.js"; +export * from "./display/ToneMappingNode.js"; +export * from "./display/ToonOutlinePassNode.js"; +export * from "./display/ViewportDepthNode.js"; +export * from "./display/ViewportDepthTextureNode.js"; +export * from "./display/ViewportSharedTextureNode.js"; +export * from "./display/ViewportTextureNode.js"; + +export * from "./display/PassNode.js"; + +export * from "./display/ColorSpaceFunctions.js"; +export * from "./display/ToneMappingFunctions.js"; + +// code +export * from "./code/CodeNode.js"; +export * from "./code/ExpressionNode.js"; +export * from "./code/FunctionCallNode.js"; +export * from "./code/FunctionNode.js"; +export * from "./code/ScriptableNode.js"; +export * from "./code/ScriptableValueNode.js"; + +// fog +export * from "./fog/FogExp2Node.js"; +export * from "./fog/FogNode.js"; +export * from "./fog/FogRangeNode.js"; + +// geometry +export * from "./geometry/RangeNode.js"; + +// gpgpu +export * from "./gpgpu/ComputeNode.js"; + +// lighting +export * from "./lighting/LightingContextNode.js"; +export * from "./lighting/LightNode.js"; +export * from "./lighting/LightsNode.js"; +export * from "./lighting/PointLightNode.js"; +export * from "./lighting/ShadowNode.js"; + +// pmrem +export * from "./pmrem/PMREMNode.js"; +export * from "./pmrem/PMREMUtils.js"; + +// procedural +export * from "./procedural/Checker.js"; + +// materialX +export * from "./materialx/MaterialXNodes.js"; + +// functions +export { default as BRDF_GGX } from "./functions/BSDF/BRDF_GGX.js"; +export { default as BRDF_Lambert } from "./functions/BSDF/BRDF_Lambert.js"; +export { default as D_GGX } from "./functions/BSDF/D_GGX.js"; +export { default as DFGApprox } from "./functions/BSDF/DFGApprox.js"; +export { default as F_Schlick } from "./functions/BSDF/F_Schlick.js"; +export { default as Schlick_to_F0 } from "./functions/BSDF/Schlick_to_F0.js"; +export { default as V_GGX_SmithCorrelated } from "./functions/BSDF/V_GGX_SmithCorrelated.js"; + +export * from "./lighting/LightUtils.js"; + +export { default as getGeometryRoughness } from "./functions/material/getGeometryRoughness.js"; +export { default as getRoughness } from "./functions/material/getRoughness.js"; +export { default as getShIrradianceAt } from "./functions/material/getShIrradianceAt.js"; diff --git a/src-testing/src/nodes/accessors/AccessorsUtils.d.ts b/src-testing/src/nodes/accessors/AccessorsUtils.d.ts new file mode 100644 index 000000000..e42044673 --- /dev/null +++ b/src-testing/src/nodes/accessors/AccessorsUtils.d.ts @@ -0,0 +1,9 @@ +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +export const TBNViewMatrix: ShaderNodeObject; + +export const parallaxDirection: ShaderNodeObject; +export const parallaxUV: (uv: ShaderNodeObject, scale: NodeRepresentation) => ShaderNodeObject; + +export const transformedBentNormalView: ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/BatchNode.d.ts b/src-testing/src/nodes/accessors/BatchNode.d.ts new file mode 100644 index 000000000..51db8b6bb --- /dev/null +++ b/src-testing/src/nodes/accessors/BatchNode.d.ts @@ -0,0 +1,13 @@ +import { BatchedMesh } from "../../objects/BatchedMesh.js"; +import Node from "../core/Node.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +export default class BatchNode extends Node { + batchMesh: BatchedMesh; + + batchingIdNode: Node | null; + + constructor(batchMesh: BatchedMesh); +} + +export const batch: (batchMesh: BatchedMesh) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/Bitangent.d.ts b/src-testing/src/nodes/accessors/Bitangent.d.ts new file mode 100644 index 000000000..bcdc4d6e2 --- /dev/null +++ b/src-testing/src/nodes/accessors/Bitangent.d.ts @@ -0,0 +1,9 @@ +import MathNode from "../math/MathNode.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +export const bitangentGeometry: ShaderNodeObject; +export const bitangentLocal: ShaderNodeObject; +export const bitangentView: ShaderNodeObject; +export const bitangentWorld: ShaderNodeObject; +export const transformedBitangentView: ShaderNodeObject; +export const transformedBitangentWorld: ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/BufferAttributeNode.ts b/src-testing/src/nodes/accessors/BufferAttributeNode.ts new file mode 100644 index 000000000..97456dbc2 --- /dev/null +++ b/src-testing/src/nodes/accessors/BufferAttributeNode.ts @@ -0,0 +1,135 @@ +import InputNode from '../core/InputNode.js'; +import { nodeObject, addMethodChaining } from '../tsl/TSLCore.js'; +import { varying } from '../core/VaryingNode.js'; + +import { InterleavedBufferAttribute } from '../../core/InterleavedBufferAttribute.js'; +import { InterleavedBuffer } from '../../core/InterleavedBuffer.js'; +import { StaticDrawUsage, DynamicDrawUsage } from '../../constants.js'; + +class BufferAttributeNode extends InputNode { + static get type() { + return 'BufferAttributeNode'; + } + + constructor(value, bufferType = null, bufferStride = 0, bufferOffset = 0) { + super(value, bufferType); + + this.isBufferNode = true; + + this.bufferType = bufferType; + this.bufferStride = bufferStride; + this.bufferOffset = bufferOffset; + + this.usage = StaticDrawUsage; + this.instanced = false; + + this.attribute = null; + + this.global = true; + + if (value && value.isBufferAttribute === true) { + this.attribute = value; + this.usage = value.usage; + this.instanced = value.isInstancedBufferAttribute; + } + } + + getHash(builder) { + if (this.bufferStride === 0 && this.bufferOffset === 0) { + let bufferData = builder.globalCache.getData(this.value); + + if (bufferData === undefined) { + bufferData = { + node: this, + }; + + builder.globalCache.setData(this.value, bufferData); + } + + return bufferData.node.uuid; + } + + return this.uuid; + } + + getNodeType(builder) { + if (this.bufferType === null) { + this.bufferType = builder.getTypeFromAttribute(this.attribute); + } + + return this.bufferType; + } + + setup(builder) { + if (this.attribute !== null) return; + + const type = this.getNodeType(builder); + const array = this.value; + const itemSize = builder.getTypeLength(type); + const stride = this.bufferStride || itemSize; + const offset = this.bufferOffset; + + const buffer = array.isInterleavedBuffer === true ? array : new InterleavedBuffer(array, stride); + const bufferAttribute = new InterleavedBufferAttribute(buffer, itemSize, offset); + + buffer.setUsage(this.usage); + + this.attribute = bufferAttribute; + this.attribute.isInstancedBufferAttribute = this.instanced; // @TODO: Add a possible: InstancedInterleavedBufferAttribute + } + + generate(builder) { + const nodeType = this.getNodeType(builder); + + const nodeAttribute = builder.getBufferAttributeFromNode(this, nodeType); + const propertyName = builder.getPropertyName(nodeAttribute); + + let output = null; + + if (builder.shaderStage === 'vertex' || builder.shaderStage === 'compute') { + this.name = propertyName; + + output = propertyName; + } else { + const nodeVarying = varying(this); + + output = nodeVarying.build(builder, nodeType); + } + + return output; + } + + getInputType(/*builder*/) { + return 'bufferAttribute'; + } + + setUsage(value) { + this.usage = value; + + if (this.attribute && this.attribute.isBufferAttribute === true) { + this.attribute.usage = value; + } + + return this; + } + + setInstanced(value) { + this.instanced = value; + + return this; + } +} + +export default BufferAttributeNode; + +export const bufferAttribute = (array, type, stride, offset) => + nodeObject(new BufferAttributeNode(array, type, stride, offset)); +export const dynamicBufferAttribute = (array, type, stride, offset) => + bufferAttribute(array, type, stride, offset).setUsage(DynamicDrawUsage); + +export const instancedBufferAttribute = (array, type, stride, offset) => + bufferAttribute(array, type, stride, offset).setInstanced(true); +export const instancedDynamicBufferAttribute = (array, type, stride, offset) => + dynamicBufferAttribute(array, type, stride, offset).setInstanced(true); + +addMethodChaining('toAttribute', bufferNode => bufferAttribute(bufferNode.value)); diff --git a/src-testing/src/nodes/accessors/BufferNode.d.ts b/src-testing/src/nodes/accessors/BufferNode.d.ts new file mode 100644 index 000000000..4db9ccccd --- /dev/null +++ b/src-testing/src/nodes/accessors/BufferNode.d.ts @@ -0,0 +1,17 @@ +import UniformNode from "../core/UniformNode.js"; +import { NodeOrType, ShaderNodeObject } from "../tsl/TSLCore.js"; + +export default class BufferNode extends UniformNode { + isBufferNode: true; + + bufferType: string; + bufferCount: number; + + constructor(value: unknown, bufferType: string, bufferCount?: number); +} + +export const buffer: ( + value: unknown, + nodeOrType: NodeOrType, + count: number, +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/Camera.d.ts b/src-testing/src/nodes/accessors/Camera.d.ts new file mode 100644 index 000000000..6fd332889 --- /dev/null +++ b/src-testing/src/nodes/accessors/Camera.d.ts @@ -0,0 +1,14 @@ +import { Matrix3 } from "../../math/Matrix3.js"; +import { Matrix4 } from "../../math/Matrix4.js"; +import { Vector3 } from "../../math/Vector3.js"; +import UniformNode from "../core/UniformNode.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +export const cameraNear: ShaderNodeObject>; +export const cameraFar: ShaderNodeObject>; +export const cameraProjectionMatrix: ShaderNodeObject>; +export const cameraProjectionMatrixInverse: ShaderNodeObject>; +export const cameraViewMatrix: ShaderNodeObject>; +export const cameraWorldMatrix: ShaderNodeObject>; +export const cameraNormalMatrix: ShaderNodeObject>; +export const cameraPosition: ShaderNodeObject>; diff --git a/src-testing/src/nodes/accessors/ClippingNode.d.ts b/src-testing/src/nodes/accessors/ClippingNode.d.ts new file mode 100644 index 000000000..bb2cac1cd --- /dev/null +++ b/src-testing/src/nodes/accessors/ClippingNode.d.ts @@ -0,0 +1,16 @@ +import Node from "../core/Node.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +export type ClippingNodeScope = typeof ClippingNode.ALPHA_TO_COVERAGE | typeof ClippingNode.DEFAULT; + +export default class ClippingNode extends Node { + scope: ClippingNodeScope; + + constructor(scope?: ClippingNodeScope); + + static ALPHA_TO_COVERAGE: "alphaToCoverage"; + static DEFAULT: "default"; +} + +export const clipping: () => ShaderNodeObject; +export const clippingAlpha: () => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/CubeTextureNode.d.ts b/src-testing/src/nodes/accessors/CubeTextureNode.d.ts new file mode 100644 index 000000000..c25d51999 --- /dev/null +++ b/src-testing/src/nodes/accessors/CubeTextureNode.d.ts @@ -0,0 +1,28 @@ +import { CubeTexture } from "../../textures/CubeTexture.js"; +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; +import TextureNode from "./TextureNode.js"; + +declare class CubeTextureNode extends TextureNode { + isCubeTextureNode: boolean; + uvNode: ShaderNodeObject | null; + levelNode: ShaderNodeObject | null; + + constructor( + value: CubeTexture, + uvNode?: ShaderNodeObject | null, + levelNode?: ShaderNodeObject | null, + biasNode?: ShaderNodeObject | null, + ); + + getDefaultUV(): Node; +} + +export default CubeTextureNode; + +export const cubeTexture: ( + value: CubeTexture, + uvNode?: NodeRepresentation, + levelNode?: NodeRepresentation, + biasNode?: NodeRepresentation, +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/InstanceNode.d.ts b/src-testing/src/nodes/accessors/InstanceNode.d.ts new file mode 100644 index 000000000..c6cd43993 --- /dev/null +++ b/src-testing/src/nodes/accessors/InstanceNode.d.ts @@ -0,0 +1,13 @@ +import { InstancedMesh } from "../../objects/InstancedMesh.js"; +import Node from "../core/Node.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +export default class InstanceNode extends Node { + instanceMesh: InstancedMesh; + instanceMatrixNode: Node | null; + instanceColorNode: Node | null; + + constructor(instanceMesh: InstancedMesh); +} + +export const instance: (instanceMesh: InstancedMesh) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/MaterialNode.d.ts b/src-testing/src/nodes/accessors/MaterialNode.d.ts new file mode 100644 index 000000000..a29160b0e --- /dev/null +++ b/src-testing/src/nodes/accessors/MaterialNode.d.ts @@ -0,0 +1,129 @@ +import { Vector2 } from "../../math/Vector2.js"; +import Node from "../core/Node.js"; +import UniformNode from "../core/UniformNode.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +export type MaterialNodeScope = + | typeof MaterialNode.ALPHA_TEST + | typeof MaterialNode.COLOR + | typeof MaterialNode.OPACITY + | typeof MaterialNode.SHININESS + | typeof MaterialNode.SPECULAR + | typeof MaterialNode.SPECULAR_STRENGTH + | typeof MaterialNode.SPECULAR_INTENSITY + | typeof MaterialNode.SPECULAR_COLOR + | typeof MaterialNode.REFLECTIVITY + | typeof MaterialNode.ROUGHNESS + | typeof MaterialNode.METALNESS + | typeof MaterialNode.NORMAL + | typeof MaterialNode.CLEARCOAT + | typeof MaterialNode.CLEARCOAT_ROUGHNESS + | typeof MaterialNode.CLEARCOAT_NORMAL + | typeof MaterialNode.EMISSIVE + | typeof MaterialNode.ROTATION + | typeof MaterialNode.SHEEN + | typeof MaterialNode.SHEEN_ROUGHNESS + | typeof MaterialNode.ANISOTROPY + | typeof MaterialNode.IRIDESCENCE + | typeof MaterialNode.IRIDESCENCE_IOR + | typeof MaterialNode.IRIDESCENCE_THICKNESS + | typeof MaterialNode.IOR + | typeof MaterialNode.TRANSMISSION + | typeof MaterialNode.THICKNESS + | typeof MaterialNode.ATTENUATION_DISTANCE + | typeof MaterialNode.ATTENUATION_COLOR + | typeof MaterialNode.LINE_SCALE + | typeof MaterialNode.LINE_DASH_SIZE + | typeof MaterialNode.LINE_GAP_SIZE + | typeof MaterialNode.LINE_WIDTH + | typeof MaterialNode.LINE_DASH_OFFSET + | typeof MaterialNode.POINT_WIDTH + | typeof MaterialNode.DISPERSION + | typeof MaterialNode.LIGHT_MAP + | typeof MaterialNode.AO_MAP + | typeof MaterialNode.REFRACTION_RATIO; + +export default class MaterialNode extends Node { + static ALPHA_TEST: "alphaTest"; + static COLOR: "color"; + static OPACITY: "opacity"; + static SHININESS: "shininess"; + static SPECULAR: "specular"; + static SPECULAR_STRENGTH: "specularStrength"; + static SPECULAR_INTENSITY: "specularIntensity"; + static SPECULAR_COLOR: "specularColor"; + static REFLECTIVITY: "reflectivity"; + static ROUGHNESS: "roughness"; + static METALNESS: "metalness"; + static NORMAL: "normal"; + static CLEARCOAT: "clearcoat"; + static CLEARCOAT_ROUGHNESS: "clearcoatRoughness"; + static CLEARCOAT_NORMAL: "clearcoatNormal"; + static EMISSIVE: "emissive"; + static ROTATION: "rotation"; + static SHEEN: "sheen"; + static SHEEN_ROUGHNESS: "sheenRoughness"; + static ANISOTROPY: "anisotropy"; + static IRIDESCENCE: "iridescence"; + static IRIDESCENCE_IOR: "iridescenceIOR"; + static IRIDESCENCE_THICKNESS: "iridescenceThickness"; + static IOR: "ior"; + static TRANSMISSION: "transmission"; + static THICKNESS: "thickness"; + static ATTENUATION_DISTANCE: "attenuationDistance"; + static ATTENUATION_COLOR: "attenuationColor"; + static LINE_SCALE: "scale"; + static LINE_DASH_SIZE: "dashSize"; + static LINE_GAP_SIZE: "gapSize"; + static LINE_WIDTH: "linewidth"; + static LINE_DASH_OFFSET: "dashOffset"; + static POINT_WIDTH: "pointWidth"; + static DISPERSION: "dispersion"; + static LIGHT_MAP: "light"; + static AO_MAP: "ao"; + static REFRACTION_RATIO: "refractionRatio"; + + scope: MaterialNodeScope; + constructor(scope?: MaterialNodeScope); +} + +export const materialAlphaTest: ShaderNodeObject; +export const materialColor: ShaderNodeObject; +export const materialShininess: ShaderNodeObject; +export const materialEmissive: ShaderNodeObject; +export const materialOpacity: ShaderNodeObject; +export const materialSpecular: ShaderNodeObject; + +export const materialSpecularIntensity: ShaderNodeObject; +export const materialSpecularColor: ShaderNodeObject; + +export const materialSpecularStrength: ShaderNodeObject; +export const materialReflectivity: ShaderNodeObject; +export const materialRoughness: ShaderNodeObject; +export const materialMetalness: ShaderNodeObject; +export const materialNormal: ShaderNodeObject; +export const materialClearcoat: ShaderNodeObject; +export const materialClearcoatRoughness: ShaderNodeObject; +export const materialClearcoatNormal: ShaderNodeObject; +export const materialRotation: ShaderNodeObject; +export const materialSheen: ShaderNodeObject; +export const materialSheenRoughness: ShaderNodeObject; +export const materialAnisotropy: ShaderNodeObject; +export const materialIridescence: ShaderNodeObject; +export const materialIridescenceIOR: ShaderNodeObject; +export const materialIridescenceThickness: ShaderNodeObject; +export const materialTransmission: ShaderNodeObject; +export const materialThickness: ShaderNodeObject; +export const materialIOR: ShaderNodeObject; +export const materialAttenuationDistance: ShaderNodeObject; +export const materialAttenuationColor: ShaderNodeObject; +export const materialLineScale: ShaderNodeObject; +export const materialLineDashSize: ShaderNodeObject; +export const materialLineGapSize: ShaderNodeObject; +export const materialLineWidth: ShaderNodeObject; +export const materialLineDashOffset: ShaderNodeObject; +export const materialPointWidth: ShaderNodeObject; +export const materialDispersion: ShaderNodeObject; +export const materialLightMap: ShaderNodeObject; +export const materialAOMap: ShaderNodeObject; +export const materialAnisotropyVector: ShaderNodeObject>; diff --git a/src-testing/src/nodes/accessors/MaterialProperties.d.ts b/src-testing/src/nodes/accessors/MaterialProperties.d.ts new file mode 100644 index 000000000..3e07ecf0b --- /dev/null +++ b/src-testing/src/nodes/accessors/MaterialProperties.d.ts @@ -0,0 +1,4 @@ +import UniformNode from "../core/UniformNode.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +export const materialRefractionRatio: ShaderNodeObject>; diff --git a/src-testing/src/nodes/accessors/MaterialReferenceNode.d.ts b/src-testing/src/nodes/accessors/MaterialReferenceNode.d.ts new file mode 100644 index 000000000..7b0cdf4ac --- /dev/null +++ b/src-testing/src/nodes/accessors/MaterialReferenceNode.d.ts @@ -0,0 +1,15 @@ +import { Material } from "../../materials/Material.js"; +import { NodeOrType, ShaderNodeObject } from "../tsl/TSLCore.js"; +import ReferenceNode from "./ReferenceNode.js"; + +export default class MaterialReferenceNode extends ReferenceNode { + readonly isMaterialReferenceNode: true; + + constructor(property: string, inputType: string, material?: Material | null); +} + +export const materialReference: ( + name: string, + nodeOrType: NodeOrType, + material?: Material | null, +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/ModelNode.d.ts b/src-testing/src/nodes/accessors/ModelNode.d.ts new file mode 100644 index 000000000..12280a2b6 --- /dev/null +++ b/src-testing/src/nodes/accessors/ModelNode.d.ts @@ -0,0 +1,24 @@ +import { Matrix4 } from "../../math/Matrix4.js"; +import Node from "../core/Node.js"; +import { UniformNode } from "../Nodes.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; +import Object3DNode from "./Object3DNode.js"; + +/** + * Similar to {@link Object3DNode} but the object comes from {@link NodeFrame} + */ +export default class ModelNode extends Object3DNode { + constructor(scope: string); +} + +export const modelDirection: ShaderNodeObject; +export const modelWorldMatrix: ShaderNodeObject; +export const modelPosition: ShaderNodeObject; +export const modelScale: ShaderNodeObject; +export const modelViewPosition: ShaderNodeObject; +export const modelNormalMatrix: ShaderNodeObject; +export const modelWorldMatrixInverse: ShaderNodeObject>; +export const modelViewMatrix: ShaderNodeObject; + +export const highPrecisionModelViewMatrix: ShaderNodeObject; +export const highPrecisionModelNormalViewMatrix: ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/ModelViewProjectionNode.d.ts b/src-testing/src/nodes/accessors/ModelViewProjectionNode.d.ts new file mode 100644 index 000000000..18302d638 --- /dev/null +++ b/src-testing/src/nodes/accessors/ModelViewProjectionNode.d.ts @@ -0,0 +1,8 @@ +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +export default class ModelViewProjectionNode extends Node { + constructor(positionNode?: Node); +} + +export const modelViewProjection: (position?: NodeRepresentation) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/MorphNode.d.ts b/src-testing/src/nodes/accessors/MorphNode.d.ts new file mode 100644 index 000000000..8987acf6e --- /dev/null +++ b/src-testing/src/nodes/accessors/MorphNode.d.ts @@ -0,0 +1,15 @@ +import { Mesh } from "../../objects/Mesh.js"; +import Node from "../core/Node.js"; +import UniformNode from "../core/UniformNode.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +declare class MorphNode extends Node { + mesh: Mesh; + morphBaseInfluence: UniformNode; + + constructor(mesh: Mesh); +} + +export default MorphNode; + +export const morphReference: (mesh: Mesh) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/Normal.d.ts b/src-testing/src/nodes/accessors/Normal.d.ts new file mode 100644 index 000000000..706130a8d --- /dev/null +++ b/src-testing/src/nodes/accessors/Normal.d.ts @@ -0,0 +1,25 @@ +import { Matrix4 } from "../../math/Matrix4.js"; +import AttributeNode from "../core/AttributeNode.js"; +import Node from "../core/Node.js"; +import VarNode from "../core/VarNode.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +export const normalGeometry: ShaderNodeObject; + +export const normalLocal: ShaderNodeObject; + +export const normalFlat: ShaderNodeObject; + +export const normalView: ShaderNodeObject; + +export const normalWorld: ShaderNodeObject; + +export const transformedNormalView: ShaderNodeObject; + +export const transformedNormalWorld: ShaderNodeObject; + +export const transformedClearcoatNormalView: ShaderNodeObject; + +export const transformNormal: (normal: Node, matrix?: Node) => ShaderNodeObject; + +export const transformNormalToView: (normal: Node) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/Object3DNode.d.ts b/src-testing/src/nodes/accessors/Object3DNode.d.ts new file mode 100644 index 000000000..21e6776c9 --- /dev/null +++ b/src-testing/src/nodes/accessors/Object3DNode.d.ts @@ -0,0 +1,22 @@ +import { Object3D } from "../../core/Object3D.js"; +import Node from "../core/Node.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +export default class Object3DNode extends Node { + scope: string; + object3d: Object3D | null; + + constructor(scope: string, object3d?: Object3D | null); + + static WORLD_MATRIX: "worldMatrix"; + static POSITION: "position"; + static SCALE: "scale"; + static VIEW_POSITION: "viewPosition"; + static DIRECTION: "direction"; +} + +export const objectDirection: (object3d: Object3D) => ShaderNodeObject; +export const objectWorldMatrix: (object3d: Object3D) => ShaderNodeObject; +export const objectPosition: (object3d: Object3D) => ShaderNodeObject; +export const objectScale: (object3d: Object3D) => ShaderNodeObject; +export const objectViewPosition: (object3d: Object3D) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/PointUVNode.d.ts b/src-testing/src/nodes/accessors/PointUVNode.d.ts new file mode 100644 index 000000000..2220e5563 --- /dev/null +++ b/src-testing/src/nodes/accessors/PointUVNode.d.ts @@ -0,0 +1,10 @@ +import Node from "../core/Node.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +export default class PointUVNode extends Node { + isPointUVNode: true; + + constructor(); +} + +export const pointUV: ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/Position.d.ts b/src-testing/src/nodes/accessors/Position.d.ts new file mode 100644 index 000000000..a9f6fc811 --- /dev/null +++ b/src-testing/src/nodes/accessors/Position.d.ts @@ -0,0 +1,10 @@ +import Node from "../core/Node.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +export const positionGeometry: ShaderNodeObject; +export const positionLocal: ShaderNodeObject; +export const positionPrevious: ShaderNodeObject; +export const positionWorld: ShaderNodeObject; +export const positionWorldDirection: ShaderNodeObject; +export const positionView: ShaderNodeObject; +export const positionViewDirection: ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/ReferenceBaseNode.d.ts b/src-testing/src/nodes/accessors/ReferenceBaseNode.d.ts new file mode 100644 index 000000000..586fde349 --- /dev/null +++ b/src-testing/src/nodes/accessors/ReferenceBaseNode.d.ts @@ -0,0 +1,27 @@ +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +declare class ReferenceBaseNode extends Node { + property: string; + uniformType: string; + object: T; + count: number | null; + + properties: string[]; + reference: T | null; + node: Node | null; + + constructor(property: string, uniformType: string, object?: T | null, count?: number | null); + + setNodeType(uniformType: string): void; +} + +export default ReferenceBaseNode; + +export const reference: (name: string, type: string, object: T) => ShaderNodeObject>; +export const referenceBuffer: ( + name: string, + type: string, + count: number, + object: T, +) => ShaderNodeObject>; diff --git a/src-testing/src/nodes/accessors/ReferenceNode.d.ts b/src-testing/src/nodes/accessors/ReferenceNode.d.ts new file mode 100644 index 000000000..1dea4d31f --- /dev/null +++ b/src-testing/src/nodes/accessors/ReferenceNode.d.ts @@ -0,0 +1,29 @@ +import Node from "../core/Node.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +declare class ReferenceNode extends Node { + property: string; + + uniformType: string; + + object: T; + count: number | null; + + properties: string[]; + reference: T | null; + node: Node | null; + + constructor(property: string, uniformType: string, object?: T | null, count?: number | null); + + setNodeType(uniformType: string): void; +} + +export default ReferenceNode; + +export const reference: (name: string, type: string, object: T) => ShaderNodeObject>; +export const referenceBuffer: ( + name: string, + type: string, + count: number, + object: T, +) => ShaderNodeObject>; diff --git a/src-testing/src/nodes/accessors/ReflectVector.d.ts b/src-testing/src/nodes/accessors/ReflectVector.d.ts new file mode 100644 index 000000000..4978b4975 --- /dev/null +++ b/src-testing/src/nodes/accessors/ReflectVector.d.ts @@ -0,0 +1,9 @@ +import Node from "../core/Node.js"; +import VarNode from "../core/VarNode.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +export const reflectView: ShaderNodeObject; +export const refractView: ShaderNodeObject; + +export const reflectVector: ShaderNodeObject; +export const refractVector: ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/RendererReferenceNode.d.ts b/src-testing/src/nodes/accessors/RendererReferenceNode.d.ts new file mode 100644 index 000000000..0e100b049 --- /dev/null +++ b/src-testing/src/nodes/accessors/RendererReferenceNode.d.ts @@ -0,0 +1,15 @@ +import Renderer from "../../renderers/common/Renderer.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; +import ReferenceNode from "./ReferenceNode.js"; + +export default class RendererReferenceNode extends ReferenceNode { + renderer: Renderer | null; + + constructor(property: string, inputType: string, renderer?: Renderer | null); +} + +export const rendererReference: ( + name: string, + type: string, + renderer?: Renderer | null, +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/SceneNode.d.ts b/src-testing/src/nodes/accessors/SceneNode.d.ts new file mode 100644 index 000000000..34bdea1be --- /dev/null +++ b/src-testing/src/nodes/accessors/SceneNode.d.ts @@ -0,0 +1,20 @@ +import { Scene } from "../../scenes/Scene.js"; +import Node from "../core/Node.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +export type SceneNodeScope = typeof SceneNode.BACKGROUND_BLURRINESS | typeof SceneNode.BACKGROUND_INTENSITY; + +declare class SceneNode extends Node { + scope: SceneNodeScope; + scene: Scene | null; + + constructor(scope?: SceneNodeScope, scene?: Scene | null); + + static BACKGROUND_BLURRINESS: "backgroundBlurriness"; + static BACKGROUND_INTENSITY: "backgroundIntensity"; +} + +export default SceneNode; + +export const backgroundBlurriness: ShaderNodeObject; +export const backgroundIntensity: ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/SkinningNode.d.ts b/src-testing/src/nodes/accessors/SkinningNode.d.ts new file mode 100644 index 000000000..3bef01c33 --- /dev/null +++ b/src-testing/src/nodes/accessors/SkinningNode.d.ts @@ -0,0 +1,30 @@ +import { SkinnedMesh } from "../../objects/SkinnedMesh.js"; +import Node from "../core/Node.js"; +import NodeBuilder from "../core/NodeBuilder.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +export default class SkinningNode extends Node { + skinnedMesh: SkinnedMesh; + useReference: boolean; + + skinIndexNode: Node; + skinWeightNode: Node; + + bindMatrixNode: Node; + bindMatrixInverseNode: Node; + boneMatricesNode: Node; + previousBoneMatricesNode: Node | null; + + constructor(skinnedMesh: SkinnedMesh, useReference?: boolean); + + getSkinnedPosition(boneMatrices?: Node, position?: Node): ShaderNodeObject; + + getSkinnedNormal(boneMatrices?: Node, normal?: Node): ShaderNodeObject; + + getPreviousSkinnedPosition(builder: NodeBuilder): ShaderNodeObject; + + needsPreviousBoneMatrices(builder: NodeBuilder): boolean; +} + +export const skinning: (skinnedMesh: SkinnedMesh) => ShaderNodeObject; +export const skinningReference: (skinnedMesh: SkinnedMesh) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/StorageBufferNode.d.ts b/src-testing/src/nodes/accessors/StorageBufferNode.d.ts new file mode 100644 index 000000000..d56cac59a --- /dev/null +++ b/src-testing/src/nodes/accessors/StorageBufferNode.d.ts @@ -0,0 +1,38 @@ +import StorageBufferAttribute from "../../renderers/common/StorageBufferAttribute.js"; +import StorageInstancedBufferAttribute from "../../renderers/common/StorageInstancedBufferAttribute.js"; +import { GPUBufferBindingType } from "../../renderers/webgpu/utils/WebGPUConstants.js"; +import { NodeOrType, NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; +import StorageArrayElementNode from "../utils/StorageArrayElementNode.js"; +import BufferNode from "./BufferNode.js"; + +export default class StorageBufferNode extends BufferNode { + readonly isStorageBufferNode: true; + bufferObject: boolean; + + access: GPUBufferBindingType; + + constructor( + value: StorageBufferAttribute | StorageInstancedBufferAttribute, + bufferType: string, + bufferCount?: number, + ); + + element(indexNode: NodeRepresentation): ShaderNodeObject; + + setBufferObject(value: boolean): this; + + setAccess(value: GPUBufferBindingType): this; + + toReadOnly(): this; +} + +export const storage: ( + value: StorageBufferAttribute | StorageInstancedBufferAttribute, + nodeOrType: NodeOrType, + count: number, +) => ShaderNodeObject; +export const storageObject: ( + value: StorageBufferAttribute | StorageInstancedBufferAttribute, + nodeOrType: NodeOrType, + count: number, +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/StorageTextureNode.d.ts b/src-testing/src/nodes/accessors/StorageTextureNode.d.ts new file mode 100644 index 000000000..0b4acdceb --- /dev/null +++ b/src-testing/src/nodes/accessors/StorageTextureNode.d.ts @@ -0,0 +1,40 @@ +import { GPUStorageTextureAccess } from "../../renderers/webgpu/utils/WebGPUConstants.js"; +import { Texture } from "../../textures/Texture.js"; +import Node from "../core/Node.js"; +import NodeBuilder from "../core/NodeBuilder.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; +import TextureNode from "./TextureNode.js"; + +export default class StorageTextureNode extends TextureNode { + storeNode: Node | null; + + readonly isStorageTextureNode: true; + + access: GPUStorageTextureAccess; + + constructor( + value: Texture, + uvNode?: ShaderNodeObject | null, + storeNode?: Node | null, + ); + + setAccess(value: GPUStorageTextureAccess): this; + + toReadOnly(): this; + + toWriteOnly(): this; + + generateStore(builder: NodeBuilder): void; +} + +export const storageTexture: ( + value: Texture, + uvNode?: NodeRepresentation, + storeNode?: NodeRepresentation, +) => ShaderNodeObject; + +export const textureStore: ( + value: Texture, + uvNode?: NodeRepresentation, + storeNode?: NodeRepresentation, +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/Tangent.d.ts b/src-testing/src/nodes/accessors/Tangent.d.ts new file mode 100644 index 000000000..94ec48330 --- /dev/null +++ b/src-testing/src/nodes/accessors/Tangent.d.ts @@ -0,0 +1,12 @@ +import AttributeNode from "../core/AttributeNode.js"; +import VarNode from "../core/VarNode.js"; +import VaryingNode from "../core/VaryingNode.js"; +import MathNode from "../math/MathNode.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +export const tangentGeometry: ShaderNodeObject; +export const tangentLocal: ShaderNodeObject; +export const tangentView: ShaderNodeObject; +export const tangentWorld: ShaderNodeObject; +export const transformedTangentView: ShaderNodeObject; +export const transformedTangentWorld: ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/Texture3DNode.d.ts b/src-testing/src/nodes/accessors/Texture3DNode.d.ts new file mode 100644 index 000000000..da589f034 --- /dev/null +++ b/src-testing/src/nodes/accessors/Texture3DNode.d.ts @@ -0,0 +1,17 @@ +import { CubeTexture } from "../../textures/CubeTexture.js"; +import { Texture } from "../../textures/Texture.js"; +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; +import TextureNode from "./TextureNode.js"; + +export default class Texture3DNode extends TextureNode { + readonly isTexture3DNode: true; + + constructor(value: Texture, uvNode?: ShaderNodeObject | null, levelNode?: ShaderNodeObject | null); +} + +export const texture3D: ( + value: Texture, + uvNode?: NodeRepresentation, + levelNode?: NodeRepresentation, +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/TextureBicubic.d.ts b/src-testing/src/nodes/accessors/TextureBicubic.d.ts new file mode 100644 index 000000000..b55ca57e9 --- /dev/null +++ b/src-testing/src/nodes/accessors/TextureBicubic.d.ts @@ -0,0 +1,4 @@ +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +export const textureBicubic: (textureNode: Node, lodNode?: NodeRepresentation) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/TextureNode.ts b/src-testing/src/nodes/accessors/TextureNode.ts new file mode 100644 index 000000000..f97a04d11 --- /dev/null +++ b/src-testing/src/nodes/accessors/TextureNode.ts @@ -0,0 +1,370 @@ +import UniformNode, { uniform } from '../core/UniformNode.js'; +import { uv } from './UV.js'; +import { textureSize } from './TextureSizeNode.js'; +import { colorSpaceToWorking } from '../display/ColorSpaceNode.js'; +import { expression } from '../code/ExpressionNode.js'; +import { maxMipLevel } from '../utils/MaxMipLevelNode.js'; +import { nodeProxy, vec3, nodeObject, int } from '../tsl/TSLBase.js'; +import { NodeUpdateType } from '../core/constants.js'; + +import { IntType, UnsignedIntType } from '../../constants.js'; + +class TextureNode extends UniformNode { + static get type() { + return 'TextureNode'; + } + + constructor(value, uvNode = null, levelNode = null, biasNode = null) { + super(value); + + this.isTextureNode = true; + + this.uvNode = uvNode; + this.levelNode = levelNode; + this.biasNode = biasNode; + this.compareNode = null; + this.depthNode = null; + this.gradNode = null; + + this.sampler = true; + this.updateMatrix = false; + this.updateType = NodeUpdateType.NONE; + + this.referenceNode = null; + + this._value = value; + this._matrixUniform = null; + + this.setUpdateMatrix(uvNode === null); + } + + set value(value) { + if (this.referenceNode) { + this.referenceNode.value = value; + } else { + this._value = value; + } + } + + get value() { + return this.referenceNode ? this.referenceNode.value : this._value; + } + + getUniformHash(/*builder*/) { + return this.value.uuid; + } + + getNodeType(/*builder*/) { + if (this.value.isDepthTexture === true) return 'float'; + + if (this.value.type === UnsignedIntType) { + return 'uvec4'; + } else if (this.value.type === IntType) { + return 'ivec4'; + } + + return 'vec4'; + } + + getInputType(/*builder*/) { + return 'texture'; + } + + getDefaultUV() { + return uv(this.value.channel); + } + + updateReference(/*state*/) { + return this.value; + } + + getTransformedUV(uvNode) { + if (this._matrixUniform === null) this._matrixUniform = uniform(this.value.matrix); + + return this._matrixUniform.mul(vec3(uvNode, 1)).xy; + } + + setUpdateMatrix(value) { + this.updateMatrix = value; + this.updateType = value ? NodeUpdateType.FRAME : NodeUpdateType.NONE; + + return this; + } + + setupUV(builder, uvNode) { + const texture = this.value; + + if ( + builder.isFlipY() && + (texture.isRenderTargetTexture === true || + texture.isFramebufferTexture === true || + texture.isDepthTexture === true) + ) { + if (this.sampler) { + uvNode = uvNode.flipY(); + } else { + uvNode = uvNode.setY(int(textureSize(this, this.levelNode).y).sub(uvNode.y).sub(1)); + } + } + + return uvNode; + } + + setup(builder) { + const properties = builder.getNodeProperties(this); + properties.referenceNode = this.referenceNode; + + // + + let uvNode = this.uvNode; + + if ((uvNode === null || builder.context.forceUVContext === true) && builder.context.getUV) { + uvNode = builder.context.getUV(this); + } + + if (!uvNode) uvNode = this.getDefaultUV(); + + if (this.updateMatrix === true) { + uvNode = this.getTransformedUV(uvNode); + } + + uvNode = this.setupUV(builder, uvNode); + + // + + let levelNode = this.levelNode; + + if (levelNode === null && builder.context.getTextureLevel) { + levelNode = builder.context.getTextureLevel(this); + } + + // + + properties.uvNode = uvNode; + properties.levelNode = levelNode; + properties.biasNode = this.biasNode; + properties.compareNode = this.compareNode; + properties.gradNode = this.gradNode; + properties.depthNode = this.depthNode; + } + + generateUV(builder, uvNode) { + return uvNode.build(builder, this.sampler === true ? 'vec2' : 'ivec2'); + } + + generateSnippet( + builder, + textureProperty, + uvSnippet, + levelSnippet, + biasSnippet, + depthSnippet, + compareSnippet, + gradSnippet, + ) { + const texture = this.value; + + let snippet; + + if (levelSnippet) { + snippet = builder.generateTextureLevel(texture, textureProperty, uvSnippet, levelSnippet, depthSnippet); + } else if (biasSnippet) { + snippet = builder.generateTextureBias(texture, textureProperty, uvSnippet, biasSnippet, depthSnippet); + } else if (gradSnippet) { + snippet = builder.generateTextureGrad(texture, textureProperty, uvSnippet, gradSnippet, depthSnippet); + } else if (compareSnippet) { + snippet = builder.generateTextureCompare(texture, textureProperty, uvSnippet, compareSnippet, depthSnippet); + } else if (this.sampler === false) { + snippet = builder.generateTextureLoad(texture, textureProperty, uvSnippet, depthSnippet); + } else { + snippet = builder.generateTexture(texture, textureProperty, uvSnippet, depthSnippet); + } + + return snippet; + } + + generate(builder, output) { + const properties = builder.getNodeProperties(this); + + const texture = this.value; + + if (!texture || texture.isTexture !== true) { + throw new Error('TextureNode: Need a three.js texture.'); + } + + const textureProperty = super.generate(builder, 'property'); + + if (output === 'sampler') { + return textureProperty + '_sampler'; + } else if (builder.isReference(output)) { + return textureProperty; + } else { + const nodeData = builder.getDataFromNode(this); + + let propertyName = nodeData.propertyName; + + if (propertyName === undefined) { + const { uvNode, levelNode, biasNode, compareNode, depthNode, gradNode } = properties; + + const uvSnippet = this.generateUV(builder, uvNode); + const levelSnippet = levelNode ? levelNode.build(builder, 'float') : null; + const biasSnippet = biasNode ? biasNode.build(builder, 'float') : null; + const depthSnippet = depthNode ? depthNode.build(builder, 'int') : null; + const compareSnippet = compareNode ? compareNode.build(builder, 'float') : null; + const gradSnippet = gradNode + ? [gradNode[0].build(builder, 'vec2'), gradNode[1].build(builder, 'vec2')] + : null; + + const nodeVar = builder.getVarFromNode(this); + + propertyName = builder.getPropertyName(nodeVar); + + const snippet = this.generateSnippet( + builder, + textureProperty, + uvSnippet, + levelSnippet, + biasSnippet, + depthSnippet, + compareSnippet, + gradSnippet, + ); + + builder.addLineFlowCode(`${propertyName} = ${snippet}`, this); + + nodeData.snippet = snippet; + nodeData.propertyName = propertyName; + } + + let snippet = propertyName; + const nodeType = this.getNodeType(builder); + + if (builder.needsToWorkingColorSpace(texture)) { + snippet = colorSpaceToWorking(expression(snippet, nodeType), texture.colorSpace) + .setup(builder) + .build(builder, nodeType); + } + + return builder.format(snippet, nodeType, output); + } + } + + setSampler(value) { + this.sampler = value; + + return this; + } + + getSampler() { + return this.sampler; + } + + // @TODO: Move to TSL + + uv(uvNode) { + const textureNode = this.clone(); + textureNode.uvNode = nodeObject(uvNode); + textureNode.referenceNode = this.getSelf(); + + return nodeObject(textureNode); + } + + blur(amountNode) { + const textureNode = this.clone(); + textureNode.biasNode = nodeObject(amountNode).mul(maxMipLevel(textureNode)); + textureNode.referenceNode = this.getSelf(); + + return nodeObject(textureNode); + } + + level(levelNode) { + const textureNode = this.clone(); + textureNode.levelNode = nodeObject(levelNode); + textureNode.referenceNode = this.getSelf(); + + return nodeObject(textureNode); + } + + size(levelNode) { + return textureSize(this, levelNode); + } + + bias(biasNode) { + const textureNode = this.clone(); + textureNode.biasNode = nodeObject(biasNode); + textureNode.referenceNode = this.getSelf(); + + return nodeObject(textureNode); + } + + compare(compareNode) { + const textureNode = this.clone(); + textureNode.compareNode = nodeObject(compareNode); + textureNode.referenceNode = this.getSelf(); + + return nodeObject(textureNode); + } + + grad(gradNodeX, gradNodeY) { + const textureNode = this.clone(); + textureNode.gradNode = [nodeObject(gradNodeX), nodeObject(gradNodeY)]; + textureNode.referenceNode = this.getSelf(); + + return nodeObject(textureNode); + } + + depth(depthNode) { + const textureNode = this.clone(); + textureNode.depthNode = nodeObject(depthNode); + textureNode.referenceNode = this.getSelf(); + + return nodeObject(textureNode); + } + + // -- + + serialize(data) { + super.serialize(data); + + data.value = this.value.toJSON(data.meta).uuid; + data.sampler = this.sampler; + data.updateMatrix = this.updateMatrix; + data.updateType = this.updateType; + } + + deserialize(data) { + super.deserialize(data); + + this.value = data.meta.textures[data.value]; + this.sampler = data.sampler; + this.updateMatrix = data.updateMatrix; + this.updateType = data.updateType; + } + + update() { + const texture = this.value; + const matrixUniform = this._matrixUniform; + + if (matrixUniform !== null) matrixUniform.value = texture.matrix; + + if (texture.matrixAutoUpdate === true) { + texture.updateMatrix(); + } + } + + clone() { + const newNode = new this.constructor(this.value, this.uvNode, this.levelNode, this.biasNode); + newNode.sampler = this.sampler; + + return newNode; + } +} + +export default TextureNode; + +export const texture = /*@__PURE__*/ nodeProxy(TextureNode); +export const textureLoad = (...params) => texture(...params).setSampler(false); + +//export const textureLevel = ( value, uv, level ) => texture( value, uv ).level( level ); + +export const sampler = aTexture => (aTexture.isNode === true ? aTexture : texture(aTexture)).convert('sampler'); diff --git a/src-testing/src/nodes/accessors/TextureSizeNode.d.ts b/src-testing/src/nodes/accessors/TextureSizeNode.d.ts new file mode 100644 index 000000000..0b995fccf --- /dev/null +++ b/src-testing/src/nodes/accessors/TextureSizeNode.d.ts @@ -0,0 +1,18 @@ +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +declare class TextureSizeNode extends Node { + readonly isTextureSizeNode: true; + + textureNode: Node; + levelNode: Node | null; + + constructor(textureNode: Node, levelNode?: Node | null); +} + +export default TextureSizeNode; + +export const textureSize: ( + textureNode: NodeRepresentation, + levelNode?: NodeRepresentation | null, +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/UV.d.ts b/src-testing/src/nodes/accessors/UV.d.ts new file mode 100644 index 000000000..aedabbd02 --- /dev/null +++ b/src-testing/src/nodes/accessors/UV.d.ts @@ -0,0 +1,4 @@ +import AttributeNode from "../core/AttributeNode.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +export const uv: (index?: number) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/UniformArrayNode.d.ts b/src-testing/src/nodes/accessors/UniformArrayNode.d.ts new file mode 100644 index 000000000..72e539cb4 --- /dev/null +++ b/src-testing/src/nodes/accessors/UniformArrayNode.d.ts @@ -0,0 +1,30 @@ +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; +import ArrayElementNode from "../utils/ArrayElementNode.js"; +import BufferNode from "./BufferNode.js"; + +declare class UniformArrayElementNode extends ArrayElementNode { + constructor(arrayBuffer: Node, indexNode: Node); +} + +declare class UniformArrayNode extends BufferNode { + array: unknown[]; + elementType: string | null; + + readonly isArrayBufferNode: true; + + constructor(value: unknown[], elementType?: string | null); + + getElementLength(): number; + + element(indexNode: NodeRepresentation): ShaderNodeObject; +} + +export default UniformArrayNode; + +export const uniformArray: (values: unknown[], nodeType?: string | null) => ShaderNodeObject; + +/** + * @deprecated uniforms() has been renamed to uniformArray(). + */ +export const uniforms: (values: unknown[], nodeType?: string | null) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/UserDataNode.d.ts b/src-testing/src/nodes/accessors/UserDataNode.d.ts new file mode 100644 index 000000000..647c18412 --- /dev/null +++ b/src-testing/src/nodes/accessors/UserDataNode.d.ts @@ -0,0 +1,15 @@ +import { ShaderNodeObject } from "../tsl/TSLCore.js"; +import ReferenceNode from "./ReferenceNode.js"; + +export type NodeUserData = Record; + +export default class UserDataNode extends ReferenceNode { + userData: NodeUserData | null; + constructor(property: string, inputType: string, userData?: NodeUserData | null); +} + +export const userData: ( + name: string, + inputType: string, + userData?: NodeUserData, +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/VelocityNode.d.ts b/src-testing/src/nodes/accessors/VelocityNode.d.ts new file mode 100644 index 000000000..32c040c16 --- /dev/null +++ b/src-testing/src/nodes/accessors/VelocityNode.d.ts @@ -0,0 +1,20 @@ +import { Matrix4 } from "../../math/Matrix4.js"; +import TempNode from "../core/TempNode.js"; +import UniformNode from "../core/UniformNode.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +declare class VelocityNode extends TempNode { + projectionMatrix: Matrix4 | null; + + previousModelWorldMatrix: UniformNode; + previousProjectionMatrix: UniformNode; + previousCameraViewMatrix: UniformNode; + + constructor(); + + setProjectionMatrix(projectionMatrix: Matrix4 | null): void; +} + +export default VelocityNode; + +export const velocity: ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/VertexColorNode.d.ts b/src-testing/src/nodes/accessors/VertexColorNode.d.ts new file mode 100644 index 000000000..b2bb76339 --- /dev/null +++ b/src-testing/src/nodes/accessors/VertexColorNode.d.ts @@ -0,0 +1,12 @@ +import AttributeNode from "../core/AttributeNode.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +export default class VertexColorNode extends AttributeNode { + readonly isVertexColorNode: true; + + index: number; + + constructor(index?: number); +} + +export const vertexColor: (index?: number) => ShaderNodeObject; diff --git a/src-testing/src/nodes/code/CodeNode.ts b/src-testing/src/nodes/code/CodeNode.ts new file mode 100644 index 000000000..2f4c60511 --- /dev/null +++ b/src-testing/src/nodes/code/CodeNode.ts @@ -0,0 +1,68 @@ +import Node from '../core/Node.js'; +import { nodeProxy } from '../tsl/TSLBase.js'; + +class CodeNode extends Node { + static get type() { + return 'CodeNode'; + } + + constructor(code = '', includes = [], language = '') { + super('code'); + + this.isCodeNode = true; + + this.code = code; + this.language = language; + + this.includes = includes; + } + + isGlobal() { + return true; + } + + setIncludes(includes) { + this.includes = includes; + + return this; + } + + getIncludes(/*builder*/) { + return this.includes; + } + + generate(builder) { + const includes = this.getIncludes(builder); + + for (const include of includes) { + include.build(builder); + } + + const nodeCode = builder.getCodeFromNode(this, this.getNodeType(builder)); + nodeCode.code = this.code; + + return nodeCode.code; + } + + serialize(data) { + super.serialize(data); + + data.code = this.code; + data.language = this.language; + } + + deserialize(data) { + super.deserialize(data); + + this.code = data.code; + this.language = data.language; + } +} + +export default CodeNode; + +export const code = /*@__PURE__*/ nodeProxy(CodeNode); + +export const js = (src, includes) => code(src, includes, 'js'); +export const wgsl = (src, includes) => code(src, includes, 'wgsl'); +export const glsl = (src, includes) => code(src, includes, 'glsl'); diff --git a/src-testing/src/nodes/code/ExpressionNode.d.ts b/src-testing/src/nodes/code/ExpressionNode.d.ts new file mode 100644 index 000000000..ce5fc783b --- /dev/null +++ b/src-testing/src/nodes/code/ExpressionNode.d.ts @@ -0,0 +1,9 @@ +import TempNode from "../core/TempNode.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +export default class ExpressionNode extends TempNode { + snipped: string; /* sic */ + constructor(snipped?: string, nodeType?: string); +} + +export const expression: (snipped?: string, nodeType?: string) => ShaderNodeObject; diff --git a/src-testing/src/nodes/code/FunctionCallNode.d.ts b/src-testing/src/nodes/code/FunctionCallNode.d.ts new file mode 100644 index 000000000..7bf6d7360 --- /dev/null +++ b/src-testing/src/nodes/code/FunctionCallNode.d.ts @@ -0,0 +1,25 @@ +import Node from "../core/Node.js"; +import TempNode from "../core/TempNode.js"; +import { ProxiedObject, ShaderNodeObject } from "../tsl/TSLCore.js"; +import FunctionNode, { FunctionNodeArguments } from "./FunctionNode.js"; + +export default class FunctionCallNode

extends TempNode { + functionNode: FunctionNode

; + parameters: { [name: string]: Node }; + + constructor(functionNode?: FunctionNode

, parameters?: P); + + setParameters(parameters: P): this; + getParameters(): P; +} + +export const call:

( + functionNode?: FunctionNode

, + parameters?: ProxiedObject

, +) => ShaderNodeObject>; + +declare module "../tsl/TSLCore.js" { + interface NodeElements { + call: typeof call; + } +} diff --git a/src-testing/src/nodes/code/FunctionNode.ts b/src-testing/src/nodes/code/FunctionNode.ts new file mode 100644 index 000000000..54d8a5c54 --- /dev/null +++ b/src-testing/src/nodes/code/FunctionNode.ts @@ -0,0 +1,87 @@ +import CodeNode from './CodeNode.js'; +import { nodeObject } from '../tsl/TSLBase.js'; + +class FunctionNode extends CodeNode { + static get type() { + return 'FunctionNode'; + } + + constructor(code = '', includes = [], language = '') { + super(code, includes, language); + } + + getNodeType(builder) { + return this.getNodeFunction(builder).type; + } + + getInputs(builder) { + return this.getNodeFunction(builder).inputs; + } + + getNodeFunction(builder) { + const nodeData = builder.getDataFromNode(this); + + let nodeFunction = nodeData.nodeFunction; + + if (nodeFunction === undefined) { + nodeFunction = builder.parser.parseFunction(this.code); + + nodeData.nodeFunction = nodeFunction; + } + + return nodeFunction; + } + + generate(builder, output) { + super.generate(builder); + + const nodeFunction = this.getNodeFunction(builder); + + const name = nodeFunction.name; + const type = nodeFunction.type; + + const nodeCode = builder.getCodeFromNode(this, type); + + if (name !== '') { + // use a custom property name + + nodeCode.name = name; + } + + const propertyName = builder.getPropertyName(nodeCode); + + const code = this.getNodeFunction(builder).getCode(propertyName); + + nodeCode.code = code + '\n'; + + if (output === 'property') { + return propertyName; + } else { + return builder.format(`${propertyName}()`, type, output); + } + } +} + +export default FunctionNode; + +const nativeFn = (code, includes = [], language = '') => { + for (let i = 0; i < includes.length; i++) { + const include = includes[i]; + + // TSL Function: glslFn, wgslFn + + if (typeof include === 'function') { + includes[i] = include.functionNode; + } + } + + const functionNode = nodeObject(new FunctionNode(code, includes, language)); + + const fn = (...params) => functionNode.call(...params); + fn.functionNode = functionNode; + + return fn; +}; + +export const glslFn = (code, includes) => nativeFn(code, includes, 'glsl'); +export const wgslFn = (code, includes) => nativeFn(code, includes, 'wgsl'); diff --git a/src-testing/src/nodes/code/ScriptableNode.d.ts b/src-testing/src/nodes/code/ScriptableNode.d.ts new file mode 100644 index 000000000..7922afe12 --- /dev/null +++ b/src-testing/src/nodes/code/ScriptableNode.d.ts @@ -0,0 +1,22 @@ +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +declare class Resources extends Map { + get(key: string, callback?: ((...args: TArgs) => void) | null, ...params: TArgs): unknown; +} + +export const global: Resources; + +declare class ScriptableNode extends Node { + codeNode: Node | null; + parameters: Record; + + constructor(codeNode?: Node | null, parameters?: Record); +} + +export default ScriptableNode; + +export const scriptable: ( + codeNode?: NodeRepresentation | null, + parameters?: Record, +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/code/ScriptableValueNode.d.ts b/src-testing/src/nodes/code/ScriptableValueNode.d.ts new file mode 100644 index 000000000..eccec90c6 --- /dev/null +++ b/src-testing/src/nodes/code/ScriptableValueNode.d.ts @@ -0,0 +1,10 @@ +import Node from "../core/Node.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +declare class ScriptableValueNode extends Node { + constructor(value: unknown); +} + +export default ScriptableValueNode; + +export const scriptableValue: (value?: unknown) => ShaderNodeObject; diff --git a/src-testing/src/nodes/core/AssignNode.d.ts b/src-testing/src/nodes/core/AssignNode.d.ts new file mode 100644 index 000000000..a5628e76c --- /dev/null +++ b/src-testing/src/nodes/core/AssignNode.d.ts @@ -0,0 +1,18 @@ +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; +import Node from "./Node.js"; +import NodeBuilder from "./NodeBuilder.js"; +import TempNode from "./TempNode.js"; + +export default class AssignNode extends TempNode { + constructor(targetNode: Node, sourceNode: Node); + + needsSplitAssign(builder: NodeBuilder): boolean; +} + +export const assign: (targetNode: NodeRepresentation, sourceNode: NodeRepresentation) => ShaderNodeObject; + +declare module "../tsl/TSLCore.js" { + interface NodeElements { + assign: typeof assign; + } +} diff --git a/src-testing/src/nodes/core/AttributeNode.d.ts b/src-testing/src/nodes/core/AttributeNode.d.ts new file mode 100644 index 000000000..179f07b74 --- /dev/null +++ b/src-testing/src/nodes/core/AttributeNode.d.ts @@ -0,0 +1,16 @@ +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; +import Node from "./Node.js"; +import NodeBuilder from "./NodeBuilder.js"; + +export default class AttributeNode extends Node { + constructor(attributeName: string, nodeType?: string | null); + + setAttributeName(attributeName: string): this; + + getAttributeName(builder: NodeBuilder): string; +} + +export const attribute: ( + name: string, + nodeType?: string | null, +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/core/BypassNode.d.ts b/src-testing/src/nodes/core/BypassNode.d.ts new file mode 100644 index 000000000..5d152654d --- /dev/null +++ b/src-testing/src/nodes/core/BypassNode.d.ts @@ -0,0 +1,18 @@ +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; +import Node from "./Node.js"; + +export default class BypassNode extends Node { + isBypassNode: true; + outputNode: Node; + callNode: Node; + + constructor(returnNode: Node, callNode: Node); +} + +export const bypass: (returnNode: NodeRepresentation, callNode: NodeRepresentation) => ShaderNodeObject; + +declare module "../tsl/TSLCore.js" { + interface NodeElements { + bypass: typeof bypass; + } +} diff --git a/src-testing/src/nodes/core/CacheNode.d.ts b/src-testing/src/nodes/core/CacheNode.d.ts new file mode 100644 index 000000000..4b7f173d1 --- /dev/null +++ b/src-testing/src/nodes/core/CacheNode.d.ts @@ -0,0 +1,20 @@ +import { ShaderNodeObject } from "../tsl/TSLCore.js"; +import Node from "./Node.js"; +import NodeCache from "./NodeCache.js"; + +export default class CacheNode extends Node { + node: Node; + parent: boolean; + + readonly isCacheNode: true; + + constructor(node: Node, parent?: boolean); +} + +export const cache: (node: Node, cache?: NodeCache) => ShaderNodeObject; + +declare module "../tsl/TSLCore.js" { + interface NodeElements { + cache: typeof cache; + } +} diff --git a/src-testing/src/nodes/core/ConstNode.d.ts b/src-testing/src/nodes/core/ConstNode.d.ts new file mode 100644 index 000000000..f866b0c0c --- /dev/null +++ b/src-testing/src/nodes/core/ConstNode.d.ts @@ -0,0 +1,9 @@ +import InputNode from "./InputNode.js"; +import NodeBuilder from "./NodeBuilder.js"; + +export default class ConstNode extends InputNode { + isConstNode: true; + constructor(value: Value, nodeType?: string | null); + + generateConst(builder: NodeBuilder): string; +} diff --git a/src-testing/src/nodes/core/ContextNode.ts b/src-testing/src/nodes/core/ContextNode.ts new file mode 100644 index 000000000..32b8ac0af --- /dev/null +++ b/src-testing/src/nodes/core/ContextNode.ts @@ -0,0 +1,61 @@ +import Node from './Node.js'; +import { addMethodChaining, nodeProxy } from '../tsl/TSLCore.js'; + +class ContextNode extends Node { + static get type() { + return 'ContextNode'; + } + + constructor(node, value = {}) { + super(); + + this.isContextNode = true; + + this.node = node; + this.value = value; + } + + getScope() { + return this.node.getScope(); + } + + getNodeType(builder) { + return this.node.getNodeType(builder); + } + + analyze(builder) { + this.node.build(builder); + } + + setup(builder) { + const previousContext = builder.getContext(); + + builder.setContext({ ...builder.context, ...this.value }); + + const node = this.node.build(builder); + + builder.setContext(previousContext); + + return node; + } + + generate(builder, output) { + const previousContext = builder.getContext(); + + builder.setContext({ ...builder.context, ...this.value }); + + const snippet = this.node.build(builder, output); + + builder.setContext(previousContext); + + return snippet; + } +} + +export default ContextNode; + +export const context = /*@__PURE__*/ nodeProxy(ContextNode); +export const label = (node, name) => context(node, { label: name }); + +addMethodChaining('context', context); +addMethodChaining('label', label); diff --git a/src-testing/src/nodes/core/IndexNode.d.ts b/src-testing/src/nodes/core/IndexNode.d.ts new file mode 100644 index 000000000..ebaba50ae --- /dev/null +++ b/src-testing/src/nodes/core/IndexNode.d.ts @@ -0,0 +1,28 @@ +import { ShaderNodeObject } from "../tsl/TSLCore.js"; +import Node from "./Node.js"; + +export type IndexNodeScope = + | typeof IndexNode.VERTEX + | typeof IndexNode.INSTANCE + | typeof IndexNode.INVOCATION_LOCAL + | typeof IndexNode.DRAW; + +declare class IndexNode extends Node { + scope: IndexNodeScope; + + readonly isInstanceNode: true; + + constructor(scope: IndexNodeScope); + + static VERTEX: "vertex"; + static INSTANCE: "instance"; + static INVOCATION_LOCAL: "invocationLocal"; + static DRAW: "draw"; +} + +export default IndexNode; + +export const vertexIndex: ShaderNodeObject; +export const instanceIndex: ShaderNodeObject; +export const invocationLocalIndex: ShaderNodeObject; +export const drawIndex: ShaderNodeObject; diff --git a/src-testing/src/nodes/core/InputNode.ts b/src-testing/src/nodes/core/InputNode.ts new file mode 100644 index 000000000..07af45dc3 --- /dev/null +++ b/src-testing/src/nodes/core/InputNode.ts @@ -0,0 +1,67 @@ +import Node from './Node.js'; +import { getValueType, getValueFromType, arrayBufferToBase64 } from './NodeUtils.js'; + +class InputNode extends Node { + static get type() { + return 'InputNode'; + } + + constructor(value, nodeType = null) { + super(nodeType); + + this.isInputNode = true; + + this.value = value; + this.precision = null; + } + + getNodeType(/*builder*/) { + if (this.nodeType === null) { + return getValueType(this.value); + } + + return this.nodeType; + } + + getInputType(builder) { + return this.getNodeType(builder); + } + + setPrecision(precision) { + this.precision = precision; + + return this; + } + + serialize(data) { + super.serialize(data); + + data.value = this.value; + + if (this.value && this.value.toArray) data.value = this.value.toArray(); + + data.valueType = getValueType(this.value); + data.nodeType = this.nodeType; + + if (data.valueType === 'ArrayBuffer') data.value = arrayBufferToBase64(data.value); + + data.precision = this.precision; + } + + deserialize(data) { + super.deserialize(data); + + this.nodeType = data.nodeType; + this.value = Array.isArray(data.value) ? getValueFromType(data.valueType, ...data.value) : data.value; + + this.precision = data.precision || null; + + if (this.value && this.value.fromArray) this.value = this.value.fromArray(data.value); + } + + generate(/*builder, output*/) { + console.warn('Abstract function.'); + } +} + +export default InputNode; diff --git a/src-testing/src/nodes/core/LightingModel.d.ts b/src-testing/src/nodes/core/LightingModel.d.ts new file mode 100644 index 000000000..f64dd07db --- /dev/null +++ b/src-testing/src/nodes/core/LightingModel.d.ts @@ -0,0 +1,46 @@ +import Node from "./Node.js"; +import NodeBuilder from "./NodeBuilder.js"; +import StackNode from "./StackNode.js"; + +export interface LightingModelReflectedLight { + directDiffuse: Node; + directSpecular: Node; + indirectDiffuse: Node; + indirectSpecular: Node; +} + +export interface LightingModelDirectInput { + lightDirection: Node; + lightColor: Node; + reflectedLight: LightingModelReflectedLight; +} + +export interface LightingModelDirectRectAreaInput { + lightColor: Node; + lightPosition: Node; + halfWidth: Node; + halfHeight: Node; + reflectedLight: LightingModelReflectedLight; + ltc_1: Node; + ltc_2: Node; +} + +export interface LightingModelIndirectInput { + radiance: Node; + irradiance: Node; + iblIrradiance: Node; + ambientOcclusion: Node; + reflectedLight: LightingModelReflectedLight; + backdrop: Node; + backdropAlpha: Node; + outgoingLight: Node; +} + +export default class LightingModel { + start(input: LightingModelIndirectInput, stack: StackNode, builder: NodeBuilder): void; + finish(input: LightingModelIndirectInput, stack: StackNode, builder: NodeBuilder): void; + direct(input: LightingModelDirectInput, stack: StackNode, builder: NodeBuilder): void; + directRectArea(input: LightingModelDirectRectAreaInput, stack: StackNode, builder: NodeBuilder): void; + indirect(input: LightingModelIndirectInput, stack: StackNode, builder: NodeBuilder): void; + ambientOcclusion(input: LightingModelIndirectInput, stack: StackNode, builder: NodeBuilder): void; +} diff --git a/src-testing/src/nodes/core/MRTNode.d.ts b/src-testing/src/nodes/core/MRTNode.d.ts new file mode 100644 index 000000000..ef223da73 --- /dev/null +++ b/src-testing/src/nodes/core/MRTNode.d.ts @@ -0,0 +1,24 @@ +import { Texture } from "../../textures/Texture.js"; +import { Node } from "../Nodes.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; +import OutputStructNode from "./OutputStructNode.js"; + +export function getTextureIndex(textures: ReadonlyArray, name: string): number; + +declare class MRTNode extends OutputStructNode { + outputNodes: { [name: string]: Node }; + + readonly isMRTNode: true; + + constructor(outputNodes: { [name: string]: Node }); + + has(name: string): boolean; + + get(name: string): Node; + + merge(mrtNode: MRTNode): ShaderNodeObject; +} + +export default MRTNode; + +export const mrt: (outputNodes: { [name: string]: Node }) => ShaderNodeObject; diff --git a/src-testing/src/nodes/core/Node.ts b/src-testing/src/nodes/core/Node.ts new file mode 100644 index 000000000..2e54fce07 --- /dev/null +++ b/src-testing/src/nodes/core/Node.ts @@ -0,0 +1,401 @@ +import { NodeUpdateType } from './constants.js'; +import { getNodeChildren, getCacheKey } from './NodeUtils.js'; + +import { EventDispatcher } from '../../core/EventDispatcher.js'; +import { MathUtils } from '../../math/MathUtils.js'; + +let _nodeId = 0; + +class Node extends EventDispatcher { + static get type() { + return 'Node'; + } + + constructor(nodeType = null) { + super(); + + this.nodeType = nodeType; + + this.updateType = NodeUpdateType.NONE; + this.updateBeforeType = NodeUpdateType.NONE; + this.updateAfterType = NodeUpdateType.NONE; + + this.uuid = MathUtils.generateUUID(); + + this.version = 0; + + this._cacheKey = null; + this._cacheKeyVersion = 0; + + this.global = false; + + this.isNode = true; + + Object.defineProperty(this, 'id', { value: _nodeId++ }); + } + + set needsUpdate(value) { + if (value === true) { + this.version++; + } + } + + get type() { + return this.constructor.type; + } + + onUpdate(callback, updateType) { + this.updateType = updateType; + this.update = callback.bind(this.getSelf()); + + return this; + } + + onFrameUpdate(callback) { + return this.onUpdate(callback, NodeUpdateType.FRAME); + } + + onRenderUpdate(callback) { + return this.onUpdate(callback, NodeUpdateType.RENDER); + } + + onObjectUpdate(callback) { + return this.onUpdate(callback, NodeUpdateType.OBJECT); + } + + onReference(callback) { + this.updateReference = callback.bind(this.getSelf()); + + return this; + } + + getSelf() { + // Returns non-node object. + + return this.self || this; + } + + updateReference(/*state*/) { + return this; + } + + isGlobal(/*builder*/) { + return this.global; + } + + *getChildren() { + for (const { childNode } of getNodeChildren(this)) { + yield childNode; + } + } + + dispose() { + this.dispatchEvent({ type: 'dispose' }); + } + + traverse(callback) { + callback(this); + + for (const childNode of this.getChildren()) { + childNode.traverse(callback); + } + } + + getCacheKey(force = false) { + force = force || this.version !== this._cacheKeyVersion; + + if (force === true || this._cacheKey === null) { + this._cacheKey = getCacheKey(this, force); + this._cacheKeyVersion = this.version; + } + + return this._cacheKey; + } + + getScope() { + return this; + } + + getHash(/*builder*/) { + return this.uuid; + } + + getUpdateType() { + return this.updateType; + } + + getUpdateBeforeType() { + return this.updateBeforeType; + } + + getUpdateAfterType() { + return this.updateAfterType; + } + + getElementType(builder) { + const type = this.getNodeType(builder); + const elementType = builder.getElementType(type); + + return elementType; + } + + getNodeType(builder) { + const nodeProperties = builder.getNodeProperties(this); + + if (nodeProperties.outputNode) { + return nodeProperties.outputNode.getNodeType(builder); + } + + return this.nodeType; + } + + getShared(builder) { + const hash = this.getHash(builder); + const nodeFromHash = builder.getNodeFromHash(hash); + + return nodeFromHash || this; + } + + setup(builder) { + const nodeProperties = builder.getNodeProperties(this); + + let index = 0; + + for (const childNode of this.getChildren()) { + nodeProperties['node' + index++] = childNode; + } + + // return a outputNode if exists + return null; + } + + analyze(builder) { + const usageCount = builder.increaseUsage(this); + + if (usageCount === 1) { + // node flow children + + const nodeProperties = builder.getNodeProperties(this); + + for (const childNode of Object.values(nodeProperties)) { + if (childNode && childNode.isNode === true) { + childNode.build(builder); + } + } + } + } + + generate(builder, output) { + const { outputNode } = builder.getNodeProperties(this); + + if (outputNode && outputNode.isNode === true) { + return outputNode.build(builder, output); + } + } + + updateBefore(/*frame*/) { + console.warn('Abstract function.'); + } + + updateAfter(/*frame*/) { + console.warn('Abstract function.'); + } + + update(/*frame*/) { + console.warn('Abstract function.'); + } + + build(builder, output = null) { + const refNode = this.getShared(builder); + + if (this !== refNode) { + return refNode.build(builder, output); + } + + builder.addNode(this); + builder.addChain(this); + + /* Build stages expected results: + - "setup" -> Node + - "analyze" -> null + - "generate" -> String + */ + let result = null; + + const buildStage = builder.getBuildStage(); + + if (buildStage === 'setup') { + this.updateReference(builder); + + const properties = builder.getNodeProperties(this); + + if (properties.initialized !== true) { + const stackNodesBeforeSetup = builder.stack.nodes.length; + + properties.initialized = true; + properties.outputNode = this.setup(builder); + + if (properties.outputNode !== null && builder.stack.nodes.length !== stackNodesBeforeSetup) { + // !! no outputNode !! + //properties.outputNode = builder.stack; + } + + for (const childNode of Object.values(properties)) { + if (childNode && childNode.isNode === true) { + childNode.build(builder); + } + } + } + } else if (buildStage === 'analyze') { + this.analyze(builder); + } else if (buildStage === 'generate') { + const isGenerateOnce = this.generate.length === 1; + + if (isGenerateOnce) { + const type = this.getNodeType(builder); + const nodeData = builder.getDataFromNode(this); + + result = nodeData.snippet; + + if (result === undefined) { + result = this.generate(builder) || ''; + + nodeData.snippet = result; + } else if (nodeData.flowCodes !== undefined && builder.context.nodeBlock !== undefined) { + builder.addFlowCodeHierarchy(this, builder.context.nodeBlock); + } + + result = builder.format(result, type, output); + } else { + result = this.generate(builder, output) || ''; + } + } + + builder.removeChain(this); + builder.addSequentialNode(this); + + return result; + } + + getSerializeChildren() { + return getNodeChildren(this); + } + + serialize(json) { + const nodeChildren = this.getSerializeChildren(); + + const inputNodes = {}; + + for (const { property, index, childNode } of nodeChildren) { + if (index !== undefined) { + if (inputNodes[property] === undefined) { + inputNodes[property] = Number.isInteger(index) ? [] : {}; + } + + inputNodes[property][index] = childNode.toJSON(json.meta).uuid; + } else { + inputNodes[property] = childNode.toJSON(json.meta).uuid; + } + } + + if (Object.keys(inputNodes).length > 0) { + json.inputNodes = inputNodes; + } + } + + deserialize(json) { + if (json.inputNodes !== undefined) { + const nodes = json.meta.nodes; + + for (const property in json.inputNodes) { + if (Array.isArray(json.inputNodes[property])) { + const inputArray = []; + + for (const uuid of json.inputNodes[property]) { + inputArray.push(nodes[uuid]); + } + + this[property] = inputArray; + } else if (typeof json.inputNodes[property] === 'object') { + const inputObject = {}; + + for (const subProperty in json.inputNodes[property]) { + const uuid = json.inputNodes[property][subProperty]; + + inputObject[subProperty] = nodes[uuid]; + } + + this[property] = inputObject; + } else { + const uuid = json.inputNodes[property]; + + this[property] = nodes[uuid]; + } + } + } + } + + toJSON(meta) { + const { uuid, type } = this; + const isRoot = meta === undefined || typeof meta === 'string'; + + if (isRoot) { + meta = { + textures: {}, + images: {}, + nodes: {}, + }; + } + + // serialize + + let data = meta.nodes[uuid]; + + if (data === undefined) { + data = { + uuid, + type, + meta, + metadata: { + version: 4.6, + type: 'Node', + generator: 'Node.toJSON', + }, + }; + + if (isRoot !== true) meta.nodes[data.uuid] = data; + + this.serialize(data); + + delete data.meta; + } + + // TODO: Copied from Object3D.toJSON + + function extractFromCache(cache) { + const values = []; + + for (const key in cache) { + const data = cache[key]; + delete data.metadata; + values.push(data); + } + + return values; + } + + if (isRoot) { + const textures = extractFromCache(meta.textures); + const images = extractFromCache(meta.images); + const nodes = extractFromCache(meta.nodes); + + if (textures.length > 0) data.textures = textures; + if (images.length > 0) data.images = images; + if (nodes.length > 0) data.nodes = nodes; + } + + return data; + } +} + +export default Node; diff --git a/src-testing/src/nodes/core/NodeAttribute.ts b/src-testing/src/nodes/core/NodeAttribute.ts new file mode 100644 index 000000000..190fe8c51 --- /dev/null +++ b/src-testing/src/nodes/core/NodeAttribute.ts @@ -0,0 +1,11 @@ +class NodeAttribute { + constructor(name, type, node = null) { + this.isNodeAttribute = true; + + this.name = name; + this.type = type; + this.node = node; + } +} + +export default NodeAttribute; diff --git a/src-testing/src/nodes/core/NodeBuilder.ts b/src-testing/src/nodes/core/NodeBuilder.ts new file mode 100644 index 000000000..3003d1680 --- /dev/null +++ b/src-testing/src/nodes/core/NodeBuilder.ts @@ -0,0 +1,1208 @@ +import NodeUniform from './NodeUniform.js'; +import NodeAttribute from './NodeAttribute.js'; +import NodeVarying from './NodeVarying.js'; +import NodeVar from './NodeVar.js'; +import NodeCode from './NodeCode.js'; +import NodeCache from './NodeCache.js'; +import ParameterNode from './ParameterNode.js'; +import FunctionNode from '../code/FunctionNode.js'; +import NodeMaterial from '../../materials/nodes/NodeMaterial.js'; +import { NodeUpdateType, defaultBuildStages, shaderStages } from './constants.js'; + +import { + NumberNodeUniform, + Vector2NodeUniform, + Vector3NodeUniform, + Vector4NodeUniform, + ColorNodeUniform, + Matrix3NodeUniform, + Matrix4NodeUniform, +} from '../../renderers/common/nodes/NodeUniform.js'; + +import { stack } from './StackNode.js'; +import { getCurrentStack, setCurrentStack } from '../tsl/TSLBase.js'; + +import CubeRenderTarget from '../../renderers/common/CubeRenderTarget.js'; +import ChainMap from '../../renderers/common/ChainMap.js'; + +import PMREMGenerator from '../../renderers/common/extras/PMREMGenerator.js'; + +import BindGroup from '../../renderers/common/BindGroup.js'; + +import { REVISION } from '../../constants.js'; +import { RenderTarget } from '../../core/RenderTarget.js'; +import { Color } from '../../math/Color.js'; +import { Vector2 } from '../../math/Vector2.js'; +import { Vector3 } from '../../math/Vector3.js'; +import { Vector4 } from '../../math/Vector4.js'; +import { Float16BufferAttribute } from '../../core/BufferAttribute.js'; +import { + IntType, + UnsignedIntType, + LinearFilter, + LinearMipmapNearestFilter, + NearestMipmapLinearFilter, + LinearMipmapLinearFilter, +} from '../../constants.js'; + +const rendererCache = new WeakMap(); + +const typeFromLength = new Map([ + [2, 'vec2'], + [3, 'vec3'], + [4, 'vec4'], + [9, 'mat3'], + [16, 'mat4'], +]); + +const typeFromArray = new Map([ + [Int8Array, 'int'], + [Int16Array, 'int'], + [Int32Array, 'int'], + [Uint8Array, 'uint'], + [Uint16Array, 'uint'], + [Uint32Array, 'uint'], + [Float32Array, 'float'], +]); + +const toFloat = value => { + if (/e/g.test(value)) { + return String(value).replace(/\+/g, ''); + } else { + value = Number(value); + + return value + (value % 1 ? '' : '.0'); + } +}; + +class NodeBuilder { + constructor(object, renderer, parser) { + this.object = object; + this.material = (object && object.material) || null; + this.geometry = (object && object.geometry) || null; + this.renderer = renderer; + this.parser = parser; + this.scene = null; + this.camera = null; + + this.nodes = []; + this.sequentialNodes = []; + this.updateNodes = []; + this.updateBeforeNodes = []; + this.updateAfterNodes = []; + this.hashNodes = {}; + + this.monitor = null; + + this.lightsNode = null; + this.environmentNode = null; + this.fogNode = null; + + this.clippingContext = null; + + this.vertexShader = null; + this.fragmentShader = null; + this.computeShader = null; + + this.flowNodes = { vertex: [], fragment: [], compute: [] }; + this.flowCode = { vertex: '', fragment: '', compute: '' }; + this.uniforms = { vertex: [], fragment: [], compute: [], index: 0 }; + this.structs = { vertex: [], fragment: [], compute: [], index: 0 }; + this.bindings = { vertex: {}, fragment: {}, compute: {} }; + this.bindingsIndexes = {}; + this.bindGroups = null; + this.attributes = []; + this.bufferAttributes = []; + this.varyings = []; + this.codes = {}; + this.vars = {}; + this.flow = { code: '' }; + this.chaining = []; + this.stack = stack(); + this.stacks = []; + this.tab = '\t'; + + this.currentFunctionNode = null; + + this.context = { + material: this.material, + }; + + this.cache = new NodeCache(); + this.globalCache = this.cache; + + this.flowsData = new WeakMap(); + + this.shaderStage = null; + this.buildStage = null; + + this.useComparisonMethod = false; + } + + getBindGroupsCache() { + let bindGroupsCache = rendererCache.get(this.renderer); + + if (bindGroupsCache === undefined) { + bindGroupsCache = new ChainMap(); + + rendererCache.set(this.renderer, bindGroupsCache); + } + + return bindGroupsCache; + } + + createRenderTarget(width, height, options) { + return new RenderTarget(width, height, options); + } + + createCubeRenderTarget(size, options) { + return new CubeRenderTarget(size, options); + } + + createPMREMGenerator() { + // TODO: Move Materials.js to outside of the Nodes.js in order to remove this function and improve tree-shaking support + + return new PMREMGenerator(this.renderer); + } + + includes(node) { + return this.nodes.includes(node); + } + + _getBindGroup(groupName, bindings) { + const bindGroupsCache = this.getBindGroupsCache(); + + // + + const bindingsArray = []; + + let sharedGroup = true; + + for (const binding of bindings) { + bindingsArray.push(binding); + + sharedGroup = sharedGroup && binding.groupNode.shared !== true; + } + + // + + let bindGroup; + + if (sharedGroup) { + bindGroup = bindGroupsCache.get(bindingsArray); + + if (bindGroup === undefined) { + bindGroup = new BindGroup( + groupName, + bindingsArray, + this.bindingsIndexes[groupName].group, + bindingsArray, + ); + + bindGroupsCache.set(bindingsArray, bindGroup); + } + } else { + bindGroup = new BindGroup(groupName, bindingsArray, this.bindingsIndexes[groupName].group, bindingsArray); + } + + return bindGroup; + } + + getBindGroupArray(groupName, shaderStage) { + const bindings = this.bindings[shaderStage]; + + let bindGroup = bindings[groupName]; + + if (bindGroup === undefined) { + if (this.bindingsIndexes[groupName] === undefined) { + this.bindingsIndexes[groupName] = { binding: 0, group: Object.keys(this.bindingsIndexes).length }; + } + + bindings[groupName] = bindGroup = []; + } + + return bindGroup; + } + + getBindings() { + let bindingsGroups = this.bindGroups; + + if (bindingsGroups === null) { + const groups = {}; + const bindings = this.bindings; + + for (const shaderStage of shaderStages) { + for (const groupName in bindings[shaderStage]) { + const uniforms = bindings[shaderStage][groupName]; + + const groupUniforms = groups[groupName] || (groups[groupName] = []); + groupUniforms.push(...uniforms); + } + } + + bindingsGroups = []; + + for (const groupName in groups) { + const group = groups[groupName]; + + const bindingsGroup = this._getBindGroup(groupName, group); + + bindingsGroups.push(bindingsGroup); + } + + this.bindGroups = bindingsGroups; + } + + return bindingsGroups; + } + + sortBindingGroups() { + const bindingsGroups = this.getBindings(); + + bindingsGroups.sort((a, b) => a.bindings[0].groupNode.order - b.bindings[0].groupNode.order); + + for (let i = 0; i < bindingsGroups.length; i++) { + const bindingGroup = bindingsGroups[i]; + this.bindingsIndexes[bindingGroup.name].group = i; + + bindingGroup.index = i; + } + } + + setHashNode(node, hash) { + this.hashNodes[hash] = node; + } + + addNode(node) { + if (this.nodes.includes(node) === false) { + this.nodes.push(node); + + this.setHashNode(node, node.getHash(this)); + } + } + + addSequentialNode(node) { + if (this.sequentialNodes.includes(node) === false) { + this.sequentialNodes.push(node); + } + } + + buildUpdateNodes() { + for (const node of this.nodes) { + const updateType = node.getUpdateType(); + + if (updateType !== NodeUpdateType.NONE) { + this.updateNodes.push(node.getSelf()); + } + } + + for (const node of this.sequentialNodes) { + const updateBeforeType = node.getUpdateBeforeType(); + const updateAfterType = node.getUpdateAfterType(); + + if (updateBeforeType !== NodeUpdateType.NONE) { + this.updateBeforeNodes.push(node.getSelf()); + } + + if (updateAfterType !== NodeUpdateType.NONE) { + this.updateAfterNodes.push(node.getSelf()); + } + } + } + + get currentNode() { + return this.chaining[this.chaining.length - 1]; + } + + isFilteredTexture(texture) { + return ( + texture.magFilter === LinearFilter || + texture.magFilter === LinearMipmapNearestFilter || + texture.magFilter === NearestMipmapLinearFilter || + texture.magFilter === LinearMipmapLinearFilter || + texture.minFilter === LinearFilter || + texture.minFilter === LinearMipmapNearestFilter || + texture.minFilter === NearestMipmapLinearFilter || + texture.minFilter === LinearMipmapLinearFilter + ); + } + + addChain(node) { + /* + if ( this.chaining.indexOf( node ) !== - 1 ) { + + console.warn( 'Recursive node: ', node ); + + } + */ + + this.chaining.push(node); + } + + removeChain(node) { + const lastChain = this.chaining.pop(); + + if (lastChain !== node) { + throw new Error('NodeBuilder: Invalid node chaining!'); + } + } + + getMethod(method) { + return method; + } + + getNodeFromHash(hash) { + return this.hashNodes[hash]; + } + + addFlow(shaderStage, node) { + this.flowNodes[shaderStage].push(node); + + return node; + } + + setContext(context) { + this.context = context; + } + + getContext() { + return this.context; + } + + getSharedContext() { + const context = { ...this.context }; + + delete context.material; + + return this.context; + } + + setCache(cache) { + this.cache = cache; + } + + getCache() { + return this.cache; + } + + getCacheFromNode(node, parent = true) { + const data = this.getDataFromNode(node); + if (data.cache === undefined) data.cache = new NodeCache(parent ? this.getCache() : null); + + return data.cache; + } + + isAvailable(/*name*/) { + return false; + } + + getVertexIndex() { + console.warn('Abstract function.'); + } + + getInstanceIndex() { + console.warn('Abstract function.'); + } + + getDrawIndex() { + console.warn('Abstract function.'); + } + + getFrontFacing() { + console.warn('Abstract function.'); + } + + getFragCoord() { + console.warn('Abstract function.'); + } + + isFlipY() { + return false; + } + + increaseUsage(node) { + const nodeData = this.getDataFromNode(node); + nodeData.usageCount = nodeData.usageCount === undefined ? 1 : nodeData.usageCount + 1; + + return nodeData.usageCount; + } + + generateTexture(/* texture, textureProperty, uvSnippet */) { + console.warn('Abstract function.'); + } + + generateTextureLod(/* texture, textureProperty, uvSnippet, levelSnippet */) { + console.warn('Abstract function.'); + } + + generateConst(type, value = null) { + if (value === null) { + if (type === 'float' || type === 'int' || type === 'uint') value = 0; + else if (type === 'bool') value = false; + else if (type === 'color') value = new Color(); + else if (type === 'vec2') value = new Vector2(); + else if (type === 'vec3') value = new Vector3(); + else if (type === 'vec4') value = new Vector4(); + } + + if (type === 'float') return toFloat(value); + if (type === 'int') return `${Math.round(value)}`; + if (type === 'uint') return value >= 0 ? `${Math.round(value)}u` : '0u'; + if (type === 'bool') return value ? 'true' : 'false'; + if (type === 'color') + return `${this.getType('vec3')}( ${toFloat(value.r)}, ${toFloat(value.g)}, ${toFloat(value.b)} )`; + + const typeLength = this.getTypeLength(type); + + const componentType = this.getComponentType(type); + + const generateConst = value => this.generateConst(componentType, value); + + if (typeLength === 2) { + return `${this.getType(type)}( ${generateConst(value.x)}, ${generateConst(value.y)} )`; + } else if (typeLength === 3) { + return `${this.getType(type)}( ${generateConst(value.x)}, ${generateConst(value.y)}, ${generateConst(value.z)} )`; + } else if (typeLength === 4) { + return `${this.getType(type)}( ${generateConst(value.x)}, ${generateConst(value.y)}, ${generateConst(value.z)}, ${generateConst(value.w)} )`; + } else if (typeLength > 4 && value && (value.isMatrix3 || value.isMatrix4)) { + return `${this.getType(type)}( ${value.elements.map(generateConst).join(', ')} )`; + } else if (typeLength > 4) { + return `${this.getType(type)}()`; + } + + throw new Error(`NodeBuilder: Type '${type}' not found in generate constant attempt.`); + } + + getType(type) { + if (type === 'color') return 'vec3'; + + return type; + } + + hasGeometryAttribute(name) { + return this.geometry && this.geometry.getAttribute(name) !== undefined; + } + + getAttribute(name, type) { + const attributes = this.attributes; + + // find attribute + + for (const attribute of attributes) { + if (attribute.name === name) { + return attribute; + } + } + + // create a new if no exist + + const attribute = new NodeAttribute(name, type); + + attributes.push(attribute); + + return attribute; + } + + getPropertyName(node /*, shaderStage*/) { + return node.name; + } + + isVector(type) { + return /vec\d/.test(type); + } + + isMatrix(type) { + return /mat\d/.test(type); + } + + isReference(type) { + return ( + type === 'void' || + type === 'property' || + type === 'sampler' || + type === 'texture' || + type === 'cubeTexture' || + type === 'storageTexture' || + type === 'depthTexture' || + type === 'texture3D' + ); + } + + needsToWorkingColorSpace(/*texture*/) { + return false; + } + + getComponentTypeFromTexture(texture) { + const type = texture.type; + + if (texture.isDataTexture) { + if (type === IntType) return 'int'; + if (type === UnsignedIntType) return 'uint'; + } + + return 'float'; + } + + getElementType(type) { + if (type === 'mat2') return 'vec2'; + if (type === 'mat3') return 'vec3'; + if (type === 'mat4') return 'vec4'; + + return this.getComponentType(type); + } + + getComponentType(type) { + type = this.getVectorType(type); + + if (type === 'float' || type === 'bool' || type === 'int' || type === 'uint') return type; + + const componentType = /(b|i|u|)(vec|mat)([2-4])/.exec(type); + + if (componentType === null) return null; + + if (componentType[1] === 'b') return 'bool'; + if (componentType[1] === 'i') return 'int'; + if (componentType[1] === 'u') return 'uint'; + + return 'float'; + } + + getVectorType(type) { + if (type === 'color') return 'vec3'; + if (type === 'texture' || type === 'cubeTexture' || type === 'storageTexture' || type === 'texture3D') + return 'vec4'; + + return type; + } + + getTypeFromLength(length, componentType = 'float') { + if (length === 1) return componentType; + + const baseType = typeFromLength.get(length); + const prefix = componentType === 'float' ? '' : componentType[0]; + + return prefix + baseType; + } + + getTypeFromArray(array) { + return typeFromArray.get(array.constructor); + } + + getTypeFromAttribute(attribute) { + let dataAttribute = attribute; + + if (attribute.isInterleavedBufferAttribute) dataAttribute = attribute.data; + + const array = dataAttribute.array; + const itemSize = attribute.itemSize; + const normalized = attribute.normalized; + + let arrayType; + + if (!(attribute instanceof Float16BufferAttribute) && normalized !== true) { + arrayType = this.getTypeFromArray(array); + } + + return this.getTypeFromLength(itemSize, arrayType); + } + + getTypeLength(type) { + const vecType = this.getVectorType(type); + const vecNum = /vec([2-4])/.exec(vecType); + + if (vecNum !== null) return Number(vecNum[1]); + if (vecType === 'float' || vecType === 'bool' || vecType === 'int' || vecType === 'uint') return 1; + if (/mat2/.test(type) === true) return 4; + if (/mat3/.test(type) === true) return 9; + if (/mat4/.test(type) === true) return 16; + + return 0; + } + + getVectorFromMatrix(type) { + return type.replace('mat', 'vec'); + } + + changeComponentType(type, newComponentType) { + return this.getTypeFromLength(this.getTypeLength(type), newComponentType); + } + + getIntegerType(type) { + const componentType = this.getComponentType(type); + + if (componentType === 'int' || componentType === 'uint') return type; + + return this.changeComponentType(type, 'int'); + } + + addStack() { + this.stack = stack(this.stack); + + this.stacks.push(getCurrentStack() || this.stack); + setCurrentStack(this.stack); + + return this.stack; + } + + removeStack() { + const lastStack = this.stack; + this.stack = lastStack.parent; + + setCurrentStack(this.stacks.pop()); + + return lastStack; + } + + getDataFromNode(node, shaderStage = this.shaderStage, cache = null) { + cache = cache === null ? (node.isGlobal(this) ? this.globalCache : this.cache) : cache; + + let nodeData = cache.getData(node); + + if (nodeData === undefined) { + nodeData = {}; + + cache.setData(node, nodeData); + } + + if (nodeData[shaderStage] === undefined) nodeData[shaderStage] = {}; + + return nodeData[shaderStage]; + } + + getNodeProperties(node, shaderStage = 'any') { + const nodeData = this.getDataFromNode(node, shaderStage); + + return nodeData.properties || (nodeData.properties = { outputNode: null }); + } + + getBufferAttributeFromNode(node, type) { + const nodeData = this.getDataFromNode(node); + + let bufferAttribute = nodeData.bufferAttribute; + + if (bufferAttribute === undefined) { + const index = this.uniforms.index++; + + bufferAttribute = new NodeAttribute('nodeAttribute' + index, type, node); + + this.bufferAttributes.push(bufferAttribute); + + nodeData.bufferAttribute = bufferAttribute; + } + + return bufferAttribute; + } + + getStructTypeFromNode(node, shaderStage = this.shaderStage) { + const nodeData = this.getDataFromNode(node, shaderStage); + + if (nodeData.structType === undefined) { + const index = this.structs.index++; + + node.name = `StructType${index}`; + this.structs[shaderStage].push(node); + + nodeData.structType = node; + } + + return node; + } + + getUniformFromNode(node, type, shaderStage = this.shaderStage, name = null) { + const nodeData = this.getDataFromNode(node, shaderStage, this.globalCache); + + let nodeUniform = nodeData.uniform; + + if (nodeUniform === undefined) { + const index = this.uniforms.index++; + + nodeUniform = new NodeUniform(name || 'nodeUniform' + index, type, node); + + this.uniforms[shaderStage].push(nodeUniform); + + nodeData.uniform = nodeUniform; + } + + return nodeUniform; + } + + getVarFromNode(node, name = null, type = node.getNodeType(this), shaderStage = this.shaderStage) { + const nodeData = this.getDataFromNode(node, shaderStage); + + let nodeVar = nodeData.variable; + + if (nodeVar === undefined) { + const vars = this.vars[shaderStage] || (this.vars[shaderStage] = []); + + if (name === null) name = 'nodeVar' + vars.length; + + nodeVar = new NodeVar(name, type); + + vars.push(nodeVar); + + nodeData.variable = nodeVar; + } + + return nodeVar; + } + + getVaryingFromNode(node, name = null, type = node.getNodeType(this)) { + const nodeData = this.getDataFromNode(node, 'any'); + + let nodeVarying = nodeData.varying; + + if (nodeVarying === undefined) { + const varyings = this.varyings; + const index = varyings.length; + + if (name === null) name = 'nodeVarying' + index; + + nodeVarying = new NodeVarying(name, type); + + varyings.push(nodeVarying); + + nodeData.varying = nodeVarying; + } + + return nodeVarying; + } + + getCodeFromNode(node, type, shaderStage = this.shaderStage) { + const nodeData = this.getDataFromNode(node); + + let nodeCode = nodeData.code; + + if (nodeCode === undefined) { + const codes = this.codes[shaderStage] || (this.codes[shaderStage] = []); + const index = codes.length; + + nodeCode = new NodeCode('nodeCode' + index, type); + + codes.push(nodeCode); + + nodeData.code = nodeCode; + } + + return nodeCode; + } + + addFlowCodeHierarchy(node, nodeBlock) { + const { flowCodes, flowCodeBlock } = this.getDataFromNode(node); + + let needsFlowCode = true; + let nodeBlockHierarchy = nodeBlock; + + while (nodeBlockHierarchy) { + if (flowCodeBlock.get(nodeBlockHierarchy) === true) { + needsFlowCode = false; + break; + } + + nodeBlockHierarchy = this.getDataFromNode(nodeBlockHierarchy).parentNodeBlock; + } + + if (needsFlowCode) { + for (const flowCode of flowCodes) { + this.addLineFlowCode(flowCode); + } + } + } + + addLineFlowCodeBlock(node, code, nodeBlock) { + const nodeData = this.getDataFromNode(node); + const flowCodes = nodeData.flowCodes || (nodeData.flowCodes = []); + const codeBlock = nodeData.flowCodeBlock || (nodeData.flowCodeBlock = new WeakMap()); + + flowCodes.push(code); + codeBlock.set(nodeBlock, true); + } + + addLineFlowCode(code, node = null) { + if (code === '') return this; + + if (node !== null && this.context.nodeBlock) { + this.addLineFlowCodeBlock(node, code, this.context.nodeBlock); + } + + code = this.tab + code; + + if (!/;\s*$/.test(code)) { + code = code + ';\n'; + } + + this.flow.code += code; + + return this; + } + + addFlowCode(code) { + this.flow.code += code; + + return this; + } + + addFlowTab() { + this.tab += '\t'; + + return this; + } + + removeFlowTab() { + this.tab = this.tab.slice(0, -1); + + return this; + } + + getFlowData(node /*, shaderStage*/) { + return this.flowsData.get(node); + } + + flowNode(node) { + const output = node.getNodeType(this); + + const flowData = this.flowChildNode(node, output); + + this.flowsData.set(node, flowData); + + return flowData; + } + + buildFunctionNode(shaderNode) { + const fn = new FunctionNode(); + + const previous = this.currentFunctionNode; + + this.currentFunctionNode = fn; + + fn.code = this.buildFunctionCode(shaderNode); + + this.currentFunctionNode = previous; + + return fn; + } + + flowShaderNode(shaderNode) { + const layout = shaderNode.layout; + + const inputs = { + [Symbol.iterator]() { + let index = 0; + const values = Object.values(this); + return { + next: () => ({ + value: values[index], + done: index++ >= values.length, + }), + }; + }, + }; + + for (const input of layout.inputs) { + inputs[input.name] = new ParameterNode(input.type, input.name); + } + + // + + shaderNode.layout = null; + + const callNode = shaderNode.call(inputs); + const flowData = this.flowStagesNode(callNode, layout.type); + + shaderNode.layout = layout; + + return flowData; + } + + flowStagesNode(node, output = null) { + const previousFlow = this.flow; + const previousVars = this.vars; + const previousCache = this.cache; + const previousBuildStage = this.buildStage; + const previousStack = this.stack; + + const flow = { + code: '', + }; + + this.flow = flow; + this.vars = {}; + this.cache = new NodeCache(); + this.stack = stack(); + + for (const buildStage of defaultBuildStages) { + this.setBuildStage(buildStage); + + flow.result = node.build(this, output); + } + + flow.vars = this.getVars(this.shaderStage); + + this.flow = previousFlow; + this.vars = previousVars; + this.cache = previousCache; + this.stack = previousStack; + + this.setBuildStage(previousBuildStage); + + return flow; + } + + getFunctionOperator() { + return null; + } + + flowChildNode(node, output = null) { + const previousFlow = this.flow; + + const flow = { + code: '', + }; + + this.flow = flow; + + flow.result = node.build(this, output); + + this.flow = previousFlow; + + return flow; + } + + flowNodeFromShaderStage(shaderStage, node, output = null, propertyName = null) { + const previousShaderStage = this.shaderStage; + + this.setShaderStage(shaderStage); + + const flowData = this.flowChildNode(node, output); + + if (propertyName !== null) { + flowData.code += `${this.tab + propertyName} = ${flowData.result};\n`; + } + + this.flowCode[shaderStage] = this.flowCode[shaderStage] + flowData.code; + + this.setShaderStage(previousShaderStage); + + return flowData; + } + + getAttributesArray() { + return this.attributes.concat(this.bufferAttributes); + } + + getAttributes(/*shaderStage*/) { + console.warn('Abstract function.'); + } + + getVaryings(/*shaderStage*/) { + console.warn('Abstract function.'); + } + + getVar(type, name) { + return `${this.getType(type)} ${name}`; + } + + getVars(shaderStage) { + let snippet = ''; + + const vars = this.vars[shaderStage]; + + if (vars !== undefined) { + for (const variable of vars) { + snippet += `${this.getVar(variable.type, variable.name)}; `; + } + } + + return snippet; + } + + getUniforms(/*shaderStage*/) { + console.warn('Abstract function.'); + } + + getCodes(shaderStage) { + const codes = this.codes[shaderStage]; + + let code = ''; + + if (codes !== undefined) { + for (const nodeCode of codes) { + code += nodeCode.code + '\n'; + } + } + + return code; + } + + getHash() { + return this.vertexShader + this.fragmentShader + this.computeShader; + } + + setShaderStage(shaderStage) { + this.shaderStage = shaderStage; + } + + getShaderStage() { + return this.shaderStage; + } + + setBuildStage(buildStage) { + this.buildStage = buildStage; + } + + getBuildStage() { + return this.buildStage; + } + + buildCode() { + console.warn('Abstract function.'); + } + + build() { + const { object, material, renderer } = this; + + if (material !== null) { + let nodeMaterial = renderer.library.fromMaterial(material); + + if (nodeMaterial === null) { + console.error(`NodeMaterial: Material "${material.type}" is not compatible.`); + + nodeMaterial = new NodeMaterial(); + } + + nodeMaterial.build(this); + } else { + this.addFlow('compute', object); + } + + // setup() -> stage 1: create possible new nodes and returns an output reference node + // analyze() -> stage 2: analyze nodes to possible optimization and validation + // generate() -> stage 3: generate shader + + for (const buildStage of defaultBuildStages) { + this.setBuildStage(buildStage); + + if (this.context.vertex && this.context.vertex.isNode) { + this.flowNodeFromShaderStage('vertex', this.context.vertex); + } + + for (const shaderStage of shaderStages) { + this.setShaderStage(shaderStage); + + const flowNodes = this.flowNodes[shaderStage]; + + for (const node of flowNodes) { + if (buildStage === 'generate') { + this.flowNode(node); + } else { + node.build(this); + } + } + } + } + + this.setBuildStage(null); + this.setShaderStage(null); + + // stage 4: build code for a specific output + + this.buildCode(); + this.buildUpdateNodes(); + + return this; + } + + getNodeUniform(uniformNode, type) { + if (type === 'float' || type === 'int' || type === 'uint') return new NumberNodeUniform(uniformNode); + if (type === 'vec2' || type === 'ivec2' || type === 'uvec2') return new Vector2NodeUniform(uniformNode); + if (type === 'vec3' || type === 'ivec3' || type === 'uvec3') return new Vector3NodeUniform(uniformNode); + if (type === 'vec4' || type === 'ivec4' || type === 'uvec4') return new Vector4NodeUniform(uniformNode); + if (type === 'color') return new ColorNodeUniform(uniformNode); + if (type === 'mat3') return new Matrix3NodeUniform(uniformNode); + if (type === 'mat4') return new Matrix4NodeUniform(uniformNode); + + throw new Error(`Uniform "${type}" not declared.`); + } + + createNodeMaterial(type = 'NodeMaterial') { + // @deprecated, r168 + + throw new Error(`THREE.NodeBuilder: createNodeMaterial() was deprecated. Use new ${type}() instead.`); + } + + format(snippet, fromType, toType) { + fromType = this.getVectorType(fromType); + toType = this.getVectorType(toType); + + if (fromType === toType || toType === null || this.isReference(toType)) { + return snippet; + } + + const fromTypeLength = this.getTypeLength(fromType); + const toTypeLength = this.getTypeLength(toType); + + if (fromTypeLength === 16 && toTypeLength === 9) { + return `${this.getType(toType)}(${snippet}[0].xyz, ${snippet}[1].xyz, ${snippet}[2].xyz)`; + } + + if (fromTypeLength === 9 && toTypeLength === 4) { + return `${this.getType(toType)}(${snippet}[0].xy, ${snippet}[1].xy)`; + } + + if (fromTypeLength > 4) { + // fromType is matrix-like + + // @TODO: ignore for now + + return snippet; + } + + if (toTypeLength > 4 || toTypeLength === 0) { + // toType is matrix-like or unknown + + // @TODO: ignore for now + + return snippet; + } + + if (fromTypeLength === toTypeLength) { + return `${this.getType(toType)}( ${snippet} )`; + } + + if (fromTypeLength > toTypeLength) { + return this.format( + `${snippet}.${'xyz'.slice(0, toTypeLength)}`, + this.getTypeFromLength(toTypeLength, this.getComponentType(fromType)), + toType, + ); + } + + if (toTypeLength === 4 && fromTypeLength > 1) { + // toType is vec4-like + + return `${this.getType(toType)}( ${this.format(snippet, fromType, 'vec3')}, 1.0 )`; + } + + if (fromTypeLength === 2) { + // fromType is vec2-like and toType is vec3-like + + return `${this.getType(toType)}( ${this.format(snippet, fromType, 'vec2')}, 0.0 )`; + } + + if (fromTypeLength === 1 && toTypeLength > 1 && fromType !== this.getComponentType(toType)) { + // fromType is float-like + + // convert a number value to vector type, e.g: + // vec3( 1u ) -> vec3( float( 1u ) ) + + snippet = `${this.getType(this.getComponentType(toType))}( ${snippet} )`; + } + + return `${this.getType(toType)}( ${snippet} )`; // fromType is float-like + } + + getSignature() { + return `// Three.js r${REVISION} - Node System\n`; + } +} + +export default NodeBuilder; diff --git a/src-testing/src/nodes/core/NodeCache.ts b/src-testing/src/nodes/core/NodeCache.ts new file mode 100644 index 000000000..ad72d50c5 --- /dev/null +++ b/src-testing/src/nodes/core/NodeCache.ts @@ -0,0 +1,26 @@ +let id = 0; + +class NodeCache { + constructor(parent = null) { + this.id = id++; + this.nodesData = new WeakMap(); + + this.parent = parent; + } + + getData(node) { + let data = this.nodesData.get(node); + + if (data === undefined && this.parent !== null) { + data = this.parent.getData(node); + } + + return data; + } + + setData(node, data) { + this.nodesData.set(node, data); + } +} + +export default NodeCache; diff --git a/src-testing/src/nodes/core/NodeCode.ts b/src-testing/src/nodes/core/NodeCode.ts new file mode 100644 index 000000000..2ee509037 --- /dev/null +++ b/src-testing/src/nodes/core/NodeCode.ts @@ -0,0 +1,11 @@ +class NodeCode { + constructor(name, type, code = '') { + this.name = name; + this.type = type; + this.code = code; + + Object.defineProperty(this, 'isNodeCode', { value: true }); + } +} + +export default NodeCode; diff --git a/src-testing/src/nodes/core/NodeFrame.ts b/src-testing/src/nodes/core/NodeFrame.ts new file mode 100644 index 000000000..ee64620ca --- /dev/null +++ b/src-testing/src/nodes/core/NodeFrame.ts @@ -0,0 +1,127 @@ +import { NodeUpdateType } from './constants.js'; + +class NodeFrame { + constructor() { + this.time = 0; + this.deltaTime = 0; + + this.frameId = 0; + this.renderId = 0; + + this.startTime = null; + + this.updateMap = new WeakMap(); + this.updateBeforeMap = new WeakMap(); + this.updateAfterMap = new WeakMap(); + + this.renderer = null; + this.material = null; + this.camera = null; + this.object = null; + this.scene = null; + } + + _getMaps(referenceMap, nodeRef) { + let maps = referenceMap.get(nodeRef); + + if (maps === undefined) { + maps = { + renderMap: new WeakMap(), + frameMap: new WeakMap(), + }; + + referenceMap.set(nodeRef, maps); + } + + return maps; + } + + updateBeforeNode(node) { + const updateType = node.getUpdateBeforeType(); + const reference = node.updateReference(this); + + if (updateType === NodeUpdateType.FRAME) { + const { frameMap } = this._getMaps(this.updateBeforeMap, reference); + + if (frameMap.get(reference) !== this.frameId) { + if (node.updateBefore(this) !== false) { + frameMap.set(reference, this.frameId); + } + } + } else if (updateType === NodeUpdateType.RENDER) { + const { renderMap } = this._getMaps(this.updateBeforeMap, reference); + + if (renderMap.get(reference) !== this.renderId) { + if (node.updateBefore(this) !== false) { + renderMap.set(reference, this.renderId); + } + } + } else if (updateType === NodeUpdateType.OBJECT) { + node.updateBefore(this); + } + } + + updateAfterNode(node) { + const updateType = node.getUpdateAfterType(); + const reference = node.updateReference(this); + + if (updateType === NodeUpdateType.FRAME) { + const { frameMap } = this._getMaps(this.updateAfterMap, reference); + + if (frameMap.get(reference) !== this.frameId) { + if (node.updateAfter(this) !== false) { + frameMap.set(reference, this.frameId); + } + } + } else if (updateType === NodeUpdateType.RENDER) { + const { renderMap } = this._getMaps(this.updateAfterMap, reference); + + if (renderMap.get(reference) !== this.renderId) { + if (node.updateAfter(this) !== false) { + renderMap.set(reference, this.renderId); + } + } + } else if (updateType === NodeUpdateType.OBJECT) { + node.updateAfter(this); + } + } + + updateNode(node) { + const updateType = node.getUpdateType(); + const reference = node.updateReference(this); + + if (updateType === NodeUpdateType.FRAME) { + const { frameMap } = this._getMaps(this.updateMap, reference); + + if (frameMap.get(reference) !== this.frameId) { + if (node.update(this) !== false) { + frameMap.set(reference, this.frameId); + } + } + } else if (updateType === NodeUpdateType.RENDER) { + const { renderMap } = this._getMaps(this.updateMap, reference); + + if (renderMap.get(reference) !== this.renderId) { + if (node.update(this) !== false) { + renderMap.set(reference, this.renderId); + } + } + } else if (updateType === NodeUpdateType.OBJECT) { + node.update(this); + } + } + + update() { + this.frameId++; + + if (this.lastTime === undefined) this.lastTime = performance.now(); + + this.deltaTime = (performance.now() - this.lastTime) / 1000; + + this.lastTime = performance.now(); + + this.time += this.deltaTime; + } +} + +export default NodeFrame; diff --git a/src-testing/src/nodes/core/NodeFunction.ts b/src-testing/src/nodes/core/NodeFunction.ts new file mode 100644 index 000000000..d05afb5e6 --- /dev/null +++ b/src-testing/src/nodes/core/NodeFunction.ts @@ -0,0 +1,16 @@ +class NodeFunction { + constructor(type, inputs, name = '', precision = '') { + this.type = type; + this.inputs = inputs; + this.name = name; + this.precision = precision; + } + + getCode(/*name = this.name*/) { + console.warn('Abstract function.'); + } +} + +NodeFunction.isNodeFunction = true; + +export default NodeFunction; diff --git a/src-testing/src/nodes/core/NodeFunctionInput.d.ts b/src-testing/src/nodes/core/NodeFunctionInput.d.ts new file mode 100644 index 000000000..a8231d126 --- /dev/null +++ b/src-testing/src/nodes/core/NodeFunctionInput.d.ts @@ -0,0 +1,7 @@ +export default class NodeFunctionInput { + isNodeFunctionInput: true; + count: null | number; + qualifier: string; + isConst: boolean; + constructor(type: string, name: string, count?: number, qualifier?: string, isConst?: boolean); +} diff --git a/src-testing/src/nodes/core/NodeParser.ts b/src-testing/src/nodes/core/NodeParser.ts new file mode 100644 index 000000000..9849452f1 --- /dev/null +++ b/src-testing/src/nodes/core/NodeParser.ts @@ -0,0 +1,7 @@ +class NodeParser { + parseFunction(/*source*/) { + console.warn('Abstract function.'); + } +} + +export default NodeParser; diff --git a/src-testing/src/nodes/core/NodeUniform.ts b/src-testing/src/nodes/core/NodeUniform.ts new file mode 100644 index 000000000..ca43958fc --- /dev/null +++ b/src-testing/src/nodes/core/NodeUniform.ts @@ -0,0 +1,27 @@ +class NodeUniform { + constructor(name, type, node) { + this.isNodeUniform = true; + + this.name = name; + this.type = type; + this.node = node.getSelf(); + } + + get value() { + return this.node.value; + } + + set value(val) { + this.node.value = val; + } + + get id() { + return this.node.id; + } + + get groupNode() { + return this.node.groupNode; + } +} + +export default NodeUniform; diff --git a/src-testing/src/nodes/core/NodeUtils.ts b/src-testing/src/nodes/core/NodeUtils.ts new file mode 100644 index 000000000..7ebac01f9 --- /dev/null +++ b/src-testing/src/nodes/core/NodeUtils.ts @@ -0,0 +1,171 @@ +import { Color } from '../../math/Color.js'; +import { Matrix3 } from '../../math/Matrix3.js'; +import { Matrix4 } from '../../math/Matrix4.js'; +import { Vector2 } from '../../math/Vector2.js'; +import { Vector3 } from '../../math/Vector3.js'; +import { Vector4 } from '../../math/Vector4.js'; + +// cyrb53 (c) 2018 bryc (github.com/bryc). License: Public domain. Attribution appreciated. +// A fast and simple 64-bit (or 53-bit) string hash function with decent collision resistance. +// Largely inspired by MurmurHash2/3, but with a focus on speed/simplicity. +// See https://stackoverflow.com/questions/7616461/generate-a-hash-from-string-in-javascript/52171480#52171480 +// https://github.com/bryc/code/blob/master/jshash/experimental/cyrb53.js +function cyrb53(value, seed = 0) { + let h1 = 0xdeadbeef ^ seed, + h2 = 0x41c6ce57 ^ seed; + + if (value instanceof Array) { + for (let i = 0, val; i < value.length; i++) { + val = value[i]; + h1 = Math.imul(h1 ^ val, 2654435761); + h2 = Math.imul(h2 ^ val, 1597334677); + } + } else { + for (let i = 0, ch; i < value.length; i++) { + ch = value.charCodeAt(i); + h1 = Math.imul(h1 ^ ch, 2654435761); + h2 = Math.imul(h2 ^ ch, 1597334677); + } + } + + h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507); + h1 ^= Math.imul(h2 ^ (h2 >>> 13), 3266489909); + h2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507); + h2 ^= Math.imul(h1 ^ (h1 >>> 13), 3266489909); + + return 4294967296 * (2097151 & h2) + (h1 >>> 0); +} + +export const hashString = str => cyrb53(str); +export const hashArray = array => cyrb53(array); +export const hash = (...params) => cyrb53(params); + +export function getCacheKey(object, force = false) { + const values = []; + + if (object.isNode === true) { + values.push(object.id); + object = object.getSelf(); + } + + for (const { property, childNode } of getNodeChildren(object)) { + values.push(values, cyrb53(property.slice(0, -4)), childNode.getCacheKey(force)); + } + + return cyrb53(values); +} + +export function* getNodeChildren(node, toJSON = false) { + for (const property in node) { + // Ignore private properties. + if (property.startsWith('_') === true) continue; + + const object = node[property]; + + if (Array.isArray(object) === true) { + for (let i = 0; i < object.length; i++) { + const child = object[i]; + + if (child && (child.isNode === true || (toJSON && typeof child.toJSON === 'function'))) { + yield { property, index: i, childNode: child }; + } + } + } else if (object && object.isNode === true) { + yield { property, childNode: object }; + } else if (typeof object === 'object') { + for (const subProperty in object) { + const child = object[subProperty]; + + if (child && (child.isNode === true || (toJSON && typeof child.toJSON === 'function'))) { + yield { property, index: subProperty, childNode: child }; + } + } + } + } +} + +export function getValueType(value) { + if (value === undefined || value === null) return null; + + const typeOf = typeof value; + + if (value.isNode === true) { + return 'node'; + } else if (typeOf === 'number') { + return 'float'; + } else if (typeOf === 'boolean') { + return 'bool'; + } else if (typeOf === 'string') { + return 'string'; + } else if (typeOf === 'function') { + return 'shader'; + } else if (value.isVector2 === true) { + return 'vec2'; + } else if (value.isVector3 === true) { + return 'vec3'; + } else if (value.isVector4 === true) { + return 'vec4'; + } else if (value.isMatrix3 === true) { + return 'mat3'; + } else if (value.isMatrix4 === true) { + return 'mat4'; + } else if (value.isColor === true) { + return 'color'; + } else if (value instanceof ArrayBuffer) { + return 'ArrayBuffer'; + } + + return null; +} + +export function getValueFromType(type, ...params) { + const last4 = type ? type.slice(-4) : undefined; + + if (params.length === 1) { + // ensure same behaviour as in NodeBuilder.format() + + if (last4 === 'vec2') params = [params[0], params[0]]; + else if (last4 === 'vec3') params = [params[0], params[0], params[0]]; + else if (last4 === 'vec4') params = [params[0], params[0], params[0], params[0]]; + } + + if (type === 'color') { + return new Color(...params); + } else if (last4 === 'vec2') { + return new Vector2(...params); + } else if (last4 === 'vec3') { + return new Vector3(...params); + } else if (last4 === 'vec4') { + return new Vector4(...params); + } else if (last4 === 'mat3') { + return new Matrix3(...params); + } else if (last4 === 'mat4') { + return new Matrix4(...params); + } else if (type === 'bool') { + return params[0] || false; + } else if (type === 'float' || type === 'int' || type === 'uint') { + return params[0] || 0; + } else if (type === 'string') { + return params[0] || ''; + } else if (type === 'ArrayBuffer') { + return base64ToArrayBuffer(params[0]); + } + + return null; +} + +export function arrayBufferToBase64(arrayBuffer) { + let chars = ''; + + const array = new Uint8Array(arrayBuffer); + + for (let i = 0; i < array.length; i++) { + chars += String.fromCharCode(array[i]); + } + + return btoa(chars); +} + +export function base64ToArrayBuffer(base64) { + return Uint8Array.from(atob(base64), c => c.charCodeAt(0)).buffer; +} diff --git a/src-testing/src/nodes/core/NodeVar.ts b/src-testing/src/nodes/core/NodeVar.ts new file mode 100644 index 000000000..e6e935b31 --- /dev/null +++ b/src-testing/src/nodes/core/NodeVar.ts @@ -0,0 +1,10 @@ +class NodeVar { + constructor(name, type) { + this.isNodeVar = true; + + this.name = name; + this.type = type; + } +} + +export default NodeVar; diff --git a/src-testing/src/nodes/core/NodeVarying.ts b/src-testing/src/nodes/core/NodeVarying.ts new file mode 100644 index 000000000..a14823628 --- /dev/null +++ b/src-testing/src/nodes/core/NodeVarying.ts @@ -0,0 +1,13 @@ +import NodeVar from './NodeVar.js'; + +class NodeVarying extends NodeVar { + constructor(name, type) { + super(name, type); + + this.needsInterpolation = false; + + this.isNodeVarying = true; + } +} + +export default NodeVarying; diff --git a/src-testing/src/nodes/core/OutputStructNode.d.ts b/src-testing/src/nodes/core/OutputStructNode.d.ts new file mode 100644 index 000000000..5a7fc6e7b --- /dev/null +++ b/src-testing/src/nodes/core/OutputStructNode.d.ts @@ -0,0 +1,12 @@ +import { ShaderNodeObject } from "../tsl/TSLCore.js"; +import Node from "./Node.js"; + +export default class OutputStructNode extends Node { + members: Node[]; + + readonly isOutputStructNode: true; + + constructor(...members: Node[]); +} + +export const outputStruct: (...members: Node[]) => ShaderNodeObject; diff --git a/src-testing/src/nodes/core/ParameterNode.d.ts b/src-testing/src/nodes/core/ParameterNode.d.ts new file mode 100644 index 000000000..02629dbf5 --- /dev/null +++ b/src-testing/src/nodes/core/ParameterNode.d.ts @@ -0,0 +1,12 @@ +import { ShaderNodeObject } from "../tsl/TSLCore.js"; +import PropertyNode from "./PropertyNode.js"; + +declare class ParameterNode extends PropertyNode { + readonly isParameterNode: true; + + constructor(nodeType: string, name?: string | null); +} + +export default ParameterNode; + +export const parameter: (type: string, name?: string | null) => ShaderNodeObject; diff --git a/src-testing/src/nodes/core/PropertyNode.d.ts b/src-testing/src/nodes/core/PropertyNode.d.ts new file mode 100644 index 000000000..b365d107b --- /dev/null +++ b/src-testing/src/nodes/core/PropertyNode.d.ts @@ -0,0 +1,43 @@ +import { ShaderNodeObject } from "../tsl/TSLCore.js"; +import Node from "./Node.js"; + +export default class PropertyNode extends Node { + name: string | null; + varying: boolean; + + readonly isPropertyNode: true; + + constructor(nodeType?: string | null, name?: string | null, varying?: boolean); +} + +export const property: (type?: string | null, name?: string | null) => ShaderNodeObject; +export const varyingProperty: (type?: string | null, name?: string | null) => ShaderNodeObject; + +export const diffuseColor: ShaderNodeObject; +export const emissive: ShaderNodeObject; +export const roughness: ShaderNodeObject; +export const metalness: ShaderNodeObject; +export const clearcoat: ShaderNodeObject; +export const clearcoatRoughness: ShaderNodeObject; +export const sheen: ShaderNodeObject; +export const sheenRoughness: ShaderNodeObject; +export const iridescence: ShaderNodeObject; +export const iridescenceIOR: ShaderNodeObject; +export const iridescenceThickness: ShaderNodeObject; +export const alphaT: ShaderNodeObject; +export const anisotropy: ShaderNodeObject; +export const anisotropyT: ShaderNodeObject; +export const anisotropyB: ShaderNodeObject; +export const specularColor: ShaderNodeObject; +export const specularF90: ShaderNodeObject; +export const shininess: ShaderNodeObject; +export const output: ShaderNodeObject; +export const dashSize: ShaderNodeObject; +export const gapSize: ShaderNodeObject; +export const pointWidth: ShaderNodeObject; +export const ior: ShaderNodeObject; +export const transmission: ShaderNodeObject; +export const thickness: ShaderNodeObject; +export const attenuationDistance: ShaderNodeObject; +export const attenuationColor: ShaderNodeObject; +export const dispersion: ShaderNodeObject; diff --git a/src-testing/src/nodes/core/StackNode.ts b/src-testing/src/nodes/core/StackNode.ts new file mode 100644 index 000000000..79313afad --- /dev/null +++ b/src-testing/src/nodes/core/StackNode.ts @@ -0,0 +1,89 @@ +import Node from './Node.js'; +import { select } from '../math/ConditionalNode.js'; +import { ShaderNode, nodeProxy, getCurrentStack, setCurrentStack } from '../tsl/TSLBase.js'; + +class StackNode extends Node { + static get type() { + return 'StackNode'; + } + + constructor(parent = null) { + super(); + + this.nodes = []; + this.outputNode = null; + + this.parent = parent; + + this._currentCond = null; + + this.isStackNode = true; + } + + getNodeType(builder) { + return this.outputNode ? this.outputNode.getNodeType(builder) : 'void'; + } + + add(node) { + this.nodes.push(node); + + return this; + } + + If(boolNode, method) { + const methodNode = new ShaderNode(method); + this._currentCond = select(boolNode, methodNode); + + return this.add(this._currentCond); + } + + ElseIf(boolNode, method) { + const methodNode = new ShaderNode(method); + const ifNode = select(boolNode, methodNode); + + this._currentCond.elseNode = ifNode; + this._currentCond = ifNode; + + return this; + } + + Else(method) { + this._currentCond.elseNode = new ShaderNode(method); + + return this; + } + + build(builder, ...params) { + const previousStack = getCurrentStack(); + + setCurrentStack(this); + + for (const node of this.nodes) { + node.build(builder, 'void'); + } + + setCurrentStack(previousStack); + + return this.outputNode ? this.outputNode.build(builder, ...params) : super.build(builder, ...params); + } + + // + + else(...params) { + // @deprecated, r168 + + console.warn('TSL.StackNode: .else() has been renamed to .Else().'); + return this.Else(...params); + } + + elseif(...params) { + // @deprecated, r168 + + console.warn('TSL.StackNode: .elseif() has been renamed to .ElseIf().'); + return this.ElseIf(...params); + } +} + +export default StackNode; + +export const stack = /*@__PURE__*/ nodeProxy(StackNode); diff --git a/src-testing/src/nodes/core/StructTypeNode.ts b/src-testing/src/nodes/core/StructTypeNode.ts new file mode 100644 index 000000000..acadb07e1 --- /dev/null +++ b/src-testing/src/nodes/core/StructTypeNode.ts @@ -0,0 +1,20 @@ +import Node from './Node.js'; + +class StructTypeNode extends Node { + static get type() { + return 'StructTypeNode'; + } + + constructor(types) { + super(); + + this.types = types; + this.isStructTypeNode = true; + } + + getMemberTypes() { + return this.types; + } +} + +export default StructTypeNode; diff --git a/src-testing/src/nodes/core/TempNode.d.ts b/src-testing/src/nodes/core/TempNode.d.ts new file mode 100644 index 000000000..367f5ade1 --- /dev/null +++ b/src-testing/src/nodes/core/TempNode.d.ts @@ -0,0 +1,10 @@ +import Node from "./Node.js"; +import NodeBuilder from "./NodeBuilder.js"; + +export default class TempNode extends Node { + isTempNode: true; + + constructor(type: string | null); + + hasDependencies(builder: NodeBuilder): boolean; +} diff --git a/src-testing/src/nodes/core/UniformGroup.d.ts b/src-testing/src/nodes/core/UniformGroup.d.ts new file mode 100644 index 000000000..60339877b --- /dev/null +++ b/src-testing/src/nodes/core/UniformGroup.d.ts @@ -0,0 +1,7 @@ +export default class UniformGroup { + name: string; + + readonly isUniformGroup: true; + + constructor(name: string); +} diff --git a/src-testing/src/nodes/core/UniformGroupNode.ts b/src-testing/src/nodes/core/UniformGroupNode.ts new file mode 100644 index 000000000..829fd3ee8 --- /dev/null +++ b/src-testing/src/nodes/core/UniformGroupNode.ts @@ -0,0 +1,47 @@ +import Node from './Node.js'; + +class UniformGroupNode extends Node { + static get type() { + return 'UniformGroupNode'; + } + + constructor(name, shared = false, order = 1) { + super('string'); + + this.name = name; + this.version = 0; + + this.shared = shared; + this.order = order; + this.isUniformGroup = true; + } + + set needsUpdate(value) { + if (value === true) this.version++; + } + + serialize(data) { + super.serialize(data); + + data.name = this.name; + data.version = this.version; + data.shared = this.shared; + } + + deserialize(data) { + super.deserialize(data); + + this.name = data.name; + this.version = data.version; + this.shared = data.shared; + } +} + +export default UniformGroupNode; + +export const uniformGroup = name => new UniformGroupNode(name); +export const sharedUniformGroup = (name, order = 0) => new UniformGroupNode(name, true, order); + +export const frameGroup = /*@__PURE__*/ sharedUniformGroup('frame'); +export const renderGroup = /*@__PURE__*/ sharedUniformGroup('render'); +export const objectGroup = /*@__PURE__*/ uniformGroup('object'); diff --git a/src-testing/src/nodes/core/UniformNode.ts b/src-testing/src/nodes/core/UniformNode.ts new file mode 100644 index 000000000..ec9fa9aee --- /dev/null +++ b/src-testing/src/nodes/core/UniformNode.ts @@ -0,0 +1,91 @@ +import InputNode from './InputNode.js'; +import { objectGroup } from './UniformGroupNode.js'; +import { nodeObject, getConstNodeType } from '../tsl/TSLCore.js'; + +class UniformNode extends InputNode { + static get type() { + return 'UniformNode'; + } + + constructor(value, nodeType = null) { + super(value, nodeType); + + this.isUniformNode = true; + + this.name = ''; + this.groupNode = objectGroup; + } + + label(name) { + this.name = name; + + return this; + } + + setGroup(group) { + this.groupNode = group; + + return this; + } + + getGroup() { + return this.groupNode; + } + + getUniformHash(builder) { + return this.getHash(builder); + } + + onUpdate(callback, updateType) { + const self = this.getSelf(); + + callback = callback.bind(self); + + return super.onUpdate(frame => { + const value = callback(frame, self); + + if (value !== undefined) { + this.value = value; + } + }, updateType); + } + + generate(builder, output) { + const type = this.getNodeType(builder); + + const hash = this.getUniformHash(builder); + + let sharedNode = builder.getNodeFromHash(hash); + + if (sharedNode === undefined) { + builder.setHashNode(this, hash); + + sharedNode = this; + } + + const sharedNodeType = sharedNode.getInputType(builder); + + const nodeUniform = builder.getUniformFromNode( + sharedNode, + sharedNodeType, + builder.shaderStage, + this.name || builder.context.label, + ); + const propertyName = builder.getPropertyName(nodeUniform); + + if (builder.context.label !== undefined) delete builder.context.label; + + return builder.format(propertyName, type, output); + } +} + +export default UniformNode; + +export const uniform = (arg1, arg2) => { + const nodeType = getConstNodeType(arg2 || arg1); + + // @TODO: get ConstNode from .traverse() in the future + const value = arg1 && arg1.isNode === true ? (arg1.node && arg1.node.value) || arg1.value : arg1; + + return nodeObject(new UniformNode(value, nodeType)); +}; diff --git a/src-testing/src/nodes/core/VarNode.d.ts b/src-testing/src/nodes/core/VarNode.d.ts new file mode 100644 index 000000000..327df482a --- /dev/null +++ b/src-testing/src/nodes/core/VarNode.d.ts @@ -0,0 +1,31 @@ +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; +import Node from "./Node.js"; + +export default class VarNode extends Node { + node: Node; + name: string | null; + + readonly isVarNode: true; + + constructor(node: Node, name?: string | null); +} + +declare module "../tsl/TSLCore.js" { + interface NodeElements { + toVar: (node: NodeRepresentation, name?: string | null) => ShaderNodeObject; + } +} + +/** + * @deprecated Use ".toVar()" instead. + */ +export const temp: (node: NodeRepresentation, name?: string | null) => ShaderNodeObject; + +declare module "../tsl/TSLCore.js" { + interface NodeElements { + /** + * @deprecated Use ".toVar()" instead. + */ + temp: typeof temp; + } +} diff --git a/src-testing/src/nodes/core/VaryingNode.d.ts b/src-testing/src/nodes/core/VaryingNode.d.ts new file mode 100644 index 000000000..f10077ce0 --- /dev/null +++ b/src-testing/src/nodes/core/VaryingNode.d.ts @@ -0,0 +1,21 @@ +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; +import Node from "./Node.js"; +import NodeBuilder from "./NodeBuilder.js"; +import NodeVarying from "./NodeVarying.js"; + +export default class VaryingNode extends Node { + node: Node; + name: string | null; + + constructor(node: Node, name?: string | null); + + setupVarying(builder: NodeBuilder): NodeVarying; +} + +export const varying: (node: NodeRepresentation, name?: string) => ShaderNodeObject; + +declare module "../tsl/TSLCore.js" { + interface NodeElements { + varying: typeof varying; + } +} diff --git a/src-testing/src/nodes/core/constants.ts b/src-testing/src/nodes/core/constants.ts new file mode 100644 index 000000000..3b01a9a6d --- /dev/null +++ b/src-testing/src/nodes/core/constants.ts @@ -0,0 +1,28 @@ +export const NodeShaderStage = { + VERTEX: 'vertex', + FRAGMENT: 'fragment', +}; + +export const NodeUpdateType = { + NONE: 'none', + FRAME: 'frame', + RENDER: 'render', + OBJECT: 'object', +}; + +export const NodeType = { + BOOLEAN: 'bool', + INTEGER: 'int', + FLOAT: 'float', + VECTOR2: 'vec2', + VECTOR3: 'vec3', + VECTOR4: 'vec4', + MATRIX2: 'mat2', + MATRIX3: 'mat3', + MATRIX4: 'mat4', +}; + +export const defaultShaderStages = ['fragment', 'vertex']; +export const defaultBuildStages = ['setup', 'analyze', 'generate']; +export const shaderStages = [...defaultShaderStages, 'compute']; +export const vectorComponents = ['x', 'y', 'z', 'w']; diff --git a/src-testing/src/nodes/display/BlendMode.d.ts b/src-testing/src/nodes/display/BlendMode.d.ts new file mode 100644 index 000000000..1f2d23991 --- /dev/null +++ b/src-testing/src/nodes/display/BlendMode.d.ts @@ -0,0 +1,10 @@ +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +export const burn: (base: NodeRepresentation, blend: NodeRepresentation) => ShaderNodeObject; + +export const dodge: (base: NodeRepresentation, blend: NodeRepresentation) => ShaderNodeObject; + +export const screen: (base: NodeRepresentation, blend: NodeRepresentation) => ShaderNodeObject; + +export const overlay: (base: NodeRepresentation, blend: NodeRepresentation) => ShaderNodeObject; diff --git a/src-testing/src/nodes/display/BumpMapNode.d.ts b/src-testing/src/nodes/display/BumpMapNode.d.ts new file mode 100644 index 000000000..726f55685 --- /dev/null +++ b/src-testing/src/nodes/display/BumpMapNode.d.ts @@ -0,0 +1,16 @@ +import TempNode from "../core/TempNode.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +declare class BumpMapNode extends TempNode { + textureNode: Node; + scaleNode: Node | null; + + constructor(textureNode: Node, scaleNode?: Node | null); +} + +export default BumpMapNode; + +export const bumpMap: ( + textureNode: NodeRepresentation, + scaleNode?: NodeRepresentation | null, +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/display/ColorAdjustment.d.ts b/src-testing/src/nodes/display/ColorAdjustment.d.ts new file mode 100644 index 000000000..4de024be7 --- /dev/null +++ b/src-testing/src/nodes/display/ColorAdjustment.d.ts @@ -0,0 +1,56 @@ +import Node from "../core/Node.js"; +import MathNode from "../math/MathNode.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +export const grayscale: (color: NodeRepresentation) => ShaderNodeObject; + +export const saturation: ( + color: NodeRepresentation, + adjustment?: NodeRepresentation, +) => ShaderNodeObject; + +export const vibrance: ( + color: NodeRepresentation, + adjustment?: NodeRepresentation, +) => ShaderNodeObject; + +export const hue: ( + color: NodeRepresentation, + adjustment?: NodeRepresentation, +) => ShaderNodeObject; + +export const luminance: ( + color: NodeRepresentation, + luminanceCoefficients?: NodeRepresentation, +) => ShaderNodeObject; + +export const threshold: (color: NodeRepresentation, thershold: NodeRepresentation) => ShaderNodeObject; + +/** + * Color Decision List (CDL) v1.2 + * + * Compact representation of color grading information, defined by slope, offset, power, and saturation. The CDL should + * be typically be given input in a log space (such as LogC, ACEScc, or AgX Log), and will return output in the same + * space. Output may require clamping >=0. + * + * References: + * - ASC CDL v1.2 + * - https://blender.stackexchange.com/a/55239/43930 + * - https://docs.acescentral.com/specifications/acescc/ + * + * @param color Input (-Infinity < input < +Infinity) + * @param slope Slope (0 ≤ slope < +Infinity) + * @param offset Offset (-Infinity < offset < +Infinity; typically -1 < offset < 1) + * @param power Power (0 < power < +Infinity) + * @param saturation Saturation (0 ≤ saturation < +Infinity; typically 0 ≤ saturation < 4) + * @param luminanceCoefficients Luminance coefficients for saturation term, typically Rec. 709 + * @return Output, -Infinity < output < +Infinity + */ +export const cdl: ( + color: NodeRepresentation, + slope?: NodeRepresentation, + offset?: NodeRepresentation, + power?: NodeRepresentation, + saturation?: NodeRepresentation, + luminanceCoefficients?: NodeRepresentation, +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/display/ColorSpaceFunctions.d.ts b/src-testing/src/nodes/display/ColorSpaceFunctions.d.ts new file mode 100644 index 000000000..a4bd01216 --- /dev/null +++ b/src-testing/src/nodes/display/ColorSpaceFunctions.d.ts @@ -0,0 +1,6 @@ +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +export const sRGBTransferEOTF: (color: NodeRepresentation) => ShaderNodeObject; + +export const sRGBTransferOETF: (color: NodeRepresentation) => ShaderNodeObject; diff --git a/src-testing/src/nodes/display/ColorSpaceNode.d.ts b/src-testing/src/nodes/display/ColorSpaceNode.d.ts new file mode 100644 index 000000000..c0de945da --- /dev/null +++ b/src-testing/src/nodes/display/ColorSpaceNode.d.ts @@ -0,0 +1,60 @@ +import { LinearSRGBColorSpace, SRGBColorSpace } from "../../constants.js"; +import Node from "../core/Node.js"; +import NodeBuilder from "../core/NodeBuilder.js"; +import TempNode from "../core/TempNode.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +export type WorkingOrOutputColorSpace = "WorkingColorSpace" | "OutputColorSpace"; + +export type ColorSpaceMethod = "LinearTosRGB" | "sRGBToLinear" | "LinearToLinear" | "sRGBTosRGB"; + +export function getColorSpaceMethod( + source: typeof LinearSRGBColorSpace | typeof SRGBColorSpace, + target: typeof LinearSRGBColorSpace | typeof SRGBColorSpace, +): ColorSpaceMethod; + +export default class ColorSpaceNode extends TempNode { + colorNode: Node; + source: string; + target: string; + + constructor( + colorNode: Node, + source: string, + target: string, + ); + + resolveColorSpace(nodeBuilder: NodeBuilder, colorSpace: WorkingOrOutputColorSpace): string; +} + +export const toOutputColorSpace: ( + node: NodeRepresentation, +) => ShaderNodeObject; +export const toWorkingColorSpace: ( + node: NodeRepresentation, +) => ShaderNodeObject; + +export const workingToColorSpace: ( + node: NodeRepresentation, + colorSpace: string, +) => ShaderNodeObject; +export const colorSpaceToWorking: ( + node: NodeRepresentation, + colorSpace: string, +) => ShaderNodeObject; + +export const convertColorSpace: ( + node: NodeRepresentation, + sourceColorSpace: string, + targetColorSpace: string, +) => ShaderNodeObject; + +declare module "../tsl/TSLCore.js" { + interface NodeElements { + toOutputColorSpace: typeof toOutputColorSpace; + toWorkingColorSpace: typeof toWorkingColorSpace; + + workingToColorSpace: typeof workingToColorSpace; + colorSpaceToWorking: typeof colorSpaceToWorking; + } +} diff --git a/src-testing/src/nodes/display/FrontFacingNode.d.ts b/src-testing/src/nodes/display/FrontFacingNode.d.ts new file mode 100644 index 000000000..f550ecacf --- /dev/null +++ b/src-testing/src/nodes/display/FrontFacingNode.d.ts @@ -0,0 +1,12 @@ +import Node from "../core/Node.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +declare class FrontFacingNode extends Node { + isFrontFacingNode: true; + constructor(); +} + +export default FrontFacingNode; + +export const frontFacing: ShaderNodeObject; +export const faceDirection: ShaderNodeObject; diff --git a/src-testing/src/nodes/display/NormalMapNode.d.ts b/src-testing/src/nodes/display/NormalMapNode.d.ts new file mode 100644 index 000000000..d06459502 --- /dev/null +++ b/src-testing/src/nodes/display/NormalMapNode.d.ts @@ -0,0 +1,17 @@ +import { NormalMapTypes } from "../../constants.js"; +import Node from "../core/Node.js"; +import TempNode from "../core/TempNode.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +declare class NormalMapNode extends TempNode { + node: Node; + scaleNode: Node | null; + + normalMapType: NormalMapTypes; + + constructor(node: Node, scaleNode?: Node | null); +} + +export default NormalMapNode; + +export const normalMap: (node: Node, scaleNode?: Node) => ShaderNodeObject; diff --git a/src-testing/src/nodes/display/PassNode.d.ts b/src-testing/src/nodes/display/PassNode.d.ts new file mode 100644 index 000000000..97bad417f --- /dev/null +++ b/src-testing/src/nodes/display/PassNode.d.ts @@ -0,0 +1,71 @@ +import { Camera } from "../../cameras/Camera.js"; +import { RenderTarget, RenderTargetOptions } from "../../core/RenderTarget.js"; +import { Scene } from "../../scenes/Scene.js"; +import { Texture } from "../../textures/Texture.js"; +import TextureNode from "../accessors/TextureNode.js"; +import MRTNode from "../core/MRTNode.js"; +import Node from "../core/Node.js"; +import TempNode from "../core/TempNode.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +declare class PassTextureNode extends TextureNode { + passNode: PassNode; + + constructor(passNode: PassNode, texture: Texture); +} + +declare class PassMultipleTextureNode extends PassTextureNode { + textureName: string; + previousTexture: boolean; + + constructor(passNode: PassNode, textureName: string, previousTexture?: boolean); + + updateTexture(): void; +} + +declare class PassNode extends TempNode { + scope: PassNodeScope; + scene: Scene; + camera: Camera; + + renderTarget: RenderTarget; + + readonly isPassNode: true; + + constructor(scope: PassNodeScope, scene: Scene, camera: Camera, options?: RenderTargetOptions); + + setMRT(mrt: MRTNode | null): this; + + getMRT(): MRTNode | null; + + getTexture(name: string): Texture; + + getPreviousTexture(name: string): Texture; + + toggleTexture(name: string): void; + + getTextureNode(name?: string): ShaderNodeObject; + + getPreviousTextureNode(name?: string): ShaderNodeObject; + + getViewZNode(name?: string): ShaderNodeObject; + + getLinearDepthNode(name?: string): ShaderNodeObject; + + setSize(width: number, height: number): void; + + setPixelRatio(pixelRatio: number): void; + + dispose(): void; + + static COLOR: "color"; + static DEPTH: "depth"; +} + +export type PassNodeScope = typeof PassNode.COLOR | typeof PassNode.DEPTH; + +export default PassNode; + +export const pass: (scene: Scene, camera: Camera, options?: RenderTargetOptions) => ShaderNodeObject; +export const passTexture: (pass: PassNode, texture: Texture) => ShaderNodeObject; +export const depthPass: (scene: Scene, camera: Camera) => ShaderNodeObject; diff --git a/src-testing/src/nodes/display/PosterizeNode.d.ts b/src-testing/src/nodes/display/PosterizeNode.d.ts new file mode 100644 index 000000000..17eb0fe52 --- /dev/null +++ b/src-testing/src/nodes/display/PosterizeNode.d.ts @@ -0,0 +1,14 @@ +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +export default class PosterizeNode extends Node { + sourceNode: Node; + stepsNode: Node; + + constructor(sourceNode: Node, stepsNode: Node); +} + +export const posterize: ( + sourceNode: NodeRepresentation, + stepsNode: NodeRepresentation, +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/display/RenderOutputNode.d.ts b/src-testing/src/nodes/display/RenderOutputNode.d.ts new file mode 100644 index 000000000..b7edad754 --- /dev/null +++ b/src-testing/src/nodes/display/RenderOutputNode.d.ts @@ -0,0 +1,28 @@ +import { ToneMapping } from "../../constants.js"; +import Node from "../core/Node.js"; +import TempNode from "../core/TempNode.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +declare class RenderOutputNode extends TempNode { + colorNode: Node; + toneMapping: ToneMapping | null; + outputColorSpace: string | null; + + readonly isRenderOutput: true; + + constructor(colorNode: Node, toneMapping?: ToneMapping | null, outputColorSpace?: string | null); +} + +export default RenderOutputNode; + +export const renderOutput: ( + color: NodeRepresentation, + toneMapping?: ToneMapping | null, + outputColorSpace?: string | null, +) => ShaderNodeObject; + +declare module "../tsl/TSLCore.js" { + interface NodeElements { + renderOutput: typeof renderOutput; + } +} diff --git a/src-testing/src/nodes/display/ScreenNode.d.ts b/src-testing/src/nodes/display/ScreenNode.d.ts new file mode 100644 index 000000000..f9ed102fc --- /dev/null +++ b/src-testing/src/nodes/display/ScreenNode.d.ts @@ -0,0 +1,48 @@ +import Node from "../core/Node.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +export type ScreenNodeScope = + | typeof ScreenNode.COORDINATE + | typeof ScreenNode.VIEWPORT + | typeof ScreenNode.SIZE + | typeof ScreenNode.UV; + +declare class ScreenNode extends Node { + scope: ScreenNodeScope; + + readonly isViewportNode: true; + + constructor(scope: ScreenNodeScope); + + static COORDINATE: "coordinate"; + static VIEWPORT: "viewport"; + static SIZE: "size"; + static UV: "uv"; +} + +export default ScreenNode; + +// Screen + +export const screenUV: ShaderNodeObject; +export const screenSize: ShaderNodeObject; +export const screenCoordinate: ShaderNodeObject; + +// Viewport + +export const viewport: ShaderNodeObject; +export const viewportSize: ShaderNodeObject; +export const viewportCoordinate: ShaderNodeObject; +export const viewportUV: ShaderNodeObject; + +// Deprecated + +/** + * @deprecated "viewportTopLeft" is deprecated. Use "viewportUV" instead. + */ +export const viewportTopLeft: ShaderNodeObject; + +/** + * @deprecated "viewportBottomLeft" is deprecated. Use "viewportUV.flipY()" instead. + */ +export const viewportBottomLeft: ShaderNodeObject; diff --git a/src-testing/src/nodes/display/ToneMappingFunctions.d.ts b/src-testing/src/nodes/display/ToneMappingFunctions.d.ts new file mode 100644 index 000000000..b972d6b6f --- /dev/null +++ b/src-testing/src/nodes/display/ToneMappingFunctions.d.ts @@ -0,0 +1,14 @@ +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +export const linearToneMapping: (color: NodeRepresentation, exposure: NodeRepresentation) => ShaderNodeObject; + +export const reinhardToneMapping: (color: NodeRepresentation, exposure: NodeRepresentation) => ShaderNodeObject; + +export const cineonToneMapping: (color: NodeRepresentation, exposure: NodeRepresentation) => ShaderNodeObject; + +export const acesFilmicToneMapping: (color: NodeRepresentation, exposure: NodeRepresentation) => ShaderNodeObject; + +export const agxToneMapping: (color: NodeRepresentation, exposure: NodeRepresentation) => ShaderNodeObject; + +export const neutralToneMapping: (color: NodeRepresentation, exposure: NodeRepresentation) => ShaderNodeObject; diff --git a/src-testing/src/nodes/display/ToneMappingNode.d.ts b/src-testing/src/nodes/display/ToneMappingNode.d.ts new file mode 100644 index 000000000..e4fdf9cf6 --- /dev/null +++ b/src-testing/src/nodes/display/ToneMappingNode.d.ts @@ -0,0 +1,32 @@ +import { ToneMapping } from "../../constants.js"; +import RendererReferenceNode from "../accessors/RendererReferenceNode.js"; +import Node from "../core/Node.js"; +import TempNode from "../core/TempNode.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +declare class ToneMappingNode extends TempNode { + toneMapping: ToneMapping; + exposureNode: Node; + colorNode: Node | null; + + constructor(toneMapping: ToneMapping, exposureNode?: Node, colorNode?: Node | null); +} + +export default ToneMappingNode; + +export const toneMapping: ( + mapping: ToneMapping, + exposure: NodeRepresentation, + color?: NodeRepresentation, +) => ShaderNodeObject; +export const toneMappingExposure: ShaderNodeObject; + +declare module "../tsl/TSLCore.js" { + interface NodeElements { + toneMapping: ( + color: NodeRepresentation, + mapping?: NodeRepresentation, + exposure?: NodeRepresentation, + ) => ShaderNodeObject; + } +} diff --git a/src-testing/src/nodes/display/ToonOutlinePassNode.d.ts b/src-testing/src/nodes/display/ToonOutlinePassNode.d.ts new file mode 100644 index 000000000..fe556b505 --- /dev/null +++ b/src-testing/src/nodes/display/ToonOutlinePassNode.d.ts @@ -0,0 +1,24 @@ +import { Camera } from "../../cameras/Camera.js"; +import { Color } from "../../math/Color.js"; +import { Scene } from "../../scenes/Scene.js"; +import Node from "../core/Node.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; +import PassNode from "./PassNode.js"; + +declare class ToonOutlinePassNode extends PassNode { + colorNode: Node; + thicknessNode: Node; + alphaNode: Node; + + constructor(scene: Scene, camera: Camera, colorNode: Node, thicknessNode: Node, alphaNode: Node); +} + +export default ToonOutlinePassNode; + +export const toonOutlinePass: ( + scene: Scene, + camera: Camera, + color?: Color, + thickness?: number, + alpha?: number, +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/display/ViewportDepthNode.d.ts b/src-testing/src/nodes/display/ViewportDepthNode.d.ts new file mode 100644 index 000000000..c741caba9 --- /dev/null +++ b/src-testing/src/nodes/display/ViewportDepthNode.d.ts @@ -0,0 +1,36 @@ +import Node from "../core/Node.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +declare class ViewportDepthNode extends Node { + scope: ViewportDepthNodeScope; + valueNode: Node; + + readonly isViewportDepthNode: true; + + constructor(scope: ViewportDepthNodeScope, valueNode?: Node | null); + + static DEPTH_BASE: "depthBase"; + static DEPTH: "depth"; + static LINEAR_DEPTH: "linearDepth"; +} + +export type ViewportDepthNodeScope = + | typeof ViewportDepthNode.DEPTH_BASE + | typeof ViewportDepthNode.DEPTH + | typeof ViewportDepthNode.LINEAR_DEPTH; + +export default ViewportDepthNode; + +export const viewZToOrthographicDepth: (viewZ: Node, near: Node, far: Node) => Node; + +export const orthographicDepthToViewZ: (depth: Node, near: Node, far: Node) => Node; + +export const viewZToPerspectiveDepth: (viewZ: Node, near: Node, far: Node) => Node; + +export const perspectiveDepthToViewZ: (depth: Node, near: Node, far: Node) => Node; + +export const perspectiveDepthToLogarithmicDepth: (perspectiveW: Node, near: Node, far: Node) => Node; + +export const depth: ShaderNodeObject; +export const linearDepth: (valueNode?: Node | null) => ShaderNodeObject; +export const viewportLinearDepth: ShaderNodeObject; diff --git a/src-testing/src/nodes/display/ViewportDepthTextureNode.d.ts b/src-testing/src/nodes/display/ViewportDepthTextureNode.d.ts new file mode 100644 index 000000000..7c1102e45 --- /dev/null +++ b/src-testing/src/nodes/display/ViewportDepthTextureNode.d.ts @@ -0,0 +1,14 @@ +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; +import ViewportTextureNode from "./ViewportTextureNode.js"; + +declare class ViewportDepthTextureNode extends ViewportTextureNode { + constructor(uvNode?: Node, levelNode?: Node | null); +} + +export default ViewportDepthTextureNode; + +export const viewportDepthTexture: ( + uvNode?: NodeRepresentation, + levelNode?: NodeRepresentation, +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/display/ViewportSharedTextureNode.d.ts b/src-testing/src/nodes/display/ViewportSharedTextureNode.d.ts new file mode 100644 index 000000000..307bfbde5 --- /dev/null +++ b/src-testing/src/nodes/display/ViewportSharedTextureNode.d.ts @@ -0,0 +1,14 @@ +import Node from "../core/Node.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; +import ViewportTextureNode from "./ViewportTextureNode.js"; + +declare class ViewportSharedTextureNode extends ViewportTextureNode { + constructor(uvNode?: Node, levelNode?: Node | null); +} + +export default ViewportSharedTextureNode; + +export const viewportSharedTexture: ( + uvNode?: Node, + levelNode?: Node | null, +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/display/ViewportTextureNode.d.ts b/src-testing/src/nodes/display/ViewportTextureNode.d.ts new file mode 100644 index 000000000..ade4ea51e --- /dev/null +++ b/src-testing/src/nodes/display/ViewportTextureNode.d.ts @@ -0,0 +1,28 @@ +import { FramebufferTexture } from "../../textures/FramebufferTexture.js"; +import TextureNode from "../accessors/TextureNode.js"; +import { NodeUpdateType } from "../core/constants.js"; +import Node from "../core/Node.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +declare class ViewportTextureNode extends TextureNode { + generateMipmaps: boolean; + + readonly isOutputTextureNode: true; + + updateBeforeType: NodeUpdateType; + + constructor(uvNode?: Node, levelNode?: Node | null, framebufferTexture?: FramebufferTexture | null); +} + +export default ViewportTextureNode; + +export const viewportTexture: ( + uvNode?: Node, + levelNode?: Node | null, + framebufferTexture?: FramebufferTexture | null, +) => ShaderNodeObject; +export const viewportMipTexture: ( + uvNode?: Node, + levelNode?: Node | null, + framebufferTexture?: FramebufferTexture | null, +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/fog/FogExp2Node.d.ts b/src-testing/src/nodes/fog/FogExp2Node.d.ts new file mode 100644 index 000000000..d129d2c72 --- /dev/null +++ b/src-testing/src/nodes/fog/FogExp2Node.d.ts @@ -0,0 +1,14 @@ +import Node from "../core/Node.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; +import FogNode from "./FogNode.js"; + +declare class FogExp2Node extends FogNode { + isFogExp2Node: true; + densityNode: Node; + + constructor(colorNode: Node, densityNode: Node); +} + +export default FogExp2Node; + +export const densityFog: (colorNode: Node, densityNode: Node) => ShaderNodeObject; diff --git a/src-testing/src/nodes/fog/FogNode.ts b/src-testing/src/nodes/fog/FogNode.ts new file mode 100644 index 000000000..f08efb700 --- /dev/null +++ b/src-testing/src/nodes/fog/FogNode.ts @@ -0,0 +1,38 @@ +import Node from '../core/Node.js'; +import { positionView } from '../accessors/Position.js'; +import { nodeProxy } from '../tsl/TSLBase.js'; + +class FogNode extends Node { + static get type() { + return 'FogNode'; + } + + constructor(colorNode, factorNode) { + super('float'); + + this.isFogNode = true; + + this.colorNode = colorNode; + this.factorNode = factorNode; + } + + getViewZNode(builder) { + let viewZ; + + const getViewZ = builder.context.getViewZ; + + if (getViewZ !== undefined) { + viewZ = getViewZ(this); + } + + return (viewZ || positionView.z).negate(); + } + + setup() { + return this.factorNode; + } +} + +export default FogNode; + +export const fog = /*@__PURE__*/ nodeProxy(FogNode); diff --git a/src-testing/src/nodes/fog/FogRangeNode.d.ts b/src-testing/src/nodes/fog/FogRangeNode.d.ts new file mode 100644 index 000000000..d0e1c7cf2 --- /dev/null +++ b/src-testing/src/nodes/fog/FogRangeNode.d.ts @@ -0,0 +1,19 @@ +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; +import FogNode from "./FogNode.js"; + +declare class FogRangeNode extends FogNode { + isFogRangeNode: true; + nearNode: Node | null; + farNode: Node | null; + + constructor(colorNode: Node | null, nearNode: Node | null, farNode: Node | null); +} + +export default FogRangeNode; + +export const rangeFog: ( + colorNode: NodeRepresentation | null, + nearNode: NodeRepresentation | null, + farNode: NodeRepresentation | null, +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/functions/BSDF/BRDF_GGX.d.ts b/src-testing/src/nodes/functions/BSDF/BRDF_GGX.d.ts new file mode 100644 index 000000000..a22bb480a --- /dev/null +++ b/src-testing/src/nodes/functions/BSDF/BRDF_GGX.d.ts @@ -0,0 +1,15 @@ +import Node from "../../core/Node.js"; +import OperatorNode from "../../math/OperatorNode.js"; +import { ShaderNodeObject } from "../../tsl/TSLCore.js"; + +declare const BRDF_GGX: (args: { + lightDirection: Node; + f0: Node; + f90: Node; + roughness: Node; + f?: Node; + USE_IRIDESCENCE?: Node; + USE_ANISOTROPY?: Node; +}) => ShaderNodeObject; + +export default BRDF_GGX; diff --git a/src-testing/src/nodes/functions/BSDF/BRDF_Lambert.d.ts b/src-testing/src/nodes/functions/BSDF/BRDF_Lambert.d.ts new file mode 100644 index 000000000..591fc262d --- /dev/null +++ b/src-testing/src/nodes/functions/BSDF/BRDF_Lambert.d.ts @@ -0,0 +1,7 @@ +import Node from "../../core/Node.js"; +import OperatorNode from "../../math/OperatorNode.js"; +import { ShaderNodeObject } from "../../tsl/TSLCore.js"; + +declare const BRDF_Lambert: (args: { diffuseColor: Node }) => ShaderNodeObject; + +export default BRDF_Lambert; diff --git a/src-testing/src/nodes/functions/BSDF/BRDF_Sheen.d.ts b/src-testing/src/nodes/functions/BSDF/BRDF_Sheen.d.ts new file mode 100644 index 000000000..3e5b218e8 --- /dev/null +++ b/src-testing/src/nodes/functions/BSDF/BRDF_Sheen.d.ts @@ -0,0 +1,7 @@ +import Node from "../../core/Node.js"; +import OperatorNode from "../../math/OperatorNode.js"; +import { ShaderNodeObject } from "../../tsl/TSLCore.js"; + +declare const BRDF_Sheen: (args: { lightDirection: Node }) => ShaderNodeObject; + +export default BRDF_Sheen; diff --git a/src-testing/src/nodes/functions/BSDF/DFGApprox.d.ts b/src-testing/src/nodes/functions/BSDF/DFGApprox.d.ts new file mode 100644 index 000000000..010b70ccc --- /dev/null +++ b/src-testing/src/nodes/functions/BSDF/DFGApprox.d.ts @@ -0,0 +1,11 @@ +import Node from "../../core/Node.js"; +import OperatorNode from "../../math/OperatorNode.js"; +import { ShaderNodeObject } from "../../tsl/TSLCore.js"; + +// Analytical approximation of the DFG LUT, one half of the +// split-sum approximation used in indirect specular lighting. +// via 'environmentBRDF' from "Physically Based Shading on Mobile" +// https://www.unrealengine.com/blog/physically-based-shading-on-mobile +declare const DFGApprox: (args: { roughness: Node; dotNV: Node }) => ShaderNodeObject; + +export default DFGApprox; diff --git a/src-testing/src/nodes/functions/BSDF/D_GGX.d.ts b/src-testing/src/nodes/functions/BSDF/D_GGX.d.ts new file mode 100644 index 000000000..71b673c6c --- /dev/null +++ b/src-testing/src/nodes/functions/BSDF/D_GGX.d.ts @@ -0,0 +1,10 @@ +import Node from "../../core/Node.js"; +import OperatorNode from "../../math/OperatorNode.js"; +import { ShaderNodeObject } from "../../tsl/TSLCore.js"; + +// Microfacet Models for Refraction through Rough Surfaces - equation (33) +// http://graphicrants.blogspot.com/2013/08/specular-brdf-reference.html +// alpha is "roughness squared" in Disney’s reparameterization +declare const D_GGX: (args: { alpha: Node; dotNH: Node }) => ShaderNodeObject; + +export default D_GGX; diff --git a/src-testing/src/nodes/functions/BSDF/D_GGX_Anisotropic.d.ts b/src-testing/src/nodes/functions/BSDF/D_GGX_Anisotropic.d.ts new file mode 100644 index 000000000..e296ea11d --- /dev/null +++ b/src-testing/src/nodes/functions/BSDF/D_GGX_Anisotropic.d.ts @@ -0,0 +1,10 @@ +import Node from "../../core/Node.js"; +import OperatorNode from "../../math/OperatorNode.js"; +import { ShaderNodeObject } from "../../tsl/TSLCore.js"; + +// https://google.github.io/filament/Filament.md.html#materialsystem/anisotropicmodel/anisotropicspecularbrdf +declare const D_GGX_Anisotropic: ( + args: { alphaT: Node; alphaB: Node; dotNH: Node; dotTH: Node; dotBH: Node }, +) => ShaderNodeObject; + +export default D_GGX_Anisotropic; diff --git a/src-testing/src/nodes/functions/BSDF/F_Schlick.d.ts b/src-testing/src/nodes/functions/BSDF/F_Schlick.d.ts new file mode 100644 index 000000000..46940e6a3 --- /dev/null +++ b/src-testing/src/nodes/functions/BSDF/F_Schlick.d.ts @@ -0,0 +1,7 @@ +import Node from "../../core/Node.js"; +import OperatorNode from "../../math/OperatorNode.js"; +import { ShaderNodeObject } from "../../tsl/TSLCore.js"; + +declare const F_Schlick: (args: { f0: Node; f90: Node; dotVH: Node }) => ShaderNodeObject; + +export default F_Schlick; diff --git a/src-testing/src/nodes/functions/BSDF/LTC.d.ts b/src-testing/src/nodes/functions/BSDF/LTC.d.ts new file mode 100644 index 000000000..4bd6d7f76 --- /dev/null +++ b/src-testing/src/nodes/functions/BSDF/LTC.d.ts @@ -0,0 +1,9 @@ +import Node from "../../core/Node.js"; + +declare const LTC_Uv: (args: { N: Node; V: Node; roughness: Node }) => Node; + +declare const LTC_Evaluate: ( + args: { N: Node; V: Node; P: Node; mInv: Node; p0: Node; p1: Node; p2: Node; p3: Node }, +) => Node; + +export { LTC_Evaluate, LTC_Uv }; diff --git a/src-testing/src/nodes/functions/BSDF/Schlick_to_F0.d.ts b/src-testing/src/nodes/functions/BSDF/Schlick_to_F0.d.ts new file mode 100644 index 000000000..d0554ba2c --- /dev/null +++ b/src-testing/src/nodes/functions/BSDF/Schlick_to_F0.d.ts @@ -0,0 +1,10 @@ +import Node from "../../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../../tsl/TSLCore.js"; + +declare const Schlick_to_F0: ( + f: NodeRepresentation, + f90: NodeRepresentation, + dotVH: NodeRepresentation, +) => ShaderNodeObject; + +export default Schlick_to_F0; diff --git a/src-testing/src/nodes/functions/BSDF/V_GGX_SmithCorrelated.d.ts b/src-testing/src/nodes/functions/BSDF/V_GGX_SmithCorrelated.d.ts new file mode 100644 index 000000000..b6c1ca80c --- /dev/null +++ b/src-testing/src/nodes/functions/BSDF/V_GGX_SmithCorrelated.d.ts @@ -0,0 +1,11 @@ +import Node from "../../core/Node.js"; +import OperatorNode from "../../math/OperatorNode.js"; +import { ShaderNodeObject } from "../../tsl/TSLCore.js"; + +declare const V_GGX_SmithCorrelated: (inputs: { + alpha: Node; + dotNL: Node; + dotNV: Node; +}) => ShaderNodeObject; + +export default V_GGX_SmithCorrelated; diff --git a/src-testing/src/nodes/functions/BSDF/V_GGX_SmithCorrelated_Anisotropic.d.ts b/src-testing/src/nodes/functions/BSDF/V_GGX_SmithCorrelated_Anisotropic.d.ts new file mode 100644 index 000000000..5150bf6b1 --- /dev/null +++ b/src-testing/src/nodes/functions/BSDF/V_GGX_SmithCorrelated_Anisotropic.d.ts @@ -0,0 +1,16 @@ +import Node from "../../core/Node.js"; +import MathNode from "../../math/MathNode.js"; +import { ShaderNodeObject } from "../../tsl/TSLCore.js"; + +declare const V_GGX_SmithCorrelated: (inputs: { + alphaT: Node; + alphaB: Node; + dotTV: Node; + dotBV: Node; + dotTL: Node; + dotBL: Node; + dotNV: Node; + dotNL: Node; +}) => ShaderNodeObject; + +export default V_GGX_SmithCorrelated; diff --git a/src-testing/src/nodes/functions/BasicLightingModel.d.ts b/src-testing/src/nodes/functions/BasicLightingModel.d.ts new file mode 100644 index 000000000..a64fafd44 --- /dev/null +++ b/src-testing/src/nodes/functions/BasicLightingModel.d.ts @@ -0,0 +1,7 @@ +import LightingModel from "../core/LightingModel.js"; + +declare class BasicLightingModel extends LightingModel { + constructor(); +} + +export default BasicLightingModel; diff --git a/src-testing/src/nodes/functions/PhongLightingModel.d.ts b/src-testing/src/nodes/functions/PhongLightingModel.d.ts new file mode 100644 index 000000000..5df595269 --- /dev/null +++ b/src-testing/src/nodes/functions/PhongLightingModel.d.ts @@ -0,0 +1,7 @@ +import BasicLightingModel from "./BasicLightingModel.js"; + +export default class PhongLightingModel extends BasicLightingModel { + specular: boolean; + + constructor(specular?: boolean); +} diff --git a/src-testing/src/nodes/functions/PhysicalLightingModel.d.ts b/src-testing/src/nodes/functions/PhysicalLightingModel.d.ts new file mode 100644 index 000000000..bec381051 --- /dev/null +++ b/src-testing/src/nodes/functions/PhysicalLightingModel.d.ts @@ -0,0 +1,30 @@ +import LightingModel from "../core/LightingModel.js"; +import Node from "../core/Node.js"; + +export default class PhysicalLightingModel extends LightingModel { + clearcoat: boolean; + sheen: boolean; + iridescence: boolean; + anisotropy: boolean; + transmission: boolean; + dispersion: boolean; + + clearcoatRadiance: Node | null; + clearcoatSpecularDirect: Node | null; + clearcoatSpecularIndirect: Node | null; + sheenSpecularDirect: Node | null; + sheenSpecularIndirect: Node | null; + iridescenceFresnel: Node | null; + iridescenceF0: Node | null; + + constructor( + clearcoat?: boolean, + sheen?: boolean, + iridescence?: boolean, + anisotropy?: boolean, + transmission?: boolean, + dispersion?: boolean, + ); + + computeMultiscattering(singleScatter: Node, multiScatter: Node, specularF90: Node): void; +} diff --git a/src-testing/src/nodes/functions/ShadowMaskModel.d.ts b/src-testing/src/nodes/functions/ShadowMaskModel.d.ts new file mode 100644 index 000000000..bcdee8b5c --- /dev/null +++ b/src-testing/src/nodes/functions/ShadowMaskModel.d.ts @@ -0,0 +1,9 @@ +import LightingModel from "../core/LightingModel.js"; +import VarNode from "../core/VarNode.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +export default class ShadowMaskModel extends LightingModel { + shadowNode: ShaderNodeObject; + + constructor(); +} diff --git a/src-testing/src/nodes/functions/ToonLightingModel.d.ts b/src-testing/src/nodes/functions/ToonLightingModel.d.ts new file mode 100644 index 000000000..d26db3457 --- /dev/null +++ b/src-testing/src/nodes/functions/ToonLightingModel.d.ts @@ -0,0 +1,4 @@ +import LightingModel from "../core/LightingModel.js"; + +export default class ToonLightingModel extends LightingModel { +} diff --git a/src-testing/src/nodes/functions/material/getGeometryRoughness.d.ts b/src-testing/src/nodes/functions/material/getGeometryRoughness.d.ts new file mode 100644 index 000000000..dd629cee0 --- /dev/null +++ b/src-testing/src/nodes/functions/material/getGeometryRoughness.d.ts @@ -0,0 +1,6 @@ +import MathNode from "../../math/MathNode.js"; +import { ShaderNodeObject } from "../../tsl/TSLCore.js"; + +declare const getGeometryRoughness: () => ShaderNodeObject; + +export default getGeometryRoughness; diff --git a/src-testing/src/nodes/functions/material/getRoughness.d.ts b/src-testing/src/nodes/functions/material/getRoughness.d.ts new file mode 100644 index 000000000..7022672b0 --- /dev/null +++ b/src-testing/src/nodes/functions/material/getRoughness.d.ts @@ -0,0 +1,7 @@ +import Node from "../../core/Node.js"; +import MathNode from "../../math/MathNode.js"; +import { ShaderNodeObject } from "../../tsl/TSLCore.js"; + +declare const getRoughness: (args: { roughness: Node }) => ShaderNodeObject; + +export default getRoughness; diff --git a/src-testing/src/nodes/functions/material/getShIrradianceAt.d.ts b/src-testing/src/nodes/functions/material/getShIrradianceAt.d.ts new file mode 100644 index 000000000..95c8d03c5 --- /dev/null +++ b/src-testing/src/nodes/functions/material/getShIrradianceAt.d.ts @@ -0,0 +1,6 @@ +import Node from "../../core/Node.js"; +import { ShaderNodeObject } from "../../tsl/TSLCore.js"; + +declare const getShIrradianceAt: (normal: Node, shCoefficients: Node) => ShaderNodeObject; + +export default getShIrradianceAt; diff --git a/src-testing/src/nodes/geometry/RangeNode.d.ts b/src-testing/src/nodes/geometry/RangeNode.d.ts new file mode 100644 index 000000000..c4c932486 --- /dev/null +++ b/src-testing/src/nodes/geometry/RangeNode.d.ts @@ -0,0 +1,19 @@ +import { Color } from "../../math/Color.js"; +import { Vector2 } from "../../math/Vector2.js"; +import { Vector3 } from "../../math/Vector3.js"; +import { Vector4 } from "../../math/Vector4.js"; +import Node from "../core/Node.js"; +import NodeBuilder from "../core/NodeBuilder.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +export type RangeModeBound = number | Color | Vector2 | Vector3 | Vector4; + +export default class RangeNode extends Node { + min: RangeModeBound; + max: RangeModeBound; + + constructor(min: RangeModeBound, max: RangeModeBound); + getVectorLength(builder: NodeBuilder): number; +} + +export const range: (min: RangeModeBound, max: RangeModeBound) => ShaderNodeObject; diff --git a/src-testing/src/nodes/gpgpu/ComputeNode.ts b/src-testing/src/nodes/gpgpu/ComputeNode.ts new file mode 100644 index 000000000..30d5be0b3 --- /dev/null +++ b/src-testing/src/nodes/gpgpu/ComputeNode.ts @@ -0,0 +1,75 @@ +import Node from '../core/Node.js'; +import { NodeUpdateType } from '../core/constants.js'; +import { addMethodChaining, nodeObject } from '../tsl/TSLCore.js'; + +class ComputeNode extends Node { + static get type() { + return 'ComputeNode'; + } + + constructor(computeNode, count, workgroupSize = [64]) { + super('void'); + + this.isComputeNode = true; + + this.computeNode = computeNode; + + this.count = count; + this.workgroupSize = workgroupSize; + this.dispatchCount = 0; + + this.version = 1; + this.updateBeforeType = NodeUpdateType.OBJECT; + + this.onInitFunction = null; + + this.updateDispatchCount(); + } + + dispose() { + this.dispatchEvent({ type: 'dispose' }); + } + + set needsUpdate(value) { + if (value === true) this.version++; + } + + updateDispatchCount() { + const { count, workgroupSize } = this; + + let size = workgroupSize[0]; + + for (let i = 1; i < workgroupSize.length; i++) size *= workgroupSize[i]; + + this.dispatchCount = Math.ceil(count / size); + } + + onInit(callback) { + this.onInitFunction = callback; + + return this; + } + + updateBefore({ renderer }) { + renderer.compute(this); + } + + generate(builder) { + const { shaderStage } = builder; + + if (shaderStage === 'compute') { + const snippet = this.computeNode.build(builder, 'void'); + + if (snippet !== '') { + builder.addLineFlowCode(snippet, this); + } + } + } +} + +export default ComputeNode; + +export const compute = (node, count, workgroupSize) => + nodeObject(new ComputeNode(nodeObject(node), count, workgroupSize)); + +addMethodChaining('compute', compute); diff --git a/src-testing/src/nodes/lighting/AONode.d.ts b/src-testing/src/nodes/lighting/AONode.d.ts new file mode 100644 index 000000000..998ec5236 --- /dev/null +++ b/src-testing/src/nodes/lighting/AONode.d.ts @@ -0,0 +1,8 @@ +import Node from "../core/Node.js"; +import LightingNode from "./LightingNode.js"; + +export default class AONode extends LightingNode { + aoNode: Node | null; + + constructor(aoNode?: Node | null); +} diff --git a/src-testing/src/nodes/lighting/AmbientLightNode.d.ts b/src-testing/src/nodes/lighting/AmbientLightNode.d.ts new file mode 100644 index 000000000..3b7cc6fb6 --- /dev/null +++ b/src-testing/src/nodes/lighting/AmbientLightNode.d.ts @@ -0,0 +1,8 @@ +import { AmbientLight } from "../../lights/AmbientLight.js"; +import AnalyticLightNode from "./AnalyticLightNode.js"; + +declare class AmbientLightNode extends AnalyticLightNode { + constructor(light?: AmbientLight | null); +} + +export default AmbientLightNode; diff --git a/src-testing/src/nodes/lighting/AnalyticLightNode.d.ts b/src-testing/src/nodes/lighting/AnalyticLightNode.d.ts new file mode 100644 index 000000000..d8cea32ef --- /dev/null +++ b/src-testing/src/nodes/lighting/AnalyticLightNode.d.ts @@ -0,0 +1,8 @@ +import { Light } from "../../lights/Light.js"; +import LightingNode from "./LightingNode.js"; + +export default class AnalyticLightNode extends LightingNode { + light: T | null; + + constructor(light?: T | null); +} diff --git a/src-testing/src/nodes/lighting/BasicEnvironmentNode.d.ts b/src-testing/src/nodes/lighting/BasicEnvironmentNode.d.ts new file mode 100644 index 000000000..de244562f --- /dev/null +++ b/src-testing/src/nodes/lighting/BasicEnvironmentNode.d.ts @@ -0,0 +1,10 @@ +import Node from "../core/Node.js"; +import LightingNode from "./LightingNode.js"; + +declare class BasicEnvironmentNode extends LightingNode { + envNode: Node | null; + + constructor(envNode?: Node | null); +} + +export default BasicEnvironmentNode; diff --git a/src-testing/src/nodes/lighting/BasicLightMapNode.d.ts b/src-testing/src/nodes/lighting/BasicLightMapNode.d.ts new file mode 100644 index 000000000..c759e8857 --- /dev/null +++ b/src-testing/src/nodes/lighting/BasicLightMapNode.d.ts @@ -0,0 +1,8 @@ +import Node from "../core/Node.js"; +import LightingNode from "./LightingNode.js"; + +declare class BasicLightMapNode extends LightingNode { + constructor(lightMapNode?: Node | null); +} + +export default BasicLightMapNode; diff --git a/src-testing/src/nodes/lighting/DirectionalLightNode.d.ts b/src-testing/src/nodes/lighting/DirectionalLightNode.d.ts new file mode 100644 index 000000000..41908abaf --- /dev/null +++ b/src-testing/src/nodes/lighting/DirectionalLightNode.d.ts @@ -0,0 +1,8 @@ +import { DirectionalLight } from "../../lights/DirectionalLight.js"; +import AnalyticLightNode from "./AnalyticLightNode.js"; + +declare class DirectionalLightNode extends AnalyticLightNode { + constructor(light?: DirectionalLight | null); +} + +export default DirectionalLightNode; diff --git a/src-testing/src/nodes/lighting/EnvironmentNode.ts b/src-testing/src/nodes/lighting/EnvironmentNode.ts new file mode 100644 index 000000000..eab24fba0 --- /dev/null +++ b/src-testing/src/nodes/lighting/EnvironmentNode.ts @@ -0,0 +1,114 @@ +import LightingNode from './LightingNode.js'; +import { cache } from '../core/CacheNode.js'; +import { roughness, clearcoatRoughness } from '../core/PropertyNode.js'; +import { cameraViewMatrix } from '../accessors/Camera.js'; +import { transformedClearcoatNormalView, transformedNormalView, transformedNormalWorld } from '../accessors/Normal.js'; +import { positionViewDirection } from '../accessors/Position.js'; +import { float } from '../tsl/TSLBase.js'; +import { reference } from '../accessors/ReferenceNode.js'; +import { transformedBentNormalView } from '../accessors/AccessorsUtils.js'; +import { pmremTexture } from '../pmrem/PMREMNode.js'; + +const _envNodeCache = new WeakMap(); + +class EnvironmentNode extends LightingNode { + static get type() { + return 'EnvironmentNode'; + } + + constructor(envNode = null) { + super(); + + this.envNode = envNode; + } + + setup(builder) { + const { material } = builder; + + let envNode = this.envNode; + + if (envNode.isTextureNode || envNode.isMaterialReferenceNode) { + const value = envNode.isTextureNode ? envNode.value : material[envNode.property]; + + let cacheEnvNode = _envNodeCache.get(value); + + if (cacheEnvNode === undefined) { + cacheEnvNode = pmremTexture(value); + + _envNodeCache.set(value, cacheEnvNode); + } + + envNode = cacheEnvNode; + } + + // + + const envMap = material.envMap; + const intensity = envMap + ? reference('envMapIntensity', 'float', builder.material) + : reference('environmentIntensity', 'float', builder.scene); // @TODO: Add materialEnvIntensity in MaterialNode + + const useAnisotropy = material.useAnisotropy === true || material.anisotropy > 0; + const radianceNormalView = useAnisotropy ? transformedBentNormalView : transformedNormalView; + + const radiance = envNode.context(createRadianceContext(roughness, radianceNormalView)).mul(intensity); + const irradiance = envNode.context(createIrradianceContext(transformedNormalWorld)).mul(Math.PI).mul(intensity); + + const isolateRadiance = cache(radiance); + const isolateIrradiance = cache(irradiance); + + // + + builder.context.radiance.addAssign(isolateRadiance); + + builder.context.iblIrradiance.addAssign(isolateIrradiance); + + // + + const clearcoatRadiance = builder.context.lightingModel.clearcoatRadiance; + + if (clearcoatRadiance) { + const clearcoatRadianceContext = envNode + .context(createRadianceContext(clearcoatRoughness, transformedClearcoatNormalView)) + .mul(intensity); + const isolateClearcoatRadiance = cache(clearcoatRadianceContext); + + clearcoatRadiance.addAssign(isolateClearcoatRadiance); + } + } +} + +export default EnvironmentNode; + +const createRadianceContext = (roughnessNode, normalViewNode) => { + let reflectVec = null; + + return { + getUV: () => { + if (reflectVec === null) { + reflectVec = positionViewDirection.negate().reflect(normalViewNode); + + // Mixing the reflection with the normal is more accurate and keeps rough objects from gathering light from behind their tangent plane. + reflectVec = roughnessNode.mul(roughnessNode).mix(reflectVec, normalViewNode).normalize(); + + reflectVec = reflectVec.transformDirection(cameraViewMatrix); + } + + return reflectVec; + }, + getTextureLevel: () => { + return roughnessNode; + }, + }; +}; + +const createIrradianceContext = normalWorldNode => { + return { + getUV: () => { + return normalWorldNode; + }, + getTextureLevel: () => { + return float(1.0); + }, + }; +}; diff --git a/src-testing/src/nodes/lighting/HemisphereLightNode.d.ts b/src-testing/src/nodes/lighting/HemisphereLightNode.d.ts new file mode 100644 index 000000000..7cf38dd79 --- /dev/null +++ b/src-testing/src/nodes/lighting/HemisphereLightNode.d.ts @@ -0,0 +1,13 @@ +import { HemisphereLight } from "../../lights/HemisphereLight.js"; +import Object3DNode from "../accessors/Object3DNode.js"; +import Node from "../core/Node.js"; +import AnalyticLightNode from "./AnalyticLightNode.js"; + +export default class HemisphereLightNode extends AnalyticLightNode { + lightPositionNode: Object3DNode; + lightDirectionNode: Node; + + groundColorNode: Node; + + constructor(light?: HemisphereLight | null); +} diff --git a/src-testing/src/nodes/lighting/IESSpotLightNode.d.ts b/src-testing/src/nodes/lighting/IESSpotLightNode.d.ts new file mode 100644 index 000000000..5906fe96d --- /dev/null +++ b/src-testing/src/nodes/lighting/IESSpotLightNode.d.ts @@ -0,0 +1,5 @@ +import SpotLightNode from "./SpotLightNode.js"; + +declare class IESSpotLightNode extends SpotLightNode {} + +export default IESSpotLightNode; diff --git a/src-testing/src/nodes/lighting/IrradianceNode.d.ts b/src-testing/src/nodes/lighting/IrradianceNode.d.ts new file mode 100644 index 000000000..a59838044 --- /dev/null +++ b/src-testing/src/nodes/lighting/IrradianceNode.d.ts @@ -0,0 +1,8 @@ +import Node from "../core/Node.js"; +import LightingNode from "./LightingNode.js"; + +export default class IrradianceNode extends LightingNode { + node: Node | null; + + constructor(node?: Node | null); +} diff --git a/src-testing/src/nodes/lighting/LightNode.d.ts b/src-testing/src/nodes/lighting/LightNode.d.ts new file mode 100644 index 000000000..de64bdb60 --- /dev/null +++ b/src-testing/src/nodes/lighting/LightNode.d.ts @@ -0,0 +1,18 @@ +import { Light } from "../../lights/Light.js"; +import Node from "../core/Node.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +export type LightNodeScope = typeof LightNode.TARGET_DIRECTION; + +declare class LightNode extends Node { + scope: LightNodeScope; + light: Light; + + constructor(scope?: LightNodeScope, light?: Light | null); + + static TARGET_DIRECTION: "targetDirection"; +} + +export default LightNode; + +export const lightTargetDirection: (light?: Light | null) => ShaderNodeObject; diff --git a/src-testing/src/nodes/lighting/LightProbeNode.d.ts b/src-testing/src/nodes/lighting/LightProbeNode.d.ts new file mode 100644 index 000000000..3a5b12963 --- /dev/null +++ b/src-testing/src/nodes/lighting/LightProbeNode.d.ts @@ -0,0 +1,11 @@ +import { LightProbe } from "../../lights/LightProbe.js"; +import UniformArrayNode from "../accessors/UniformArrayNode.js"; +import AnalyticLightNode from "./AnalyticLightNode.js"; + +declare class LightProbeNode extends AnalyticLightNode { + lightProbe: UniformArrayNode; + + constructor(light?: LightProbe | null); +} + +export default LightProbeNode; diff --git a/src-testing/src/nodes/lighting/LightUtils.d.ts b/src-testing/src/nodes/lighting/LightUtils.d.ts new file mode 100644 index 000000000..4fd41ea55 --- /dev/null +++ b/src-testing/src/nodes/lighting/LightUtils.d.ts @@ -0,0 +1,9 @@ +import Node from "../core/Node.js"; +import ConditionalNode from "../math/ConditionalNode.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +export const getDistanceAttenuation: (args: { + lightDistance: Node; + cutoffDistance: Node; + decayExponent: Node; +}) => ShaderNodeObject; diff --git a/src-testing/src/nodes/lighting/LightingContextNode.ts b/src-testing/src/nodes/lighting/LightingContextNode.ts new file mode 100644 index 000000000..f9dbf1a82 --- /dev/null +++ b/src-testing/src/nodes/lighting/LightingContextNode.ts @@ -0,0 +1,57 @@ +import ContextNode from '../core/ContextNode.js'; +import { nodeProxy, float, vec3 } from '../tsl/TSLBase.js'; + +class LightingContextNode extends ContextNode { + static get type() { + return 'LightingContextNode'; + } + + constructor(node, lightingModel = null, backdropNode = null, backdropAlphaNode = null) { + super(node); + + this.lightingModel = lightingModel; + this.backdropNode = backdropNode; + this.backdropAlphaNode = backdropAlphaNode; + + this._value = null; + } + + getContext() { + const { backdropNode, backdropAlphaNode } = this; + + const directDiffuse = vec3().toVar('directDiffuse'), + directSpecular = vec3().toVar('directSpecular'), + indirectDiffuse = vec3().toVar('indirectDiffuse'), + indirectSpecular = vec3().toVar('indirectSpecular'); + + const reflectedLight = { + directDiffuse, + directSpecular, + indirectDiffuse, + indirectSpecular, + }; + + const context = { + radiance: vec3().toVar('radiance'), + irradiance: vec3().toVar('irradiance'), + iblIrradiance: vec3().toVar('iblIrradiance'), + ambientOcclusion: float(1).toVar('ambientOcclusion'), + reflectedLight, + backdrop: backdropNode, + backdropAlpha: backdropAlphaNode, + }; + + return context; + } + + setup(builder) { + this.value = this._value || (this._value = this.getContext()); + this.value.lightingModel = this.lightingModel || builder.context.lightingModel; + + return super.setup(builder); + } +} + +export default LightingContextNode; + +export const lightingContext = /*@__PURE__*/ nodeProxy(LightingContextNode); diff --git a/src-testing/src/nodes/lighting/LightingNode.d.ts b/src-testing/src/nodes/lighting/LightingNode.d.ts new file mode 100644 index 000000000..3e8dd5424 --- /dev/null +++ b/src-testing/src/nodes/lighting/LightingNode.d.ts @@ -0,0 +1,7 @@ +import Node from "../core/Node.js"; + +export default abstract class LightingNode extends Node { + readonly isLightingNode: true; + + constructor(); +} diff --git a/src-testing/src/nodes/lighting/LightsNode.ts b/src-testing/src/nodes/lighting/LightsNode.ts new file mode 100644 index 000000000..1cf0b19ac --- /dev/null +++ b/src-testing/src/nodes/lighting/LightsNode.ts @@ -0,0 +1,200 @@ +import Node from '../core/Node.js'; +import { nodeObject, vec3 } from '../tsl/TSLBase.js'; + +const sortLights = lights => { + return lights.sort((a, b) => a.id - b.id); +}; + +const getLightNodeById = (id, lightNodes) => { + for (const lightNode of lightNodes) { + if (lightNode.isAnalyticLightNode && lightNode.light.id === id) { + return lightNode; + } + } + + return null; +}; + +const _lightsNodeRef = /*@__PURE__*/ new WeakMap(); + +class LightsNode extends Node { + static get type() { + return 'LightsNode'; + } + + constructor() { + super('vec3'); + + this.totalDiffuseNode = vec3().toVar('totalDiffuse'); + this.totalSpecularNode = vec3().toVar('totalSpecular'); + + this.outgoingLightNode = vec3().toVar('outgoingLight'); + + this._lights = []; + + this._lightNodes = null; + this._lightNodesHash = null; + + this.global = true; + } + + getHash(builder) { + if (this._lightNodesHash === null) { + if (this._lightNodes === null) this.setupLightsNode(builder); + + const hash = []; + + for (const lightNode of this._lightNodes) { + hash.push(lightNode.getSelf().getHash()); + } + + this._lightNodesHash = 'lights-' + hash.join(','); + } + + return this._lightNodesHash; + } + + analyze(builder) { + const properties = builder.getDataFromNode(this); + + for (const node of properties.nodes) { + node.build(builder); + } + } + + setupLightsNode(builder) { + const lightNodes = []; + + const previousLightNodes = this._lightNodes; + + const lights = sortLights(this._lights); + const nodeLibrary = builder.renderer.library; + + for (const light of lights) { + if (light.isNode) { + lightNodes.push(nodeObject(light)); + } else { + let lightNode = null; + + if (previousLightNodes !== null) { + lightNode = getLightNodeById(light.id, previousLightNodes); // resuse existing light node + } + + if (lightNode === null) { + const lightNodeClass = nodeLibrary.getLightNodeClass(light.constructor); + + if (lightNodeClass === null) { + console.warn(`LightsNode.setupNodeLights: Light node not found for ${light.constructor.name}`); + continue; + } + + let lightNode = null; + + if (!_lightsNodeRef.has(light)) { + lightNode = nodeObject(new lightNodeClass(light)); + _lightsNodeRef.set(light, lightNode); + } else { + lightNode = _lightsNodeRef.get(light); + } + + lightNodes.push(lightNode); + } + } + } + + this._lightNodes = lightNodes; + } + + setupLights(builder, lightNodes) { + for (const lightNode of lightNodes) { + lightNode.build(builder); + } + } + + setup(builder) { + if (this._lightNodes === null) this.setupLightsNode(builder); + + const context = builder.context; + const lightingModel = context.lightingModel; + + let outgoingLightNode = this.outgoingLightNode; + + if (lightingModel) { + const { _lightNodes, totalDiffuseNode, totalSpecularNode } = this; + + context.outgoingLight = outgoingLightNode; + + const stack = builder.addStack(); + + // + + const properties = builder.getDataFromNode(this); + properties.nodes = stack.nodes; + + // + + lightingModel.start(context, stack, builder); + + // lights + + this.setupLights(builder, _lightNodes); + + // + + lightingModel.indirect(context, stack, builder); + + // + + const { backdrop, backdropAlpha } = context; + const { directDiffuse, directSpecular, indirectDiffuse, indirectSpecular } = context.reflectedLight; + + let totalDiffuse = directDiffuse.add(indirectDiffuse); + + if (backdrop !== null) { + if (backdropAlpha !== null) { + totalDiffuse = vec3(backdropAlpha.mix(totalDiffuse, backdrop)); + } else { + totalDiffuse = vec3(backdrop); + } + + context.material.transparent = true; + } + + totalDiffuseNode.assign(totalDiffuse); + totalSpecularNode.assign(directSpecular.add(indirectSpecular)); + + outgoingLightNode.assign(totalDiffuseNode.add(totalSpecularNode)); + + // + + lightingModel.finish(context, stack, builder); + + // + + outgoingLightNode = outgoingLightNode.bypass(builder.removeStack()); + } + + return outgoingLightNode; + } + + setLights(lights) { + this._lights = lights; + + this._lightNodes = null; + this._lightNodesHash = null; + + return this; + } + + getLights() { + return this._lights; + } + + get hasLights() { + return this._lights.length > 0; + } +} + +export default LightsNode; + +export const lights = (lights = []) => nodeObject(new LightsNode()).setLights(lights); diff --git a/src-testing/src/nodes/lighting/PointLightNode.d.ts b/src-testing/src/nodes/lighting/PointLightNode.d.ts new file mode 100644 index 000000000..6ae10bc08 --- /dev/null +++ b/src-testing/src/nodes/lighting/PointLightNode.d.ts @@ -0,0 +1,20 @@ +import { PointLight } from "../../lights/PointLight.js"; +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; +import AnalyticLightNode from "./AnalyticLightNode.js"; + +export const directPointLight: ( + color: NodeRepresentation, + lightViewPosition: NodeRepresentation, + cutoffDistance: NodeRepresentation, + decayExponent: NodeRepresentation, +) => ShaderNodeObject; + +declare class PointLightNode extends AnalyticLightNode { + cutoffDistanceNode: Node; + decayExponentNode: Node; + + constructor(light?: PointLight | null); +} + +export default PointLightNode; diff --git a/src-testing/src/nodes/lighting/RectAreaLightNode.d.ts b/src-testing/src/nodes/lighting/RectAreaLightNode.d.ts new file mode 100644 index 000000000..db4d18b82 --- /dev/null +++ b/src-testing/src/nodes/lighting/RectAreaLightNode.d.ts @@ -0,0 +1,21 @@ +import { RectAreaLight } from "../../lights/RectAreaLight.js"; +import { DataTexture } from "../../textures/DataTexture.js"; +import Node from "../core/Node.js"; +import AnalyticLightNode from "./AnalyticLightNode.js"; + +export interface RectAreaLightTexturesLib { + LTC_HALF_1: DataTexture; + LTC_HALF_2: DataTexture; + + LTC_FLOAT_1: DataTexture; + LTC_FLOAT_2: DataTexture; +} + +export default class RectAreaLightNode extends AnalyticLightNode { + halfHeight: Node; + halfWidth: Node; + + constructor(light?: RectAreaLight | null); + + static setLTC(ltc: RectAreaLightTexturesLib): void; +} diff --git a/src-testing/src/nodes/lighting/ShadowNode.d.ts b/src-testing/src/nodes/lighting/ShadowNode.d.ts new file mode 100644 index 000000000..1b8d4fa9f --- /dev/null +++ b/src-testing/src/nodes/lighting/ShadowNode.d.ts @@ -0,0 +1,12 @@ +import { Light } from "../../lights/Light.js"; +import { LightShadow } from "../../lights/LightShadow.js"; +import Node from "../core/Node.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +declare class ShadowNode extends Node { + constructor(light: Light, shadow: LightShadow); +} + +export default ShadowNode; + +export const shadow: (light: Light, shadow: LightShadow) => ShaderNodeObject; diff --git a/src-testing/src/nodes/lighting/SpotLightNode.d.ts b/src-testing/src/nodes/lighting/SpotLightNode.d.ts new file mode 100644 index 000000000..0b1ae4b13 --- /dev/null +++ b/src-testing/src/nodes/lighting/SpotLightNode.d.ts @@ -0,0 +1,15 @@ +import { SpotLight } from "../../lights/SpotLight.js"; +import Node from "../core/Node.js"; +import AnalyticLightNode from "./AnalyticLightNode.js"; + +export default class PointLightNode extends AnalyticLightNode { + directionNode: Node; + + coneCosNode: Node; + penumbraCosNode: Node; + + cutoffDistanceNode: Node; + decayExponentNode: Node; + + constructor(light?: SpotLight | null); +} diff --git a/src-testing/src/nodes/materialx/MaterialXNodes.d.ts b/src-testing/src/nodes/materialx/MaterialXNodes.d.ts new file mode 100644 index 000000000..8007125a7 --- /dev/null +++ b/src-testing/src/nodes/materialx/MaterialXNodes.d.ts @@ -0,0 +1,107 @@ +import Node from "../core/Node.js"; +import MathNode from "../math/MathNode.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; +import { mx_hsvtorgb, mx_rgbtohsv } from "./lib/mx_hsv.js"; +import { mx_srgb_texture_to_lin_rec709 } from "./lib/mx_transform_color.js"; + +export function mx_aastep(threshold: NodeRepresentation, value: NodeRepresentation): ShaderNodeObject; + +export function mx_ramplr( + valuel: NodeRepresentation, + valuer: NodeRepresentation, + texcoord?: NodeRepresentation, +): ShaderNodeObject; +export function mx_ramptb( + valuet: NodeRepresentation, + valueb: NodeRepresentation, + texcoord?: NodeRepresentation, +): ShaderNodeObject; + +export function mx_splitlr( + valuel: NodeRepresentation, + valuer: NodeRepresentation, + center: NodeRepresentation, + texcoord?: NodeRepresentation, +): ShaderNodeObject; +export function mx_splittb( + valuet: NodeRepresentation, + valueb: NodeRepresentation, + center: NodeRepresentation, + texcoord?: NodeRepresentation, +): ShaderNodeObject; + +export function mx_transform_uv( + uv_scale?: NodeRepresentation, + uv_offset?: NodeRepresentation, + uv_geo?: NodeRepresentation, +): ShaderNodeObject; + +export function mx_safepower(in1: NodeRepresentation, in2?: NodeRepresentation): ShaderNodeObject; + +export function mx_contrast( + input: NodeRepresentation, + amount?: NodeRepresentation, + pivot?: NodeRepresentation, +): ShaderNodeObject; + +export function mx_noise_float( + texcoord?: NodeRepresentation, + amplitude?: NodeRepresentation, + pivot?: NodeRepresentation, +): ShaderNodeObject; +export function mx_noise_vec3( + texcoord?: NodeRepresentation, + amplitude?: NodeRepresentation, + pivot?: NodeRepresentation, +): ShaderNodeObject; +export function mx_noise_vec4( + texcoord?: NodeRepresentation, + amplitude?: NodeRepresentation, + pivot?: NodeRepresentation, +): ShaderNodeObject; + +export function mx_worley_noise_float( + texcoord?: NodeRepresentation, + jitter?: NodeRepresentation, +): ShaderNodeObject; +export function mx_worley_noise_vec2( + texcoord?: NodeRepresentation, + jitter?: NodeRepresentation, +): ShaderNodeObject; +export function mx_worley_noise_vec3( + texcoord?: NodeRepresentation, + jitter?: NodeRepresentation, +): ShaderNodeObject; + +export function mx_cell_noise_float(texcoord?: NodeRepresentation): ShaderNodeObject; + +export function mx_fractal_noise_float( + position?: NodeRepresentation, + octaves?: NodeRepresentation, + lacunarity?: NodeRepresentation, + diminish?: NodeRepresentation, + amplitude?: NodeRepresentation, +): ShaderNodeObject; +export function mx_fractal_noise_vec2( + position?: NodeRepresentation, + octaves?: NodeRepresentation, + lacunarity?: NodeRepresentation, + diminish?: NodeRepresentation, + amplitude?: NodeRepresentation, +): ShaderNodeObject; +export function mx_fractal_noise_vec3( + position?: NodeRepresentation, + octaves?: NodeRepresentation, + lacunarity?: NodeRepresentation, + diminish?: NodeRepresentation, + amplitude?: NodeRepresentation, +): ShaderNodeObject; +export function mx_fractal_noise_vec4( + position?: NodeRepresentation, + octaves?: NodeRepresentation, + lacunarity?: NodeRepresentation, + diminish?: NodeRepresentation, + amplitude?: NodeRepresentation, +): ShaderNodeObject; + +export { mx_hsvtorgb, mx_rgbtohsv, mx_srgb_texture_to_lin_rec709 }; diff --git a/src-testing/src/nodes/materialx/lib/mx_hsv.d.ts b/src-testing/src/nodes/materialx/lib/mx_hsv.d.ts new file mode 100644 index 000000000..ce11882e9 --- /dev/null +++ b/src-testing/src/nodes/materialx/lib/mx_hsv.d.ts @@ -0,0 +1,6 @@ +import Node from "../../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../../tsl/TSLCore.js"; + +export const mx_hsvtorgb: (hsv: NodeRepresentation) => ShaderNodeObject; + +export const mx_rgbtohsv: (c_immutable: NodeRepresentation) => ShaderNodeObject; diff --git a/src-testing/src/nodes/materialx/lib/mx_noise.d.ts b/src-testing/src/nodes/materialx/lib/mx_noise.d.ts new file mode 100644 index 000000000..2e5405f75 --- /dev/null +++ b/src-testing/src/nodes/materialx/lib/mx_noise.d.ts @@ -0,0 +1,359 @@ +import Node from "../../core/Node.js"; +import VarNode from "../../core/VarNode.js"; +import { NodeRepresentation, ShaderNodeObject } from "../../tsl/TSLCore.js"; + +export const mx_select: ( + b_immutable: NodeRepresentation, + t_immutable: NodeRepresentation, + f_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_negate_if: ( + val_immutable: NodeRepresentation, + b_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_floor: (x_immutable: NodeRepresentation) => ShaderNodeObject; + +export const mx_floorfrac: (x_immutable: NodeRepresentation, i: ShaderNodeObject) => ShaderNodeObject; + +export const mx_bilerp_0: ( + v0_immutable: NodeRepresentation, + v1_immutable: NodeRepresentation, + v2_immutable: NodeRepresentation, + v3_immutable: NodeRepresentation, + s_immutable: NodeRepresentation, + t_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_bilerp_1: ( + v0_immutable: NodeRepresentation, + v1_immutable: NodeRepresentation, + v2_immutable: NodeRepresentation, + v3_immutable: NodeRepresentation, + s_immutable: NodeRepresentation, + t_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_bilerp: ( + v0_immutable: NodeRepresentation, + v1_immutable: NodeRepresentation, + v2_immutable: NodeRepresentation, + v3_immutable: NodeRepresentation, + s_immutable: NodeRepresentation, + t_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_trilerp_0: ( + v0_immutable: NodeRepresentation, + v1_immutable: NodeRepresentation, + v2_immutable: NodeRepresentation, + v3_immutable: NodeRepresentation, + v4_immutable: NodeRepresentation, + v5_immutable: NodeRepresentation, + v6_immutable: NodeRepresentation, + v7_immutable: NodeRepresentation, + s_immutable: NodeRepresentation, + t_immutable: NodeRepresentation, + r_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_trilerp_1: ( + v0_immutable: NodeRepresentation, + v1_immutable: NodeRepresentation, + v2_immutable: NodeRepresentation, + v3_immutable: NodeRepresentation, + v4_immutable: NodeRepresentation, + v5_immutable: NodeRepresentation, + v6_immutable: NodeRepresentation, + v7_immutable: NodeRepresentation, + s_immutable: NodeRepresentation, + t_immutable: NodeRepresentation, + r_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_trilerp: ( + v0_immutable: NodeRepresentation, + v1_immutable: NodeRepresentation, + v2_immutable: NodeRepresentation, + v3_immutable: NodeRepresentation, + v4_immutable: NodeRepresentation, + v5_immutable: NodeRepresentation, + v6_immutable: NodeRepresentation, + v7_immutable: NodeRepresentation, + s_immutable: NodeRepresentation, + t_immutable: NodeRepresentation, + r_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_gradient_float_0: ( + hash_immutable: NodeRepresentation, + x_immutable: NodeRepresentation, + y_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_gradient_float_1: ( + hash_immutable: NodeRepresentation, + x_immutable: NodeRepresentation, + y_immutable: NodeRepresentation, + z_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_gradient_float: ( + hash_immutable: NodeRepresentation, + x_immutable: NodeRepresentation, + y_immutable: NodeRepresentation, + z_immutable?: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_gradient_vec3_0: ( + hash_immutable: NodeRepresentation, + x_immutable: NodeRepresentation, + y_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_gradient_vec3_1: ( + hash_immutable: NodeRepresentation, + x_immutable: NodeRepresentation, + y_immutable: NodeRepresentation, + z_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_gradient_vec3: ( + hash_immutable: NodeRepresentation, + x_immutable: NodeRepresentation, + y_immutable: NodeRepresentation, + z_immutable?: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_gradient_scale2d_0: (v_immutable: NodeRepresentation) => ShaderNodeObject; + +export const mx_gradient_scale3d_0: (v_immutable: NodeRepresentation) => ShaderNodeObject; + +export const mx_gradient_scale2d_1: (v_immutable: NodeRepresentation) => ShaderNodeObject; + +export const mx_gradient_scale2d: (v_immutable: NodeRepresentation) => ShaderNodeObject; + +export const mx_gradient_scale3d_1: (v_immutable: NodeRepresentation) => ShaderNodeObject; + +export const mx_gradient_scale3d: (v_immutable: NodeRepresentation) => ShaderNodeObject; + +export const mx_rotl32: (x_immutable: NodeRepresentation, k_immutable: NodeRepresentation) => ShaderNodeObject; + +export const mx_bjmix: ( + a: ShaderNodeObject, + b: ShaderNodeObject, + c: ShaderNodeObject, +) => ShaderNodeObject; + +export const mx_bjfinal: ( + a_immutable: NodeRepresentation, + b_immutable: NodeRepresentation, + c_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_bits_to_01: (bits_immutable: NodeRepresentation) => ShaderNodeObject; + +export const mx_fade: (t_immutable: NodeRepresentation) => ShaderNodeObject; + +export const mx_hash_int_0: (x_immutable: NodeRepresentation) => ShaderNodeObject; + +export const mx_hash_int_1: ( + x_immutable: NodeRepresentation, + y_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_hash_int_2: ( + x_immutable: NodeRepresentation, + y_immutable: NodeRepresentation, + z_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_hash_int_3: ( + x_immutable: NodeRepresentation, + y_immutable: NodeRepresentation, + z_immutable: NodeRepresentation, + xx_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_hash_int_4: ( + x_immutable: NodeRepresentation, + y_immutable: NodeRepresentation, + z_immutable: NodeRepresentation, + xx_immutable: NodeRepresentation, + yy_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_hash_int: ( + x_immutable: NodeRepresentation, + y_immutable?: NodeRepresentation, + z_immutable?: NodeRepresentation, + xx_immutable?: NodeRepresentation, + yy_immutable?: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_hash_vec3_0: ( + x_immutable: NodeRepresentation, + y_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_hash_vec3_1: ( + x_immutable: NodeRepresentation, + y_immutable: NodeRepresentation, + z_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_hash_vec3: ( + x_immutable: NodeRepresentation, + y_immutable: NodeRepresentation, + z_immutable?: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_perlin_noise_float_0: (p_immutable: NodeRepresentation) => ShaderNodeObject; + +export const mx_perlin_noise_float_1: (p_immutable: NodeRepresentation) => ShaderNodeObject; + +export const mx_perlin_noise_float: (p_immutable: NodeRepresentation) => ShaderNodeObject; + +export const mx_perlin_noise_vec3_0: (p_immutable: NodeRepresentation) => ShaderNodeObject; + +export const mx_perlin_noise_vec3_1: (p_immutable: NodeRepresentation) => ShaderNodeObject; + +export const mx_perlin_noise_vec3: (p_immutable: NodeRepresentation) => ShaderNodeObject; + +export const mx_cell_noise_float_0: (p_immutable: NodeRepresentation) => ShaderNodeObject; + +export const mx_cell_noise_float_1: (p_immutable: NodeRepresentation) => ShaderNodeObject; + +export const mx_cell_noise_float_2: (p_immutable: NodeRepresentation) => ShaderNodeObject; + +export const mx_cell_noise_float_3: (p_immutable: NodeRepresentation) => ShaderNodeObject; + +export const mx_cell_noise_float: (p_immutable: NodeRepresentation) => ShaderNodeObject; + +export const mx_cell_noise_vec3_0: (p_immutable: NodeRepresentation) => ShaderNodeObject; + +export const mx_cell_noise_vec3_1: (p_immutable: NodeRepresentation) => ShaderNodeObject; + +export const mx_cell_noise_vec3_2: (p_immutable: NodeRepresentation) => ShaderNodeObject; + +export const mx_cell_noise_vec3_3: (p_immutable: NodeRepresentation) => ShaderNodeObject; + +export const mx_cell_noise_vec3: (p_immutable: NodeRepresentation) => ShaderNodeObject; + +export const mx_fractal_noise_float: ( + p_immutable: NodeRepresentation, + octaves_immutable: NodeRepresentation, + lacunarity_immutable: NodeRepresentation, + diminish_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_fractal_noise_vec3: ( + p_immutable: NodeRepresentation, + octaves_immutable: NodeRepresentation, + lacunarity_immutable: NodeRepresentation, + diminish_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_fractal_noise_vec2: ( + p_immutable: NodeRepresentation, + octaves_immutable: NodeRepresentation, + lacunarity_immutable: NodeRepresentation, + diminish_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_fractal_noise_vec4: ( + p_immutable: NodeRepresentation, + octaves_immutable: NodeRepresentation, + lacunarity_immutable: NodeRepresentation, + diminish_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_worley_distance_0: ( + p_immutable: NodeRepresentation, + x_immutable: NodeRepresentation, + y_immutable: NodeRepresentation, + z_immutable: NodeRepresentation, + xoff_immutable: NodeRepresentation, + yoff_immutable: NodeRepresentation, + jitter_immutable: NodeRepresentation, + metric_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_worley_distance_1: ( + p_immutable: NodeRepresentation, + x_immutable: NodeRepresentation, + y_immutable: NodeRepresentation, + z_immutable: NodeRepresentation, + xoff_immutable: NodeRepresentation, + yoff_immutable: NodeRepresentation, + zoff_immutable: NodeRepresentation, + jitter_immutable: NodeRepresentation, + metric_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_worley_distance: ( + p_immutable: NodeRepresentation, + x_immutable: NodeRepresentation, + y_immutable: NodeRepresentation, + z_immutable: NodeRepresentation, + xoff_immutable: NodeRepresentation, + yoff_immutable: NodeRepresentation, + zoff_immutable: NodeRepresentation, + jitter_immutable: NodeRepresentation, + metric_immutable?: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_worley_noise_float_0: ( + p_immutable: NodeRepresentation, + jitter_immutable: NodeRepresentation, + metric_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_worley_noise_vec2_0: ( + p_immutable: NodeRepresentation, + jitter_immutable: NodeRepresentation, + metric_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_worley_noise_vec3_0: ( + p_immutable: NodeRepresentation, + jitter_immutable: NodeRepresentation, + metric_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_worley_noise_float_1: ( + p_immutable: NodeRepresentation, + jitter_immutable: NodeRepresentation, + metric_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_worley_noise_float: ( + p_immutable: NodeRepresentation, + jitter_immutable: NodeRepresentation, + metric_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_worley_noise_vec2_1: ( + p_immutable: NodeRepresentation, + jitter_immutable: NodeRepresentation, + metric_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_worley_noise_vec2: ( + p_immutable: NodeRepresentation, + jitter_immutable: NodeRepresentation, + metric_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_worley_noise_vec3_1: ( + p_immutable: NodeRepresentation, + jitter_immutable: NodeRepresentation, + metric_immutable: NodeRepresentation, +) => ShaderNodeObject; + +export const mx_worley_noise_vec3: ( + p_immutable: NodeRepresentation, + jitter_immutable: NodeRepresentation, + metric_immutable: NodeRepresentation, +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/materialx/lib/mx_transform_color.d.ts b/src-testing/src/nodes/materialx/lib/mx_transform_color.d.ts new file mode 100644 index 000000000..418818d0e --- /dev/null +++ b/src-testing/src/nodes/materialx/lib/mx_transform_color.d.ts @@ -0,0 +1,4 @@ +import Node from "../../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../../tsl/TSLCore.js"; + +export const mx_srgb_texture_to_lin_rec709: (color_immutable: NodeRepresentation) => ShaderNodeObject; diff --git a/src-testing/src/nodes/math/ConditionalNode.d.ts b/src-testing/src/nodes/math/ConditionalNode.d.ts new file mode 100644 index 000000000..5313a9836 --- /dev/null +++ b/src-testing/src/nodes/math/ConditionalNode.d.ts @@ -0,0 +1,39 @@ +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +declare class ConditionalNode extends Node { + condNode: Node; + ifNode: Node; + elseNode: Node; + + constructor(condNode: Node, ifNode: Node, elseNode: Node); +} + +export default ConditionalNode; + +export const select: ( + condNode: NodeRepresentation, + ifNode: NodeRepresentation, + elseNode: NodeRepresentation, +) => ShaderNodeObject; + +declare module "../tsl/TSLCore.js" { + interface NodeElements { + select: typeof select; + } +} + +/** + * @deprecated cond() has been renamed to select() + */ +export const cond: ( + condNode: NodeRepresentation, + ifNode: NodeRepresentation, + elseNode: NodeRepresentation, +) => ShaderNodeObject; + +declare module "../tsl/TSLCore.js" { + interface NodeElements { + cond: typeof cond; + } +} diff --git a/src-testing/src/nodes/math/Hash.d.ts b/src-testing/src/nodes/math/Hash.d.ts new file mode 100644 index 000000000..df9e81997 --- /dev/null +++ b/src-testing/src/nodes/math/Hash.d.ts @@ -0,0 +1,4 @@ +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +export const hash: (seed: NodeRepresentation) => ShaderNodeObject; diff --git a/src-testing/src/nodes/math/MathNode.d.ts b/src-testing/src/nodes/math/MathNode.d.ts new file mode 100644 index 000000000..f65546d75 --- /dev/null +++ b/src-testing/src/nodes/math/MathNode.d.ts @@ -0,0 +1,273 @@ +import Node from "../core/Node.js"; +import TempNode from "../core/TempNode.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; +import OperatorNode from "./OperatorNode.js"; + +export type MathNodeMethod1 = + | typeof MathNode.RADIANS + | typeof MathNode.DEGREES + | typeof MathNode.EXP + | typeof MathNode.EXP2 + | typeof MathNode.LOG + | typeof MathNode.LOG2 + | typeof MathNode.SQRT + | typeof MathNode.INVERSE_SQRT + | typeof MathNode.FLOOR + | typeof MathNode.CEIL + | typeof MathNode.NORMALIZE + | typeof MathNode.FRACT + | typeof MathNode.SIN + | typeof MathNode.COS + | typeof MathNode.TAN + | typeof MathNode.ASIN + | typeof MathNode.ACOS + | typeof MathNode.ATAN + | typeof MathNode.ABS + | typeof MathNode.SIGN + | typeof MathNode.LENGTH + | typeof MathNode.NEGATE + | typeof MathNode.ONE_MINUS + | typeof MathNode.DFDX + | typeof MathNode.DFDY + | typeof MathNode.ROUND + | typeof MathNode.RECIPROCAL + | typeof MathNode.TRUNC + | typeof MathNode.FWIDTH + | typeof MathNode.BITCAST + | typeof MathNode.TRANSPOSE; + +export type MathNodeMethod2 = + | typeof MathNode.ATAN2 + | typeof MathNode.MIN + | typeof MathNode.MAX + | typeof MathNode.MOD + | typeof MathNode.STEP + | typeof MathNode.REFLECT + | typeof MathNode.DISTANCE + | typeof MathNode.DOT + | typeof MathNode.CROSS + | typeof MathNode.POW + | typeof MathNode.TRANSFORM_DIRECTION; + +export type MathNodeMethod3 = + | typeof MathNode.MIX + | typeof MathNode.CLAMP + | typeof MathNode.REFRACT + | typeof MathNode.SMOOTHSTEP + | typeof MathNode.FACEFORWARD; + +export type MathNodeMethod = MathNodeMethod1 | MathNodeMethod2 | MathNodeMethod3; + +export default class MathNode extends TempNode { + // 1 input + + static ALL: "all"; + static ANY: "any"; + static EQUALS: "equals"; + + static RADIANS: "radians"; + static DEGREES: "degrees"; + static EXP: "exp"; + static EXP2: "exp2"; + static LOG: "log"; + static LOG2: "log2"; + static SQRT: "sqrt"; + static INVERSE_SQRT: "inversesqrt"; + static FLOOR: "floor"; + static CEIL: "ceil"; + static NORMALIZE: "normalize"; + static FRACT: "fract"; + static SIN: "sin"; + static COS: "cos"; + static TAN: "tan"; + static ASIN: "asin"; + static ACOS: "acos"; + static ATAN: "atan"; + static ABS: "abs"; + static SIGN: "sign"; + static LENGTH: "length"; + static NEGATE: "negate"; + static ONE_MINUS: "oneMinus"; + static DFDX: "dFdx"; + static DFDY: "dFdy"; + static ROUND: "round"; + static RECIPROCAL: "reciprocal"; + static TRUNC: "trunc"; + static FWIDTH: "fwidth"; + static BITCAST: "bitcast"; + static TRANSPOSE: "transpose"; + + // 2 inputs + + static ATAN2: "atan2"; + static MIN: "min"; + static MAX: "max"; + static MOD: "mod"; + static STEP: "step"; + static REFLECT: "reflect"; + static DISTANCE: "distance"; + static DOT: "dot"; + static CROSS: "cross"; + static POW: "pow"; + static TRANSFORM_DIRECTION: "transformDirection"; + + // 3 inputs + + static MIX: "mix"; + static CLAMP: "clamp"; + static REFRACT: "refract"; + static SMOOTHSTEP: "smoothstep"; + static FACEFORWARD: "faceforward"; + + method: MathNodeMethod; + aNode: Node; + bNode: Node | null; + cNode: Node | null; + + constructor(method: MathNodeMethod1, aNode: Node); + constructor(method: MathNodeMethod2, aNode: Node, bNode: Node); + constructor(method: MathNodeMethod3, aNode: Node, bNode: Node, cNode: Node); +} + +export const EPSILON: ShaderNodeObject; +export const INFINITY: ShaderNodeObject; +export const PI: ShaderNodeObject; +export const PI2: ShaderNodeObject; + +type Unary = (a: NodeRepresentation) => ShaderNodeObject; + +export const all: Unary; +export const any: Unary; +export const equals: Unary; + +export const radians: Unary; +export const degrees: Unary; +export const exp: Unary; +export const exp2: Unary; +export const log: Unary; +export const log2: Unary; +export const sqrt: Unary; +export const inverseSqrt: Unary; +export const floor: Unary; +export const ceil: Unary; +export const normalize: Unary; +export const fract: Unary; +export const sin: Unary; +export const cos: Unary; +export const tan: Unary; +export const asin: Unary; +export const acos: Unary; +export const atan: Unary; +export const abs: Unary; +export const sign: Unary; +export const length: Unary; +export const negate: Unary; +export const oneMinus: Unary; +export const dFdx: Unary; +export const dFdy: Unary; +export const round: Unary; +export const reciprocal: Unary; +export const trunc: Unary; +export const fwidth: Unary; +export const bitcast: Unary; +export const transpose: Unary; + +type Binary = (a: NodeRepresentation, b: NodeRepresentation) => ShaderNodeObject; + +export const atan2: Binary; +export const min: Binary; +export const max: Binary; +export const mod: Binary; +export const step: Binary; +export const reflect: Binary; +export const distance: Binary; +export const difference: Binary; +export const dot: Binary; +export const cross: Binary; +export const pow: Binary; +export const pow2: Binary; +export const pow3: Binary; +export const pow4: Binary; +export const transformDirection: Binary; + +type Ternary = (a: NodeRepresentation, b: NodeRepresentation, c: NodeRepresentation) => ShaderNodeObject; + +export const cbrt: Unary; +export const lengthSq: Unary; +export const mix: Ternary; +export const clamp: ( + a: NodeRepresentation, + b?: NodeRepresentation, + c?: NodeRepresentation, +) => ShaderNodeObject; +export const saturate: Unary; +export const refract: Ternary; +export const smoothstep: Ternary; +export const faceForward: Ternary; + +export const rand: (uv: NodeRepresentation) => ShaderNodeObject; + +export const mixElement: Ternary; +export const smoothstepElement: Ternary; + +declare module "../tsl/TSLCore.js" { + interface NodeElements { + all: typeof all; + any: typeof any; + equals: typeof equals; + radians: typeof radians; + degrees: typeof degrees; + exp: typeof exp; + exp2: typeof exp2; + log: typeof log; + log2: typeof log2; + sqrt: typeof sqrt; + inverseSqrt: typeof inverseSqrt; + floor: typeof floor; + ceil: typeof ceil; + normalize: typeof normalize; + fract: typeof fract; + sin: typeof sin; + cos: typeof cos; + tan: typeof tan; + asin: typeof asin; + acos: typeof acos; + atan: typeof atan; + abs: typeof abs; + sign: typeof sign; + length: typeof length; + lengthSq: typeof lengthSq; + negate: typeof negate; + oneMinus: typeof oneMinus; + dFdx: typeof dFdx; + dFdy: typeof dFdy; + round: typeof round; + reciprocal: typeof reciprocal; + trunc: typeof trunc; + fwidth: typeof fwidth; + atan2: typeof atan2; + min: typeof min; + max: typeof max; + mod: typeof mod; + step: typeof step; + reflect: typeof reflect; + distance: typeof distance; + dot: typeof dot; + cross: typeof cross; + pow: typeof pow; + pow2: typeof pow2; + pow3: typeof pow3; + pow4: typeof pow4; + transformDirection: typeof transformDirection; + mix: typeof mixElement; + clamp: typeof clamp; + refract: typeof refract; + smoothstep: typeof smoothstepElement; + faceForward: typeof faceForward; + difference: typeof difference; + saturate: typeof saturate; + cbrt: typeof cbrt; + transpose: typeof transpose; + rand: typeof rand; + } +} diff --git a/src-testing/src/nodes/math/MathUtils.d.ts b/src-testing/src/nodes/math/MathUtils.d.ts new file mode 100644 index 000000000..572d9eef5 --- /dev/null +++ b/src-testing/src/nodes/math/MathUtils.d.ts @@ -0,0 +1,6 @@ +import { Binary, Ternary } from "./MathNode.js"; + +export const parabola: Binary; +export const gain: Binary; +export const pcurve: Ternary; +export const sinc: Binary; diff --git a/src-testing/src/nodes/math/OperatorNode.d.ts b/src-testing/src/nodes/math/OperatorNode.d.ts new file mode 100644 index 000000000..77157ea73 --- /dev/null +++ b/src-testing/src/nodes/math/OperatorNode.d.ts @@ -0,0 +1,97 @@ +import Node from "../core/Node.js"; +import TempNode from "../core/TempNode.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +export type OperatorNodeOp = + | "%" + | "&" + | "|" + | "^" + | ">>" + | "<<" + | "==" + | "&&" + | "||" + | "^^" + | "<" + | ">" + | "<=" + | ">=" + | "+" + | "-" + | "*" + | "/"; + +export default class OperatorNode extends TempNode { + aNode: Node; + bNode: Node; + op: OperatorNodeOp; + + constructor(op: OperatorNodeOp, ...params: [Node, Node, ...Node[]]); +} + +type Operator = ( + a: NodeRepresentation, + b: NodeRepresentation, + ...others: NodeRepresentation[] +) => ShaderNodeObject; + +export const add: Operator; +export const sub: Operator; +export const mul: Operator; +export const div: Operator; +export const modInt: Operator; +export const equal: Operator; +export const lessThan: Operator; +export const greaterThan: Operator; +export const lessThanEqual: Operator; +export const greaterThanEqual: Operator; +export const and: Operator; +export const or: Operator; +export const not: (a: NodeRepresentation) => ShaderNodeObject; +export const xor: Operator; +export const bitAnd: Operator; +export const bitNot: (a: NodeRepresentation) => ShaderNodeObject; +export const bitOr: Operator; +export const bitXor: Operator; +export const shiftLeft: Operator; +export const shiftRight: Operator; + +declare module "../tsl/TSLCore.js" { + interface NodeElements { + add: typeof add; + sub: typeof sub; + mul: typeof mul; + div: typeof div; + modInt: typeof modInt; + equal: typeof equal; + lessThan: typeof lessThan; + greaterThan: typeof greaterThan; + lessThanEqual: typeof lessThanEqual; + greaterThanEqual: typeof greaterThanEqual; + and: typeof and; + or: typeof or; + not: typeof not; + xor: typeof xor; + bitAnd: typeof bitAnd; + bitNot: typeof bitNot; + bitOr: typeof bitOr; + bitXor: typeof bitXor; + shiftLeft: typeof shiftLeft; + shiftRight: typeof shiftRight; + } +} + +/** + * @deprecated .remainder() has been renamed to .modInt(). + */ +export const remainder: Operator; + +declare module "../tsl/TSLCore.js" { + interface NodeElements { + /** + * @deprecated .remainder() has been renamed to .modInt(). + */ + remainder: typeof remainder; + } +} diff --git a/src-testing/src/nodes/math/TriNoise3D.d.ts b/src-testing/src/nodes/math/TriNoise3D.d.ts new file mode 100644 index 000000000..f5220dbe6 --- /dev/null +++ b/src-testing/src/nodes/math/TriNoise3D.d.ts @@ -0,0 +1,12 @@ +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +export const tri: (x: NodeRepresentation) => ShaderNodeObject; + +export const tri3: (p: NodeRepresentation) => ShaderNodeObject; + +export const triNoise3D: ( + p_immutable: NodeRepresentation, + spd: NodeRepresentation, + time: NodeRepresentation, +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/parsers/GLSLNodeFunction.d.ts b/src-testing/src/nodes/parsers/GLSLNodeFunction.d.ts new file mode 100644 index 000000000..ec2396423 --- /dev/null +++ b/src-testing/src/nodes/parsers/GLSLNodeFunction.d.ts @@ -0,0 +1,9 @@ +import NodeFunction from "../core/NodeFunction.js"; + +declare class GLSLNodeFunction extends NodeFunction { + constructor(source: string); + + getCode(name?: string): string; +} + +export default GLSLNodeFunction; diff --git a/src-testing/src/nodes/parsers/GLSLNodeParser.d.ts b/src-testing/src/nodes/parsers/GLSLNodeParser.d.ts new file mode 100644 index 000000000..f6b663d4b --- /dev/null +++ b/src-testing/src/nodes/parsers/GLSLNodeParser.d.ts @@ -0,0 +1,8 @@ +import NodeParser from "../core/NodeParser.js"; +import GLSLNodeFunction from "./GLSLNodeFunction.js"; + +declare class GLSLNodeParser extends NodeParser { + parseFunction(source: string): GLSLNodeFunction; +} + +export default GLSLNodeParser; diff --git a/src-testing/src/nodes/pmrem/PMREMNode.d.ts b/src-testing/src/nodes/pmrem/PMREMNode.d.ts new file mode 100644 index 000000000..2a957c8e6 --- /dev/null +++ b/src-testing/src/nodes/pmrem/PMREMNode.d.ts @@ -0,0 +1,22 @@ +import { Texture } from "../../textures/Texture.js"; +import Node from "../core/Node.js"; +import TempNode from "../core/TempNode.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +declare class PMREMNode extends TempNode { + uvNode: Node | null; + levelNode: Node | null; + + constructor(value: Texture, uvNode?: Node | null, levelNode?: Node | null); + + set value(value: Texture); + get value(): Texture; +} + +export default PMREMNode; + +export const pmremTexture: ( + value: Texture, + uvNode?: NodeRepresentation, + levelNode?: NodeRepresentation, +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/pmrem/PMREMUtils.d.ts b/src-testing/src/nodes/pmrem/PMREMUtils.d.ts new file mode 100644 index 000000000..947e7fe25 --- /dev/null +++ b/src-testing/src/nodes/pmrem/PMREMUtils.d.ts @@ -0,0 +1,28 @@ +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +export const getDirection: (uv_immutable: NodeRepresentation, face: NodeRepresentation) => ShaderNodeObject; + +export const textureCubeUV: ( + envMap: NodeRepresentation, + sampleDir_immutable: NodeRepresentation, + roughness_immutable: NodeRepresentation, + CUBEUV_TEXEL_WIDTH: NodeRepresentation, + CUBEUV_TEXEL_HEIGHT: NodeRepresentation, + CUBEUV_MAX_MIP: NodeRepresentation, +) => ShaderNodeObject; + +export const blur: ( + n: NodeRepresentation, + latitudinal: NodeRepresentation, + poleAxis: NodeRepresentation, + outputDirection: NodeRepresentation, + weights: NodeRepresentation, + samples: NodeRepresentation, + dTheta: NodeRepresentation, + mipInt: NodeRepresentation, + envMap: NodeRepresentation, + CUBEUV_TEXEL_WIDTH: NodeRepresentation, + CUBEUV_TEXEL_HEIGHT: NodeRepresentation, + CUBEUV_MAX_MIP: NodeRepresentation, +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/procedural/Checker.d.ts b/src-testing/src/nodes/procedural/Checker.d.ts new file mode 100644 index 000000000..af7cce3a7 --- /dev/null +++ b/src-testing/src/nodes/procedural/Checker.d.ts @@ -0,0 +1,4 @@ +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +export const checker: (coord?: NodeRepresentation) => ShaderNodeObject; diff --git a/src-testing/src/nodes/tsl/TSLBase.d.ts b/src-testing/src/nodes/tsl/TSLBase.d.ts new file mode 100644 index 000000000..297b9a483 --- /dev/null +++ b/src-testing/src/nodes/tsl/TSLBase.d.ts @@ -0,0 +1,21 @@ +export * from "../accessors/BufferAttributeNode.js"; +export * from "../code/ExpressionNode.js"; +export * from "../code/FunctionCallNode.js"; +export * from "../core/AssignNode.js"; +export * from "../core/BypassNode.js"; +export * from "../core/CacheNode.js"; +export * from "../core/ContextNode.js"; +export * from "../core/PropertyNode.js"; +export * from "../core/UniformNode.js"; +export * from "../core/VarNode.js"; +export * from "../core/VaryingNode.js"; +export * from "../display/ColorSpaceNode.js"; +export * from "../display/RenderOutputNode.js"; +export * from "../display/ToneMappingNode.js"; +export * from "../gpgpu/ComputeNode.js"; +export * from "../math/ConditionalNode.js"; +export * from "../math/MathNode.js"; +export * from "../math/OperatorNode.js"; +export * from "../utils/Discard.js"; +export * from "../utils/RemapNode.js"; +export * from "./TSLCore.js"; diff --git a/src-testing/src/nodes/tsl/TSLCore.ts b/src-testing/src/nodes/tsl/TSLCore.ts new file mode 100644 index 000000000..4ac059f08 --- /dev/null +++ b/src-testing/src/nodes/tsl/TSLCore.ts @@ -0,0 +1,533 @@ +import Node from '../core/Node.js'; +import ArrayElementNode from '../utils/ArrayElementNode.js'; +import ConvertNode from '../utils/ConvertNode.js'; +import JoinNode from '../utils/JoinNode.js'; +import SplitNode from '../utils/SplitNode.js'; +import SetNode from '../utils/SetNode.js'; +import FlipNode from '../utils/FlipNode.js'; +import ConstNode from '../core/ConstNode.js'; +import { getValueFromType, getValueType } from '../core/NodeUtils.js'; + +// + +let currentStack = null; + +const NodeElements = new Map(); + +export function addMethodChaining(name, nodeElement) { + if (NodeElements.has(name)) { + console.warn(`Redefinition of method chaining ${name}`); + return; + } + + if (typeof nodeElement !== 'function') throw new Error(`Node element ${name} is not a function`); + + NodeElements.set(name, nodeElement); +} + +const parseSwizzle = props => props.replace(/r|s/g, 'x').replace(/g|t/g, 'y').replace(/b|p/g, 'z').replace(/a|q/g, 'w'); +const parseSwizzleAndSort = props => parseSwizzle(props).split('').sort().join(''); + +const shaderNodeHandler = { + setup(NodeClosure, params) { + const inputs = params.shift(); + + return NodeClosure(nodeObjects(inputs), ...params); + }, + + get(node, prop, nodeObj) { + if (typeof prop === 'string' && node[prop] === undefined) { + if (node.isStackNode !== true && prop === 'assign') { + return (...params) => { + currentStack.assign(nodeObj, ...params); + + return nodeObj; + }; + } else if (NodeElements.has(prop)) { + const nodeElement = NodeElements.get(prop); + + return node.isStackNode + ? (...params) => nodeObj.add(nodeElement(...params)) + : (...params) => nodeElement(nodeObj, ...params); + } else if (prop === 'self') { + return node; + } else if (prop.endsWith('Assign') && NodeElements.has(prop.slice(0, prop.length - 'Assign'.length))) { + const nodeElement = NodeElements.get(prop.slice(0, prop.length - 'Assign'.length)); + + return node.isStackNode + ? (...params) => nodeObj.assign(params[0], nodeElement(...params)) + : (...params) => nodeObj.assign(nodeElement(nodeObj, ...params)); + } else if (/^[xyzwrgbastpq]{1,4}$/.test(prop) === true) { + // accessing properties ( swizzle ) + + prop = parseSwizzle(prop); + + return nodeObject(new SplitNode(nodeObj, prop)); + } else if (/^set[XYZWRGBASTPQ]{1,4}$/.test(prop) === true) { + // set properties ( swizzle ) and sort to xyzw sequence + + prop = parseSwizzleAndSort(prop.slice(3).toLowerCase()); + + return value => nodeObject(new SetNode(node, prop, value)); + } else if (/^flip[XYZWRGBASTPQ]{1,4}$/.test(prop) === true) { + // set properties ( swizzle ) and sort to xyzw sequence + + prop = parseSwizzleAndSort(prop.slice(4).toLowerCase()); + + return () => nodeObject(new FlipNode(nodeObject(node), prop)); + } else if (prop === 'width' || prop === 'height' || prop === 'depth') { + // accessing property + + if (prop === 'width') prop = 'x'; + else if (prop === 'height') prop = 'y'; + else if (prop === 'depth') prop = 'z'; + + return nodeObject(new SplitNode(node, prop)); + } else if (/^\d+$/.test(prop) === true) { + // accessing array + + return nodeObject(new ArrayElementNode(nodeObj, new ConstNode(Number(prop), 'uint'))); + } + } + + return Reflect.get(node, prop, nodeObj); + }, + + set(node, prop, value, nodeObj) { + if (typeof prop === 'string' && node[prop] === undefined) { + // setting properties + + if ( + /^[xyzwrgbastpq]{1,4}$/.test(prop) === true || + prop === 'width' || + prop === 'height' || + prop === 'depth' || + /^\d+$/.test(prop) === true + ) { + nodeObj[prop].assign(value); + + return true; + } + } + + return Reflect.set(node, prop, value, nodeObj); + }, +}; + +const nodeObjectsCacheMap = new WeakMap(); +const nodeBuilderFunctionsCacheMap = new WeakMap(); + +const ShaderNodeObject = function (obj, altType = null) { + const type = getValueType(obj); + + if (type === 'node') { + let nodeObject = nodeObjectsCacheMap.get(obj); + + if (nodeObject === undefined) { + nodeObject = new Proxy(obj, shaderNodeHandler); + + nodeObjectsCacheMap.set(obj, nodeObject); + nodeObjectsCacheMap.set(nodeObject, nodeObject); + } + + return nodeObject; + } else if ( + (altType === null && (type === 'float' || type === 'boolean')) || + (type && type !== 'shader' && type !== 'string') + ) { + return nodeObject(getConstNode(obj, altType)); + } else if (type === 'shader') { + return Fn(obj); + } + + return obj; +}; + +const ShaderNodeObjects = function (objects, altType = null) { + for (const name in objects) { + objects[name] = nodeObject(objects[name], altType); + } + + return objects; +}; + +const ShaderNodeArray = function (array, altType = null) { + const len = array.length; + + for (let i = 0; i < len; i++) { + array[i] = nodeObject(array[i], altType); + } + + return array; +}; + +const ShaderNodeProxy = function (NodeClass, scope = null, factor = null, settings = null) { + const assignNode = node => nodeObject(settings !== null ? Object.assign(node, settings) : node); + + if (scope === null) { + return (...params) => { + return assignNode(new NodeClass(...nodeArray(params))); + }; + } else if (factor !== null) { + factor = nodeObject(factor); + + return (...params) => { + return assignNode(new NodeClass(scope, ...nodeArray(params), factor)); + }; + } else { + return (...params) => { + return assignNode(new NodeClass(scope, ...nodeArray(params))); + }; + } +}; + +const ShaderNodeImmutable = function (NodeClass, ...params) { + return nodeObject(new NodeClass(...nodeArray(params))); +}; + +class ShaderCallNodeInternal extends Node { + constructor(shaderNode, inputNodes) { + super(); + + this.shaderNode = shaderNode; + this.inputNodes = inputNodes; + } + + getNodeType(builder) { + return this.shaderNode.nodeType || this.getOutputNode(builder).getNodeType(builder); + } + + call(builder) { + const { shaderNode, inputNodes } = this; + + const properties = builder.getNodeProperties(shaderNode); + if (properties.onceOutput) return properties.onceOutput; + + // + + let result = null; + + if (shaderNode.layout) { + let functionNodesCacheMap = nodeBuilderFunctionsCacheMap.get(builder.constructor); + + if (functionNodesCacheMap === undefined) { + functionNodesCacheMap = new WeakMap(); + + nodeBuilderFunctionsCacheMap.set(builder.constructor, functionNodesCacheMap); + } + + let functionNode = functionNodesCacheMap.get(shaderNode); + + if (functionNode === undefined) { + functionNode = nodeObject(builder.buildFunctionNode(shaderNode)); + + functionNodesCacheMap.set(shaderNode, functionNode); + } + + if (builder.currentFunctionNode !== null) { + builder.currentFunctionNode.includes.push(functionNode); + } + + result = nodeObject(functionNode.call(inputNodes)); + } else { + const jsFunc = shaderNode.jsFunc; + const outputNode = inputNodes !== null ? jsFunc(inputNodes, builder) : jsFunc(builder); + + result = nodeObject(outputNode); + } + + if (shaderNode.once) { + properties.onceOutput = result; + } + + return result; + } + + getOutputNode(builder) { + const properties = builder.getNodeProperties(this); + + if (properties.outputNode === null) { + properties.outputNode = this.setupOutput(builder); + } + + return properties.outputNode; + } + + setup(builder) { + return this.getOutputNode(builder); + } + + setupOutput(builder) { + builder.addStack(); + + builder.stack.outputNode = this.call(builder); + + return builder.removeStack(); + } + + generate(builder, output) { + const outputNode = this.getOutputNode(builder); + + return outputNode.build(builder, output); + } +} + +class ShaderNodeInternal extends Node { + constructor(jsFunc, nodeType) { + super(nodeType); + + this.jsFunc = jsFunc; + this.layout = null; + + this.global = true; + + this.once = false; + } + + setLayout(layout) { + this.layout = layout; + + return this; + } + + call(inputs = null) { + nodeObjects(inputs); + + return nodeObject(new ShaderCallNodeInternal(this, inputs)); + } + + setup() { + return this.call(); + } +} + +const bools = [false, true]; +const uints = [0, 1, 2, 3]; +const ints = [-1, -2]; +const floats = [ + 0.5, + 1.5, + 1 / 3, + 1e-6, + 1e6, + Math.PI, + Math.PI * 2, + 1 / Math.PI, + 2 / Math.PI, + 1 / (Math.PI * 2), + Math.PI / 2, +]; + +const boolsCacheMap = new Map(); +for (const bool of bools) boolsCacheMap.set(bool, new ConstNode(bool)); + +const uintsCacheMap = new Map(); +for (const uint of uints) uintsCacheMap.set(uint, new ConstNode(uint, 'uint')); + +const intsCacheMap = new Map([...uintsCacheMap].map(el => new ConstNode(el.value, 'int'))); +for (const int of ints) intsCacheMap.set(int, new ConstNode(int, 'int')); + +const floatsCacheMap = new Map([...intsCacheMap].map(el => new ConstNode(el.value))); +for (const float of floats) floatsCacheMap.set(float, new ConstNode(float)); +for (const float of floats) floatsCacheMap.set(-float, new ConstNode(-float)); + +const cacheMaps = { bool: boolsCacheMap, uint: uintsCacheMap, ints: intsCacheMap, float: floatsCacheMap }; + +const constNodesCacheMap = new Map([...boolsCacheMap, ...floatsCacheMap]); + +const getConstNode = (value, type) => { + if (constNodesCacheMap.has(value)) { + return constNodesCacheMap.get(value); + } else if (value.isNode === true) { + return value; + } else { + return new ConstNode(value, type); + } +}; + +const safeGetNodeType = node => { + try { + return node.getNodeType(); + } catch (_) { + return undefined; + } +}; + +const ConvertType = function (type, cacheMap = null) { + return (...params) => { + if ( + params.length === 0 || + (!['bool', 'float', 'int', 'uint'].includes(type) && params.every(param => typeof param !== 'object')) + ) { + params = [getValueFromType(type, ...params)]; + } + + if (params.length === 1 && cacheMap !== null && cacheMap.has(params[0])) { + return nodeObject(cacheMap.get(params[0])); + } + + if (params.length === 1) { + const node = getConstNode(params[0], type); + if (safeGetNodeType(node) === type) return nodeObject(node); + return nodeObject(new ConvertNode(node, type)); + } + + const nodes = params.map(param => getConstNode(param)); + return nodeObject(new JoinNode(nodes, type)); + }; +}; + +// exports + +export const defined = v => (typeof v === 'object' && v !== null ? v.value : v); // TODO: remove boolean conversion and defined function + +// utils + +export const getConstNodeType = value => + value !== undefined && value !== null + ? value.nodeType || value.convertTo || (typeof value === 'string' ? value : null) + : null; + +// shader node base + +export function ShaderNode(jsFunc, nodeType) { + return new Proxy(new ShaderNodeInternal(jsFunc, nodeType), shaderNodeHandler); +} + +export const nodeObject = (val, altType = null) => /* new */ ShaderNodeObject(val, altType); +export const nodeObjects = (val, altType = null) => new ShaderNodeObjects(val, altType); +export const nodeArray = (val, altType = null) => new ShaderNodeArray(val, altType); +export const nodeProxy = (...params) => new ShaderNodeProxy(...params); +export const nodeImmutable = (...params) => new ShaderNodeImmutable(...params); + +export const Fn = (jsFunc, nodeType) => { + const shaderNode = new ShaderNode(jsFunc, nodeType); + + const fn = (...params) => { + let inputs; + + nodeObjects(params); + + if (params[0] && params[0].isNode) { + inputs = [...params]; + } else { + inputs = params[0]; + } + + return shaderNode.call(inputs); + }; + + fn.shaderNode = shaderNode; + + fn.setLayout = layout => { + shaderNode.setLayout(layout); + + return fn; + }; + + fn.once = () => { + shaderNode.once = true; + + return fn; + }; + + return fn; +}; + +export const tslFn = (...params) => { + // @deprecated, r168 + + console.warn('TSL.ShaderNode: tslFn() has been renamed to Fn().'); + return Fn(...params); +}; + +// + +addMethodChaining('toGlobal', node => { + node.global = true; + + return node; +}); + +// + +export const setCurrentStack = stack => { + if (currentStack === stack) { + //throw new Error( 'Stack already defined.' ); + } + + currentStack = stack; +}; + +export const getCurrentStack = () => currentStack; + +export const If = (...params) => currentStack.If(...params); + +export function append(node) { + if (currentStack) currentStack.add(node); + + return node; +} + +addMethodChaining('append', append); + +// types + +export const color = new ConvertType('color'); + +export const float = new ConvertType('float', cacheMaps.float); +export const int = new ConvertType('int', cacheMaps.ints); +export const uint = new ConvertType('uint', cacheMaps.uint); +export const bool = new ConvertType('bool', cacheMaps.bool); + +export const vec2 = new ConvertType('vec2'); +export const ivec2 = new ConvertType('ivec2'); +export const uvec2 = new ConvertType('uvec2'); +export const bvec2 = new ConvertType('bvec2'); + +export const vec3 = new ConvertType('vec3'); +export const ivec3 = new ConvertType('ivec3'); +export const uvec3 = new ConvertType('uvec3'); +export const bvec3 = new ConvertType('bvec3'); + +export const vec4 = new ConvertType('vec4'); +export const ivec4 = new ConvertType('ivec4'); +export const uvec4 = new ConvertType('uvec4'); +export const bvec4 = new ConvertType('bvec4'); + +export const mat2 = new ConvertType('mat2'); +export const mat3 = new ConvertType('mat3'); +export const mat4 = new ConvertType('mat4'); + +export const string = (value = '') => nodeObject(new ConstNode(value, 'string')); +export const arrayBuffer = value => nodeObject(new ConstNode(value, 'ArrayBuffer')); + +addMethodChaining('toColor', color); +addMethodChaining('toFloat', float); +addMethodChaining('toInt', int); +addMethodChaining('toUint', uint); +addMethodChaining('toBool', bool); +addMethodChaining('toVec2', vec2); +addMethodChaining('toIVec2', ivec2); +addMethodChaining('toUVec2', uvec2); +addMethodChaining('toBVec2', bvec2); +addMethodChaining('toVec3', vec3); +addMethodChaining('toIVec3', ivec3); +addMethodChaining('toUVec3', uvec3); +addMethodChaining('toBVec3', bvec3); +addMethodChaining('toVec4', vec4); +addMethodChaining('toIVec4', ivec4); +addMethodChaining('toUVec4', uvec4); +addMethodChaining('toBVec4', bvec4); +addMethodChaining('toMat2', mat2); +addMethodChaining('toMat3', mat3); +addMethodChaining('toMat4', mat4); + +// basic nodes + +export const element = /*@__PURE__*/ nodeProxy(ArrayElementNode); +export const convert = (node, types) => nodeObject(new ConvertNode(nodeObject(node), types)); +export const split = (node, channels) => nodeObject(new SplitNode(nodeObject(node), channels)); + +addMethodChaining('element', element); +addMethodChaining('convert', convert); diff --git a/src-testing/src/nodes/utils/ArrayElementNode.d.ts b/src-testing/src/nodes/utils/ArrayElementNode.d.ts new file mode 100644 index 000000000..650f04047 --- /dev/null +++ b/src-testing/src/nodes/utils/ArrayElementNode.d.ts @@ -0,0 +1,9 @@ +import Node from "../core/Node.js"; +import { TempNode } from "../Nodes.js"; + +export default class ArrayElementNode extends TempNode { + node: Node; + indexNode: Node; + + constructor(node: Node, indexNode: Node); +} diff --git a/src-testing/src/nodes/utils/ConvertNode.d.ts b/src-testing/src/nodes/utils/ConvertNode.d.ts new file mode 100644 index 000000000..7972df608 --- /dev/null +++ b/src-testing/src/nodes/utils/ConvertNode.d.ts @@ -0,0 +1,7 @@ +import Node from "../core/Node.js"; + +export default class ConvertNode extends Node { + node: Node; + convertTo: string; + constructor(node: Node, convertTo: string); +} diff --git a/src-testing/src/nodes/utils/CubeMapNode.d.ts b/src-testing/src/nodes/utils/CubeMapNode.d.ts new file mode 100644 index 000000000..6a5c47371 --- /dev/null +++ b/src-testing/src/nodes/utils/CubeMapNode.d.ts @@ -0,0 +1,13 @@ +import Node from "../core/Node.js"; +import TempNode from "../core/TempNode.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +declare class CubeMapNode extends TempNode { + envNode: Node; + + constructor(envNode: Node); +} + +export default CubeMapNode; + +export const cubeMapNode: (envNode: NodeRepresentation) => ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/Discard.d.ts b/src-testing/src/nodes/utils/Discard.d.ts new file mode 100644 index 000000000..819c009b1 --- /dev/null +++ b/src-testing/src/nodes/utils/Discard.d.ts @@ -0,0 +1,11 @@ +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +export const Discard: (conditional?: NodeRepresentation) => ShaderNodeObject; +export const Return: () => ShaderNodeObject; + +declare module "../tsl/TSLCore.js" { + interface NodeElements { + discard: typeof Discard; + } +} diff --git a/src-testing/src/nodes/utils/EquirectUVNode.d.ts b/src-testing/src/nodes/utils/EquirectUVNode.d.ts new file mode 100644 index 000000000..4e85dc40e --- /dev/null +++ b/src-testing/src/nodes/utils/EquirectUVNode.d.ts @@ -0,0 +1,8 @@ +import { Node, TempNode } from "../Nodes.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +export default class EquirectUVNode extends TempNode { + constructor(dirNode?: ShaderNodeObject); +} + +export const equirectUV: ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/FunctionOverloadingNode.d.ts b/src-testing/src/nodes/utils/FunctionOverloadingNode.d.ts new file mode 100644 index 000000000..d7c3febb4 --- /dev/null +++ b/src-testing/src/nodes/utils/FunctionOverloadingNode.d.ts @@ -0,0 +1,13 @@ +import Node from "../core/Node.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +declare class FunctionOverloadingNode extends Node { + functionNodes: Node[]; + parameterNodes: Node[]; + + constructor(functionNodes?: Node[], ...parameterNodes: Node[]); +} + +export default FunctionOverloadingNode; + +export const overloadingFn: (functionNodes: Node[]) => (...params: Node[]) => ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/JoinNode.d.ts b/src-testing/src/nodes/utils/JoinNode.d.ts new file mode 100644 index 000000000..7f456bafa --- /dev/null +++ b/src-testing/src/nodes/utils/JoinNode.d.ts @@ -0,0 +1,10 @@ +import Node from "../core/Node.js"; +import { TempNode } from "../Nodes.js"; + +/** + * This node constructs given type from elements, like vec3(a,b,c) + */ +export default class JoinNode extends TempNode { + nodes: Node[]; + constructor(nodes: Node[]); +} diff --git a/src-testing/src/nodes/utils/LoopNode.d.ts b/src-testing/src/nodes/utils/LoopNode.d.ts new file mode 100644 index 000000000..d59518588 --- /dev/null +++ b/src-testing/src/nodes/utils/LoopNode.d.ts @@ -0,0 +1,22 @@ +import Node from "../core/Node.js"; +import NodeBuilder from "../core/NodeBuilder.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +declare class LoopNode extends Node { + params: unknown[]; + + constructor(params?: unknown[]); + + getProperties(builder: NodeBuilder): unknown; +} + +export default LoopNode; + +export const Loop: (...params: unknown[]) => ShaderNodeObject; +export const Continue: () => ShaderNodeObject; +export const Break: () => ShaderNodeObject; + +/** + * @deprecated loop() has been renamed to Loop() + */ +export const loop: (...params: unknown[]) => ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/MatcapUVNode.d.ts b/src-testing/src/nodes/utils/MatcapUVNode.d.ts new file mode 100644 index 000000000..7f56667b3 --- /dev/null +++ b/src-testing/src/nodes/utils/MatcapUVNode.d.ts @@ -0,0 +1,8 @@ +import TempNode from "../core/TempNode.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +export default class MatcapUVNode extends TempNode { + constructor(); +} + +export const matcapUV: ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/MaxMipLevelNode.d.ts b/src-testing/src/nodes/utils/MaxMipLevelNode.d.ts new file mode 100644 index 000000000..455cb77a5 --- /dev/null +++ b/src-testing/src/nodes/utils/MaxMipLevelNode.d.ts @@ -0,0 +1,14 @@ +import { Texture } from "../../textures/Texture.js"; +import TextureNode from "../accessors/TextureNode.js"; +import UniformNode from "../core/UniformNode.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +export default class MaxMipLevelNode extends UniformNode<0> { + constructor(textureNode: TextureNode); + + get textureNode(): TextureNode; + + get texture(): Texture; +} + +export const maxMipLevel: (texture: Texture) => ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/Oscillators.d.ts b/src-testing/src/nodes/utils/Oscillators.d.ts new file mode 100644 index 000000000..b1a196d43 --- /dev/null +++ b/src-testing/src/nodes/utils/Oscillators.d.ts @@ -0,0 +1,7 @@ +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +export const oscSine: (timeNode?: NodeRepresentation) => ShaderNodeObject; +export const oscSquare: (timeNode?: NodeRepresentation) => ShaderNodeObject; +export const oscTriangle: (timeNode?: NodeRepresentation) => ShaderNodeObject; +export const oscSawtooth: (timeNode?: NodeRepresentation) => ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/Packing.d.ts b/src-testing/src/nodes/utils/Packing.d.ts new file mode 100644 index 000000000..61d0d039e --- /dev/null +++ b/src-testing/src/nodes/utils/Packing.d.ts @@ -0,0 +1,5 @@ +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +export const directionToColor: (node: NodeRepresentation) => ShaderNodeObject; +export const colorToDirection: (node: NodeRepresentation) => ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/PostProcessingUtils.d.ts b/src-testing/src/nodes/utils/PostProcessingUtils.d.ts new file mode 100644 index 000000000..0406e4d77 --- /dev/null +++ b/src-testing/src/nodes/utils/PostProcessingUtils.d.ts @@ -0,0 +1,45 @@ +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +/** + * Computes a position in view space based on a fragment's screen position expressed as uv coordinates, the fragments + * depth value and the camera's inverse projection matrix. + * + * @param {vec2} screenPosition - The fragment's screen position expressed as uv coordinates. + * @param {float} depth - The fragment's depth value. + * @param {mat4} projectionMatrixInverse - The camera's inverse projection matrix. + * @return {vec3} The fragments position in view space. + */ +export const getViewPosition: ( + screenPosition: NodeRepresentation, + depth: NodeRepresentation, + projectionMatrixInverse: NodeRepresentation, +) => ShaderNodeObject; + +/** + * Computes a screen position expressed as uv coordinates based on a fragment's position in view space and the camera's + * projection matrix + * + * @param {vec3} viewPosition - The fragments position in view space. + * @param {mat4} projectionMatrix - The camera's projection matrix. + * @return {vec2} The fragment's screen position expressed as uv coordinates. + */ +export const getScreenPosition: ( + viewPosition: NodeRepresentation, + projectionMatrix: NodeRepresentation, +) => ShaderNodeObject; + +/** + * Computes a normal vector based on depth data. Can be used as a fallback when no normal render target is available or + * if flat surface normals are required. + * + * @param {vec2} uv - The texture coordinate. + * @param {DepthTexture} depthTexture - The depth texture. + * @param {mat4} projectionMatrixInverse - The camera's inverse projection matrix. + * @return {vec3} The computed normal vector. + */ +export const getNormalFromDepth: ( + uv: NodeRepresentation, + depthTexture: NodeRepresentation, + projectionMatrixInverse: NodeRepresentation, +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/RTTNode.d.ts b/src-testing/src/nodes/utils/RTTNode.d.ts new file mode 100644 index 000000000..9f0d3e46e --- /dev/null +++ b/src-testing/src/nodes/utils/RTTNode.d.ts @@ -0,0 +1,45 @@ +import { TextureDataType } from "../../constants.js"; +import { RenderTarget } from "../../core/RenderTarget.js"; +import TextureNode from "../accessors/TextureNode.js"; +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +export interface RTTNodeOptions { + type: TextureDataType; +} + +declare class RTTNode extends TextureNode { + node: Node; + width: number | null; + height: number | null; + + renderTarget: RenderTarget | null; + + textureNeedsUpdate: boolean; + autoUpdate: boolean; + + pixelRatio?: number; + + constructor(node: Node, width?: number | null, height?: number | null, options?: RTTNodeOptions); + + get autoSize(): boolean; + + setSize(width: number | null, height: number | null): void; + + setPixelRatio(pixelRatio: number): void; +} + +export default RTTNode; + +export const rtt: ( + node: NodeRepresentation, + width?: number | null, + height?: number | null, + options?: RTTNodeOptions, +) => ShaderNodeObject; +export const convertToTexture: ( + node: Node, + width?: number | null, + height?: number | null, + options?: RTTNodeOptions, +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/ReflectorNode.d.ts b/src-testing/src/nodes/utils/ReflectorNode.d.ts new file mode 100644 index 000000000..54cd9abfc --- /dev/null +++ b/src-testing/src/nodes/utils/ReflectorNode.d.ts @@ -0,0 +1,45 @@ +import { Camera } from "../../cameras/Camera.js"; +import { Object3D } from "../../core/Object3D.js"; +import { RenderTarget } from "../../core/RenderTarget.js"; +import TextureNode from "../accessors/TextureNode.js"; +import Node from "../core/Node.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +export interface ReflectorNodeParameters { + target?: Object3D | undefined; + resolution?: number | undefined; + generateMipmaps?: boolean | undefined; + bounces?: boolean | undefined; +} + +declare class ReflectorNode extends TextureNode { + constructor(parameters?: ReflectorNodeParameters); + + get reflector(): ReflectorBaseNode; + + get target(): Object3D; + + getDepthNode(): ShaderNodeObject; +} + +declare class ReflectorBaseNode extends Node { + textureNode: TextureNode; + + target: Object3D; + resolution: number; + generateMipmaps: boolean; + bounces: boolean; + + virtualCameras: WeakMap; + renderTargets: WeakMap; + + constructor(textureNode: TextureNode, parameters?: ReflectorNodeParameters); + + getVirtualCamera(camera: Camera): Camera; + + getRenderTarget(camera: Camera): RenderTarget; +} + +export const reflector: (parameters?: ReflectorNodeParameters) => ShaderNodeObject; + +export default ReflectorNode; diff --git a/src-testing/src/nodes/utils/RemapNode.d.ts b/src-testing/src/nodes/utils/RemapNode.d.ts new file mode 100644 index 000000000..e50456d0a --- /dev/null +++ b/src-testing/src/nodes/utils/RemapNode.d.ts @@ -0,0 +1,36 @@ +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +export default class RemapNode extends Node { + node: Node; + inLowNode: Node; + inHighNode: Node; + outLowNode: Node; + outHighNode: Node; + + doClamp: boolean; + + constructor(node: Node, inLowNode: Node, inHighNode: Node, outLowNode?: Node, outHighNode?: Node); +} + +export const remap: ( + node: Node, + inLowNode: NodeRepresentation, + inHighNode: NodeRepresentation, + outLowNode?: NodeRepresentation, + outHighNode?: NodeRepresentation, +) => ShaderNodeObject; +export const remapClamp: ( + node: Node, + inLowNode: NodeRepresentation, + inHighNode: NodeRepresentation, + outLowNode?: NodeRepresentation, + outHighNode?: NodeRepresentation, +) => ShaderNodeObject; + +declare module "../tsl/TSLCore.js" { + interface NodeElements { + remap: typeof remap; + remapClamp: typeof remapClamp; + } +} diff --git a/src-testing/src/nodes/utils/RotateNode.d.ts b/src-testing/src/nodes/utils/RotateNode.d.ts new file mode 100644 index 000000000..8f6df796a --- /dev/null +++ b/src-testing/src/nodes/utils/RotateNode.d.ts @@ -0,0 +1,15 @@ +import Node from "../core/Node.js"; +import TempNode from "../core/TempNode.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +export default class RotateNode extends TempNode { + positionNode: Node; + rotationNode: Node; + + constructor(positionNode: Node, rotationNode: Node); +} + +export const rotate: ( + positionNode: NodeRepresentation, + rotationNode: NodeRepresentation, +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/SetNode.d.ts b/src-testing/src/nodes/utils/SetNode.d.ts new file mode 100644 index 000000000..7124d46c3 --- /dev/null +++ b/src-testing/src/nodes/utils/SetNode.d.ts @@ -0,0 +1,11 @@ +import TempNode from "../core/TempNode.js"; + +declare class SetNode extends TempNode { + sourceNode: Node; + components: string[]; + targetNode: Node; + + constructor(sourceNode: Node, components: string[], targetNode: Node); +} + +export default SetNode; diff --git a/src-testing/src/nodes/utils/SplitNode.d.ts b/src-testing/src/nodes/utils/SplitNode.d.ts new file mode 100644 index 000000000..f3aa50f41 --- /dev/null +++ b/src-testing/src/nodes/utils/SplitNode.d.ts @@ -0,0 +1,15 @@ +import Node from "../core/Node.js"; +import { SwizzleOption } from "../tsl/TSLCore.js"; + +/** swizzle node */ +export default class SplitNode extends Node { + node: Node; + components: string; + + /** + * @param node the input node + * @param components swizzle like string, default = "x" + */ + constructor(node: Node, components?: SwizzleOption); + getVectorLength(): number; +} diff --git a/src-testing/src/nodes/utils/SpriteSheetUVNode.d.ts b/src-testing/src/nodes/utils/SpriteSheetUVNode.d.ts new file mode 100644 index 000000000..9e191a390 --- /dev/null +++ b/src-testing/src/nodes/utils/SpriteSheetUVNode.d.ts @@ -0,0 +1,16 @@ +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +export default class SpriteSheetUVNode extends Node { + countNode: Node; + uvNode: Node; + frameNode: Node; + + constructor(countNode: Node, uvNode?: Node, frameNode?: Node); +} + +export const spritesheetUV: ( + countNode: NodeRepresentation, + uvNode?: NodeRepresentation, + frameNode?: NodeRepresentation, +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/SpriteUtils.d.ts b/src-testing/src/nodes/utils/SpriteUtils.d.ts new file mode 100644 index 000000000..85884df7b --- /dev/null +++ b/src-testing/src/nodes/utils/SpriteUtils.d.ts @@ -0,0 +1,6 @@ +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +export const billboarding: ( + args?: { position?: NodeRepresentation | null; horizontal?: boolean; vertical?: boolean }, +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/StorageArrayElementNode.d.ts b/src-testing/src/nodes/utils/StorageArrayElementNode.d.ts new file mode 100644 index 000000000..53ff9a79a --- /dev/null +++ b/src-testing/src/nodes/utils/StorageArrayElementNode.d.ts @@ -0,0 +1,19 @@ +import StorageBufferNode from "../accessors/StorageBufferNode.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; +import ArrayElementNode from "./ArrayElementNode.js"; + +export default class StorageArrayElementNode extends ArrayElementNode { + node: StorageBufferNode; + + readonly isStorageArrayElementNode: true; + + constructor(storageBufferNode: StorageBufferNode, indexNode: Node); + + get storageBufferNode(): StorageBufferNode; + set storageBufferNode(value: StorageBufferNode); +} + +export const storageElement: ( + storageBufferNode: NodeRepresentation, + indexNode: NodeRepresentation, +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/Timer.d.ts b/src-testing/src/nodes/utils/Timer.d.ts new file mode 100644 index 000000000..ffad3ed7f --- /dev/null +++ b/src-testing/src/nodes/utils/Timer.d.ts @@ -0,0 +1,21 @@ +import Node from "../core/Node.js"; +import { ShaderNodeObject } from "../tsl/TSLCore.js"; + +export const time: ShaderNodeObject; +export const deltaTime: ShaderNodeObject; +export const frameId: ShaderNodeObject; + +/** + * @deprecated Use "time" instead. + */ +export const timerLocal: (timeScale?: number) => ShaderNodeObject; + +/** + * @deprecated Use "time" instead. + */ +export const timerGlobal: (timeScale?: number) => ShaderNodeObject; + +/** + * @deprecated Use "deltaTime" instead. + */ +export const timerDelta: (timeScale?: number) => ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/TriplanarTexturesNode.d.ts b/src-testing/src/nodes/utils/TriplanarTexturesNode.d.ts new file mode 100644 index 000000000..1f2875c26 --- /dev/null +++ b/src-testing/src/nodes/utils/TriplanarTexturesNode.d.ts @@ -0,0 +1,36 @@ +import TextureNode from "../accessors/TextureNode.js"; +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +export default class TriplanarTexturesNode extends Node { + textureXNode: TextureNode; + textureYNode: TextureNode | null; + textureZNode: TextureNode | null; + + scaleNode: ShaderNodeObject; + + positionNode: ShaderNodeObject; + normalNode: ShaderNodeObject; + + constructor( + textureXNode: Node, + textureYNode?: TextureNode | null, + textureZNode?: TextureNode | null, + scaleNode?: ShaderNodeObject, + positionNode?: ShaderNodeObject, + normalNode?: ShaderNodeObject, + ); +} + +export const triplanarTextures: ( + textureXNode: NodeRepresentation, + textureYNode?: NodeRepresentation, + textureZNode?: NodeRepresentation, + scaleNode?: NodeRepresentation, + positionNode?: NodeRepresentation, + normalNode?: NodeRepresentation, +) => ShaderNodeObject; +export const triplanarTexture: ( + texture: NodeRepresentation, + ...params: NodeRepresentation[] +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/UVUtils.d.ts b/src-testing/src/nodes/utils/UVUtils.d.ts new file mode 100644 index 000000000..d375e1e11 --- /dev/null +++ b/src-testing/src/nodes/utils/UVUtils.d.ts @@ -0,0 +1,14 @@ +import OperatorNode from "../math/OperatorNode.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +export const rotateUV: ( + uv: NodeRepresentation, + rotation: NodeRepresentation, + center?: NodeRepresentation, +) => ShaderNodeObject; + +export const spherizeUV: ( + uv: NodeRepresentation, + strength: NodeRepresentation, + center?: NodeRepresentation, +) => ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/ViewportUtils.d.ts b/src-testing/src/nodes/utils/ViewportUtils.d.ts new file mode 100644 index 000000000..e77e7f350 --- /dev/null +++ b/src-testing/src/nodes/utils/ViewportUtils.d.ts @@ -0,0 +1,4 @@ +import Node from "../core/Node.js"; +import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; + +export const viewportSafeUV: (uv?: NodeRepresentation | null) => ShaderNodeObject; diff --git a/src-testing/src/objects/BatchedMesh.d.ts b/src-testing/src/objects/BatchedMesh.d.ts new file mode 100644 index 000000000..84044f00b --- /dev/null +++ b/src-testing/src/objects/BatchedMesh.d.ts @@ -0,0 +1,275 @@ +import { Camera } from "../cameras/Camera.js"; +import { BufferGeometry } from "../core/BufferGeometry.js"; +import { Material } from "../materials/Material.js"; +import { Box3 } from "../math/Box3.js"; +import { Color } from "../math/Color.js"; +import { Matrix4 } from "../math/Matrix4.js"; +import { Sphere } from "../math/Sphere.js"; +import { Mesh } from "./Mesh.js"; + +export interface BatchedMeshGeometryRange { + vertexStart: number; + vertexCount: number; + reservedVertexCount: number; + indexStart: number; + indexCount: number; + reservedIndexCount: number; + start: number; + count: number; +} + +/** + * A special version of {@link Mesh} with multi draw batch rendering support. Use {@link BatchedMesh} if you have to + * render a large number of objects with the same material but with different world transformations. The usage of + * {@link BatchedMesh} will help you to reduce the number of draw calls and thus improve the overall rendering + * performance in your application. + * + * If the {@link https://developer.mozilla.org/en-US/docs/Web/API/WEBGL_multi_draw WEBGL_multi_draw extension} is not + * supported then a less performant fallback is used. + * + * @example + * const box = new THREE.BoxGeometry( 1, 1, 1 ); + * const sphere = new THREE.SphereGeometry( 1, 12, 12 ); + * const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } ); + * + * // initialize and add geometries into the batched mesh + * const batchedMesh = new BatchedMesh( 10, 5000, 10000, material ); + * const boxGeometryId = batchedMesh.addGeometry( box ); + * const sphereGeometryId = batchedMesh.addGeometry( sphere ); + * + * // create instances of those geometries + * const boxInstancedId1 = batchedMesh.addInstance( boxGeometryId ); + * const boxInstancedId2 = batchedMesh.addInstance( boxGeometryId ); + * + * const sphereInstancedId1 = batchedMesh.addInstance( sphereGeometryId ); + * const sphereInstancedId2 = batchedMesh.addInstance( sphereGeometryId ); + * + * // position the geometries + * batchedMesh.setMatrixAt( boxInstancedId1, boxMatrix1 ); + * batchedMesh.setMatrixAt( boxInstancedId2, boxMatrix2 ); + * + * batchedMesh.setMatrixAt( sphereInstancedId1, sphereMatrix1 ); + * batchedMesh.setMatrixAt( sphereInstancedId2, sphereMatrix2 ); + * + * scene.add( batchedMesh ); + * + * @also Example: {@link https://threejs.org/examples/#webgl_mesh_batch WebGL / mesh / batch} + */ +declare class BatchedMesh extends Mesh { + /** + * This bounding box encloses all instances of the {@link BatchedMesh}. Can be calculated with + * {@link .computeBoundingBox()}. + * @default null + */ + boundingBox: Box3 | null; + + /** + * This bounding sphere encloses all instances of the {@link BatchedMesh}. Can be calculated with + * {@link .computeBoundingSphere()}. + * @default null + */ + boundingSphere: Sphere | null; + + customSort: ((this: this, list: Array<{ start: number; count: number; z: number }>, camera: Camera) => void) | null; + + /** + * If true then the individual objects within the {@link BatchedMesh} are frustum culled. + * @default true + */ + perObjectFrustumCulled: boolean; + + /** + * If true then the individual objects within the {@link BatchedMesh} are sorted to improve overdraw-related + * artifacts. If the material is marked as "transparent" objects are rendered back to front and if not then they are + * rendered front to back. + * @default true + */ + sortObjects: boolean; + + /** + * The maximum number of individual geometries that can be stored in the {@link BatchedMesh}. Read only. + */ + get maxInstanceCount(): number; + + get instanceCount(): number; + + get unusedVertexCount(): number; + + get unusedIndexCount(): number; + + /** + * Read-only flag to check if a given object is of type {@link BatchedMesh}. + */ + readonly isBatchedMesh: true; + + /** + * @param maxInstanceCount the max number of individual geometries planned to be added. + * @param maxVertexCount the max number of vertices to be used by all geometries. + * @param maxIndexCount the max number of indices to be used by all geometries. + * @param material an instance of {@link Material}. Default is a new {@link MeshBasicMaterial}. + */ + constructor(maxInstanceCount: number, maxVertexCount: number, maxIndexCount?: number, material?: Material); + + /** + * Computes the bounding box, updating {@link .boundingBox} attribute. + * Bounding boxes aren't computed by default. They need to be explicitly computed, otherwise they are `null`. + */ + computeBoundingBox(): void; + + /** + * Computes the bounding sphere, updating {@link .boundingSphere} attribute. + * Bounding spheres aren't computed by default. They need to be explicitly computed, otherwise they are `null`. + */ + computeBoundingSphere(): void; + + /** + * Frees the GPU-related resources allocated by this instance. Call this method whenever this instance is no longer + * used in your app. + */ + dispose(): this; + + /** + * Takes a sort a function that is run before render. The function takes a list of instances to sort and a camera. + * The objects in the list include a "z" field to perform a depth-ordered sort with. + */ + setCustomSort( + sortFunction: + | ((this: this, list: Array<{ start: number; count: number; z: number }>, camera: Camera) => void) + | null, + ): this; + + /** + * Get the color of the defined geometry. + * @param instanceId The id of an instance to get the color of. + * @param target The target object to copy the color in to. + */ + getColorAt(instanceId: number, target: Color): void; + + /** + * Get the local transformation matrix of the defined instance. + * @param instanceId The id of an instance to get the matrix of. + * @param target This 4x4 matrix will be set to the local transformation matrix of the defined instance. + */ + getMatrixAt(instanceId: number, target: Matrix4): Matrix4; + + /** + * Get whether the given instance is marked as "visible" or not. + * @param instanceId The id of an instance to get the visibility state of. + */ + getVisibleAt(instanceId: number): boolean; + + /** + * Get the range representing the subset of triangles related to the attached geometry, indicating the starting + * offset and count, or `null` if invalid. + * + * Return an object of the form: { start: Integer, count: Integer } + * @param geometryId The id of the geometry to get the range of. + * @param target Optional target object to copy the range in to. + */ + getGeometryRangeAt( + geometryId: number, + target?: BatchedMeshGeometryRange, + ): BatchedMeshGeometryRange | null; + + /** + * Get the geometryIndex of the defined instance. + * @param instanceId The id of an instance to get the geometryIndex of. + */ + getGeometryIdAt(instanceId: number): number; + + /** + * Sets the given color to the defined geometry instance. + * @param instanceId The id of the instance to set the color of. + * @param color The color to set the instance to. + */ + setColorAt(instanceId: number, color: Color): void; + + /** + * Sets the given local transformation matrix to the defined instance. + * @param instanceId The id of an instance to set the matrix of. + * @param matrix A 4x4 matrix representing the local transformation of a single instance. + */ + setMatrixAt(instanceId: number, matrix: Matrix4): this; + + /** + * Sets the visibility of the instance at the given index. + * @param instanceId The id of the instance to set the visibility of. + * @param visible A boolean value indicating the visibility state. + */ + setVisibleAt(instanceId: number, visible: boolean): this; + + /** + * Sets the geometryIndex of the instance at the given index. + * @param instanceId The id of the instance to set the geometryIndex of. + * @param geometryId The geometryIndex to be use by the instance. + */ + setGeometryIdAt(instanceId: number, geometryId: number): this; + + /** + * Adds the given geometry to the {@link BatchedMesh} and returns the associated index referring to it. + * @param geometry The geometry to add into the {@link BatchedMesh}. + * @param reservedVertexRange Optional parameter specifying the amount of vertex buffer space to reserve for the + * added geometry. This is necessary if it is planned to set a new geometry at this index at a later time that is + * larger than the original geometry. Defaults to the length of the given geometry vertex buffer. + * @param reservedIndexRange Optional parameter specifying the amount of index buffer space to reserve for the added + * geometry. This is necessary if it is planned to set a new geometry at this index at a later time that is larger + * than the original geometry. Defaults to the length of the given geometry index buffer. + */ + addGeometry(geometry: BufferGeometry, reservedVertexRange?: number, reservedIndexRange?: number): number; + + /** + * Adds a new instance to the {@link BatchedMesh} using the geometry of the given geometryId and returns a new id + * referring to the new instance to be used by other functions. + * @param geometryId The id of a previously added geometry via "addGeometry" to add into the {@link BatchedMesh} to + * render. + */ + addInstance(geometryId: number): number; + + /** + * @param geometryId The id of a geometry to remove from the [name] that was previously added via "addGeometry". Any + * instances referencing this geometry will also be removed as a side effect. + */ + deleteGeometry(geometryId: number): this; + + /** + * Removes an existing instance from the BatchedMesh using the given instanceId. + * @param instanceId The id of an instance to remove from the BatchedMesh that was previously added via + * "addInstance". + */ + deleteInstance(instanceId: number): this; + + /** + * Replaces the geometry at `geometryId` with the provided geometry. Throws an error if there is not enough space + * reserved for geometry. Calling this will change all instances that are rendering that geometry. + * @param geometryId Which geometry id to replace with this geometry. + * @param geometry The geometry to substitute at the given geometry id. + */ + setGeometryAt(geometryId: number, geometry: BufferGeometry): number; + + /** + * Repacks the sub geometries in [name] to remove any unused space remaining from previously deleted geometry, + * freeing up space to add new geometry. + */ + optimize(): this; + + /** + * Resizes the available space in BatchedMesh's vertex and index buffer attributes to the provided sizes. If the + * provided arguments shrink the geometry buffers but there is not enough unused space at the end of the geometry + * attributes then an error is thrown. + * @param maxVertexCount the max number of vertices to be used by all unique geometries to resize to. + * @param maxIndexCount the max number of indices to be used by all unique geometries to resize to. + */ + setGeometrySize(maxVertexCount: number, maxIndexCount: number): void; + + /** + * Resizes the necessary buffers to support the provided number of instances. If the provided arguments shrink the + * number of instances but there are not enough unused ids at the end of the list then an error is thrown. + * @param maxInstanceCount the max number of individual instances that can be added and rendered by the BatchedMesh. + */ + setInstanceCount(maxInstanceCount: number): void; + + getBoundingBoxAt(geometryId: number, target: Box3): Box3 | null; + getBoundingSphereAt(geometryId: number, target: Sphere): Sphere | null; +} + +export { BatchedMesh }; diff --git a/src-testing/src/objects/Bone.d.ts b/src-testing/src/objects/Bone.d.ts new file mode 100644 index 000000000..3400ea1b6 --- /dev/null +++ b/src-testing/src/objects/Bone.d.ts @@ -0,0 +1,36 @@ +import { Object3D, Object3DEventMap } from "../core/Object3D.js"; + +/** + * A {@link Bone} which is part of a {@link THREE.Skeleton | Skeleton} + * @remarks + * The skeleton in turn is used by the {@link THREE.SkinnedMesh | SkinnedMesh} + * Bones are almost identical to a blank {@link THREE.Object3D | Object3D}. + * @example + * ```typescript + * const root = new THREE.Bone(); + * const child = new THREE.Bone(); + * root.add(child); + * child.position.y = 5; + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/objects/Bone | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/objects/Bone.js | Source} + */ +export class Bone extends Object3D { + /** + * Creates a new {@link Bone}. + */ + constructor(); + + /** + * Read-only flag to check if a given object is of type {@link Bone}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isBone: true; + + /** + * @override + * @defaultValue `Bone` + */ + override readonly type: string | "Bone"; +} diff --git a/src-testing/src/objects/Group.d.ts b/src-testing/src/objects/Group.d.ts new file mode 100644 index 000000000..4b882d2e9 --- /dev/null +++ b/src-testing/src/objects/Group.d.ts @@ -0,0 +1,37 @@ +import { Object3D, Object3DEventMap } from "../core/Object3D.js"; + +/** + * Its purpose is to make working with groups of objects syntactically clearer. + * @remarks This is almost identical to an {@link Object3D | Object3D} + * @example + * ```typescript + * const geometry = new THREE.BoxGeometry(1, 1, 1); + * const material = new THREE.MeshBasicMaterial({ + * color: 0x00ff00 + * }); + * const cubeA = new THREE.Mesh(geometry, material); + * cubeA.position.set(100, 100, 0); + * const cubeB = new THREE.Mesh(geometry, material); + * cubeB.position.set(-100, -100, 0); + * //create a {@link Group} and add the two cubes + * //These cubes can now be rotated / scaled etc as a {@link Group} * const {@link Group} = new THREE.Group(); + * group.add(cubeA); + * group.add(cubeB); + * scene.add(group); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/objects/Group | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/objects/Group.js | Source} + */ +export class Group extends Object3D { + /** + * Creates a new {@link Group}. + */ + constructor(); + + /** + * Read-only flag to check if a given object is of type {@link Group}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isGroup: true; +} diff --git a/src-testing/src/objects/InstancedMesh.d.ts b/src-testing/src/objects/InstancedMesh.d.ts new file mode 100644 index 000000000..b239afb7a --- /dev/null +++ b/src-testing/src/objects/InstancedMesh.d.ts @@ -0,0 +1,179 @@ +import { BufferAttributeJSON } from "./../core/BufferAttribute.js"; +import { BufferGeometry } from "../core/BufferGeometry.js"; +import { InstancedBufferAttribute } from "../core/InstancedBufferAttribute.js"; +import { JSONMeta, Object3DEventMap } from "../core/Object3D.js"; +import { Material } from "../materials/Material.js"; +import { Box3 } from "../math/Box3.js"; +import { Color } from "../math/Color.js"; +import { Matrix4 } from "../math/Matrix4.js"; +import { Sphere } from "../math/Sphere.js"; +import { DataTexture } from "../textures/DataTexture.js"; +import { Mesh, MeshJSONObject } from "./Mesh.js"; + +export interface InstancedMeshJSONObject extends MeshJSONObject { + count: number; + instanceMatrix: BufferAttributeJSON; + instanceColor?: BufferAttributeJSON; +} + +export interface InstancedMeshJSON extends MeshJSONObject { + object: InstancedMeshJSONObject; +} + +export interface InstancedMeshEventMap extends Object3DEventMap { + dispose: {}; +} + +/** + * A special version of {@link THREE.Mesh | Mesh} with instanced rendering support + * @remarks + * Use {@link InstancedMesh} if you have to render a large number of objects with the same geometry and material(s) but with different world transformations + * @remarks + * The usage of {@link InstancedMesh} will help you to reduce the number of draw calls and thus improve the overall rendering performance in your application. + * @see Example: {@link https://threejs.org/examples/#webgl_instancing_dynamic | WebGL / instancing / dynamic} + * @see Example: {@link https://threejs.org/examples/#webgl_instancing_performance | WebGL / instancing / performance} + * @see Example: {@link https://threejs.org/examples/#webgl_instancing_scatter | WebGL / instancing / scatter} + * @see Example: {@link https://threejs.org/examples/#webgl_instancing_raycast | WebGL / instancing / raycast} + * @see {@link https://threejs.org/docs/index.html#api/en/objects/InstancedMesh | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/objects/InstancedMesh.js | Source} + */ +export class InstancedMesh< + TGeometry extends BufferGeometry = BufferGeometry, + TMaterial extends Material | Material[] = Material | Material[], + TEventMap extends InstancedMeshEventMap = InstancedMeshEventMap, +> extends Mesh { + /** + * Create a new instance of {@link InstancedMesh} + * @param geometry An instance of {@link BufferGeometry}. + * @param material A single or an array of {@link Material}. Default is a new {@link MeshBasicMaterial}. + * @param count The **maximum** number of instances of this Mesh. Expects a `Integer` + */ + constructor(geometry: TGeometry | undefined, material: TMaterial | undefined, count: number); + + /** + * Read-only flag to check if a given object is of type {@link InstancedMesh}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isInstancedMesh: true; + + /** + * This bounding box encloses all instances of the {@link InstancedMesh},, which can be calculated with {@link computeBoundingBox | .computeBoundingBox()}. + * @remarks Bounding boxes aren't computed by default. They need to be explicitly computed, otherwise they are `null`. + * @defaultValue `null` + */ + boundingBox: Box3 | null; + + /** + * This bounding sphere encloses all instances of the {@link InstancedMesh}, which can be calculated with {@link computeBoundingSphere | .computeBoundingSphere()}. + * @remarks bounding spheres aren't computed by default. They need to be explicitly computed, otherwise they are `null`. + * @defaultValue `null` + */ + boundingSphere: Sphere | null; + + /** + * The number of instances. + * @remarks + * The `count` value passed into the {@link InstancedMesh | constructor} represents the **maximum** number of instances of this mesh. + * You can change the number of instances at runtime to an integer value in the range `[0, count]`. + * @remarks If you need more instances than the original `count` value, you have to create a new InstancedMesh. + * @remarks Expects a `Integer` + */ + count: number; + + /** + * Represents the colors of all instances. + * You have to set {@link InstancedBufferAttribute.needsUpdate | .instanceColor.needsUpdate()} flag to `true` if you modify instanced data via {@link setColorAt | .setColorAt()}. + * @defaultValue `null` + */ + instanceColor: InstancedBufferAttribute | null; + + /** + * Represents the local transformation of all instances. + * You have to set {@link InstancedBufferAttribute.needsUpdate | .instanceMatrix.needsUpdate()} flag to `true` if you modify instanced data via {@link setMatrixAt | .setMatrixAt()}. + */ + instanceMatrix: InstancedBufferAttribute; + + /** + * Represents the morph target weights of all instances. You have to set its {@link .needsUpdate} flag to true if + * you modify instanced data via {@link .setMorphAt}. + */ + morphTexture: DataTexture | null; + + /** + * Computes the bounding box of the instanced mesh, and updates the {@link .boundingBox} attribute. The bounding box + * is not computed by the engine; it must be computed by your app. You may need to recompute the bounding box if an + * instance is transformed via {@link .setMatrixAt()}. + */ + computeBoundingBox(): void; + + /** + * Computes the bounding sphere of the instanced mesh, and updates the {@link .boundingSphere} attribute. The engine + * automatically computes the bounding sphere when it is needed, e.g., for ray casting or view frustum culling. You + * may need to recompute the bounding sphere if an instance is transformed via [page:.setMatrixAt](). + */ + computeBoundingSphere(): void; + + /** + * Get the color of the defined instance. + * @param index The index of an instance. Values have to be in the range `[0, count]`. Expects a `Integer` + * @param color This color object will be set to the color of the defined instance. + */ + getColorAt(index: number, color: Color): void; + + /** + * Sets the given color to the defined instance + * @remarks + * Make sure you set {@link InstancedBufferAttribute.needsUpdate | .instanceColor.needsUpdate()} to `true` after updating all the colors. + * @param index The index of an instance. Values have to be in the range `[0, count]`. Expects a `Integer` + * @param color The color of a single instance. + */ + setColorAt(index: number, color: Color): void; + + /** + * Get the local transformation matrix of the defined instance. + * @param index The index of an instance Values have to be in the range `[0, count]`. Expects a `Integer` + * @param matrix This 4x4 matrix will be set to the local transformation matrix of the defined instance. + */ + getMatrixAt(index: number, matrix: Matrix4): void; + + /** + * Get the morph target weights of the defined instance. + * @param index The index of an instance. Values have to be in the range [0, count]. + * @param mesh The {@link .morphTargetInfluences} property of this mesh will be filled with the morph target weights of the defined instance. + */ + getMorphAt(index: number, mesh: Mesh): void; + + /** + * Sets the given local transformation matrix to the defined instance. + * @remarks + * Make sure you set {@link InstancedBufferAttribute.needsUpdate | .instanceMatrix.needsUpdate()} flag to `true` after updating all the matrices. + * @param index The index of an instance. Values have to be in the range `[0, count]`. Expects a `Integer` + * @param matrix A 4x4 matrix representing the local transformation of a single instance. + */ + setMatrixAt(index: number, matrix: Matrix4): void; + + /** + * Sets the morph target weights to the defined instance. Make sure you set {@link .morphTexture}{@link .needsUpdate} + * to true after updating all the influences. + * @param index The index of an instance. Values have to be in the range [0, count]. + * @param mesh A mesh with {@link .morphTargetInfluences} property containing the morph target weights of a single instance. + */ + setMorphAt(index: number, mesh: Mesh): void; + + /** + * No effect in {@link InstancedMesh}. + * @ignore + * @hidden + */ + override updateMorphTargets(): void; + + /** + * Frees the GPU-related resources allocated by this instance + * @remarks + * Call this method whenever this instance is no longer used in your app. + */ + dispose(): this; + + toJSON(meta?: JSONMeta): InstancedMeshJSON; +} diff --git a/src-testing/src/objects/LOD.d.ts b/src-testing/src/objects/LOD.d.ts new file mode 100644 index 000000000..2440b8503 --- /dev/null +++ b/src-testing/src/objects/LOD.d.ts @@ -0,0 +1,111 @@ +import { Camera } from "../cameras/Camera.js"; +import { JSONMeta, Object3D, Object3DEventMap, Object3DJSON, Object3DJSONObject } from "../core/Object3D.js"; + +export interface LODJSONObject extends Object3DJSONObject { + autoUpdate?: boolean; + + levels: Array<{ + object: string; + distance: number; + hysteresis: number; + }>; +} + +export interface LODJSON extends Object3DJSON { + object: LODJSONObject; +} + +/** + * Every level is associated with an object, and rendering can be switched between them at the distances specified + * @remarks + * Typically you would create, say, three meshes, one for far away (low detail), one for mid range (medium detail) and one for close up (high detail). + * @example + * ```typescript + * const {@link LOD} = new THREE.LOD(); + * //Create spheres with 3 levels of detail and create new {@link LOD} levels for them + * for (let i = 0; i & lt; 3; i++) { + * const geometry = new THREE.IcosahedronGeometry(10, 3 - i) + * const mesh = new THREE.Mesh(geometry, material); + * lod.addLevel(mesh, i * 75); + * } + * scene.add(lod); + * ``` + * @see Example: {@link https://threejs.org/examples/#webgl_lod | webgl / {@link LOD} } + * @see {@link https://threejs.org/docs/index.html#api/en/objects/LOD | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/objects/LOD.js | Source} + */ +export class LOD extends Object3D { + /** + * Creates a new {@link LOD}. + */ + constructor(); + + /** + * Read-only flag to check if a given object is of type {@link LOD}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isLOD: true; + + /** + * @override + * @defaultValue `LOD` + */ + override readonly type: string | "LOD"; + + /** + * An array of level objects + */ + levels: Array<{ + /** The Object3D to display at this level. */ + object: Object3D; + /** The distance at which to display this level of detail. Expects a `Float`. */ + distance: number; + /** Threshold used to avoid flickering at LOD boundaries, as a fraction of distance. Expects a `Float`. */ + hysteresis: number; + }>; + + /** + * Whether the {@link LOD} object is updated automatically by the renderer per frame or not. + * If set to `false`, you have to call {@link update | .update()} in the render loop by yourself. + * @defaultValue `true` + */ + autoUpdate: boolean; + + /** + * Adds a mesh that will display at a certain distance and greater. Typically the further away the distance, the lower the detail on the mesh. + * + * @param object The Object3D to display at this level. + * @param distance The distance at which to display this level of detail. Expects a `Float`. Default `0.0`. + * @param hysteresis Threshold used to avoid flickering at LOD boundaries, as a fraction of distance. Expects a `Float`. Default `0.0`. + */ + addLevel(object: Object3D, distance?: number, hysteresis?: number): this; + + /** + * Removes an existing level, based on the distance from the camera. Returns `true` when the level has been removed. + * Otherwise `false`. + * @param distance Distance of the level to delete. + */ + removeLabel(distance: number): boolean; + + /** + * Get the currently active {@link LOD} level + * @remarks + * As index of the levels array. + */ + getCurrentLevel(): number; + + /** + * Get a reference to the first {@link THREE.Object3D | Object3D} (mesh) that is greater than {@link distance}. + * @param distance Expects a `Float` + */ + getObjectForDistance(distance: number): Object3D | null; + + /** + * Set the visibility of each {@link levels | level}'s {@link THREE.Object3D | object} based on distance from the {@link THREE.Camera | camera}. + * @param camera + */ + update(camera: Camera): void; + + toJSON(meta?: JSONMeta): LODJSON; +} diff --git a/src-testing/src/objects/Line.d.ts b/src-testing/src/objects/Line.d.ts new file mode 100644 index 000000000..2d76dec69 --- /dev/null +++ b/src-testing/src/objects/Line.d.ts @@ -0,0 +1,87 @@ +import { BufferGeometry } from "../core/BufferGeometry.js"; +import { Object3D, Object3DEventMap } from "../core/Object3D.js"; +import { Material } from "../materials/Material.js"; + +/** + * A continuous line. + * @remarks + * This is nearly the same as {@link THREE.LineSegments | LineSegments}, + * the only difference is that it is rendered using {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/drawElements | gl.LINE_STRIP} + * instead of {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/drawElements | gl.LINES} + * @example + * ```typescript + * const material = new THREE.LineBasicMaterial({ + * color: 0x0000ff + * }); + * const points = []; + * points.push(new THREE.Vector3(-10, 0, 0)); + * points.push(new THREE.Vector3(0, 10, 0)); + * points.push(new THREE.Vector3(10, 0, 0)); + * const geometry = new THREE.BufferGeometry().setFromPoints(points); + * const {@link Line} = new THREE.Line(geometry, material); + * scene.add(line); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/objects/Line | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/objects/Line.js | Source} + */ +export class Line< + TGeometry extends BufferGeometry = BufferGeometry, + TMaterial extends Material | Material[] = Material | Material[], + TEventMap extends Object3DEventMap = Object3DEventMap, +> extends Object3D { + /** + * Create a new instance of {@link Line} + * @param geometry Vertices representing the {@link Line} segment(s). Default {@link THREE.BufferGeometry | `new THREE.BufferGeometry()`}. + * @param material Material for the line. Default {@link THREE.LineBasicMaterial | `new THREE.LineBasicMaterial()`}. + */ + constructor(geometry?: TGeometry, material?: TMaterial); + + /** + * Read-only flag to check if a given object is of type {@link Line}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isLine: true; + + /** + * @override + * @defaultValue `Line` + */ + override readonly type: string | "Line"; + + /** + * Vertices representing the {@link Line} segment(s). + */ + geometry: TGeometry; + + /** + * Material for the line. + */ + material: TMaterial; + + /** + * An array of weights typically from `0-1` that specify how much of the morph is applied. + * @defaultValue `undefined`, but reset to a blank array by {@link updateMorphTargets | .updateMorphTargets()}. + */ + morphTargetInfluences?: number[] | undefined; + + /** + * A dictionary of morphTargets based on the `morphTarget.name` property. + * @defaultValue `undefined`, but reset to a blank array by {@link updateMorphTargets | .updateMorphTargets()}. + */ + morphTargetDictionary?: { [key: string]: number } | undefined; + + /** + * Computes an array of distance values which are necessary for {@link THREE.LineDashedMaterial | LineDashedMaterial} + * @remarks + * For each vertex in the geometry, the method calculates the cumulative length from the current point to the very beginning of the line. + */ + computeLineDistances(): this; + + /** + * Updates the morphTargets to have no influence on the object + * @remarks + * Resets the {@link morphTargetInfluences | .morphTargetInfluences} and {@link morphTargetDictionary | .morphTargetDictionary} properties. + */ + updateMorphTargets(): void; +} diff --git a/src-testing/src/objects/LineLoop.d.ts b/src-testing/src/objects/LineLoop.d.ts new file mode 100644 index 000000000..0a070a838 --- /dev/null +++ b/src-testing/src/objects/LineLoop.d.ts @@ -0,0 +1,40 @@ +import { BufferGeometry } from "../core/BufferGeometry.js"; +import { Object3DEventMap } from "../core/Object3D.js"; +import { Material } from "../materials/Material.js"; +import { Line } from "./Line.js"; + +/** + * A continuous line that connects back to the start. + * @remarks + * This is nearly the same as {@link THREE.Line | Line}, + * the only difference is that it is rendered using {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/drawElements | gl.LINE_LOOP} + * instead of {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/drawElements | gl.LINE_STRIP}, + * which draws a straight line to the next vertex, and connects the last vertex back to the first. + * @see {@link https://threejs.org/docs/index.html#api/en/objects/LineLoop | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/objects/LineLoop.js | Source} + */ +export class LineLoop< + TGeometry extends BufferGeometry = BufferGeometry, + TMaterial extends Material | Material[] = Material | Material[], + TEventMap extends Object3DEventMap = Object3DEventMap, +> extends Line { + /** + * Create a new instance of {@link LineLoop} + * @param geometry List of vertices representing points on the line loop. Default {@link THREE.BufferGeometry | `new THREE.BufferGeometry()`}. + * @param material Material for the line. Default {@link THREE.LineBasicMaterial | `new THREE.LineBasicMaterial()`}. + */ + constructor(geometry?: TGeometry, material?: TMaterial); + + /** + * Read-only flag to check if a given object is of type {@link LineLoop}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isLineLoop: true; + + /** + * @override + * @defaultValue `LineLoop` + */ + override readonly type: string | "LineLoop"; +} diff --git a/src-testing/src/objects/LineSegments.d.ts b/src-testing/src/objects/LineSegments.d.ts new file mode 100644 index 000000000..9a8199bdc --- /dev/null +++ b/src-testing/src/objects/LineSegments.d.ts @@ -0,0 +1,41 @@ +import { BufferGeometry } from "../core/BufferGeometry.js"; +import { Object3DEventMap } from "../core/Object3D.js"; +import { Material } from "../materials/Material.js"; +import { Line } from "./Line.js"; + +/** + * A series of lines drawn between pairs of vertices. + * @remarks + * This is nearly the same as {@link THREE.Line | Line}, + * the only difference is that it is rendered using {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/drawElements | gl.LINES} + * instead of {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/drawElements | gl.LINE_STRIP}. + * @see {@link https://threejs.org/docs/index.html#api/en/objects/LineSegments | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/objects/LineSegments.js | Source} + */ +export class LineSegments< + TGeometry extends BufferGeometry = BufferGeometry, + TMaterial extends Material | Material[] = Material | Material[], + TEventMap extends Object3DEventMap = Object3DEventMap, +> extends Line { + /** + * Create a new instance of {@link LineSegments} + * @param geometry Pair(s) of vertices representing each line segment(s). Default {@link THREE.BufferGeometry | `new THREE.BufferGeometry()`}. + * @param material Material for the line. Default {@link THREE.LineBasicMaterial | `new THREE.LineBasicMaterial()`}. + */ + constructor(geometry?: TGeometry, material?: TMaterial); + + /** + * Read-only flag to check if a given object is of type {@link LineSegments}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isLineSegments: true; + + /** + * A Read-only _string_ to check if `this` object type. + * @remarks Sub-classes will update this value. + * @override + * @defaultValue `LineSegments` + */ + override readonly type: string | "LineSegments"; +} diff --git a/src-testing/src/objects/Mesh.d.ts b/src-testing/src/objects/Mesh.d.ts new file mode 100644 index 000000000..38dad1c73 --- /dev/null +++ b/src-testing/src/objects/Mesh.d.ts @@ -0,0 +1,94 @@ +import { BufferGeometry } from "../core/BufferGeometry.js"; +import { JSONMeta, Object3D, Object3DEventMap, Object3DJSON, Object3DJSONObject } from "../core/Object3D.js"; +import { Material } from "../materials/Material.js"; +import { Vector3 } from "../math/Vector3.js"; + +export interface MeshJSONObject extends Object3DJSONObject { + geometry: string; +} + +export interface MeshJSON extends Object3DJSON { + object: MeshJSONObject; +} + +/** + * Class representing triangular {@link https://en.wikipedia.org/wiki/Polygon_mesh | polygon mesh} based objects. + * @remarks + * Also serves as a base for other classes such as {@link THREE.SkinnedMesh | SkinnedMesh}, {@link THREE.InstancedMesh | InstancedMesh}. + * @example + * ```typescript + * const geometry = new THREE.BoxGeometry(1, 1, 1); + * const material = new THREE.MeshBasicMaterial({ + * color: 0xffff00 + * }); + * const {@link Mesh} = new THREE.Mesh(geometry, material); + * scene.add(mesh); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/objects/Mesh | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/objects/Mesh.js | Source} + */ +export class Mesh< + TGeometry extends BufferGeometry = BufferGeometry, + TMaterial extends Material | Material[] = Material | Material[], + TEventMap extends Object3DEventMap = Object3DEventMap, +> extends Object3D { + /** + * Create a new instance of {@link Mesh} + * @param geometry An instance of {@link THREE.BufferGeometry | BufferGeometry}. Default {@link THREE.BufferGeometry | `new THREE.BufferGeometry()`}. + * @param material A single or an array of {@link THREE.Material | Material}. Default {@link THREE.MeshBasicMaterial | `new THREE.MeshBasicMaterial()`}. + */ + constructor(geometry?: TGeometry, material?: TMaterial); + + /** + * Read-only flag to check if a given object is of type {@link Mesh}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isMesh: true; + + /** + * @override + * @defaultValue `Mesh` + */ + override readonly type: string | "Mesh"; + + /** + * An instance of {@link THREE.BufferGeometry | BufferGeometry} (or derived classes), defining the object's structure. + * @defaultValue {@link THREE.BufferGeometry | `new THREE.BufferGeometry()`}. + */ + geometry: TGeometry; + + /** + * An instance of material derived from the {@link THREE.Material | Material} base class or an array of materials, defining the object's appearance. + * @defaultValue {@link THREE.MeshBasicMaterial | `new THREE.MeshBasicMaterial()`}. + */ + material: TMaterial; + + /** + * An array of weights typically from `0-1` that specify how much of the morph is applied. + * @defaultValue `undefined`, _but reset to a blank array by {@link updateMorphTargets | .updateMorphTargets()}._ + */ + morphTargetInfluences?: number[] | undefined; + + /** + * A dictionary of morphTargets based on the `morphTarget.name` property. + * @defaultValue `undefined`, _but rebuilt by {@link updateMorphTargets | .updateMorphTargets()}._ + */ + morphTargetDictionary?: { [key: string]: number } | undefined; + + /** + * Updates the morphTargets to have no influence on the object + * @remarks Resets the {@link morphTargetInfluences} and {@link morphTargetDictionary} properties. + */ + updateMorphTargets(): void; + + /** + * Get the local-space position of the vertex at the given index, + * taking into account the current animation state of both morph targets and skinning. + * @param index Expects a `Integer` + * @param target + */ + getVertexPosition(index: number, target: Vector3): Vector3; + + toJSON(meta?: JSONMeta): MeshJSON; +} diff --git a/src-testing/src/objects/Points.d.ts b/src-testing/src/objects/Points.d.ts new file mode 100644 index 000000000..3cba2c74b --- /dev/null +++ b/src-testing/src/objects/Points.d.ts @@ -0,0 +1,66 @@ +import { BufferGeometry, NormalOrGLBufferAttributes } from "../core/BufferGeometry.js"; +import { Object3D, Object3DEventMap } from "../core/Object3D.js"; +import { Material } from "../materials/Material.js"; + +/** + * A class for displaying {@link Points} + * @remarks + * The {@link Points} are rendered by the {@link THREE.WebGLRenderer | WebGLRenderer} using {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/drawElements | gl.POINTS}. + * @see {@link https://threejs.org/docs/index.html#api/en/objects/Points | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/objects/Points.js | Source} + */ +export class Points< + TGeometry extends BufferGeometry = BufferGeometry, + TMaterial extends Material | Material[] = Material | Material[], + TEventMap extends Object3DEventMap = Object3DEventMap, +> extends Object3D { + /** + * Create a new instance of {@link Points} + * @param geometry An instance of {@link THREE.BufferGeometry | BufferGeometry}. Default {@link THREE.BufferGeometry | `new THREE.BufferGeometry()`}. + * @param material A single or an array of {@link THREE.Material | Material}. Default {@link THREE.PointsMaterial | `new THREE.PointsMaterial()`}. + */ + constructor(geometry?: TGeometry, material?: TMaterial); + + /** + * Read-only flag to check if a given object is of type {@link Points}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isPoints: true; + + /** + * @override + * @defaultValue `Points` + */ + override readonly type: string | "Points"; + + /** + * An array of weights typically from `0-1` that specify how much of the morph is applied. + * @defaultValue `undefined`, _but reset to a blank array by {@link updateMorphTargets | .updateMorphTargets()}._ + */ + morphTargetInfluences?: number[] | undefined; + + /** + * A dictionary of morphTargets based on the `morphTarget.name` property. + * @defaultValue `undefined`, _but rebuilt by {@link updateMorphTargets | .updateMorphTargets()}._ + */ + morphTargetDictionary?: { [key: string]: number } | undefined; + + /** + * An instance of {@link THREE.BufferGeometry | BufferGeometry} (or derived classes), defining the object's structure. + * @remarks each vertex designates the position of a particle in the system. + */ + geometry: TGeometry; + + /** + * An instance of {@link THREE.Material | Material}, defining the object's appearance. + * @defaultValue {@link THREE.PointsMaterial | `new THREE.PointsMaterial()`}, _with randomised colour_. + */ + material: TMaterial; + + /** + * Updates the morphTargets to have no influence on the object + * @remarks Resets the {@link morphTargetInfluences} and {@link morphTargetDictionary} properties. + */ + updateMorphTargets(): void; +} diff --git a/src-testing/src/objects/Skeleton.d.ts b/src-testing/src/objects/Skeleton.d.ts new file mode 100644 index 000000000..aaeb3198b --- /dev/null +++ b/src-testing/src/objects/Skeleton.d.ts @@ -0,0 +1,120 @@ +import { Matrix4, Matrix4Tuple } from "../math/Matrix4.js"; +import { DataTexture } from "../textures/DataTexture.js"; +import { Bone } from "./Bone.js"; + +export interface SkeletonJSON { + metadata: { version: number; type: string; generator: string }; + bones: string[]; + boneInverses: Matrix4Tuple[]; + uuid: string; +} + +/** + * Use an array of {@link Bone | bones} to create a {@link Skeleton} that can be used by a {@link THREE.SkinnedMesh | SkinnedMesh}. + * @example + * ```typescript + * // Create a simple "arm" + * const bones = []; + * const shoulder = new THREE.Bone(); + * const elbow = new THREE.Bone(); + * const hand = new THREE.Bone(); + * shoulder.add(elbow); + * elbow.add(hand); + * bones.push(shoulder); + * bones.push(elbow); + * bones.push(hand); + * shoulder.position.y = -5; + * elbow.position.y = 0; + * hand.position.y = 5; + * const armSkeleton = new THREE.Skeleton(bones); + * See the[page: SkinnedMesh] page + * for an example of usage with standard[page: BufferGeometry]. + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/objects/Skeleton | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/objects/Skeleton.js | Source} + */ +export class Skeleton { + /** + * Creates a new Skeleton. + * @param bones The array of {@link THREE.Bone | bones}. Default `[]`. + * @param boneInverses An array of {@link THREE.Matrix4 | Matrix4s}. Default `[]`. + */ + constructor(bones?: Bone[], boneInverses?: Matrix4[]); + + /** + * {@link http://en.wikipedia.org/wiki/Universally_unique_identifier | UUID} of this object instance. + * @remarks This gets automatically assigned and shouldn't be edited. + */ + uuid: string; + + /** + * The array of {@link THREE.Bone | Bones}. + * @remarks Note this is a copy of the original array, not a reference, so you can modify the original array without effecting this one. + */ + bones: Bone[]; + + /** + * An array of {@link Matrix4 | Matrix4s} that represent the inverse of the {@link THREE.Matrix4 | matrixWorld} of the individual bones. + */ + boneInverses: Matrix4[]; + + /** + * The array buffer holding the bone data when using a vertex texture. + */ + boneMatrices: Float32Array; + + /** + * The {@link THREE.DataTexture | DataTexture} holding the bone data when using a vertex texture. + */ + boneTexture: null | DataTexture; + + frame: number; + + init(): void; + + /** + * Generates the {@link boneInverses} array if not provided in the constructor. + */ + calculateInverses(): void; + + /** + * Computes an instance of {@link THREE.DataTexture | DataTexture} in order to pass the bone data more efficiently to the shader + * @remarks + * The texture is assigned to {@link boneTexture}. + */ + computeBoneTexture(): this; + + /** + * Returns the skeleton to the base pose. + */ + pose(): void; + + /** + * Updates the {@link boneMatrices} and {@link boneTexture} after changing the bones + * @remarks + * This is called automatically by the {@link THREE.WebGLRenderer | WebGLRenderer} if the {@link Skeleton} is used with a {@link THREE.SkinnedMesh | SkinnedMesh}. + */ + update(): void; + + /** + * Returns a clone of this {@link Skeleton} object. + */ + clone(): Skeleton; + + /** + * Searches through the skeleton's bone array and returns the first with a matching name. + * @param name String to match to the Bone's {@link THREE.Bone.name | .name} property. + */ + getBoneByName(name: string): undefined | Bone; + + /** + * Frees the GPU-related resources allocated by this instance + * @remarks + * Call this method whenever this instance is no longer used in your app. + */ + dispose(): void; + + toJSON(): SkeletonJSON; + + fromJSON(json: SkeletonJSON, bones: Record): void; +} diff --git a/src-testing/src/objects/SkinnedMesh.d.ts b/src-testing/src/objects/SkinnedMesh.d.ts new file mode 100644 index 000000000..35149c5d1 --- /dev/null +++ b/src-testing/src/objects/SkinnedMesh.d.ts @@ -0,0 +1,160 @@ +import { BindMode } from "../constants.js"; +import { BufferGeometry } from "../core/BufferGeometry.js"; +import { JSONMeta, Object3DEventMap } from "../core/Object3D.js"; +import { Material } from "../materials/Material.js"; +import { Box3 } from "../math/Box3.js"; +import { Matrix4, Matrix4Tuple } from "../math/Matrix4.js"; +import { Sphere } from "../math/Sphere.js"; +import { Vector3 } from "../math/Vector3.js"; +import { Mesh, MeshJSON, MeshJSONObject } from "./Mesh.js"; +import { Skeleton } from "./Skeleton.js"; + +export interface SkinnedMeshJSONObject extends MeshJSONObject { + bindMode: BindMode; + bindMatrix: Matrix4Tuple; + skeleton?: string; +} + +export interface SkinnedMeshJSON extends MeshJSON { + object: SkinnedMeshJSONObject; +} + +/** + * A mesh that has a {@link THREE.Skeleton | Skeleton} with {@link Bone | bones} that can then be used to animate the vertices of the geometry. + * @example + * ```typescript + * const geometry = new THREE.CylinderGeometry(5, 5, 5, 5, 15, 5, 30); + * // create the skin indices and skin weights manually + * // (typically a loader would read this data from a 3D model for you) + * const position = geometry.attributes.position; + * const vertex = new THREE.Vector3(); + * const skinIndices = []; + * const skinWeights = []; + * for (let i = 0; i & lt; position.count; i++) { + * vertex.fromBufferAttribute(position, i); + * // compute skinIndex and skinWeight based on some configuration data + * const y = (vertex.y + sizing.halfHeight); + * const skinIndex = Math.floor(y / sizing.segmentHeight); + * const skinWeight = (y % sizing.segmentHeight) / sizing.segmentHeight; + * skinIndices.push(skinIndex, skinIndex + 1, 0, 0); + * skinWeights.push(1 - skinWeight, skinWeight, 0, 0); + * } + * geometry.setAttribute('skinIndex', new THREE.Uint16BufferAttribute(skinIndices, 4)); + * geometry.setAttribute('skinWeight', new THREE.Float32BufferAttribute(skinWeights, 4)); + * // create skinned mesh and skeleton + * const mesh = new THREE.SkinnedMesh(geometry, material); + * const skeleton = new THREE.Skeleton(bones); + * // see example from THREE.Skeleton + * const rootBone = skeleton.bones[0]; + * mesh.add(rootBone); + * // bind the skeleton to the mesh + * mesh.bind(skeleton); + * // move the bones and manipulate the model + * skeleton.bones[0].rotation.x = -0.1; + * skeleton.bones[1].rotation.x = 0.2; + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/objects/SkinnedMesh | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/objects/SkinnedMesh.js | Source} + */ +export class SkinnedMesh< + TGeometry extends BufferGeometry = BufferGeometry, + TMaterial extends Material | Material[] = Material | Material[], + TEventMap extends Object3DEventMap = Object3DEventMap, +> extends Mesh { + /** + * Create a new instance of {@link SkinnedMesh} + * @param geometry An instance of {@link THREE.BufferGeometry | BufferGeometry}. Default {@link THREE.BufferGeometry | `new THREE.BufferGeometry()`}. + * @param material A single or an array of {@link THREE.Material | Material}. Default {@link THREE.MeshBasicMaterial | `new THREE.MeshBasicMaterial()`}. + */ + constructor(geometry?: TGeometry, material?: TMaterial, useVertexTexture?: boolean); + + /** + * Read-only flag to check if a given object is of type {@link SkinnedMesh}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isSkinnedMesh: true; + + /** + * @override + * @defaultValue `SkinnedMesh` + */ + override readonly type: string | "SkinnedMesh"; + + /** + * Either {@link AttachedBindMode} or {@link DetachedBindMode}. {@link AttachedBindMode} means the skinned mesh + * shares the same world space as the skeleton. This is not true when using {@link DetachedBindMode} which is useful + * when sharing a skeleton across multiple skinned meshes. + * @defaultValue `AttachedBindMode` + */ + bindMode: BindMode; + + /** + * The base matrix that is used for the bound bone transforms. + */ + bindMatrix: Matrix4; + /** + * The base matrix that is used for resetting the bound bone transforms. + */ + bindMatrixInverse: Matrix4; + + /** + * The bounding box of the SkinnedMesh. Can be calculated with {@link computeBoundingBox | .computeBoundingBox()}. + * @default `null` + */ + boundingBox: Box3; + + /** + * The bounding box of the SkinnedMesh. Can be calculated with {@link computeBoundingSphere | .computeBoundingSphere()}. + * @default `null` + */ + boundingSphere: Sphere; + + /** + * {@link THREE.Skeleton | Skeleton} representing the bone hierarchy of the skinned mesh. + */ + skeleton: Skeleton; + + /** + * Bind a skeleton to the skinned mesh + * @remarks + * The bindMatrix gets saved to .bindMatrix property and the .bindMatrixInverse gets calculated. + * @param skeleton {@link THREE.Skeleton | Skeleton} created from a {@link Bone | Bones} tree. + * @param bindMatrix {@link THREE.Matrix4 | Matrix4} that represents the base transform of the skeleton. + */ + bind(skeleton: Skeleton, bindMatrix?: Matrix4): void; + + /** + * Computes the bounding box of the skinned mesh, and updates the {@link .boundingBox} attribute. The bounding box + * is not computed by the engine; it must be computed by your app. If the skinned mesh is animated, the bounding box + * should be recomputed per frame. + */ + computeBoundingBox(): void; + + /** + * Computes the bounding sphere of the skinned mesh, and updates the {@link .boundingSphere} attribute. The bounding + * sphere is automatically computed by the engine when it is needed, e.g., for ray casting and view frustum culling. + * If the skinned mesh is animated, the bounding sphere should be recomputed per frame. + */ + computeBoundingSphere(): void; + + /** + * This method sets the skinned mesh in the rest pose (resets the pose). + */ + pose(): void; + + /** + * Normalizes the skin weights. + */ + normalizeSkinWeights(): void; + + /** + * Applies the bone transform associated with the given index to the given position vector + * @remarks Returns the updated vector. + * @param index Expects a `Integer` + * @param vector + */ + applyBoneTransform(index: number, vector: Vector3): Vector3; + + toJSON(meta?: JSONMeta): SkinnedMeshJSON; +} diff --git a/src-testing/src/objects/Sprite.d.ts b/src-testing/src/objects/Sprite.d.ts new file mode 100644 index 000000000..427b8b414 --- /dev/null +++ b/src-testing/src/objects/Sprite.d.ts @@ -0,0 +1,65 @@ +import { BufferGeometry } from "../core/BufferGeometry.js"; +import { Object3D, Object3DEventMap } from "../core/Object3D.js"; +import { SpriteMaterial } from "../materials/Materials.js"; +import { Vector2 } from "../math/Vector2.js"; + +/** + * A {@link Sprite} is a plane that always faces towards the camera, generally with a partially transparent texture applied. + * @remarks Sprites do not cast shadows, setting `castShadow = true` will have no effect. + * @example + * ```typescript + * const map = new THREE.TextureLoader().load('sprite.png'); + * const material = new THREE.SpriteMaterial({ + * map: map + * }); + * const {@link Sprite} = new THREE.Sprite(material); + * scene.add(sprite); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/objects/Sprite | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/objects/Sprite.js | Source} + */ +export class Sprite extends Object3D { + /** + * Creates a new Sprite. + * @param material An instance of {@link THREE.SpriteMaterial | SpriteMaterial}. Default {@link THREE.SpriteMaterial | `new SpriteMaterial()`}, _with white color_. + */ + constructor(material?: SpriteMaterial); + + /** + * Read-only flag to check if a given object is of type {@link Sprite}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isSprite: true; + + /** + * @override + * @defaultValue `Sprite` + */ + override readonly type: string | "Sprite"; + + /** + * Whether the object gets rendered into shadow map. + * No effect in {@link Sprite}. + * @ignore + * @hidden + * @defaultValue `false` + */ + override castShadow: false; + + geometry: BufferGeometry; + + /** + * An instance of {@link THREE.SpriteMaterial | SpriteMaterial}, defining the object's appearance. + * @defaultValue {@link THREE.SpriteMaterial | `new SpriteMaterial()`}, _with white color_. + */ + material: SpriteMaterial; + + /** + * The sprite's anchor point, and the point around which the {@link Sprite} rotates. + * A value of (0.5, 0.5) corresponds to the midpoint of the sprite. + * A value of (0, 0) corresponds to the lower left corner of the sprite. + * @defaultValue {@link THREE.Vector2 | `new Vector2(0.5, 0.5)`}. + */ + center: Vector2; +} diff --git a/src-testing/src/renderers/WebGL3DRenderTarget.d.ts b/src-testing/src/renderers/WebGL3DRenderTarget.d.ts new file mode 100644 index 000000000..420caa97e --- /dev/null +++ b/src-testing/src/renderers/WebGL3DRenderTarget.d.ts @@ -0,0 +1,29 @@ +import { RenderTargetOptions } from "../core/RenderTarget.js"; +import { Data3DTexture } from "../textures/Data3DTexture.js"; +import { WebGLRenderTarget } from "./WebGLRenderTarget.js"; + +/** + * Represents a three-dimensional render target. + */ +export class WebGL3DRenderTarget extends WebGLRenderTarget { + /** + * Creates a new WebGL3DRenderTarget. + * + * @param width the width of the render target, in pixels. Default is `1`. + * @param height the height of the render target, in pixels. Default is `1`. + * @param depth the depth of the render target. Default is `1`. + * @param options optional object that holds texture parameters for an auto-generated target texture and + * depthBuffer/stencilBuffer booleans. See {@link WebGLRenderTarget} for details. + */ + constructor(width?: number, height?: number, depth?: number, options?: RenderTargetOptions); + + textures: Data3DTexture[]; + + /** + * The texture property is overwritten with an instance of {@link Data3DTexture}. + */ + get texture(): Data3DTexture; + set texture(value: Data3DTexture); + + readonly isWebGL3DRenderTarget: true; +} diff --git a/src-testing/src/renderers/WebGLArrayRenderTarget.d.ts b/src-testing/src/renderers/WebGLArrayRenderTarget.d.ts new file mode 100644 index 000000000..1ac617889 --- /dev/null +++ b/src-testing/src/renderers/WebGLArrayRenderTarget.d.ts @@ -0,0 +1,29 @@ +import { RenderTargetOptions } from "../core/RenderTarget.js"; +import { DataArrayTexture } from "../textures/DataArrayTexture.js"; +import { WebGLRenderTarget } from "./WebGLRenderTarget.js"; + +/** + * This type of render target represents an array of textures. + */ +export class WebGLArrayRenderTarget extends WebGLRenderTarget { + /** + * Creates a new WebGLArrayRenderTarget. + * + * @param width the width of the render target, in pixels. Default is `1`. + * @param height the height of the render target, in pixels. Default is `1`. + * @param depth the depth/layer count of the render target. Default is `1`. + * @param options optional object that holds texture parameters for an auto-generated target texture and + * depthBuffer/stencilBuffer booleans. See {@link WebGLRenderTarget} for details. + */ + constructor(width?: number, height?: number, depth?: number, options?: RenderTargetOptions); + + textures: DataArrayTexture[]; + + /** + * The texture property is overwritten with an instance of {@link DataArrayTexture}. + */ + get texture(): DataArrayTexture; + set texture(value: DataArrayTexture); + + readonly isWebGLArrayRenderTarget: true; +} diff --git a/src-testing/src/renderers/WebGLCubeRenderTarget.d.ts b/src-testing/src/renderers/WebGLCubeRenderTarget.d.ts new file mode 100644 index 000000000..c390adb67 --- /dev/null +++ b/src-testing/src/renderers/WebGLCubeRenderTarget.d.ts @@ -0,0 +1,18 @@ +import { RenderTargetOptions } from "../core/RenderTarget.js"; +import { CubeTexture } from "../textures/CubeTexture.js"; +import { Texture } from "../textures/Texture.js"; +import { WebGLRenderer } from "./WebGLRenderer.js"; +import { WebGLRenderTarget } from "./WebGLRenderTarget.js"; + +export class WebGLCubeRenderTarget extends WebGLRenderTarget { + constructor(size?: number, options?: RenderTargetOptions); + + textures: CubeTexture[]; + + get texture(): CubeTexture; + set texture(value: CubeTexture); + + fromEquirectangularTexture(renderer: WebGLRenderer, texture: Texture): this; + + clear(renderer: WebGLRenderer, color: boolean, depth: boolean, stencil: boolean): void; +} diff --git a/src-testing/src/renderers/WebGLRenderTarget.d.ts b/src-testing/src/renderers/WebGLRenderTarget.d.ts new file mode 100644 index 000000000..fdff12e78 --- /dev/null +++ b/src-testing/src/renderers/WebGLRenderTarget.d.ts @@ -0,0 +1,8 @@ +import { RenderTarget, RenderTargetOptions } from "../core/RenderTarget.js"; +import { Texture } from "../textures/Texture.js"; + +export class WebGLRenderTarget extends RenderTarget { + constructor(width?: number, height?: number, options?: RenderTargetOptions); + + readonly isWebGLRenderTarget: true; +} diff --git a/src-testing/src/renderers/WebGLRenderer.d.ts b/src-testing/src/renderers/WebGLRenderer.d.ts new file mode 100644 index 000000000..963fd850a --- /dev/null +++ b/src-testing/src/renderers/WebGLRenderer.d.ts @@ -0,0 +1,558 @@ +import { Camera } from "../cameras/Camera.js"; +import { CullFace, ShadowMapType, ToneMapping, WebGLCoordinateSystem } from "../constants.js"; +import { TypedArray } from "../core/BufferAttribute.js"; +import { BufferGeometry } from "../core/BufferGeometry.js"; +import { Object3D } from "../core/Object3D.js"; +import { Material } from "../materials/Material.js"; +import { Box2 } from "../math/Box2.js"; +import { Box3 } from "../math/Box3.js"; +import { Color, ColorRepresentation } from "../math/Color.js"; +import { Plane } from "../math/Plane.js"; +import { Vector2 } from "../math/Vector2.js"; +import { Vector3 } from "../math/Vector3.js"; +import { Vector4 } from "../math/Vector4.js"; +import { Scene } from "../scenes/Scene.js"; +import { Data3DTexture } from "../textures/Data3DTexture.js"; +import { DataArrayTexture } from "../textures/DataArrayTexture.js"; +import { OffscreenCanvas, Texture } from "../textures/Texture.js"; +import { WebGLCapabilities, WebGLCapabilitiesParameters } from "./webgl/WebGLCapabilities.js"; +import { WebGLExtensions } from "./webgl/WebGLExtensions.js"; +import { WebGLInfo } from "./webgl/WebGLInfo.js"; +import { WebGLProgram } from "./webgl/WebGLProgram.js"; +import { WebGLProperties } from "./webgl/WebGLProperties.js"; +import { WebGLRenderLists } from "./webgl/WebGLRenderLists.js"; +import { WebGLShadowMap } from "./webgl/WebGLShadowMap.js"; +import { WebGLState } from "./webgl/WebGLState.js"; +import { WebGLRenderTarget } from "./WebGLRenderTarget.js"; +import { WebXRManager } from "./webxr/WebXRManager.js"; + +export interface Renderer { + domElement: HTMLCanvasElement; + + render(scene: Object3D, camera: Camera): void; + setSize(width: number, height: number, updateStyle?: boolean): void; +} + +export interface WebGLRendererParameters extends WebGLCapabilitiesParameters { + /** + * A Canvas where the renderer draws its output. + */ + canvas?: HTMLCanvasElement | OffscreenCanvas | undefined; + + /** + * A WebGL Rendering Context. + * (https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext) + * Default is null + */ + context?: WebGLRenderingContext | undefined; + + /** + * default is false. + */ + alpha?: boolean | undefined; + + /** + * default is true. + */ + premultipliedAlpha?: boolean | undefined; + + /** + * default is false. + */ + antialias?: boolean | undefined; + + /** + * default is false. + */ + stencil?: boolean | undefined; + + /** + * default is false. + */ + preserveDrawingBuffer?: boolean | undefined; + + /** + * Can be "high-performance", "low-power" or "default" + */ + powerPreference?: WebGLPowerPreference | undefined; + + /** + * default is true. + */ + depth?: boolean | undefined; + + /** + * default is false. + */ + failIfMajorPerformanceCaveat?: boolean | undefined; +} + +export interface WebGLDebug { + /** + * Enables error checking and reporting when shader programs are being compiled. + */ + checkShaderErrors: boolean; + + /** + * A callback function that can be used for custom error reporting. The callback receives the WebGL context, an + * instance of WebGLProgram as well two instances of WebGLShader representing the vertex and fragment shader. + * Assigning a custom function disables the default error reporting. + * @default `null` + */ + onShaderError: + | (( + gl: WebGLRenderingContext, + program: WebGLProgram, + glVertexShader: WebGLShader, + glFragmentShader: WebGLShader, + ) => void) + | null; +} + +/** + * The WebGL renderer displays your beautifully crafted scenes using WebGL, if your device supports it. + * This renderer has way better performance than CanvasRenderer. + * + * see {@link https://github.com/mrdoob/three.js/blob/master/src/renderers/WebGLRenderer.js|src/renderers/WebGLRenderer.js} + */ +export class WebGLRenderer implements Renderer { + /** + * parameters is an optional object with properties defining the renderer's behavior. + * The constructor also accepts no parameters at all. + * In all cases, it will assume sane defaults when parameters are missing. + */ + constructor(parameters?: WebGLRendererParameters); + + /** + * A Canvas where the renderer draws its output. + * This is automatically created by the renderer in the constructor (if not provided already); you just need to add it to your page. + * @default document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' ) + */ + domElement: HTMLCanvasElement; + + /** + * Defines whether the renderer should automatically clear its output before rendering. + * @default true + */ + autoClear: boolean; + + /** + * If autoClear is true, defines whether the renderer should clear the color buffer. Default is true. + * @default true + */ + autoClearColor: boolean; + + /** + * If autoClear is true, defines whether the renderer should clear the depth buffer. Default is true. + * @default true + */ + autoClearDepth: boolean; + + /** + * If autoClear is true, defines whether the renderer should clear the stencil buffer. Default is true. + * @default true + */ + autoClearStencil: boolean; + + /** + * Debug configurations. + * @default { checkShaderErrors: true } + */ + debug: WebGLDebug; + + /** + * Defines whether the renderer should sort objects. Default is true. + * @default true + */ + sortObjects: boolean; + + /** + * @default [] + */ + clippingPlanes: Plane[]; + + /** + * @default false + */ + localClippingEnabled: boolean; + + extensions: WebGLExtensions; + + /** + * Color space used for output to HTMLCanvasElement. Supported values are + * {@link SRGBColorSpace} and {@link LinearSRGBColorSpace}. + * @default THREE.SRGBColorSpace. + */ + get outputColorSpace(): string; + set outputColorSpace(colorSpace: string); + + get coordinateSystem(): typeof WebGLCoordinateSystem; + + /** + * @default THREE.NoToneMapping + */ + toneMapping: ToneMapping; + + /** + * @default 1 + */ + toneMappingExposure: number; + + info: WebGLInfo; + + shadowMap: WebGLShadowMap; + + pixelRatio: number; + + capabilities: WebGLCapabilities; + properties: WebGLProperties; + renderLists: WebGLRenderLists; + state: WebGLState; + + xr: WebXRManager; + + /** + * Return the WebGL context. + */ + getContext(): WebGLRenderingContext | WebGL2RenderingContext; + getContextAttributes(): any; + forceContextLoss(): void; + forceContextRestore(): void; + + /** + * @deprecated Use {@link WebGLCapabilities#getMaxAnisotropy .capabilities.getMaxAnisotropy()} instead. + */ + getMaxAnisotropy(): number; + + /** + * @deprecated Use {@link WebGLCapabilities#precision .capabilities.precision} instead. + */ + getPrecision(): string; + + getPixelRatio(): number; + setPixelRatio(value: number): void; + + getDrawingBufferSize(target: Vector2): Vector2; + setDrawingBufferSize(width: number, height: number, pixelRatio: number): void; + + getSize(target: Vector2): Vector2; + + /** + * Resizes the output canvas to (width, height), and also sets the viewport to fit that size, starting in (0, 0). + */ + setSize(width: number, height: number, updateStyle?: boolean): void; + + getCurrentViewport(target: Vector4): Vector4; + + /** + * Copies the viewport into target. + */ + getViewport(target: Vector4): Vector4; + + /** + * Sets the viewport to render from (x, y) to (x + width, y + height). + * (x, y) is the lower-left corner of the region. + */ + setViewport(x: Vector4 | number, y?: number, width?: number, height?: number): void; + + /** + * Copies the scissor area into target. + */ + getScissor(target: Vector4): Vector4; + + /** + * Sets the scissor area from (x, y) to (x + width, y + height). + */ + setScissor(x: Vector4 | number, y?: number, width?: number, height?: number): void; + + /** + * Returns true if scissor test is enabled; returns false otherwise. + */ + getScissorTest(): boolean; + + /** + * Enable the scissor test. When this is enabled, only the pixels within the defined scissor area will be affected by further renderer actions. + */ + setScissorTest(enable: boolean): void; + + /** + * Sets the custom opaque sort function for the WebGLRenderLists. Pass null to use the default painterSortStable function. + */ + setOpaqueSort(method: (a: any, b: any) => number): void; + + /** + * Sets the custom transparent sort function for the WebGLRenderLists. Pass null to use the default reversePainterSortStable function. + */ + setTransparentSort(method: (a: any, b: any) => number): void; + + /** + * Returns a THREE.Color instance with the current clear color. + */ + getClearColor(target: Color): Color; + + /** + * Sets the clear color, using color for the color and alpha for the opacity. + */ + setClearColor(color: ColorRepresentation, alpha?: number): void; + + /** + * Returns a float with the current clear alpha. Ranges from 0 to 1. + */ + getClearAlpha(): number; + + setClearAlpha(alpha: number): void; + + /** + * Tells the renderer to clear its color, depth or stencil drawing buffer(s). + * Arguments default to true + */ + clear(color?: boolean, depth?: boolean, stencil?: boolean): void; + + clearColor(): void; + clearDepth(): void; + clearStencil(): void; + clearTarget(renderTarget: WebGLRenderTarget, color: boolean, depth: boolean, stencil: boolean): void; + + /** + * @deprecated Use {@link WebGLState#reset .state.reset()} instead. + */ + resetGLState(): void; + dispose(): void; + + renderBufferDirect( + camera: Camera, + scene: Scene, + geometry: BufferGeometry, + material: Material, + object: Object3D, + geometryGroup: any, + ): void; + + /** + * A build in function that can be used instead of requestAnimationFrame. For WebXR projects this function must be used. + * @param callback The function will be called every available frame. If `null` is passed it will stop any already ongoing animation. + */ + setAnimationLoop(callback: XRFrameRequestCallback | null): void; + + /** + * @deprecated Use {@link WebGLRenderer#setAnimationLoop .setAnimationLoop()} instead. + */ + animate(callback: () => void): void; + + /** + * Compiles all materials in the scene with the camera. This is useful to precompile shaders before the first + * rendering. If you want to add a 3D object to an existing scene, use the third optional parameter for applying the + * target scene. + * Note that the (target) scene's lighting should be configured before calling this method. + */ + compile: (scene: Object3D, camera: Camera, targetScene?: Scene | null) => Set; + + /** + * Asynchronous version of {@link compile}(). The method returns a Promise that resolves when the given scene can be + * rendered without unnecessary stalling due to shader compilation. + * This method makes use of the KHR_parallel_shader_compile WebGL extension. + */ + compileAsync: (scene: Object3D, camera: Camera, targetScene?: Scene | null) => Promise; + + /** + * Render a scene or an object using a camera. + * The render is done to a previously specified {@link WebGLRenderTarget#renderTarget .renderTarget} set by calling + * {@link WebGLRenderer#setRenderTarget .setRenderTarget} or to the canvas as usual. + * + * By default render buffers are cleared before rendering but you can prevent this by setting the property + * {@link WebGLRenderer#autoClear autoClear} to false. If you want to prevent only certain buffers being cleared + * you can set either the {@link WebGLRenderer#autoClearColor autoClearColor}, + * {@link WebGLRenderer#autoClearStencil autoClearStencil} or {@link WebGLRenderer#autoClearDepth autoClearDepth} + * properties to false. To forcibly clear one ore more buffers call {@link WebGLRenderer#clear .clear}. + */ + render(scene: Object3D, camera: Camera): void; + + /** + * Returns the current active cube face. + */ + getActiveCubeFace(): number; + + /** + * Returns the current active mipmap level. + */ + getActiveMipmapLevel(): number; + + /** + * Returns the current render target. If no render target is set, null is returned. + */ + getRenderTarget(): WebGLRenderTarget | null; + + /** + * @deprecated Use {@link WebGLRenderer#getRenderTarget .getRenderTarget()} instead. + */ + getCurrentRenderTarget(): WebGLRenderTarget | null; + + /** + * Sets the active render target. + * + * @param renderTarget The {@link WebGLRenderTarget renderTarget} that needs to be activated. When `null` is given, the canvas is set as the active render target instead. + * @param activeCubeFace Specifies the active cube side (PX 0, NX 1, PY 2, NY 3, PZ 4, NZ 5) of {@link WebGLCubeRenderTarget}. + * @param activeMipmapLevel Specifies the active mipmap level. + */ + setRenderTarget( + renderTarget: WebGLRenderTarget | WebGLRenderTarget | null, + activeCubeFace?: number, + activeMipmapLevel?: number, + ): void; + + readRenderTargetPixels( + renderTarget: WebGLRenderTarget | WebGLRenderTarget, + x: number, + y: number, + width: number, + height: number, + buffer: TypedArray, + activeCubeFaceIndex?: number, + ): void; + + readRenderTargetPixelsAsync( + renderTarget: WebGLRenderTarget | WebGLRenderTarget, + x: number, + y: number, + width: number, + height: number, + buffer: TypedArray, + activeCubeFaceIndex?: number, + ): Promise; + + /** + * Copies a region of the currently bound framebuffer into the selected mipmap level of the selected texture. + * This region is defined by the size of the destination texture's mip level, offset by the input position. + * + * @param texture Specifies the destination texture. + * @param position Specifies the pixel offset from which to copy out of the framebuffer. + * @param level Specifies the destination mipmap level of the texture. + */ + copyFramebufferToTexture(texture: Texture, position?: Vector2 | null, level?: number): void; + + /** + * Copies the pixels of a texture in the bounds `srcRegion` in the destination texture starting from the given + * position. The `depthTexture` and `texture` property of render targets are supported as well. + * + * When using render target textures as `srcTexture` and `dstTexture`, you must make sure both render targets are + * intitialized e.g. via {@link .initRenderTarget}(). + * + * @param srcTexture Specifies the source texture. + * @param dstTexture Specifies the destination texture. + * @param srcRegion Specifies the bounds + * @param dstPosition Specifies the pixel offset into the dstTexture where the copy will occur. + * @param level Specifies the destination mipmap level of the texture. + */ + copyTextureToTexture( + srcTexture: Texture, + dstTexture: Texture, + srcRegion?: Box2 | null, + dstPosition?: Vector2 | null, + level?: number, + ): void; + + /** + * Copies the pixels of a texture in the bounds `srcRegion` in the destination texture starting from the given + * position. The `depthTexture` and `texture` property of 3D render targets are supported as well. + * + * When using render target textures as `srcTexture` and `dstTexture`, you must make sure both render targets are + * intitialized e.g. via {@link .initRenderTarget}(). + * + * @param srcTexture Specifies the source texture. + * @param dstTexture Specifies the destination texture. + * @param srcRegion Specifies the bounds + * @param dstPosition Specifies the pixel offset into the dstTexture where the copy will occur. + * @param level Specifies the destination mipmap level of the texture. + */ + copyTextureToTexture3D( + srcTexture: Texture, + dstTexture: Data3DTexture | DataArrayTexture, + srcRegion?: Box3 | null, + dstPosition?: Vector3 | null, + level?: number, + ): void; + + /** + * Initializes the given WebGLRenderTarget memory. Useful for initializing a render target so data can be copied + * into it using {@link WebGLRenderer.copyTextureToTexture} before it has been rendered to. + * @param target + */ + initRenderTarget(target: WebGLRenderTarget): void; + + /** + * Initializes the given texture. Can be used to preload a texture rather than waiting until first render (which can cause noticeable lags due to decode and GPU upload overhead). + * + * @param texture The texture to Initialize. + */ + initTexture(texture: Texture): void; + + /** + * Can be used to reset the internal WebGL state. + */ + resetState(): void; + + /** + * @deprecated Use {@link WebGLRenderer#xr .xr} instead. + */ + vr: boolean; + + /** + * @deprecated Use {@link WebGLShadowMap#enabled .shadowMap.enabled} instead. + */ + shadowMapEnabled: boolean; + + /** + * @deprecated Use {@link WebGLShadowMap#type .shadowMap.type} instead. + */ + shadowMapType: ShadowMapType; + + /** + * @deprecated Use {@link WebGLShadowMap#cullFace .shadowMap.cullFace} instead. + */ + shadowMapCullFace: CullFace; + + /** + * @deprecated Use {@link WebGLExtensions#get .extensions.get( 'OES_texture_float' )} instead. + */ + supportsFloatTextures(): any; + + /** + * @deprecated Use {@link WebGLExtensions#get .extensions.get( 'OES_texture_half_float' )} instead. + */ + supportsHalfFloatTextures(): any; + + /** + * @deprecated Use {@link WebGLExtensions#get .extensions.get( 'OES_standard_derivatives' )} instead. + */ + supportsStandardDerivatives(): any; + + /** + * @deprecated Use {@link WebGLExtensions#get .extensions.get( 'WEBGL_compressed_texture_s3tc' )} instead. + */ + supportsCompressedTextureS3TC(): any; + + /** + * @deprecated Use {@link WebGLExtensions#get .extensions.get( 'WEBGL_compressed_texture_pvrtc' )} instead. + */ + supportsCompressedTexturePVRTC(): any; + + /** + * @deprecated Use {@link WebGLExtensions#get .extensions.get( 'EXT_blend_minmax' )} instead. + */ + supportsBlendMinMax(): any; + + /** + * @deprecated Use {@link WebGLCapabilities#vertexTextures .capabilities.vertexTextures} instead. + */ + supportsVertexTextures(): any; + + /** + * @deprecated Use {@link WebGLExtensions#get .extensions.get( 'ANGLE_instanced_arrays' )} instead. + */ + supportsInstancedArrays(): any; + + /** + * @deprecated Use {@link WebGLRenderer#setScissorTest .setScissorTest()} instead. + */ + enableScissorTest(boolean: any): any; +} diff --git a/src-testing/src/renderers/common/Animation.ts b/src-testing/src/renderers/common/Animation.ts new file mode 100644 index 000000000..0b00319a1 --- /dev/null +++ b/src-testing/src/renderers/common/Animation.ts @@ -0,0 +1,38 @@ +class Animation { + constructor(nodes, info) { + this.nodes = nodes; + this.info = info; + + this.animationLoop = null; + this.requestId = null; + + this._init(); + } + + _init() { + const update = (time, frame) => { + this.requestId = self.requestAnimationFrame(update); + + if (this.info.autoReset === true) this.info.reset(); + + this.nodes.nodeFrame.update(); + + this.info.frame = this.nodes.nodeFrame.frameId; + + if (this.animationLoop !== null) this.animationLoop(time, frame); + }; + + update(); + } + + dispose() { + self.cancelAnimationFrame(this.requestId); + this.requestId = null; + } + + setAnimationLoop(callback) { + this.animationLoop = callback; + } +} + +export default Animation; diff --git a/src-testing/src/renderers/common/Attributes.ts b/src-testing/src/renderers/common/Attributes.ts new file mode 100644 index 000000000..4631d528b --- /dev/null +++ b/src-testing/src/renderers/common/Attributes.ts @@ -0,0 +1,56 @@ +import DataMap from './DataMap.js'; +import { AttributeType } from './Constants.js'; + +import { DynamicDrawUsage } from '../../constants.js'; + +class Attributes extends DataMap { + constructor(backend) { + super(); + + this.backend = backend; + } + + delete(attribute) { + const attributeData = super.delete(attribute); + + if (attributeData !== undefined) { + this.backend.destroyAttribute(attribute); + } + + return attributeData; + } + + update(attribute, type) { + const data = this.get(attribute); + + if (data.version === undefined) { + if (type === AttributeType.VERTEX) { + this.backend.createAttribute(attribute); + } else if (type === AttributeType.INDEX) { + this.backend.createIndexAttribute(attribute); + } else if (type === AttributeType.STORAGE) { + this.backend.createStorageAttribute(attribute); + } else if (type === AttributeType.INDIRECT) { + this.backend.createIndirectStorageAttribute(attribute); + } + + data.version = this._getBufferAttribute(attribute).version; + } else { + const bufferAttribute = this._getBufferAttribute(attribute); + + if (data.version < bufferAttribute.version || bufferAttribute.usage === DynamicDrawUsage) { + this.backend.updateAttribute(attribute); + + data.version = bufferAttribute.version; + } + } + } + + _getBufferAttribute(attribute) { + if (attribute.isInterleavedBufferAttribute) attribute = attribute.data; + + return attribute; + } +} + +export default Attributes; diff --git a/src-testing/src/renderers/common/Backend.ts b/src-testing/src/renderers/common/Backend.ts new file mode 100644 index 000000000..edd4fcf9c --- /dev/null +++ b/src-testing/src/renderers/common/Backend.ts @@ -0,0 +1,170 @@ +let vector2 = null; +let vector4 = null; +let color4 = null; + +import Color4 from './Color4.js'; +import { Vector2 } from '../../math/Vector2.js'; +import { Vector4 } from '../../math/Vector4.js'; +import { createCanvasElement } from '../../utils.js'; +import { REVISION } from '../../constants.js'; + +class Backend { + constructor(parameters = {}) { + this.parameters = Object.assign({}, parameters); + this.data = new WeakMap(); + this.renderer = null; + this.domElement = null; + } + + async init(renderer) { + this.renderer = renderer; + } + + // render context + + begin(/*renderContext*/) {} + + finish(/*renderContext*/) {} + + // render object + + draw(/*renderObject, info*/) {} + + // program + + createProgram(/*program*/) {} + + destroyProgram(/*program*/) {} + + // bindings + + createBindings(/*bingGroup, bindings*/) {} + + updateBindings(/*bingGroup, bindings*/) {} + + // pipeline + + createRenderPipeline(/*renderObject*/) {} + + createComputePipeline(/*computeNode, pipeline*/) {} + + destroyPipeline(/*pipeline*/) {} + + // cache key + + needsRenderUpdate(/*renderObject*/) {} // return Boolean ( fast test ) + + getRenderCacheKey(/*renderObject*/) {} // return String + + // node builder + + createNodeBuilder(/*renderObject*/) {} // return NodeBuilder (ADD IT) + + // textures + + createSampler(/*texture*/) {} + + createDefaultTexture(/*texture*/) {} + + createTexture(/*texture*/) {} + + copyTextureToBuffer(/*texture, x, y, width, height*/) {} + + // attributes + + createAttribute(/*attribute*/) {} + + createIndexAttribute(/*attribute*/) {} + + updateAttribute(/*attribute*/) {} + + destroyAttribute(/*attribute*/) {} + + // canvas + + getContext() {} + + updateSize() {} + + // utils + + resolveTimestampAsync(/*renderContext, type*/) {} + + hasFeatureAsync(/*name*/) {} // return Boolean + + hasFeature(/*name*/) {} // return Boolean + + getInstanceCount(renderObject) { + const { object, geometry } = renderObject; + + return geometry.isInstancedBufferGeometry ? geometry.instanceCount : object.count > 1 ? object.count : 1; + } + + getDrawingBufferSize() { + vector2 = vector2 || new Vector2(); + + return this.renderer.getDrawingBufferSize(vector2); + } + + getScissor() { + vector4 = vector4 || new Vector4(); + + return this.renderer.getScissor(vector4); + } + + setScissorTest(/*boolean*/) {} + + getClearColor() { + const renderer = this.renderer; + + color4 = color4 || new Color4(); + + renderer.getClearColor(color4); + + color4.getRGB(color4, this.renderer.currentColorSpace); + + return color4; + } + + getDomElement() { + let domElement = this.domElement; + + if (domElement === null) { + domElement = this.parameters.canvas !== undefined ? this.parameters.canvas : createCanvasElement(); + + // OffscreenCanvas does not have setAttribute, see #22811 + if ('setAttribute' in domElement) domElement.setAttribute('data-engine', `three.js r${REVISION} webgpu`); + + this.domElement = domElement; + } + + return domElement; + } + + // resource properties + + set(object, value) { + this.data.set(object, value); + } + + get(object) { + let map = this.data.get(object); + + if (map === undefined) { + map = {}; + this.data.set(object, map); + } + + return map; + } + + has(object) { + return this.data.has(object); + } + + delete(object) { + this.data.delete(object); + } +} + +export default Backend; diff --git a/src-testing/src/renderers/common/Background.ts b/src-testing/src/renderers/common/Background.ts new file mode 100644 index 000000000..b56dd3724 --- /dev/null +++ b/src-testing/src/renderers/common/Background.ts @@ -0,0 +1,133 @@ +import DataMap from './DataMap.js'; +import Color4 from './Color4.js'; +import { + vec4, + context, + normalWorld, + backgroundBlurriness, + backgroundIntensity, + modelViewProjection, +} from '../../nodes/TSL.js'; +import NodeMaterial from '../../materials/nodes/NodeMaterial.js'; + +import { Mesh } from '../../objects/Mesh.js'; +import { SphereGeometry } from '../../geometries/SphereGeometry.js'; +import { BackSide, LinearSRGBColorSpace } from '../../constants.js'; + +const _clearColor = /*@__PURE__*/ new Color4(); + +class Background extends DataMap { + constructor(renderer, nodes) { + super(); + + this.renderer = renderer; + this.nodes = nodes; + } + + update(scene, renderList, renderContext) { + const renderer = this.renderer; + const background = this.nodes.getBackgroundNode(scene) || scene.background; + + let forceClear = false; + + if (background === null) { + // no background settings, use clear color configuration from the renderer + + renderer._clearColor.getRGB(_clearColor, LinearSRGBColorSpace); + _clearColor.a = renderer._clearColor.a; + } else if (background.isColor === true) { + // background is an opaque color + + background.getRGB(_clearColor, LinearSRGBColorSpace); + _clearColor.a = 1; + + forceClear = true; + } else if (background.isNode === true) { + const sceneData = this.get(scene); + const backgroundNode = background; + + _clearColor.copy(renderer._clearColor); + + let backgroundMesh = sceneData.backgroundMesh; + + if (backgroundMesh === undefined) { + const backgroundMeshNode = context(vec4(backgroundNode).mul(backgroundIntensity), { + // @TODO: Add Texture2D support using node context + getUV: () => normalWorld, + getTextureLevel: () => backgroundBlurriness, + }); + + let viewProj = modelViewProjection(); + viewProj = viewProj.setZ(viewProj.w); + + const nodeMaterial = new NodeMaterial(); + nodeMaterial.name = 'Background.material'; + nodeMaterial.side = BackSide; + nodeMaterial.depthTest = false; + nodeMaterial.depthWrite = false; + nodeMaterial.fog = false; + nodeMaterial.lights = false; + nodeMaterial.vertexNode = viewProj; + nodeMaterial.colorNode = backgroundMeshNode; + + sceneData.backgroundMeshNode = backgroundMeshNode; + sceneData.backgroundMesh = backgroundMesh = new Mesh(new SphereGeometry(1, 32, 32), nodeMaterial); + backgroundMesh.frustumCulled = false; + backgroundMesh.name = 'Background.mesh'; + + backgroundMesh.onBeforeRender = function (renderer, scene, camera) { + this.matrixWorld.copyPosition(camera.matrixWorld); + }; + } + + const backgroundCacheKey = backgroundNode.getCacheKey(); + + if (sceneData.backgroundCacheKey !== backgroundCacheKey) { + sceneData.backgroundMeshNode.node = vec4(backgroundNode).mul(backgroundIntensity); + sceneData.backgroundMeshNode.needsUpdate = true; + + backgroundMesh.material.needsUpdate = true; + + sceneData.backgroundCacheKey = backgroundCacheKey; + } + + renderList.unshift(backgroundMesh, backgroundMesh.geometry, backgroundMesh.material, 0, 0, null); + } else { + console.error('THREE.Renderer: Unsupported background configuration.', background); + } + + // + + if (renderer.autoClear === true || forceClear === true) { + const clearColorValue = renderContext.clearColorValue; + + clearColorValue.r = _clearColor.r; + clearColorValue.g = _clearColor.g; + clearColorValue.b = _clearColor.b; + clearColorValue.a = _clearColor.a; + + // premultiply alpha + + if (renderer.backend.isWebGLBackend === true || renderer.alpha === true) { + clearColorValue.r *= clearColorValue.a; + clearColorValue.g *= clearColorValue.a; + clearColorValue.b *= clearColorValue.a; + } + + // + + renderContext.depthClearValue = renderer._clearDepth; + renderContext.stencilClearValue = renderer._clearStencil; + + renderContext.clearColor = renderer.autoClearColor === true; + renderContext.clearDepth = renderer.autoClearDepth === true; + renderContext.clearStencil = renderer.autoClearStencil === true; + } else { + renderContext.clearColor = false; + renderContext.clearDepth = false; + renderContext.clearStencil = false; + } + } +} + +export default Background; diff --git a/src-testing/src/renderers/common/BindGroup.ts b/src-testing/src/renderers/common/BindGroup.ts new file mode 100644 index 000000000..ae78d4787 --- /dev/null +++ b/src-testing/src/renderers/common/BindGroup.ts @@ -0,0 +1,14 @@ +let _id = 0; + +class BindGroup { + constructor(name = '', bindings = [], index = 0, bindingsReference = []) { + this.name = name; + this.bindings = bindings; + this.index = index; + this.bindingsReference = bindingsReference; + + this.id = _id++; + } +} + +export default BindGroup; diff --git a/src-testing/src/renderers/common/Binding.ts b/src-testing/src/renderers/common/Binding.ts new file mode 100644 index 000000000..a12f3563b --- /dev/null +++ b/src-testing/src/renderers/common/Binding.ts @@ -0,0 +1,17 @@ +class Binding { + constructor(name = '') { + this.name = name; + + this.visibility = 0; + } + + setVisibility(visibility) { + this.visibility |= visibility; + } + + clone() { + return Object.assign(new this.constructor(), this); + } +} + +export default Binding; diff --git a/src-testing/src/renderers/common/Bindings.ts b/src-testing/src/renderers/common/Bindings.ts new file mode 100644 index 000000000..1414c94fb --- /dev/null +++ b/src-testing/src/renderers/common/Bindings.ts @@ -0,0 +1,160 @@ +import DataMap from './DataMap.js'; +import { AttributeType } from './Constants.js'; + +class Bindings extends DataMap { + constructor(backend, nodes, textures, attributes, pipelines, info) { + super(); + + this.backend = backend; + this.textures = textures; + this.pipelines = pipelines; + this.attributes = attributes; + this.nodes = nodes; + this.info = info; + + this.pipelines.bindings = this; // assign bindings to pipelines + } + + getForRender(renderObject) { + const bindings = renderObject.getBindings(); + + for (const bindGroup of bindings) { + const groupData = this.get(bindGroup); + + if (groupData.bindGroup === undefined) { + // each object defines an array of bindings (ubos, textures, samplers etc.) + + this._init(bindGroup); + + this.backend.createBindings(bindGroup, bindings); + + groupData.bindGroup = bindGroup; + } + } + + return bindings; + } + + getForCompute(computeNode) { + const bindings = this.nodes.getForCompute(computeNode).bindings; + + for (const bindGroup of bindings) { + const groupData = this.get(bindGroup); + + if (groupData.bindGroup === undefined) { + this._init(bindGroup); + + this.backend.createBindings(bindGroup, bindings); + + groupData.bindGroup = bindGroup; + } + } + + return bindings; + } + + updateForCompute(computeNode) { + this._updateBindings(this.getForCompute(computeNode)); + } + + updateForRender(renderObject) { + this._updateBindings(this.getForRender(renderObject)); + } + + _updateBindings(bindings) { + for (const bindGroup of bindings) { + this._update(bindGroup, bindings); + } + } + + _init(bindGroup) { + for (const binding of bindGroup.bindings) { + if (binding.isSampledTexture) { + this.textures.updateTexture(binding.texture); + } else if (binding.isStorageBuffer) { + const attribute = binding.attribute; + const attributeType = attribute.isIndirectStorageBufferAttribute + ? AttributeType.INDIRECT + : AttributeType.STORAGE; + + this.attributes.update(attribute, attributeType); + } + } + } + + _update(bindGroup, bindings) { + const { backend } = this; + + let needsBindingsUpdate = false; + + // iterate over all bindings and check if buffer updates or a new binding group is required + + for (const binding of bindGroup.bindings) { + if (binding.isNodeUniformsGroup) { + const updated = this.nodes.updateGroup(binding); + + if (!updated) continue; + } + + if (binding.isUniformBuffer) { + const updated = binding.update(); + + if (updated) { + backend.updateBinding(binding); + } + } else if (binding.isSampler) { + binding.update(); + } else if (binding.isSampledTexture) { + if (binding.needsBindingsUpdate(this.textures.get(binding.texture).generation)) + needsBindingsUpdate = true; + + const updated = binding.update(); + + const texture = binding.texture; + + if (updated) { + this.textures.updateTexture(texture); + } + + const textureData = backend.get(texture); + + if ( + backend.isWebGPUBackend === true && + textureData.texture === undefined && + textureData.externalTexture === undefined + ) { + // TODO: Remove this once we found why updated === false isn't bound to a texture in the WebGPU backend + console.error( + 'Bindings._update: binding should be available:', + binding, + updated, + texture, + binding.textureNode.value, + needsBindingsUpdate, + ); + + this.textures.updateTexture(texture); + needsBindingsUpdate = true; + } + + if (texture.isStorageTexture === true) { + const textureData = this.get(texture); + + if (binding.store === true) { + textureData.needsMipmap = true; + } else if (this.textures.needsMipmaps(texture) && textureData.needsMipmap === true) { + this.backend.generateMipmaps(texture); + + textureData.needsMipmap = false; + } + } + } + } + + if (needsBindingsUpdate === true) { + this.backend.updateBindings(bindGroup, bindings); + } + } +} + +export default Bindings; diff --git a/src-testing/src/renderers/common/Buffer.ts b/src-testing/src/renderers/common/Buffer.ts new file mode 100644 index 000000000..17013c6dc --- /dev/null +++ b/src-testing/src/renderers/common/Buffer.ts @@ -0,0 +1,28 @@ +import Binding from './Binding.js'; +import { getFloatLength } from './BufferUtils.js'; + +class Buffer extends Binding { + constructor(name, buffer = null) { + super(name); + + this.isBuffer = true; + + this.bytesPerElement = Float32Array.BYTES_PER_ELEMENT; + + this._buffer = buffer; + } + + get byteLength() { + return getFloatLength(this._buffer.byteLength); + } + + get buffer() { + return this._buffer; + } + + update() { + return true; + } +} + +export default Buffer; diff --git a/src-testing/src/renderers/common/BufferUtils.ts b/src-testing/src/renderers/common/BufferUtils.ts new file mode 100644 index 000000000..99ddcb48b --- /dev/null +++ b/src-testing/src/renderers/common/BufferUtils.ts @@ -0,0 +1,23 @@ +import { GPU_CHUNK_BYTES } from './Constants.js'; + +function getFloatLength(floatLength) { + // ensure chunk size alignment (STD140 layout) + + return floatLength + ((GPU_CHUNK_BYTES - (floatLength % GPU_CHUNK_BYTES)) % GPU_CHUNK_BYTES); +} + +function getVectorLength(count, vectorLength = 4) { + const strideLength = getStrideLength(vectorLength); + + const floatLength = strideLength * count; + + return getFloatLength(floatLength); +} + +function getStrideLength(vectorLength) { + const strideLength = 4; + + return vectorLength + ((strideLength - (vectorLength % strideLength)) % strideLength); +} + +export { getFloatLength, getVectorLength, getStrideLength }; diff --git a/src-testing/src/renderers/common/BundleGroup.ts b/src-testing/src/renderers/common/BundleGroup.ts new file mode 100644 index 000000000..1dd8e0a2c --- /dev/null +++ b/src-testing/src/renderers/common/BundleGroup.ts @@ -0,0 +1,20 @@ +import { Group } from '../../objects/Group.js'; + +class BundleGroup extends Group { + constructor() { + super(); + + this.isBundleGroup = true; + + this.type = 'BundleGroup'; + + this.static = true; + this.version = 0; + } + + set needsUpdate(value) { + if (value === true) this.version++; + } +} + +export default BundleGroup; diff --git a/src-testing/src/renderers/common/ChainMap.ts b/src-testing/src/renderers/common/ChainMap.ts new file mode 100644 index 000000000..b17e7080f --- /dev/null +++ b/src-testing/src/renderers/common/ChainMap.ts @@ -0,0 +1,43 @@ +export default class ChainMap { + constructor() { + this.weakMap = new WeakMap(); + } + + get(keys) { + let map = this.weakMap; + + for (let i = 0; i < keys.length; i++) { + map = map.get(keys[i]); + + if (map === undefined) return undefined; + } + + return map.get(keys[keys.length - 1]); + } + + set(keys, value) { + let map = this.weakMap; + + for (let i = 0; i < keys.length; i++) { + const key = keys[i]; + + if (map.has(key) === false) map.set(key, new WeakMap()); + + map = map.get(key); + } + + return map.set(keys[keys.length - 1], value); + } + + delete(keys) { + let map = this.weakMap; + + for (let i = 0; i < keys.length; i++) { + map = map.get(keys[i]); + + if (map === undefined) return false; + } + + return map.delete(keys[keys.length - 1]); + } +} diff --git a/src-testing/src/renderers/common/ClippingContext.ts b/src-testing/src/renderers/common/ClippingContext.ts new file mode 100644 index 000000000..c5659721a --- /dev/null +++ b/src-testing/src/renderers/common/ClippingContext.ts @@ -0,0 +1,136 @@ +import { Matrix3 } from '../../math/Matrix3.js'; +import { Plane } from '../../math/Plane.js'; +import { Vector4 } from '../../math/Vector4.js'; +import { hash } from '../../nodes/core/NodeUtils.js'; + +const _plane = /*@__PURE__*/ new Plane(); + +class ClippingContext { + constructor() { + this.version = 0; + + this.globalClippingCount = 0; + + this.localClippingCount = 0; + this.localClippingEnabled = false; + this.localClipIntersection = false; + + this.planes = []; + + this.parentVersion = 0; + this.viewNormalMatrix = new Matrix3(); + this.cacheKey = 0; + } + + projectPlanes(source, offset) { + const l = source.length; + const planes = this.planes; + + for (let i = 0; i < l; i++) { + _plane.copy(source[i]).applyMatrix4(this.viewMatrix, this.viewNormalMatrix); + + const v = planes[offset + i]; + const normal = _plane.normal; + + v.x = -normal.x; + v.y = -normal.y; + v.z = -normal.z; + v.w = _plane.constant; + } + } + + updateGlobal(renderer, camera) { + const rendererClippingPlanes = renderer.clippingPlanes; + this.viewMatrix = camera.matrixWorldInverse; + + this.viewNormalMatrix.getNormalMatrix(this.viewMatrix); + + let update = false; + + if (Array.isArray(rendererClippingPlanes) && rendererClippingPlanes.length !== 0) { + const l = rendererClippingPlanes.length; + + if (l !== this.globalClippingCount) { + const planes = []; + + for (let i = 0; i < l; i++) { + planes.push(new Vector4()); + } + + this.globalClippingCount = l; + this.planes = planes; + + update = true; + } + + this.projectPlanes(rendererClippingPlanes, 0); + } else if (this.globalClippingCount !== 0) { + this.globalClippingCount = 0; + this.planes = []; + update = true; + } + + if (renderer.localClippingEnabled !== this.localClippingEnabled) { + this.localClippingEnabled = renderer.localClippingEnabled; + update = true; + } + + if (update) { + this.version++; + this.cacheKey = hash(this.globalClippingCount, this.localClippingEnabled === true ? 1 : 0); + } + } + + update(parent, material) { + let update = false; + + if (this !== parent && parent.version !== this.parentVersion) { + this.globalClippingCount = material.isShadowNodeMaterial ? 0 : parent.globalClippingCount; + this.localClippingEnabled = parent.localClippingEnabled; + this.planes = Array.from(parent.planes); + this.parentVersion = parent.version; + this.viewMatrix = parent.viewMatrix; + this.viewNormalMatrix = parent.viewNormalMatrix; + + update = true; + } + + if (this.localClippingEnabled) { + const localClippingPlanes = material.clippingPlanes; + + if (Array.isArray(localClippingPlanes) && localClippingPlanes.length !== 0) { + const l = localClippingPlanes.length; + const planes = this.planes; + const offset = this.globalClippingCount; + + if (update || l !== this.localClippingCount) { + planes.length = offset + l; + + for (let i = 0; i < l; i++) { + planes[offset + i] = new Vector4(); + } + + this.localClippingCount = l; + update = true; + } + + this.projectPlanes(localClippingPlanes, offset); + } else if (this.localClippingCount !== 0) { + this.localClippingCount = 0; + update = true; + } + + if (this.localClipIntersection !== material.clipIntersection) { + this.localClipIntersection = material.clipIntersection; + update = true; + } + } + + if (update) { + this.version += parent.version; + this.cacheKey = hash(parent.cacheKey, this.localClippingCount, this.localClipIntersection === true ? 1 : 0); + } + } +} + +export default ClippingContext; diff --git a/src-testing/src/renderers/common/Color4.ts b/src-testing/src/renderers/common/Color4.ts new file mode 100644 index 000000000..77caa31e0 --- /dev/null +++ b/src-testing/src/renderers/common/Color4.ts @@ -0,0 +1,27 @@ +import { Color } from '../../math/Color.js'; + +class Color4 extends Color { + constructor(r, g, b, a = 1) { + super(r, g, b); + + this.a = a; + } + + set(r, g, b, a = 1) { + this.a = a; + + return super.set(r, g, b); + } + + copy(color) { + if (color.a !== undefined) this.a = color.a; + + return super.copy(color); + } + + clone() { + return new this.constructor(this.r, this.g, this.b, this.a); + } +} + +export default Color4; diff --git a/src-testing/src/renderers/common/ComputePipeline.ts b/src-testing/src/renderers/common/ComputePipeline.ts new file mode 100644 index 000000000..0fd3ca531 --- /dev/null +++ b/src-testing/src/renderers/common/ComputePipeline.ts @@ -0,0 +1,13 @@ +import Pipeline from './Pipeline.js'; + +class ComputePipeline extends Pipeline { + constructor(cacheKey, computeProgram) { + super(cacheKey); + + this.computeProgram = computeProgram; + + this.isComputePipeline = true; + } +} + +export default ComputePipeline; diff --git a/src-testing/src/renderers/common/Constants.ts b/src-testing/src/renderers/common/Constants.ts new file mode 100644 index 000000000..c2dfad4c4 --- /dev/null +++ b/src-testing/src/renderers/common/Constants.ts @@ -0,0 +1,15 @@ +export const AttributeType = { + VERTEX: 1, + INDEX: 2, + STORAGE: 3, + INDIRECT: 4, +}; + +// size of a chunk in bytes (STD140 layout) + +export const GPU_CHUNK_BYTES = 16; + +// @TODO: Move to src/constants.js + +export const BlendColorFactor = 211; +export const OneMinusBlendColorFactor = 212; diff --git a/src-testing/src/renderers/common/CubeRenderTarget.ts b/src-testing/src/renderers/common/CubeRenderTarget.ts new file mode 100644 index 000000000..00c0fd8c4 --- /dev/null +++ b/src-testing/src/renderers/common/CubeRenderTarget.ts @@ -0,0 +1,71 @@ +import { equirectUV } from '../../nodes/utils/EquirectUVNode.js'; +import { texture as TSL_Texture } from '../../nodes/accessors/TextureNode.js'; +import { positionWorldDirection } from '../../nodes/accessors/Position.js'; +import NodeMaterial from '../../materials/nodes/NodeMaterial.js'; + +import { WebGLCubeRenderTarget } from '../../renderers/WebGLCubeRenderTarget.js'; +import { Scene } from '../../scenes/Scene.js'; +import { CubeCamera } from '../../cameras/CubeCamera.js'; +import { BoxGeometry } from '../../geometries/BoxGeometry.js'; +import { Mesh } from '../../objects/Mesh.js'; +import { BackSide, NoBlending, LinearFilter, LinearMipmapLinearFilter } from '../../constants.js'; + +// @TODO: Consider rename WebGLCubeRenderTarget to just CubeRenderTarget + +class CubeRenderTarget extends WebGLCubeRenderTarget { + constructor(size = 1, options = {}) { + super(size, options); + + this.isCubeRenderTarget = true; + } + + fromEquirectangularTexture(renderer, texture) { + const currentMinFilter = texture.minFilter; + const currentGenerateMipmaps = texture.generateMipmaps; + + texture.generateMipmaps = true; + + this.texture.type = texture.type; + this.texture.colorSpace = texture.colorSpace; + + this.texture.generateMipmaps = texture.generateMipmaps; + this.texture.minFilter = texture.minFilter; + this.texture.magFilter = texture.magFilter; + + const geometry = new BoxGeometry(5, 5, 5); + + const uvNode = equirectUV(positionWorldDirection); + + const material = new NodeMaterial(); + material.colorNode = TSL_Texture(texture, uvNode, 0); + material.side = BackSide; + material.blending = NoBlending; + + const mesh = new Mesh(geometry, material); + + const scene = new Scene(); + scene.add(mesh); + + // Avoid blurred poles + if (texture.minFilter === LinearMipmapLinearFilter) texture.minFilter = LinearFilter; + + const camera = new CubeCamera(1, 10, this); + + const currentMRT = renderer.getMRT(); + renderer.setMRT(null); + + camera.update(renderer, scene); + + renderer.setMRT(currentMRT); + + texture.minFilter = currentMinFilter; + texture.currentGenerateMipmaps = currentGenerateMipmaps; + + mesh.geometry.dispose(); + mesh.material.dispose(); + + return this; + } +} + +export default CubeRenderTarget; diff --git a/src-testing/src/renderers/common/DataMap.ts b/src-testing/src/renderers/common/DataMap.ts new file mode 100644 index 000000000..006bc2950 --- /dev/null +++ b/src-testing/src/renderers/common/DataMap.ts @@ -0,0 +1,38 @@ +class DataMap { + constructor() { + this.data = new WeakMap(); + } + + get(object) { + let map = this.data.get(object); + + if (map === undefined) { + map = {}; + this.data.set(object, map); + } + + return map; + } + + delete(object) { + let map; + + if (this.data.has(object)) { + map = this.data.get(object); + + this.data.delete(object); + } + + return map; + } + + has(object) { + return this.data.has(object); + } + + dispose() { + this.data = new WeakMap(); + } +} + +export default DataMap; diff --git a/src-testing/src/renderers/common/Geometries.ts b/src-testing/src/renderers/common/Geometries.ts new file mode 100644 index 000000000..14c52f6f6 --- /dev/null +++ b/src-testing/src/renderers/common/Geometries.ts @@ -0,0 +1,199 @@ +import DataMap from './DataMap.js'; +import { AttributeType } from './Constants.js'; + +import { Uint16BufferAttribute, Uint32BufferAttribute } from '../../core/BufferAttribute.js'; + +function arrayNeedsUint32(array) { + // assumes larger values usually on last + + for (let i = array.length - 1; i >= 0; --i) { + if (array[i] >= 65535) return true; // account for PRIMITIVE_RESTART_FIXED_INDEX, #24565 + } + + return false; +} + +function getWireframeVersion(geometry) { + return geometry.index !== null ? geometry.index.version : geometry.attributes.position.version; +} + +function getWireframeIndex(geometry) { + const indices = []; + + const geometryIndex = geometry.index; + const geometryPosition = geometry.attributes.position; + + if (geometryIndex !== null) { + const array = geometryIndex.array; + + for (let i = 0, l = array.length; i < l; i += 3) { + const a = array[i + 0]; + const b = array[i + 1]; + const c = array[i + 2]; + + indices.push(a, b, b, c, c, a); + } + } else { + const array = geometryPosition.array; + + for (let i = 0, l = array.length / 3 - 1; i < l; i += 3) { + const a = i + 0; + const b = i + 1; + const c = i + 2; + + indices.push(a, b, b, c, c, a); + } + } + + const attribute = new (arrayNeedsUint32(indices) ? Uint32BufferAttribute : Uint16BufferAttribute)(indices, 1); + attribute.version = getWireframeVersion(geometry); + + return attribute; +} + +class Geometries extends DataMap { + constructor(attributes, info) { + super(); + + this.attributes = attributes; + this.info = info; + + this.wireframes = new WeakMap(); + + this.attributeCall = new WeakMap(); + } + + has(renderObject) { + const geometry = renderObject.geometry; + + return super.has(geometry) && this.get(geometry).initialized === true; + } + + updateForRender(renderObject) { + if (this.has(renderObject) === false) this.initGeometry(renderObject); + + this.updateAttributes(renderObject); + } + + initGeometry(renderObject) { + const geometry = renderObject.geometry; + const geometryData = this.get(geometry); + + geometryData.initialized = true; + + this.info.memory.geometries++; + + const onDispose = () => { + this.info.memory.geometries--; + + const index = geometry.index; + const geometryAttributes = renderObject.getAttributes(); + + if (index !== null) { + this.attributes.delete(index); + } + + for (const geometryAttribute of geometryAttributes) { + this.attributes.delete(geometryAttribute); + } + + const wireframeAttribute = this.wireframes.get(geometry); + + if (wireframeAttribute !== undefined) { + this.attributes.delete(wireframeAttribute); + } + + geometry.removeEventListener('dispose', onDispose); + }; + + geometry.addEventListener('dispose', onDispose); + } + + updateAttributes(renderObject) { + // attributes + + const attributes = renderObject.getAttributes(); + + for (const attribute of attributes) { + if (attribute.isStorageBufferAttribute || attribute.isStorageInstancedBufferAttribute) { + this.updateAttribute(attribute, AttributeType.STORAGE); + } else { + this.updateAttribute(attribute, AttributeType.VERTEX); + } + } + + // indexes + + const index = this.getIndex(renderObject); + + if (index !== null) { + this.updateAttribute(index, AttributeType.INDEX); + } + + // indirect + + const indirect = renderObject.geometry.indirect; + + if (indirect !== null) { + this.updateAttribute(indirect, AttributeType.INDIRECT); + } + } + + updateAttribute(attribute, type) { + const callId = this.info.render.calls; + + if (!attribute.isInterleavedBufferAttribute) { + if (this.attributeCall.get(attribute) !== callId) { + this.attributes.update(attribute, type); + + this.attributeCall.set(attribute, callId); + } + } else { + if (this.attributeCall.get(attribute) === undefined) { + this.attributes.update(attribute, type); + + this.attributeCall.set(attribute, callId); + } else if (this.attributeCall.get(attribute.data) !== callId) { + this.attributes.update(attribute, type); + + this.attributeCall.set(attribute.data, callId); + + this.attributeCall.set(attribute, callId); + } + } + } + + getIndirect(renderObject) { + return renderObject.geometry.indirect; + } + + getIndex(renderObject) { + const { geometry, material } = renderObject; + + let index = geometry.index; + + if (material.wireframe === true) { + const wireframes = this.wireframes; + + let wireframeAttribute = wireframes.get(geometry); + + if (wireframeAttribute === undefined) { + wireframeAttribute = getWireframeIndex(geometry); + + wireframes.set(geometry, wireframeAttribute); + } else if (wireframeAttribute.version !== getWireframeVersion(geometry)) { + this.attributes.delete(wireframeAttribute); + + wireframeAttribute = getWireframeIndex(geometry); + + wireframes.set(geometry, wireframeAttribute); + } + + index = wireframeAttribute; + } + + return index; + } +} + +export default Geometries; diff --git a/src-testing/src/renderers/common/IndirectStorageBufferAttribute.d.ts b/src-testing/src/renderers/common/IndirectStorageBufferAttribute.d.ts new file mode 100644 index 000000000..925294395 --- /dev/null +++ b/src-testing/src/renderers/common/IndirectStorageBufferAttribute.d.ts @@ -0,0 +1,10 @@ +import { TypedArray } from "../../core/BufferAttribute.js"; +import StorageBufferAttribute from "./StorageBufferAttribute.js"; + +declare class IndirectStorageBufferAttribute extends StorageBufferAttribute { + readonly isIndirectStorageBufferAttribute: true; + + constructor(array: TypedArray, itemSize: number); +} + +export default IndirectStorageBufferAttribute; diff --git a/src-testing/src/renderers/common/Info.ts b/src-testing/src/renderers/common/Info.ts new file mode 100644 index 000000000..4ede75de7 --- /dev/null +++ b/src-testing/src/renderers/common/Info.ts @@ -0,0 +1,95 @@ +class Info { + constructor() { + this.autoReset = true; + + this.frame = 0; + this.calls = 0; + + this.render = { + calls: 0, + frameCalls: 0, + drawCalls: 0, + triangles: 0, + points: 0, + lines: 0, + timestamp: 0, + previousFrameCalls: 0, + timestampCalls: 0, + }; + + this.compute = { + calls: 0, + frameCalls: 0, + timestamp: 0, + previousFrameCalls: 0, + timestampCalls: 0, + }; + + this.memory = { + geometries: 0, + textures: 0, + }; + } + + update(object, count, instanceCount) { + this.render.drawCalls++; + + if (object.isMesh || object.isSprite) { + this.render.triangles += instanceCount * (count / 3); + } else if (object.isPoints) { + this.render.points += instanceCount * count; + } else if (object.isLineSegments) { + this.render.lines += instanceCount * (count / 2); + } else if (object.isLine) { + this.render.lines += instanceCount * (count - 1); + } else { + console.error('THREE.WebGPUInfo: Unknown object type.'); + } + } + + updateTimestamp(type, time) { + if (this[type].timestampCalls === 0) { + this[type].timestamp = 0; + } + + this[type].timestamp += time; + + this[type].timestampCalls++; + + if (this[type].timestampCalls >= this[type].previousFrameCalls) { + this[type].timestampCalls = 0; + } + } + + reset() { + const previousRenderFrameCalls = this.render.frameCalls; + this.render.previousFrameCalls = previousRenderFrameCalls; + + const previousComputeFrameCalls = this.compute.frameCalls; + this.compute.previousFrameCalls = previousComputeFrameCalls; + + this.render.drawCalls = 0; + this.render.frameCalls = 0; + this.compute.frameCalls = 0; + + this.render.triangles = 0; + this.render.points = 0; + this.render.lines = 0; + } + + dispose() { + this.reset(); + + this.calls = 0; + + this.render.calls = 0; + this.compute.calls = 0; + + this.render.timestamp = 0; + this.compute.timestamp = 0; + this.memory.geometries = 0; + this.memory.textures = 0; + } +} + +export default Info; diff --git a/src-testing/src/renderers/common/Lighting.d.ts b/src-testing/src/renderers/common/Lighting.d.ts new file mode 100644 index 000000000..72842e6e7 --- /dev/null +++ b/src-testing/src/renderers/common/Lighting.d.ts @@ -0,0 +1,15 @@ +import { Camera } from "../../cameras/Camera.js"; +import { Object3D } from "../../core/Object3D.js"; +import { Light } from "../../lights/Light.js"; +import LightsNode from "../../nodes/lighting/LightsNode.js"; +import ChainMap from "./ChainMap.js"; + +declare class Lighting extends ChainMap<[Object3D, Camera], LightsNode> { + constructor(); + + createNode(lights?: Light[]): LightsNode; + + getNode(scene: Object3D, camera: Camera): LightsNode; +} + +export default Lighting; diff --git a/src-testing/src/renderers/common/Pipeline.ts b/src-testing/src/renderers/common/Pipeline.ts new file mode 100644 index 000000000..16017455a --- /dev/null +++ b/src-testing/src/renderers/common/Pipeline.ts @@ -0,0 +1,9 @@ +class Pipeline { + constructor(cacheKey) { + this.cacheKey = cacheKey; + + this.usedTimes = 0; + } +} + +export default Pipeline; diff --git a/src-testing/src/renderers/common/Pipelines.ts b/src-testing/src/renderers/common/Pipelines.ts new file mode 100644 index 000000000..68c8f223c --- /dev/null +++ b/src-testing/src/renderers/common/Pipelines.ts @@ -0,0 +1,270 @@ +import DataMap from './DataMap.js'; +import RenderPipeline from './RenderPipeline.js'; +import ComputePipeline from './ComputePipeline.js'; +import ProgrammableStage from './ProgrammableStage.js'; + +class Pipelines extends DataMap { + constructor(backend, nodes) { + super(); + + this.backend = backend; + this.nodes = nodes; + + this.bindings = null; // set by the bindings + + this.caches = new Map(); + this.programs = { + vertex: new Map(), + fragment: new Map(), + compute: new Map(), + }; + } + + getForCompute(computeNode, bindings) { + const { backend } = this; + + const data = this.get(computeNode); + + if (this._needsComputeUpdate(computeNode)) { + const previousPipeline = data.pipeline; + + if (previousPipeline) { + previousPipeline.usedTimes--; + previousPipeline.computeProgram.usedTimes--; + } + + // get shader + + const nodeBuilderState = this.nodes.getForCompute(computeNode); + + // programmable stage + + let stageCompute = this.programs.compute.get(nodeBuilderState.computeShader); + + if (stageCompute === undefined) { + if (previousPipeline && previousPipeline.computeProgram.usedTimes === 0) + this._releaseProgram(previousPipeline.computeProgram); + + stageCompute = new ProgrammableStage( + nodeBuilderState.computeShader, + 'compute', + nodeBuilderState.transforms, + nodeBuilderState.nodeAttributes, + ); + this.programs.compute.set(nodeBuilderState.computeShader, stageCompute); + + backend.createProgram(stageCompute); + } + + // determine compute pipeline + + const cacheKey = this._getComputeCacheKey(computeNode, stageCompute); + + let pipeline = this.caches.get(cacheKey); + + if (pipeline === undefined) { + if (previousPipeline && previousPipeline.usedTimes === 0) this._releasePipeline(previousPipeline); + + pipeline = this._getComputePipeline(computeNode, stageCompute, cacheKey, bindings); + } + + // keep track of all used times + + pipeline.usedTimes++; + stageCompute.usedTimes++; + + // + + data.version = computeNode.version; + data.pipeline = pipeline; + } + + return data.pipeline; + } + + getForRender(renderObject, promises = null) { + const { backend } = this; + + const data = this.get(renderObject); + + if (this._needsRenderUpdate(renderObject)) { + const previousPipeline = data.pipeline; + + if (previousPipeline) { + previousPipeline.usedTimes--; + previousPipeline.vertexProgram.usedTimes--; + previousPipeline.fragmentProgram.usedTimes--; + } + + // get shader + + const nodeBuilderState = renderObject.getNodeBuilderState(); + + // programmable stages + + let stageVertex = this.programs.vertex.get(nodeBuilderState.vertexShader); + + if (stageVertex === undefined) { + if (previousPipeline && previousPipeline.vertexProgram.usedTimes === 0) + this._releaseProgram(previousPipeline.vertexProgram); + + stageVertex = new ProgrammableStage(nodeBuilderState.vertexShader, 'vertex'); + this.programs.vertex.set(nodeBuilderState.vertexShader, stageVertex); + + backend.createProgram(stageVertex); + } + + let stageFragment = this.programs.fragment.get(nodeBuilderState.fragmentShader); + + if (stageFragment === undefined) { + if (previousPipeline && previousPipeline.fragmentProgram.usedTimes === 0) + this._releaseProgram(previousPipeline.fragmentProgram); + + stageFragment = new ProgrammableStage(nodeBuilderState.fragmentShader, 'fragment'); + this.programs.fragment.set(nodeBuilderState.fragmentShader, stageFragment); + + backend.createProgram(stageFragment); + } + + // determine render pipeline + + const cacheKey = this._getRenderCacheKey(renderObject, stageVertex, stageFragment); + + let pipeline = this.caches.get(cacheKey); + + if (pipeline === undefined) { + if (previousPipeline && previousPipeline.usedTimes === 0) this._releasePipeline(previousPipeline); + + pipeline = this._getRenderPipeline(renderObject, stageVertex, stageFragment, cacheKey, promises); + } else { + renderObject.pipeline = pipeline; + } + + // keep track of all used times + + pipeline.usedTimes++; + stageVertex.usedTimes++; + stageFragment.usedTimes++; + + // + + data.pipeline = pipeline; + } + + return data.pipeline; + } + + delete(object) { + const pipeline = this.get(object).pipeline; + + if (pipeline) { + // pipeline + + pipeline.usedTimes--; + + if (pipeline.usedTimes === 0) this._releasePipeline(pipeline); + + // programs + + if (pipeline.isComputePipeline) { + pipeline.computeProgram.usedTimes--; + + if (pipeline.computeProgram.usedTimes === 0) this._releaseProgram(pipeline.computeProgram); + } else { + pipeline.fragmentProgram.usedTimes--; + pipeline.vertexProgram.usedTimes--; + + if (pipeline.vertexProgram.usedTimes === 0) this._releaseProgram(pipeline.vertexProgram); + if (pipeline.fragmentProgram.usedTimes === 0) this._releaseProgram(pipeline.fragmentProgram); + } + } + + return super.delete(object); + } + + dispose() { + super.dispose(); + + this.caches = new Map(); + this.programs = { + vertex: new Map(), + fragment: new Map(), + compute: new Map(), + }; + } + + updateForRender(renderObject) { + this.getForRender(renderObject); + } + + _getComputePipeline(computeNode, stageCompute, cacheKey, bindings) { + // check for existing pipeline + + cacheKey = cacheKey || this._getComputeCacheKey(computeNode, stageCompute); + + let pipeline = this.caches.get(cacheKey); + + if (pipeline === undefined) { + pipeline = new ComputePipeline(cacheKey, stageCompute); + + this.caches.set(cacheKey, pipeline); + + this.backend.createComputePipeline(pipeline, bindings); + } + + return pipeline; + } + + _getRenderPipeline(renderObject, stageVertex, stageFragment, cacheKey, promises) { + // check for existing pipeline + + cacheKey = cacheKey || this._getRenderCacheKey(renderObject, stageVertex, stageFragment); + + let pipeline = this.caches.get(cacheKey); + + if (pipeline === undefined) { + pipeline = new RenderPipeline(cacheKey, stageVertex, stageFragment); + + this.caches.set(cacheKey, pipeline); + + renderObject.pipeline = pipeline; + + this.backend.createRenderPipeline(renderObject, promises); + } + + return pipeline; + } + + _getComputeCacheKey(computeNode, stageCompute) { + return computeNode.id + ',' + stageCompute.id; + } + + _getRenderCacheKey(renderObject, stageVertex, stageFragment) { + return stageVertex.id + ',' + stageFragment.id + ',' + this.backend.getRenderCacheKey(renderObject); + } + + _releasePipeline(pipeline) { + this.caches.delete(pipeline.cacheKey); + } + + _releaseProgram(program) { + const code = program.code; + const stage = program.stage; + + this.programs[stage].delete(code); + } + + _needsComputeUpdate(computeNode) { + const data = this.get(computeNode); + + return data.pipeline === undefined || data.version !== computeNode.version; + } + + _needsRenderUpdate(renderObject) { + const data = this.get(renderObject); + + return data.pipeline === undefined || this.backend.needsRenderUpdate(renderObject); + } +} + +export default Pipelines; diff --git a/src-testing/src/renderers/common/PostProcessing.d.ts b/src-testing/src/renderers/common/PostProcessing.d.ts new file mode 100644 index 000000000..fdd4e5bdc --- /dev/null +++ b/src-testing/src/renderers/common/PostProcessing.d.ts @@ -0,0 +1,21 @@ +import { Node } from "../../nodes/Nodes.js"; +import Renderer from "./Renderer.js"; + +declare class PostProcessing { + renderer: Renderer; + outputNode: Node; + + outputColorTransform: boolean; + + needsUpdate: boolean; + + constructor(renderer: Renderer, outputNode?: Node); + + render(): void; + + update(): void; + + renderAsync(): Promise; +} + +export default PostProcessing; diff --git a/src-testing/src/renderers/common/PostProcessingUtils.d.ts b/src-testing/src/renderers/common/PostProcessingUtils.d.ts new file mode 100644 index 000000000..2ef80556c --- /dev/null +++ b/src-testing/src/renderers/common/PostProcessingUtils.d.ts @@ -0,0 +1,66 @@ +import { Camera } from "../../cameras/Camera.js"; +import { ToneMapping } from "../../constants.js"; +import { BufferGeometry, GeometryGroup } from "../../core/BufferGeometry.js"; +import { Object3D } from "../../core/Object3D.js"; +import { RenderTarget } from "../../core/RenderTarget.js"; +import { Material } from "../../materials/Material.js"; +import { Color } from "../../math/Color.js"; +import MRTNode from "../../nodes/core/MRTNode.js"; +import LightsNode from "../../nodes/lighting/LightsNode.js"; +import { Scene } from "../../scenes/Scene.js"; +import { CubeTexture } from "../../textures/CubeTexture.js"; +import { Texture } from "../../textures/Texture.js"; +import Color4 from "./Color4.js"; +import Renderer from "./Renderer.js"; + +// renderer state + +export interface RendererState { + toneMapping: ToneMapping; + toneMappingExposure: number; + outputColorSpace: string; + renderTarget: RenderTarget | null; + activeCubeFace: number; + activeMipmapLevel: number; + renderObjectFunction: + | (( + object: Object3D, + scene: Scene, + camera: Camera, + geometry: BufferGeometry, + material: Material, + group: GeometryGroup, + lightsNode: LightsNode, + ) => void) + | null; + pixelRatio: number; + mrt: MRTNode | null; + clearColor: Color4; + clearAlpha: number; + autoClear: boolean; + scissorTest: boolean; +} + +export function saveRendererState(renderer: Renderer, state?: RendererState): RendererState; + +export function resetRendererState(renderer: Renderer, state?: RendererState): RendererState; + +export function restoreRendererState(renderer: Renderer, state: RendererState): void; + +// renderer and scene state + +export interface RendererAndSceneState extends RendererState { + background: Color | Texture | CubeTexture | null; + backgroundNode: Node | null | undefined; + overrideMaterial: Material | null; +} + +export function saveRendererAndSceneState( + renderer: RendererState, + scene: Scene, + state?: RendererAndSceneState, +): RendererAndSceneState; + +export function resetRendererAndSceneState(renderer: Renderer, state?: RendererAndSceneState): RendererAndSceneState; + +export function restoreRendererAndSceneState(renderer: Renderer, state: RendererAndSceneState): void; diff --git a/src-testing/src/renderers/common/ProgrammableStage.ts b/src-testing/src/renderers/common/ProgrammableStage.ts new file mode 100644 index 000000000..a684e4443 --- /dev/null +++ b/src-testing/src/renderers/common/ProgrammableStage.ts @@ -0,0 +1,16 @@ +let _id = 0; + +class ProgrammableStage { + constructor(code, type, transforms = null, attributes = null) { + this.id = _id++; + + this.code = code; + this.stage = type; + this.transforms = transforms; + this.attributes = attributes; + + this.usedTimes = 0; + } +} + +export default ProgrammableStage; diff --git a/src-testing/src/renderers/common/QuadMesh.d.ts b/src-testing/src/renderers/common/QuadMesh.d.ts new file mode 100644 index 000000000..ee2bb93ba --- /dev/null +++ b/src-testing/src/renderers/common/QuadMesh.d.ts @@ -0,0 +1,16 @@ +import { OrthographicCamera } from "../../cameras/OrthographicCamera.js"; +import { Material } from "../../materials/Material.js"; +import { Mesh } from "../../objects/Mesh.js"; +import Renderer from "./Renderer.js"; + +export default class QuadMesh extends Mesh { + camera: OrthographicCamera; + + readonly isQuadMesh: true; + + constructor(material?: Material | null); + + renderAsync(renderer: Renderer): Promise; + + render(renderer: Renderer): void; +} diff --git a/src-testing/src/renderers/common/RenderBundle.ts b/src-testing/src/renderers/common/RenderBundle.ts new file mode 100644 index 000000000..e59e49378 --- /dev/null +++ b/src-testing/src/renderers/common/RenderBundle.ts @@ -0,0 +1,12 @@ +class RenderBundle { + constructor(scene, camera) { + this.scene = scene; + this.camera = camera; + } + + clone() { + return Object.assign(new this.constructor(), this); + } +} + +export default RenderBundle; diff --git a/src-testing/src/renderers/common/RenderBundles.ts b/src-testing/src/renderers/common/RenderBundles.ts new file mode 100644 index 000000000..291403652 --- /dev/null +++ b/src-testing/src/renderers/common/RenderBundles.ts @@ -0,0 +1,28 @@ +import ChainMap from './ChainMap.js'; +import RenderBundle from './RenderBundle.js'; + +class RenderBundles { + constructor() { + this.lists = new ChainMap(); + } + + get(scene, camera) { + const lists = this.lists; + const keys = [scene, camera]; + + let list = lists.get(keys); + + if (list === undefined) { + list = new RenderBundle(scene, camera); + lists.set(keys, list); + } + + return list; + } + + dispose() { + this.lists = new ChainMap(); + } +} + +export default RenderBundles; diff --git a/src-testing/src/renderers/common/RenderContext.ts b/src-testing/src/renderers/common/RenderContext.ts new file mode 100644 index 000000000..9b5ee3a28 --- /dev/null +++ b/src-testing/src/renderers/common/RenderContext.ts @@ -0,0 +1,56 @@ +import { Vector4 } from '../../math/Vector4.js'; +import { hashArray } from '../../nodes/core/NodeUtils.js'; + +let id = 0; + +class RenderContext { + constructor() { + this.id = id++; + + this.color = true; + this.clearColor = true; + this.clearColorValue = { r: 0, g: 0, b: 0, a: 1 }; + + this.depth = true; + this.clearDepth = true; + this.clearDepthValue = 1; + + this.stencil = false; + this.clearStencil = true; + this.clearStencilValue = 1; + + this.viewport = false; + this.viewportValue = new Vector4(); + + this.scissor = false; + this.scissorValue = new Vector4(); + + this.textures = null; + this.depthTexture = null; + this.activeCubeFace = 0; + this.sampleCount = 1; + + this.width = 0; + this.height = 0; + + this.isRenderContext = true; + } + + getCacheKey() { + return getCacheKey(this); + } +} + +export function getCacheKey(renderContext) { + const { textures, activeCubeFace } = renderContext; + + const values = [activeCubeFace]; + + for (const texture of textures) { + values.push(texture.id); + } + + return hashArray(values); +} + +export default RenderContext; diff --git a/src-testing/src/renderers/common/RenderContexts.ts b/src-testing/src/renderers/common/RenderContexts.ts new file mode 100644 index 000000000..e77308c1d --- /dev/null +++ b/src-testing/src/renderers/common/RenderContexts.ts @@ -0,0 +1,47 @@ +import ChainMap from './ChainMap.js'; +import RenderContext from './RenderContext.js'; + +class RenderContexts { + constructor() { + this.chainMaps = {}; + } + + get(scene, camera, renderTarget = null) { + const chainKey = [scene, camera]; + + let attachmentState; + + if (renderTarget === null) { + attachmentState = 'default'; + } else { + const format = renderTarget.texture.format; + const count = renderTarget.textures.length; + + attachmentState = `${count}:${format}:${renderTarget.samples}:${renderTarget.depthBuffer}:${renderTarget.stencilBuffer}`; + } + + const chainMap = this.getChainMap(attachmentState); + + let renderState = chainMap.get(chainKey); + + if (renderState === undefined) { + renderState = new RenderContext(); + + chainMap.set(chainKey, renderState); + } + + if (renderTarget !== null) renderState.sampleCount = renderTarget.samples === 0 ? 1 : renderTarget.samples; + + return renderState; + } + + getChainMap(attachmentState) { + return this.chainMaps[attachmentState] || (this.chainMaps[attachmentState] = new ChainMap()); + } + + dispose() { + this.chainMaps = {}; + } +} + +export default RenderContexts; diff --git a/src-testing/src/renderers/common/RenderList.ts b/src-testing/src/renderers/common/RenderList.ts new file mode 100644 index 000000000..63d236dd0 --- /dev/null +++ b/src-testing/src/renderers/common/RenderList.ts @@ -0,0 +1,142 @@ +function painterSortStable(a, b) { + if (a.groupOrder !== b.groupOrder) { + return a.groupOrder - b.groupOrder; + } else if (a.renderOrder !== b.renderOrder) { + return a.renderOrder - b.renderOrder; + } else if (a.material.id !== b.material.id) { + return a.material.id - b.material.id; + } else if (a.z !== b.z) { + return a.z - b.z; + } else { + return a.id - b.id; + } +} + +function reversePainterSortStable(a, b) { + if (a.groupOrder !== b.groupOrder) { + return a.groupOrder - b.groupOrder; + } else if (a.renderOrder !== b.renderOrder) { + return a.renderOrder - b.renderOrder; + } else if (a.z !== b.z) { + return b.z - a.z; + } else { + return a.id - b.id; + } +} + +class RenderList { + constructor(lighting, scene, camera) { + this.renderItems = []; + this.renderItemsIndex = 0; + + this.opaque = []; + this.transparent = []; + this.bundles = []; + + this.lightsNode = lighting.getNode(scene, camera); + this.lightsArray = []; + + this.scene = scene; + this.camera = camera; + + this.occlusionQueryCount = 0; + } + + begin() { + this.renderItemsIndex = 0; + + this.opaque.length = 0; + this.transparent.length = 0; + this.bundles.length = 0; + + this.lightsArray.length = 0; + + this.occlusionQueryCount = 0; + + return this; + } + + getNextRenderItem(object, geometry, material, groupOrder, z, group) { + let renderItem = this.renderItems[this.renderItemsIndex]; + + if (renderItem === undefined) { + renderItem = { + id: object.id, + object: object, + geometry: geometry, + material: material, + groupOrder: groupOrder, + renderOrder: object.renderOrder, + z: z, + group: group, + }; + + this.renderItems[this.renderItemsIndex] = renderItem; + } else { + renderItem.id = object.id; + renderItem.object = object; + renderItem.geometry = geometry; + renderItem.material = material; + renderItem.groupOrder = groupOrder; + renderItem.renderOrder = object.renderOrder; + renderItem.z = z; + renderItem.group = group; + } + + this.renderItemsIndex++; + + return renderItem; + } + + push(object, geometry, material, groupOrder, z, group) { + const renderItem = this.getNextRenderItem(object, geometry, material, groupOrder, z, group); + + if (object.occlusionTest === true) this.occlusionQueryCount++; + + (material.transparent === true || material.transmission > 0 ? this.transparent : this.opaque).push(renderItem); + } + + unshift(object, geometry, material, groupOrder, z, group) { + const renderItem = this.getNextRenderItem(object, geometry, material, groupOrder, z, group); + + (material.transparent === true ? this.transparent : this.opaque).unshift(renderItem); + } + + pushBundle(group) { + this.bundles.push(group); + } + + pushLight(light) { + this.lightsArray.push(light); + } + + sort(customOpaqueSort, customTransparentSort) { + if (this.opaque.length > 1) this.opaque.sort(customOpaqueSort || painterSortStable); + if (this.transparent.length > 1) this.transparent.sort(customTransparentSort || reversePainterSortStable); + } + + finish() { + // update lights + + this.lightsNode.setLights(this.lightsArray); + + // Clear references from inactive renderItems in the list + + for (let i = this.renderItemsIndex, il = this.renderItems.length; i < il; i++) { + const renderItem = this.renderItems[i]; + + if (renderItem.id === null) break; + + renderItem.id = null; + renderItem.object = null; + renderItem.geometry = null; + renderItem.material = null; + renderItem.groupOrder = null; + renderItem.renderOrder = null; + renderItem.z = null; + renderItem.group = null; + } + } +} + +export default RenderList; diff --git a/src-testing/src/renderers/common/RenderLists.ts b/src-testing/src/renderers/common/RenderLists.ts new file mode 100644 index 000000000..0486f7933 --- /dev/null +++ b/src-testing/src/renderers/common/RenderLists.ts @@ -0,0 +1,30 @@ +import ChainMap from './ChainMap.js'; +import RenderList from './RenderList.js'; + +class RenderLists { + constructor(lighting) { + this.lighting = lighting; + + this.lists = new ChainMap(); + } + + get(scene, camera) { + const lists = this.lists; + const keys = [scene, camera]; + + let list = lists.get(keys); + + if (list === undefined) { + list = new RenderList(this.lighting, scene, camera); + lists.set(keys, list); + } + + return list; + } + + dispose() { + this.lists = new ChainMap(); + } +} + +export default RenderLists; diff --git a/src-testing/src/renderers/common/RenderObject.ts b/src-testing/src/renderers/common/RenderObject.ts new file mode 100644 index 000000000..e46d3871f --- /dev/null +++ b/src-testing/src/renderers/common/RenderObject.ts @@ -0,0 +1,350 @@ +import { hashString } from '../../nodes/core/NodeUtils.js'; +import ClippingContext from './ClippingContext.js'; + +let _id = 0; + +function getKeys(obj) { + const keys = Object.keys(obj); + + let proto = Object.getPrototypeOf(obj); + + while (proto) { + const descriptors = Object.getOwnPropertyDescriptors(proto); + + for (const key in descriptors) { + if (descriptors[key] !== undefined) { + const descriptor = descriptors[key]; + + if (descriptor && typeof descriptor.get === 'function') { + keys.push(key); + } + } + } + + proto = Object.getPrototypeOf(proto); + } + + return keys; +} + +export default class RenderObject { + constructor(nodes, geometries, renderer, object, material, scene, camera, lightsNode, renderContext) { + this._nodes = nodes; + this._geometries = geometries; + + this.id = _id++; + + this.renderer = renderer; + this.object = object; + this.material = material; + this.scene = scene; + this.camera = camera; + this.lightsNode = lightsNode; + this.context = renderContext; + + this.geometry = object.geometry; + this.version = material.version; + + this.drawRange = null; + + this.attributes = null; + this.pipeline = null; + this.vertexBuffers = null; + this.drawParams = null; + + this.bundle = null; + + this.updateClipping(renderContext.clippingContext); + + this.clippingContextVersion = this.clippingContext.version; + + this.initialNodesCacheKey = this.getDynamicCacheKey(); + this.initialCacheKey = this.getCacheKey(); + + this._nodeBuilderState = null; + this._bindings = null; + this._monitor = null; + + this.onDispose = null; + + this.isRenderObject = true; + + this.onMaterialDispose = () => { + this.dispose(); + }; + + this.material.addEventListener('dispose', this.onMaterialDispose); + } + + updateClipping(parent) { + const material = this.material; + + let clippingContext = this.clippingContext; + + if (Array.isArray(material.clippingPlanes)) { + if (clippingContext === parent || !clippingContext) { + clippingContext = new ClippingContext(); + this.clippingContext = clippingContext; + } + + clippingContext.update(parent, material); + } else if (this.clippingContext !== parent) { + this.clippingContext = parent; + } + } + + get clippingNeedsUpdate() { + if (this.clippingContext.version === this.clippingContextVersion) return false; + + this.clippingContextVersion = this.clippingContext.version; + + return true; + } + + getNodeBuilderState() { + return this._nodeBuilderState || (this._nodeBuilderState = this._nodes.getForRender(this)); + } + + getMonitor() { + return this._monitor || (this._monitor = this.getNodeBuilderState().monitor); + } + + getBindings() { + return this._bindings || (this._bindings = this.getNodeBuilderState().createBindings()); + } + + getIndex() { + return this._geometries.getIndex(this); + } + + getIndirect() { + return this._geometries.getIndirect(this); + } + + getChainArray() { + return [this.object, this.material, this.context, this.lightsNode]; + } + + getAttributes() { + if (this.attributes !== null) return this.attributes; + + const nodeAttributes = this.getNodeBuilderState().nodeAttributes; + const geometry = this.geometry; + + const attributes = []; + const vertexBuffers = new Set(); + + for (const nodeAttribute of nodeAttributes) { + const attribute = + nodeAttribute.node && nodeAttribute.node.attribute + ? nodeAttribute.node.attribute + : geometry.getAttribute(nodeAttribute.name); + + if (attribute === undefined) continue; + + attributes.push(attribute); + + const bufferAttribute = attribute.isInterleavedBufferAttribute ? attribute.data : attribute; + vertexBuffers.add(bufferAttribute); + } + + this.attributes = attributes; + this.vertexBuffers = Array.from(vertexBuffers.values()); + + return attributes; + } + + getVertexBuffers() { + if (this.vertexBuffers === null) this.getAttributes(); + + return this.vertexBuffers; + } + + getDrawParameters() { + const { object, material, geometry, group, drawRange } = this; + + const drawParams = + this.drawParams || + (this.drawParams = { + vertexCount: 0, + firstVertex: 0, + instanceCount: 0, + firstInstance: 0, + }); + + const index = this.getIndex(); + const hasIndex = index !== null; + const instanceCount = geometry.isInstancedBufferGeometry + ? geometry.instanceCount + : object.count > 1 + ? object.count + : 1; + + if (instanceCount === 0) return null; + + drawParams.instanceCount = instanceCount; + + if (object.isBatchedMesh === true) return drawParams; + + let rangeFactor = 1; + + if ( + material.wireframe === true && + !object.isPoints && + !object.isLineSegments && + !object.isLine && + !object.isLineLoop + ) { + rangeFactor = 2; + } + + let firstVertex = drawRange.start * rangeFactor; + let lastVertex = (drawRange.start + drawRange.count) * rangeFactor; + + if (group !== null) { + firstVertex = Math.max(firstVertex, group.start * rangeFactor); + lastVertex = Math.min(lastVertex, (group.start + group.count) * rangeFactor); + } + + const position = geometry.attributes.position; + let itemCount = Infinity; + + if (hasIndex) { + itemCount = index.count; + } else if (position !== undefined && position !== null) { + itemCount = position.count; + } + + firstVertex = Math.max(firstVertex, 0); + lastVertex = Math.min(lastVertex, itemCount); + + const count = lastVertex - firstVertex; + + if (count < 0 || count === Infinity) return null; + + drawParams.vertexCount = count; + drawParams.firstVertex = firstVertex; + + return drawParams; + } + + getGeometryCacheKey() { + const { geometry } = this; + + let cacheKey = ''; + + for (const name of Object.keys(geometry.attributes).sort()) { + const attribute = geometry.attributes[name]; + + cacheKey += name + ','; + + if (attribute.data) cacheKey += attribute.data.stride + ','; + if (attribute.offset) cacheKey += attribute.offset + ','; + if (attribute.itemSize) cacheKey += attribute.itemSize + ','; + if (attribute.normalized) cacheKey += 'n,'; + } + + if (geometry.index) { + cacheKey += 'index,'; + } + + return cacheKey; + } + + getMaterialCacheKey() { + const { object, material } = this; + + let cacheKey = material.customProgramCacheKey(); + + for (const property of getKeys(material)) { + if (/^(is[A-Z]|_)|^(visible|version|uuid|name|opacity|userData)$/.test(property)) continue; + + const value = material[property]; + + let valueKey; + + if (value !== null) { + // some material values require a formatting + + const type = typeof value; + + if (type === 'number') { + valueKey = value !== 0 ? '1' : '0'; // Convert to on/off, important for clearcoat, transmission, etc + } else if (type === 'object') { + valueKey = '{'; + + if (value.isTexture) { + valueKey += value.mapping; + } + + valueKey += '}'; + } else { + valueKey = String(value); + } + } else { + valueKey = String(value); + } + + cacheKey += /*property + ':' +*/ valueKey + ','; + } + + cacheKey += this.clippingContext.cacheKey + ','; + + if (object.geometry) { + cacheKey += this.getGeometryCacheKey(); + } + + if (object.skeleton) { + cacheKey += object.skeleton.bones.length + ','; + } + + if (object.morphTargetInfluences) { + cacheKey += object.morphTargetInfluences.length + ','; + } + + if (object.isBatchedMesh) { + cacheKey += object._matricesTexture.uuid + ','; + + if (object._colorsTexture !== null) { + cacheKey += object._colorsTexture.uuid + ','; + } + } + + if (object.count > 1) { + // TODO: https://github.com/mrdoob/three.js/pull/29066#issuecomment-2269400850 + + cacheKey += object.uuid + ','; + } + + return hashString(cacheKey); + } + + get needsUpdate() { + return ( + /*this.object.static !== true &&*/ this.initialNodesCacheKey !== this.getDynamicCacheKey() || + this.clippingNeedsUpdate + ); + } + + getDynamicCacheKey() { + // Environment Nodes Cache Key + + let cacheKey = this._nodes.getCacheKey(this.scene, this.lightsNode); + + if (this.object.receiveShadow) { + cacheKey += 1; + } + + return cacheKey; + } + + getCacheKey() { + return this.getMaterialCacheKey() + this.getDynamicCacheKey(); + } + + dispose() { + this.material.removeEventListener('dispose', this.onMaterialDispose); + + this.onDispose(); + } +} diff --git a/src-testing/src/renderers/common/RenderObjects.ts b/src-testing/src/renderers/common/RenderObjects.ts new file mode 100644 index 000000000..6bd06dd5e --- /dev/null +++ b/src-testing/src/renderers/common/RenderObjects.ts @@ -0,0 +1,107 @@ +import ChainMap from './ChainMap.js'; +import RenderObject from './RenderObject.js'; + +const chainArray = []; + +class RenderObjects { + constructor(renderer, nodes, geometries, pipelines, bindings, info) { + this.renderer = renderer; + this.nodes = nodes; + this.geometries = geometries; + this.pipelines = pipelines; + this.bindings = bindings; + this.info = info; + + this.chainMaps = {}; + } + + get(object, material, scene, camera, lightsNode, renderContext, passId) { + const chainMap = this.getChainMap(passId); + + // reuse chainArray + chainArray[0] = object; + chainArray[1] = material; + chainArray[2] = renderContext; + chainArray[3] = lightsNode; + + let renderObject = chainMap.get(chainArray); + + if (renderObject === undefined) { + renderObject = this.createRenderObject( + this.nodes, + this.geometries, + this.renderer, + object, + material, + scene, + camera, + lightsNode, + renderContext, + passId, + ); + + chainMap.set(chainArray, renderObject); + } else { + renderObject.updateClipping(renderContext.clippingContext); + + if (renderObject.version !== material.version || renderObject.needsUpdate) { + if (renderObject.initialCacheKey !== renderObject.getCacheKey()) { + renderObject.dispose(); + + renderObject = this.get(object, material, scene, camera, lightsNode, renderContext, passId); + } else { + renderObject.version = material.version; + } + } + } + + return renderObject; + } + + getChainMap(passId = 'default') { + return this.chainMaps[passId] || (this.chainMaps[passId] = new ChainMap()); + } + + dispose() { + this.chainMaps = {}; + } + + createRenderObject( + nodes, + geometries, + renderer, + object, + material, + scene, + camera, + lightsNode, + renderContext, + passId, + ) { + const chainMap = this.getChainMap(passId); + + const renderObject = new RenderObject( + nodes, + geometries, + renderer, + object, + material, + scene, + camera, + lightsNode, + renderContext, + ); + + renderObject.onDispose = () => { + this.pipelines.delete(renderObject); + this.bindings.delete(renderObject); + this.nodes.delete(renderObject); + + chainMap.delete(renderObject.getChainArray()); + }; + + return renderObject; + } +} + +export default RenderObjects; diff --git a/src-testing/src/renderers/common/RenderPipeline.ts b/src-testing/src/renderers/common/RenderPipeline.ts new file mode 100644 index 000000000..0ec34b043 --- /dev/null +++ b/src-testing/src/renderers/common/RenderPipeline.ts @@ -0,0 +1,12 @@ +import Pipeline from './Pipeline.js'; + +class RenderPipeline extends Pipeline { + constructor(cacheKey, vertexProgram, fragmentProgram) { + super(cacheKey); + + this.vertexProgram = vertexProgram; + this.fragmentProgram = fragmentProgram; + } +} + +export default RenderPipeline; diff --git a/src-testing/src/renderers/common/Renderer.ts b/src-testing/src/renderers/common/Renderer.ts new file mode 100644 index 000000000..533684051 --- /dev/null +++ b/src-testing/src/renderers/common/Renderer.ts @@ -0,0 +1,1425 @@ +import Animation from './Animation.js'; +import RenderObjects from './RenderObjects.js'; +import Attributes from './Attributes.js'; +import Geometries from './Geometries.js'; +import Info from './Info.js'; +import Pipelines from './Pipelines.js'; +import Bindings from './Bindings.js'; +import RenderLists from './RenderLists.js'; +import RenderContexts from './RenderContexts.js'; +import Textures from './Textures.js'; +import Background from './Background.js'; +import Nodes from './nodes/Nodes.js'; +import Color4 from './Color4.js'; +import ClippingContext from './ClippingContext.js'; +import QuadMesh from './QuadMesh.js'; +import RenderBundles from './RenderBundles.js'; +import NodeLibrary from './nodes/NodeLibrary.js'; +import Lighting from './Lighting.js'; + +import NodeMaterial from '../../materials/nodes/NodeMaterial.js'; + +import { Scene } from '../../scenes/Scene.js'; +import { Frustum } from '../../math/Frustum.js'; +import { Matrix4 } from '../../math/Matrix4.js'; +import { Vector2 } from '../../math/Vector2.js'; +import { Vector4 } from '../../math/Vector4.js'; +import { RenderTarget } from '../../core/RenderTarget.js'; +import { + DoubleSide, + BackSide, + FrontSide, + SRGBColorSpace, + NoToneMapping, + LinearFilter, + LinearSRGBColorSpace, + HalfFloatType, + RGBAFormat, + PCFShadowMap, +} from '../../constants.js'; + +const _scene = /*@__PURE__*/ new Scene(); +const _drawingBufferSize = /*@__PURE__*/ new Vector2(); +const _screen = /*@__PURE__*/ new Vector4(); +const _frustum = /*@__PURE__*/ new Frustum(); +const _projScreenMatrix = /*@__PURE__*/ new Matrix4(); +const _vector4 = /*@__PURE__*/ new Vector4(); + +class Renderer { + constructor(backend, parameters = {}) { + this.isRenderer = true; + + // + + const { + logarithmicDepthBuffer = false, + alpha = true, + depth = true, + stencil = false, + antialias = false, + samples = 0, + getFallback = null, + } = parameters; + + // public + this.domElement = backend.getDomElement(); + + this.backend = backend; + + this.samples = samples || antialias === true ? 4 : 0; + + this.autoClear = true; + this.autoClearColor = true; + this.autoClearDepth = true; + this.autoClearStencil = true; + + this.alpha = alpha; + + this.logarithmicDepthBuffer = logarithmicDepthBuffer; + + this.outputColorSpace = SRGBColorSpace; + + this.toneMapping = NoToneMapping; + this.toneMappingExposure = 1.0; + + this.sortObjects = true; + + this.depth = depth; + this.stencil = stencil; + + this.clippingPlanes = []; + + this.info = new Info(); + + this.nodes = { + modelViewMatrix: null, + modelNormalViewMatrix: null, + }; + + this.library = new NodeLibrary(); + this.lighting = new Lighting(); + + // internals + + this._getFallback = getFallback; + + this._pixelRatio = 1; + this._width = this.domElement.width; + this._height = this.domElement.height; + + this._viewport = new Vector4(0, 0, this._width, this._height); + this._scissor = new Vector4(0, 0, this._width, this._height); + this._scissorTest = false; + + this._attributes = null; + this._geometries = null; + this._nodes = null; + this._animation = null; + this._bindings = null; + this._objects = null; + this._pipelines = null; + this._bundles = null; + this._renderLists = null; + this._renderContexts = null; + this._textures = null; + this._background = null; + + this._quad = new QuadMesh(new NodeMaterial()); + this._quad.material.type = 'Renderer_output'; + + this._currentRenderContext = null; + + this._opaqueSort = null; + this._transparentSort = null; + + this._frameBufferTarget = null; + + const alphaClear = this.alpha === true ? 0 : 1; + + this._clearColor = new Color4(0, 0, 0, alphaClear); + this._clearDepth = 1; + this._clearStencil = 0; + + this._renderTarget = null; + this._activeCubeFace = 0; + this._activeMipmapLevel = 0; + + this._mrt = null; + + this._renderObjectFunction = null; + this._currentRenderObjectFunction = null; + this._currentRenderBundle = null; + + this._handleObjectFunction = this._renderObjectDirect; + + this._initialized = false; + this._initPromise = null; + + this._compilationPromises = null; + + this.transparent = true; + this.opaque = true; + + this.shadowMap = { + enabled: false, + type: PCFShadowMap, + }; + + this.xr = { + enabled: false, + }; + + this.debug = { + checkShaderErrors: true, + onShaderError: null, + getShaderAsync: async (scene, camera, object) => { + await this.compileAsync(scene, camera); + + const renderList = this._renderLists.get(scene, camera); + const renderContext = this._renderContexts.get(scene, camera, this._renderTarget); + + const material = scene.overrideMaterial || object.material; + + const renderObject = this._objects.get( + object, + material, + scene, + camera, + renderList.lightsNode, + renderContext, + ); + + const { fragmentShader, vertexShader } = renderObject.getNodeBuilderState(); + + return { fragmentShader, vertexShader }; + }, + }; + } + + async init() { + if (this._initialized) { + throw new Error('Renderer: Backend has already been initialized.'); + } + + if (this._initPromise !== null) { + return this._initPromise; + } + + this._initPromise = new Promise(async (resolve, reject) => { + let backend = this.backend; + + try { + await backend.init(this); + } catch (error) { + if (this._getFallback !== null) { + // try the fallback + + try { + this.backend = backend = this._getFallback(error); + await backend.init(this); + } catch (error) { + reject(error); + return; + } + } else { + reject(error); + return; + } + } + + this._nodes = new Nodes(this, backend); + this._animation = new Animation(this._nodes, this.info); + this._attributes = new Attributes(backend); + this._background = new Background(this, this._nodes); + this._geometries = new Geometries(this._attributes, this.info); + this._textures = new Textures(this, backend, this.info); + this._pipelines = new Pipelines(backend, this._nodes); + this._bindings = new Bindings( + backend, + this._nodes, + this._textures, + this._attributes, + this._pipelines, + this.info, + ); + this._objects = new RenderObjects( + this, + this._nodes, + this._geometries, + this._pipelines, + this._bindings, + this.info, + ); + this._renderLists = new RenderLists(this.lighting); + this._bundles = new RenderBundles(); + this._renderContexts = new RenderContexts(); + + // + + this._initialized = true; + + resolve(); + }); + + return this._initPromise; + } + + get coordinateSystem() { + return this.backend.coordinateSystem; + } + + async compileAsync(scene, camera, targetScene = null) { + if (this._initialized === false) await this.init(); + + // preserve render tree + + const nodeFrame = this._nodes.nodeFrame; + + const previousRenderId = nodeFrame.renderId; + const previousRenderContext = this._currentRenderContext; + const previousRenderObjectFunction = this._currentRenderObjectFunction; + const previousCompilationPromises = this._compilationPromises; + + // + + const sceneRef = scene.isScene === true ? scene : _scene; + + if (targetScene === null) targetScene = scene; + + const renderTarget = this._renderTarget; + const renderContext = this._renderContexts.get(targetScene, camera, renderTarget); + const activeMipmapLevel = this._activeMipmapLevel; + + const compilationPromises = []; + + this._currentRenderContext = renderContext; + this._currentRenderObjectFunction = this.renderObject; + + this._handleObjectFunction = this._createObjectPipeline; + + this._compilationPromises = compilationPromises; + + nodeFrame.renderId++; + + // + + nodeFrame.update(); + + // + + renderContext.depth = this.depth; + renderContext.stencil = this.stencil; + + if (!renderContext.clippingContext) renderContext.clippingContext = new ClippingContext(); + renderContext.clippingContext.updateGlobal(this, camera); + + // + + sceneRef.onBeforeRender(this, scene, camera, renderTarget); + + // + + const renderList = this._renderLists.get(scene, camera); + renderList.begin(); + + this._projectObject(scene, camera, 0, renderList); + + // include lights from target scene + if (targetScene !== scene) { + targetScene.traverseVisible(function (object) { + if (object.isLight && object.layers.test(camera.layers)) { + renderList.pushLight(object); + } + }); + } + + renderList.finish(); + + // + + if (renderTarget !== null) { + this._textures.updateRenderTarget(renderTarget, activeMipmapLevel); + + const renderTargetData = this._textures.get(renderTarget); + + renderContext.textures = renderTargetData.textures; + renderContext.depthTexture = renderTargetData.depthTexture; + } else { + renderContext.textures = null; + renderContext.depthTexture = null; + } + + // + + this._nodes.updateScene(sceneRef); + + // + + this._background.update(sceneRef, renderList, renderContext); + + // process render lists + + const opaqueObjects = renderList.opaque; + const transparentObjects = renderList.transparent; + const lightsNode = renderList.lightsNode; + + if (this.opaque === true && opaqueObjects.length > 0) + this._renderObjects(opaqueObjects, camera, sceneRef, lightsNode); + if (this.transparent === true && transparentObjects.length > 0) + this._renderObjects(transparentObjects, camera, sceneRef, lightsNode); + + // restore render tree + + nodeFrame.renderId = previousRenderId; + + this._currentRenderContext = previousRenderContext; + this._currentRenderObjectFunction = previousRenderObjectFunction; + this._compilationPromises = previousCompilationPromises; + + this._handleObjectFunction = this._renderObjectDirect; + + // wait for all promises setup by backends awaiting compilation/linking/pipeline creation to complete + + await Promise.all(compilationPromises); + } + + async renderAsync(scene, camera) { + if (this._initialized === false) await this.init(); + + const renderContext = this._renderScene(scene, camera); + + await this.backend.resolveTimestampAsync(renderContext, 'render'); + } + + async waitForGPU() { + await this.backend.waitForGPU(); + } + + setMRT(mrt) { + this._mrt = mrt; + + return this; + } + + getMRT() { + return this._mrt; + } + + _renderBundle(bundle, sceneRef, lightsNode) { + const { bundleGroup, camera, renderList } = bundle; + + const renderContext = this._currentRenderContext; + + // + + const renderBundle = this._bundles.get(bundleGroup, camera); + const renderBundleData = this.backend.get(renderBundle); + + if (renderBundleData.renderContexts === undefined) renderBundleData.renderContexts = new Set(); + + // + + const needsUpdate = bundleGroup.version !== renderBundleData.version; + const renderBundleNeedsUpdate = renderBundleData.renderContexts.has(renderContext) === false || needsUpdate; + + renderBundleData.renderContexts.add(renderContext); + + if (renderBundleNeedsUpdate) { + this.backend.beginBundle(renderContext); + + if (renderBundleData.renderObjects === undefined || needsUpdate) { + renderBundleData.renderObjects = []; + } + + this._currentRenderBundle = renderBundle; + + const opaqueObjects = renderList.opaque; + + if (opaqueObjects.length > 0) this._renderObjects(opaqueObjects, camera, sceneRef, lightsNode); + + this._currentRenderBundle = null; + + // + + this.backend.finishBundle(renderContext, renderBundle); + + renderBundleData.version = bundleGroup.version; + } else { + const { renderObjects } = renderBundleData; + + for (let i = 0, l = renderObjects.length; i < l; i++) { + const renderObject = renderObjects[i]; + + if (this._nodes.needsRefresh(renderObject)) { + this._nodes.updateBefore(renderObject); + + this._nodes.updateForRender(renderObject); + this._bindings.updateForRender(renderObject); + + this._nodes.updateAfter(renderObject); + } + } + } + + this.backend.addBundle(renderContext, renderBundle); + } + + render(scene, camera) { + if (this._initialized === false) { + console.warn( + 'THREE.Renderer: .render() called before the backend is initialized. Try using .renderAsync() instead.', + ); + + return this.renderAsync(scene, camera); + } + + this._renderScene(scene, camera); + } + + _getFrameBufferTarget() { + const { currentToneMapping, currentColorSpace } = this; + + const useToneMapping = currentToneMapping !== NoToneMapping; + const useColorSpace = currentColorSpace !== LinearSRGBColorSpace; + + if (useToneMapping === false && useColorSpace === false) return null; + + const { width, height } = this.getDrawingBufferSize(_drawingBufferSize); + const { depth, stencil } = this; + + let frameBufferTarget = this._frameBufferTarget; + + if (frameBufferTarget === null) { + frameBufferTarget = new RenderTarget(width, height, { + depthBuffer: depth, + stencilBuffer: stencil, + type: HalfFloatType, // FloatType + format: RGBAFormat, + colorSpace: LinearSRGBColorSpace, + generateMipmaps: false, + minFilter: LinearFilter, + magFilter: LinearFilter, + samples: this.samples, + }); + + frameBufferTarget.isPostProcessingRenderTarget = true; + + this._frameBufferTarget = frameBufferTarget; + } + + frameBufferTarget.depthBuffer = depth; + frameBufferTarget.stencilBuffer = stencil; + frameBufferTarget.setSize(width, height); + frameBufferTarget.viewport.copy(this._viewport); + frameBufferTarget.scissor.copy(this._scissor); + frameBufferTarget.viewport.multiplyScalar(this._pixelRatio); + frameBufferTarget.scissor.multiplyScalar(this._pixelRatio); + frameBufferTarget.scissorTest = this._scissorTest; + + return frameBufferTarget; + } + + _renderScene(scene, camera, useFrameBufferTarget = true) { + const frameBufferTarget = useFrameBufferTarget ? this._getFrameBufferTarget() : null; + + // preserve render tree + + const nodeFrame = this._nodes.nodeFrame; + + const previousRenderId = nodeFrame.renderId; + const previousRenderContext = this._currentRenderContext; + const previousRenderObjectFunction = this._currentRenderObjectFunction; + + // + + const sceneRef = scene.isScene === true ? scene : _scene; + + const outputRenderTarget = this._renderTarget; + + const activeCubeFace = this._activeCubeFace; + const activeMipmapLevel = this._activeMipmapLevel; + + // + + let renderTarget; + + if (frameBufferTarget !== null) { + renderTarget = frameBufferTarget; + + this.setRenderTarget(renderTarget); + } else { + renderTarget = outputRenderTarget; + } + + // + + const renderContext = this._renderContexts.get(scene, camera, renderTarget); + + this._currentRenderContext = renderContext; + this._currentRenderObjectFunction = this._renderObjectFunction || this.renderObject; + + // + + this.info.calls++; + this.info.render.calls++; + this.info.render.frameCalls++; + + nodeFrame.renderId = this.info.calls; + + // + + const coordinateSystem = this.coordinateSystem; + + if (camera.coordinateSystem !== coordinateSystem) { + camera.coordinateSystem = coordinateSystem; + + camera.updateProjectionMatrix(); + } + + // + + if (scene.matrixWorldAutoUpdate === true) scene.updateMatrixWorld(); + + if (camera.parent === null && camera.matrixWorldAutoUpdate === true) camera.updateMatrixWorld(); + + // + + let viewport = this._viewport; + let scissor = this._scissor; + let pixelRatio = this._pixelRatio; + + if (renderTarget !== null) { + viewport = renderTarget.viewport; + scissor = renderTarget.scissor; + pixelRatio = 1; + } + + this.getDrawingBufferSize(_drawingBufferSize); + + _screen.set(0, 0, _drawingBufferSize.width, _drawingBufferSize.height); + + const minDepth = viewport.minDepth === undefined ? 0 : viewport.minDepth; + const maxDepth = viewport.maxDepth === undefined ? 1 : viewport.maxDepth; + + renderContext.viewportValue.copy(viewport).multiplyScalar(pixelRatio).floor(); + renderContext.viewportValue.width >>= activeMipmapLevel; + renderContext.viewportValue.height >>= activeMipmapLevel; + renderContext.viewportValue.minDepth = minDepth; + renderContext.viewportValue.maxDepth = maxDepth; + renderContext.viewport = renderContext.viewportValue.equals(_screen) === false; + + renderContext.scissorValue.copy(scissor).multiplyScalar(pixelRatio).floor(); + renderContext.scissor = this._scissorTest && renderContext.scissorValue.equals(_screen) === false; + renderContext.scissorValue.width >>= activeMipmapLevel; + renderContext.scissorValue.height >>= activeMipmapLevel; + + if (!renderContext.clippingContext) renderContext.clippingContext = new ClippingContext(); + renderContext.clippingContext.updateGlobal(this, camera); + + // + + sceneRef.onBeforeRender(this, scene, camera, renderTarget); + + // + + _projScreenMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse); + _frustum.setFromProjectionMatrix(_projScreenMatrix, coordinateSystem); + + const renderList = this._renderLists.get(scene, camera); + renderList.begin(); + + this._projectObject(scene, camera, 0, renderList); + + renderList.finish(); + + if (this.sortObjects === true) { + renderList.sort(this._opaqueSort, this._transparentSort); + } + + // + + if (renderTarget !== null) { + this._textures.updateRenderTarget(renderTarget, activeMipmapLevel); + + const renderTargetData = this._textures.get(renderTarget); + + renderContext.textures = renderTargetData.textures; + renderContext.depthTexture = renderTargetData.depthTexture; + renderContext.width = renderTargetData.width; + renderContext.height = renderTargetData.height; + renderContext.renderTarget = renderTarget; + renderContext.depth = renderTarget.depthBuffer; + renderContext.stencil = renderTarget.stencilBuffer; + } else { + renderContext.textures = null; + renderContext.depthTexture = null; + renderContext.width = this.domElement.width; + renderContext.height = this.domElement.height; + renderContext.depth = this.depth; + renderContext.stencil = this.stencil; + } + + renderContext.width >>= activeMipmapLevel; + renderContext.height >>= activeMipmapLevel; + renderContext.activeCubeFace = activeCubeFace; + renderContext.activeMipmapLevel = activeMipmapLevel; + renderContext.occlusionQueryCount = renderList.occlusionQueryCount; + + // + + this._nodes.updateScene(sceneRef); + + // + + this._background.update(sceneRef, renderList, renderContext); + + // + + this.backend.beginRender(renderContext); + + // process render lists + + const { bundles, lightsNode, transparent: transparentObjects, opaque: opaqueObjects } = renderList; + + if (bundles.length > 0) this._renderBundles(bundles, sceneRef, lightsNode); + if (this.opaque === true && opaqueObjects.length > 0) + this._renderObjects(opaqueObjects, camera, sceneRef, lightsNode); + if (this.transparent === true && transparentObjects.length > 0) + this._renderObjects(transparentObjects, camera, sceneRef, lightsNode); + + // finish render pass + + this.backend.finishRender(renderContext); + + // restore render tree + + nodeFrame.renderId = previousRenderId; + + this._currentRenderContext = previousRenderContext; + this._currentRenderObjectFunction = previousRenderObjectFunction; + + // + + if (frameBufferTarget !== null) { + this.setRenderTarget(outputRenderTarget, activeCubeFace, activeMipmapLevel); + + const quad = this._quad; + + if (this._nodes.hasOutputChange(renderTarget.texture)) { + quad.material.fragmentNode = this._nodes.getOutputNode(renderTarget.texture); + quad.material.needsUpdate = true; + } + + this._renderScene(quad, quad.camera, false); + } + + // + + sceneRef.onAfterRender(this, scene, camera, renderTarget); + + // + + return renderContext; + } + + getMaxAnisotropy() { + return this.backend.getMaxAnisotropy(); + } + + getActiveCubeFace() { + return this._activeCubeFace; + } + + getActiveMipmapLevel() { + return this._activeMipmapLevel; + } + + async setAnimationLoop(callback) { + if (this._initialized === false) await this.init(); + + this._animation.setAnimationLoop(callback); + } + + async getArrayBufferAsync(attribute) { + return await this.backend.getArrayBufferAsync(attribute); + } + + getContext() { + return this.backend.getContext(); + } + + getPixelRatio() { + return this._pixelRatio; + } + + getDrawingBufferSize(target) { + return target.set(this._width * this._pixelRatio, this._height * this._pixelRatio).floor(); + } + + getSize(target) { + return target.set(this._width, this._height); + } + + setPixelRatio(value = 1) { + if (this._pixelRatio === value) return; + + this._pixelRatio = value; + + this.setSize(this._width, this._height, false); + } + + setDrawingBufferSize(width, height, pixelRatio) { + this._width = width; + this._height = height; + + this._pixelRatio = pixelRatio; + + this.domElement.width = Math.floor(width * pixelRatio); + this.domElement.height = Math.floor(height * pixelRatio); + + this.setViewport(0, 0, width, height); + + if (this._initialized) this.backend.updateSize(); + } + + setSize(width, height, updateStyle = true) { + this._width = width; + this._height = height; + + this.domElement.width = Math.floor(width * this._pixelRatio); + this.domElement.height = Math.floor(height * this._pixelRatio); + + if (updateStyle === true) { + this.domElement.style.width = width + 'px'; + this.domElement.style.height = height + 'px'; + } + + this.setViewport(0, 0, width, height); + + if (this._initialized) this.backend.updateSize(); + } + + setOpaqueSort(method) { + this._opaqueSort = method; + } + + setTransparentSort(method) { + this._transparentSort = method; + } + + getScissor(target) { + const scissor = this._scissor; + + target.x = scissor.x; + target.y = scissor.y; + target.width = scissor.width; + target.height = scissor.height; + + return target; + } + + setScissor(x, y, width, height) { + const scissor = this._scissor; + + if (x.isVector4) { + scissor.copy(x); + } else { + scissor.set(x, y, width, height); + } + } + + getScissorTest() { + return this._scissorTest; + } + + setScissorTest(boolean) { + this._scissorTest = boolean; + + this.backend.setScissorTest(boolean); + } + + getViewport(target) { + return target.copy(this._viewport); + } + + setViewport(x, y, width, height, minDepth = 0, maxDepth = 1) { + const viewport = this._viewport; + + if (x.isVector4) { + viewport.copy(x); + } else { + viewport.set(x, y, width, height); + } + + viewport.minDepth = minDepth; + viewport.maxDepth = maxDepth; + } + + getClearColor(target) { + return target.copy(this._clearColor); + } + + setClearColor(color, alpha = 1) { + this._clearColor.set(color); + this._clearColor.a = alpha; + } + + getClearAlpha() { + return this._clearColor.a; + } + + setClearAlpha(alpha) { + this._clearColor.a = alpha; + } + + getClearDepth() { + return this._clearDepth; + } + + setClearDepth(depth) { + this._clearDepth = depth; + } + + getClearStencil() { + return this._clearStencil; + } + + setClearStencil(stencil) { + this._clearStencil = stencil; + } + + isOccluded(object) { + const renderContext = this._currentRenderContext; + + return renderContext && this.backend.isOccluded(renderContext, object); + } + + clear(color = true, depth = true, stencil = true) { + if (this._initialized === false) { + console.warn( + 'THREE.Renderer: .clear() called before the backend is initialized. Try using .clearAsync() instead.', + ); + + return this.clearAsync(color, depth, stencil); + } + + const renderTarget = this._renderTarget || this._getFrameBufferTarget(); + + let renderTargetData = null; + + if (renderTarget !== null) { + this._textures.updateRenderTarget(renderTarget); + + renderTargetData = this._textures.get(renderTarget); + } + + this.backend.clear(color, depth, stencil, renderTargetData); + + if (renderTarget !== null && this._renderTarget === null) { + // If a color space transform or tone mapping is required, + // the clear operation clears the intermediate renderTarget texture, but does not update the screen canvas. + + const quad = this._quad; + + if (this._nodes.hasOutputChange(renderTarget.texture)) { + quad.material.fragmentNode = this._nodes.getOutputNode(renderTarget.texture); + quad.material.needsUpdate = true; + } + + this._renderScene(quad, quad.camera, false); + } + } + + clearColor() { + return this.clear(true, false, false); + } + + clearDepth() { + return this.clear(false, true, false); + } + + clearStencil() { + return this.clear(false, false, true); + } + + async clearAsync(color = true, depth = true, stencil = true) { + if (this._initialized === false) await this.init(); + + this.clear(color, depth, stencil); + } + + clearColorAsync() { + return this.clearAsync(true, false, false); + } + + clearDepthAsync() { + return this.clearAsync(false, true, false); + } + + clearStencilAsync() { + return this.clearAsync(false, false, true); + } + + get currentToneMapping() { + return this._renderTarget !== null ? NoToneMapping : this.toneMapping; + } + + get currentColorSpace() { + return this._renderTarget !== null ? LinearSRGBColorSpace : this.outputColorSpace; + } + + dispose() { + this.info.dispose(); + + this._animation.dispose(); + this._objects.dispose(); + this._pipelines.dispose(); + this._nodes.dispose(); + this._bindings.dispose(); + this._renderLists.dispose(); + this._renderContexts.dispose(); + this._textures.dispose(); + + this.setRenderTarget(null); + this.setAnimationLoop(null); + } + + setRenderTarget(renderTarget, activeCubeFace = 0, activeMipmapLevel = 0) { + this._renderTarget = renderTarget; + this._activeCubeFace = activeCubeFace; + this._activeMipmapLevel = activeMipmapLevel; + } + + getRenderTarget() { + return this._renderTarget; + } + + setRenderObjectFunction(renderObjectFunction) { + this._renderObjectFunction = renderObjectFunction; + } + + getRenderObjectFunction() { + return this._renderObjectFunction; + } + + compute(computeNodes) { + if (this._initialized === false) { + console.warn( + 'THREE.Renderer: .compute() called before the backend is initialized. Try using .computeAsync() instead.', + ); + + return this.computeAsync(computeNodes); + } + + // + + const nodeFrame = this._nodes.nodeFrame; + + const previousRenderId = nodeFrame.renderId; + + // + + this.info.calls++; + this.info.compute.calls++; + this.info.compute.frameCalls++; + + nodeFrame.renderId = this.info.calls; + + // + + const backend = this.backend; + const pipelines = this._pipelines; + const bindings = this._bindings; + const nodes = this._nodes; + + const computeList = Array.isArray(computeNodes) ? computeNodes : [computeNodes]; + + if (computeList[0] === undefined || computeList[0].isComputeNode !== true) { + throw new Error('THREE.Renderer: .compute() expects a ComputeNode.'); + } + + backend.beginCompute(computeNodes); + + for (const computeNode of computeList) { + // onInit + + if (pipelines.has(computeNode) === false) { + const dispose = () => { + computeNode.removeEventListener('dispose', dispose); + + pipelines.delete(computeNode); + bindings.delete(computeNode); + nodes.delete(computeNode); + }; + + computeNode.addEventListener('dispose', dispose); + + // + + const onInitFn = computeNode.onInitFunction; + + if (onInitFn !== null) { + onInitFn.call(computeNode, { renderer: this }); + } + } + + nodes.updateForCompute(computeNode); + bindings.updateForCompute(computeNode); + + const computeBindings = bindings.getForCompute(computeNode); + const computePipeline = pipelines.getForCompute(computeNode, computeBindings); + + backend.compute(computeNodes, computeNode, computeBindings, computePipeline); + } + + backend.finishCompute(computeNodes); + + // + + nodeFrame.renderId = previousRenderId; + } + + async computeAsync(computeNodes) { + if (this._initialized === false) await this.init(); + + this.compute(computeNodes); + + await this.backend.resolveTimestampAsync(computeNodes, 'compute'); + } + + async hasFeatureAsync(name) { + if (this._initialized === false) await this.init(); + + return this.backend.hasFeature(name); + } + + hasFeature(name) { + if (this._initialized === false) { + console.warn( + 'THREE.Renderer: .hasFeature() called before the backend is initialized. Try using .hasFeatureAsync() instead.', + ); + + return false; + } + + return this.backend.hasFeature(name); + } + + copyFramebufferToTexture(framebufferTexture, rectangle = null) { + const renderContext = this._currentRenderContext; + + this._textures.updateTexture(framebufferTexture); + + rectangle = + rectangle === null + ? _vector4.set(0, 0, framebufferTexture.image.width, framebufferTexture.image.height) + : rectangle; + + this.backend.copyFramebufferToTexture(framebufferTexture, renderContext, rectangle); + } + + copyTextureToTexture(srcTexture, dstTexture, srcRegion = null, dstPosition = null, level = 0) { + this._textures.updateTexture(srcTexture); + this._textures.updateTexture(dstTexture); + + this.backend.copyTextureToTexture(srcTexture, dstTexture, srcRegion, dstPosition, level); + } + + readRenderTargetPixelsAsync(renderTarget, x, y, width, height, index = 0, faceIndex = 0) { + return this.backend.copyTextureToBuffer(renderTarget.textures[index], x, y, width, height, faceIndex); + } + + _projectObject(object, camera, groupOrder, renderList) { + if (object.visible === false) return; + + const visible = object.layers.test(camera.layers); + + if (visible) { + if (object.isGroup) { + groupOrder = object.renderOrder; + } else if (object.isLOD) { + if (object.autoUpdate === true) object.update(camera); + } else if (object.isLight) { + renderList.pushLight(object); + } else if (object.isSprite) { + if (!object.frustumCulled || _frustum.intersectsSprite(object)) { + if (this.sortObjects === true) { + _vector4.setFromMatrixPosition(object.matrixWorld).applyMatrix4(_projScreenMatrix); + } + + const { geometry, material } = object; + + if (material.visible) { + renderList.push(object, geometry, material, groupOrder, _vector4.z, null); + } + } + } else if (object.isLineLoop) { + console.error( + 'THREE.Renderer: Objects of type THREE.LineLoop are not supported. Please use THREE.Line or THREE.LineSegments.', + ); + } else if (object.isMesh || object.isLine || object.isPoints) { + if (!object.frustumCulled || _frustum.intersectsObject(object)) { + const { geometry, material } = object; + + if (this.sortObjects === true) { + if (geometry.boundingSphere === null) geometry.computeBoundingSphere(); + + _vector4 + .copy(geometry.boundingSphere.center) + .applyMatrix4(object.matrixWorld) + .applyMatrix4(_projScreenMatrix); + } + + if (Array.isArray(material)) { + const groups = geometry.groups; + + for (let i = 0, l = groups.length; i < l; i++) { + const group = groups[i]; + const groupMaterial = material[group.materialIndex]; + + if (groupMaterial && groupMaterial.visible) { + renderList.push(object, geometry, groupMaterial, groupOrder, _vector4.z, group); + } + } + } else if (material.visible) { + renderList.push(object, geometry, material, groupOrder, _vector4.z, null); + } + } + } + } + + if (object.isBundleGroup === true && this.backend.beginBundle !== undefined) { + const baseRenderList = renderList; + + // replace render list + renderList = this._renderLists.get(object, camera); + + renderList.begin(); + + baseRenderList.pushBundle({ + bundleGroup: object, + camera, + renderList, + }); + + renderList.finish(); + } + + const children = object.children; + + for (let i = 0, l = children.length; i < l; i++) { + this._projectObject(children[i], camera, groupOrder, renderList); + } + } + + _renderBundles(bundles, sceneRef, lightsNode) { + for (const bundle of bundles) { + this._renderBundle(bundle, sceneRef, lightsNode); + } + } + + _renderObjects(renderList, camera, scene, lightsNode) { + // process renderable objects + + for (let i = 0, il = renderList.length; i < il; i++) { + const renderItem = renderList[i]; + + // @TODO: Add support for multiple materials per object. This will require to extract + // the material from the renderItem object and pass it with its group data to renderObject(). + + const { object, geometry, material, group } = renderItem; + + if (camera.isArrayCamera) { + const cameras = camera.cameras; + + for (let j = 0, jl = cameras.length; j < jl; j++) { + const camera2 = cameras[j]; + + if (object.layers.test(camera2.layers)) { + const vp = camera2.viewport; + const minDepth = vp.minDepth === undefined ? 0 : vp.minDepth; + const maxDepth = vp.maxDepth === undefined ? 1 : vp.maxDepth; + + const viewportValue = this._currentRenderContext.viewportValue; + viewportValue.copy(vp).multiplyScalar(this._pixelRatio).floor(); + viewportValue.minDepth = minDepth; + viewportValue.maxDepth = maxDepth; + + this.backend.updateViewport(this._currentRenderContext); + + this._currentRenderObjectFunction( + object, + scene, + camera2, + geometry, + material, + group, + lightsNode, + ); + } + } + } else { + this._currentRenderObjectFunction(object, scene, camera, geometry, material, group, lightsNode); + } + } + } + + renderObject(object, scene, camera, geometry, material, group, lightsNode) { + let overridePositionNode; + let overrideFragmentNode; + let overrideDepthNode; + + // + + object.onBeforeRender(this, scene, camera, geometry, material, group); + + // + + if (scene.overrideMaterial !== null) { + const overrideMaterial = scene.overrideMaterial; + + if (material.positionNode && material.positionNode.isNode) { + overridePositionNode = overrideMaterial.positionNode; + overrideMaterial.positionNode = material.positionNode; + } + + if (overrideMaterial.isShadowNodeMaterial) { + overrideMaterial.side = material.shadowSide === null ? material.side : material.shadowSide; + + if (material.depthNode && material.depthNode.isNode) { + overrideDepthNode = overrideMaterial.depthNode; + overrideMaterial.depthNode = material.depthNode; + } + + if (material.shadowNode && material.shadowNode.isNode) { + overrideFragmentNode = overrideMaterial.fragmentNode; + overrideMaterial.fragmentNode = material.shadowNode; + } + + if (this.localClippingEnabled) { + if (material.clipShadows) { + if (overrideMaterial.clippingPlanes !== material.clippingPlanes) { + overrideMaterial.clippingPlanes = material.clippingPlanes; + overrideMaterial.needsUpdate = true; + } + + if (overrideMaterial.clipIntersection !== material.clipIntersection) { + overrideMaterial.clipIntersection = material.clipIntersection; + } + } else if (Array.isArray(overrideMaterial.clippingPlanes)) { + overrideMaterial.clippingPlanes = null; + overrideMaterial.needsUpdate = true; + } + } + } + + material = overrideMaterial; + } + + // + + if (material.transparent === true && material.side === DoubleSide && material.forceSinglePass === false) { + material.side = BackSide; + this._handleObjectFunction(object, material, scene, camera, lightsNode, group, 'backSide'); // create backSide pass id + + material.side = FrontSide; + this._handleObjectFunction(object, material, scene, camera, lightsNode, group); // use default pass id + + material.side = DoubleSide; + } else { + this._handleObjectFunction(object, material, scene, camera, lightsNode, group); + } + + // + + if (overridePositionNode !== undefined) { + scene.overrideMaterial.positionNode = overridePositionNode; + } + + if (overrideDepthNode !== undefined) { + scene.overrideMaterial.depthNode = overrideDepthNode; + } + + if (overrideFragmentNode !== undefined) { + scene.overrideMaterial.fragmentNode = overrideFragmentNode; + } + + // + + object.onAfterRender(this, scene, camera, geometry, material, group); + } + + _renderObjectDirect(object, material, scene, camera, lightsNode, group, passId) { + const renderObject = this._objects.get( + object, + material, + scene, + camera, + lightsNode, + this._currentRenderContext, + passId, + ); + renderObject.drawRange = object.geometry.drawRange; + renderObject.group = group; + + // + + const needsRefresh = this._nodes.needsRefresh(renderObject); + + if (needsRefresh) { + this._nodes.updateBefore(renderObject); + + this._geometries.updateForRender(renderObject); + + this._nodes.updateForRender(renderObject); + this._bindings.updateForRender(renderObject); + } + + this._pipelines.updateForRender(renderObject); + + // + + if (this._currentRenderBundle !== null) { + const renderBundleData = this.backend.get(this._currentRenderBundle); + + renderBundleData.renderObjects.push(renderObject); + + renderObject.bundle = this._currentRenderBundle.scene; + } + + this.backend.draw(renderObject, this.info); + + if (needsRefresh) this._nodes.updateAfter(renderObject); + } + + _createObjectPipeline(object, material, scene, camera, lightsNode, passId) { + const renderObject = this._objects.get( + object, + material, + scene, + camera, + lightsNode, + this._currentRenderContext, + passId, + ); + + // + + this._nodes.updateBefore(renderObject); + + this._geometries.updateForRender(renderObject); + + this._nodes.updateForRender(renderObject); + this._bindings.updateForRender(renderObject); + + this._pipelines.getForRender(renderObject, this._compilationPromises); + + this._nodes.updateAfter(renderObject); + } + + get compile() { + return this.compileAsync; + } +} + +export default Renderer; diff --git a/src-testing/src/renderers/common/SampledTexture.ts b/src-testing/src/renderers/common/SampledTexture.ts new file mode 100644 index 000000000..841e6a85b --- /dev/null +++ b/src-testing/src/renderers/common/SampledTexture.ts @@ -0,0 +1,68 @@ +import Binding from './Binding.js'; + +let _id = 0; + +class SampledTexture extends Binding { + constructor(name, texture) { + super(name); + + this.id = _id++; + + this.texture = texture; + this.version = texture ? texture.version : 0; + this.store = false; + this.generation = null; + + this.isSampledTexture = true; + } + + needsBindingsUpdate(generation) { + const { texture } = this; + + if (generation !== this.generation) { + this.generation = generation; + + return true; + } + + return texture.isVideoTexture; + } + + update() { + const { texture, version } = this; + + if (version !== texture.version) { + this.version = texture.version; + + return true; + } + + return false; + } +} + +class SampledArrayTexture extends SampledTexture { + constructor(name, texture) { + super(name, texture); + + this.isSampledArrayTexture = true; + } +} + +class Sampled3DTexture extends SampledTexture { + constructor(name, texture) { + super(name, texture); + + this.isSampled3DTexture = true; + } +} + +class SampledCubeTexture extends SampledTexture { + constructor(name, texture) { + super(name, texture); + + this.isSampledCubeTexture = true; + } +} + +export { SampledTexture, SampledArrayTexture, Sampled3DTexture, SampledCubeTexture }; diff --git a/src-testing/src/renderers/common/Sampler.ts b/src-testing/src/renderers/common/Sampler.ts new file mode 100644 index 000000000..8cd20d04a --- /dev/null +++ b/src-testing/src/renderers/common/Sampler.ts @@ -0,0 +1,14 @@ +import Binding from './Binding.js'; + +class Sampler extends Binding { + constructor(name, texture) { + super(name); + + this.texture = texture; + this.version = texture ? texture.version : 0; + + this.isSampler = true; + } +} + +export default Sampler; diff --git a/src-testing/src/renderers/common/StorageBuffer.ts b/src-testing/src/renderers/common/StorageBuffer.ts new file mode 100644 index 000000000..ef5d3e464 --- /dev/null +++ b/src-testing/src/renderers/common/StorageBuffer.ts @@ -0,0 +1,13 @@ +import Buffer from './Buffer.js'; + +class StorageBuffer extends Buffer { + constructor(name, attribute) { + super(name, attribute ? attribute.array : null); + + this.attribute = attribute; + + this.isStorageBuffer = true; + } +} + +export default StorageBuffer; diff --git a/src-testing/src/renderers/common/StorageBufferAttribute.d.ts b/src-testing/src/renderers/common/StorageBufferAttribute.d.ts new file mode 100644 index 000000000..2a864f54a --- /dev/null +++ b/src-testing/src/renderers/common/StorageBufferAttribute.d.ts @@ -0,0 +1,7 @@ +import { BufferAttribute, TypedArray } from "../../core/BufferAttribute.js"; + +export default class StorageBufferAttribute extends BufferAttribute { + readonly isStorageBufferAttribute: true; + + constructor(array: TypedArray, itemSize: number); +} diff --git a/src-testing/src/renderers/common/StorageInstancedBufferAttribute.d.ts b/src-testing/src/renderers/common/StorageInstancedBufferAttribute.d.ts new file mode 100644 index 000000000..3f01891e8 --- /dev/null +++ b/src-testing/src/renderers/common/StorageInstancedBufferAttribute.d.ts @@ -0,0 +1,8 @@ +import { TypedArray } from "../../core/BufferAttribute.js"; +import { InstancedBufferAttribute } from "../../core/InstancedBufferAttribute.js"; + +export default class StorageInstancedBufferAttribute extends InstancedBufferAttribute { + readonly isStorageInstancedBufferAttribute: true; + + constructor(array: TypedArray | number, itemSize: number); +} diff --git a/src-testing/src/renderers/common/StorageTexture.d.ts b/src-testing/src/renderers/common/StorageTexture.d.ts new file mode 100644 index 000000000..435ef9ba3 --- /dev/null +++ b/src-testing/src/renderers/common/StorageTexture.d.ts @@ -0,0 +1,5 @@ +import { Texture } from "../../textures/Texture.js"; + +export default class StorageTexture extends Texture { + constructor(width?: number, height?: number); +} diff --git a/src-testing/src/renderers/common/Textures.ts b/src-testing/src/renderers/common/Textures.ts new file mode 100644 index 000000000..8d35f664f --- /dev/null +++ b/src-testing/src/renderers/common/Textures.ts @@ -0,0 +1,294 @@ +import DataMap from './DataMap.js'; + +import { Vector3 } from '../../math/Vector3.js'; +import { DepthTexture } from '../../textures/DepthTexture.js'; +import { + DepthStencilFormat, + DepthFormat, + UnsignedIntType, + UnsignedInt248Type, + EquirectangularReflectionMapping, + EquirectangularRefractionMapping, + CubeReflectionMapping, + CubeRefractionMapping, + UnsignedByteType, +} from '../../constants.js'; + +const _size = /*@__PURE__*/ new Vector3(); + +class Textures extends DataMap { + constructor(renderer, backend, info) { + super(); + + this.renderer = renderer; + this.backend = backend; + this.info = info; + } + + updateRenderTarget(renderTarget, activeMipmapLevel = 0) { + const renderTargetData = this.get(renderTarget); + + const sampleCount = renderTarget.samples === 0 ? 1 : renderTarget.samples; + const depthTextureMips = renderTargetData.depthTextureMips || (renderTargetData.depthTextureMips = {}); + + const textures = renderTarget.textures; + + const size = this.getSize(textures[0]); + + const mipWidth = size.width >> activeMipmapLevel; + const mipHeight = size.height >> activeMipmapLevel; + + let depthTexture = renderTarget.depthTexture || depthTextureMips[activeMipmapLevel]; + const useDepthTexture = renderTarget.depthBuffer === true || renderTarget.stencilBuffer === true; + + let textureNeedsUpdate = false; + + if (depthTexture === undefined && useDepthTexture) { + depthTexture = new DepthTexture(); + depthTexture.format = renderTarget.stencilBuffer ? DepthStencilFormat : DepthFormat; + depthTexture.type = renderTarget.stencilBuffer ? UnsignedInt248Type : UnsignedIntType; // FloatType + depthTexture.image.width = mipWidth; + depthTexture.image.height = mipHeight; + + depthTextureMips[activeMipmapLevel] = depthTexture; + } + + if (renderTargetData.width !== size.width || size.height !== renderTargetData.height) { + textureNeedsUpdate = true; + + if (depthTexture) { + depthTexture.needsUpdate = true; + depthTexture.image.width = mipWidth; + depthTexture.image.height = mipHeight; + } + } + + renderTargetData.width = size.width; + renderTargetData.height = size.height; + renderTargetData.textures = textures; + renderTargetData.depthTexture = depthTexture || null; + renderTargetData.depth = renderTarget.depthBuffer; + renderTargetData.stencil = renderTarget.stencilBuffer; + renderTargetData.renderTarget = renderTarget; + + if (renderTargetData.sampleCount !== sampleCount) { + textureNeedsUpdate = true; + + if (depthTexture) { + depthTexture.needsUpdate = true; + } + + renderTargetData.sampleCount = sampleCount; + } + + // + + const options = { sampleCount }; + + for (let i = 0; i < textures.length; i++) { + const texture = textures[i]; + + if (textureNeedsUpdate) texture.needsUpdate = true; + + this.updateTexture(texture, options); + } + + if (depthTexture) { + this.updateTexture(depthTexture, options); + } + + // dispose handler + + if (renderTargetData.initialized !== true) { + renderTargetData.initialized = true; + + // dispose + + const onDispose = () => { + renderTarget.removeEventListener('dispose', onDispose); + + for (let i = 0; i < textures.length; i++) { + this._destroyTexture(textures[i]); + } + + if (depthTexture) { + this._destroyTexture(depthTexture); + } + + this.delete(renderTarget); + }; + + renderTarget.addEventListener('dispose', onDispose); + } + } + + updateTexture(texture, options = {}) { + const textureData = this.get(texture); + if (textureData.initialized === true && textureData.version === texture.version) return; + + const isRenderTarget = texture.isRenderTargetTexture || texture.isDepthTexture || texture.isFramebufferTexture; + const backend = this.backend; + + if (isRenderTarget && textureData.initialized === true) { + // it's an update + + backend.destroySampler(texture); + backend.destroyTexture(texture); + } + + // + + if (texture.isFramebufferTexture) { + const renderer = this.renderer; + const renderTarget = renderer.getRenderTarget(); + + if (renderTarget) { + texture.type = renderTarget.texture.type; + } else { + texture.type = UnsignedByteType; + } + } + + // + + const { width, height, depth } = this.getSize(texture); + + options.width = width; + options.height = height; + options.depth = depth; + options.needsMipmaps = this.needsMipmaps(texture); + options.levels = options.needsMipmaps ? this.getMipLevels(texture, width, height) : 1; + + // + + if (isRenderTarget || texture.isStorageTexture === true) { + backend.createSampler(texture); + backend.createTexture(texture, options); + + textureData.generation = texture.version; + } else { + const needsCreate = textureData.initialized !== true; + + if (needsCreate) backend.createSampler(texture); + + if (texture.version > 0) { + const image = texture.image; + + if (image === undefined) { + console.warn('THREE.Renderer: Texture marked for update but image is undefined.'); + } else if (image.complete === false) { + console.warn('THREE.Renderer: Texture marked for update but image is incomplete.'); + } else { + if (texture.images) { + const images = []; + + for (const image of texture.images) { + images.push(image); + } + + options.images = images; + } else { + options.image = image; + } + + if (textureData.isDefaultTexture === undefined || textureData.isDefaultTexture === true) { + backend.createTexture(texture, options); + + textureData.isDefaultTexture = false; + textureData.generation = texture.version; + } + + if (texture.source.dataReady === true) backend.updateTexture(texture, options); + + if (options.needsMipmaps && texture.mipmaps.length === 0) backend.generateMipmaps(texture); + } + } else { + // async update + + backend.createDefaultTexture(texture); + + textureData.isDefaultTexture = true; + textureData.generation = texture.version; + } + } + + // dispose handler + + if (textureData.initialized !== true) { + textureData.initialized = true; + textureData.generation = texture.version; + + // + + this.info.memory.textures++; + + // dispose + + const onDispose = () => { + texture.removeEventListener('dispose', onDispose); + + this._destroyTexture(texture); + + this.info.memory.textures--; + }; + + texture.addEventListener('dispose', onDispose); + } + + // + + textureData.version = texture.version; + } + + getSize(texture, target = _size) { + let image = texture.images ? texture.images[0] : texture.image; + + if (image) { + if (image.image !== undefined) image = image.image; + + target.width = image.width; + target.height = image.height; + target.depth = texture.isCubeTexture ? 6 : image.depth || 1; + } else { + target.width = target.height = target.depth = 1; + } + + return target; + } + + getMipLevels(texture, width, height) { + let mipLevelCount; + + if (texture.isCompressedTexture) { + mipLevelCount = texture.mipmaps.length; + } else { + mipLevelCount = Math.floor(Math.log2(Math.max(width, height))) + 1; + } + + return mipLevelCount; + } + + needsMipmaps(texture) { + return this.isEnvironmentTexture(texture) || texture.isCompressedTexture === true || texture.generateMipmaps; + } + + isEnvironmentTexture(texture) { + const mapping = texture.mapping; + + return ( + mapping === EquirectangularReflectionMapping || + mapping === EquirectangularRefractionMapping || + mapping === CubeReflectionMapping || + mapping === CubeRefractionMapping + ); + } + + _destroyTexture(texture) { + this.backend.destroySampler(texture); + this.backend.destroyTexture(texture); + + this.delete(texture); + } +} + +export default Textures; diff --git a/src-testing/src/renderers/common/Uniform.ts b/src-testing/src/renderers/common/Uniform.ts new file mode 100644 index 000000000..80c131494 --- /dev/null +++ b/src-testing/src/renderers/common/Uniform.ts @@ -0,0 +1,105 @@ +import { Color } from '../../math/Color.js'; +import { Matrix3 } from '../../math/Matrix3.js'; +import { Matrix4 } from '../../math/Matrix4.js'; +import { Vector2 } from '../../math/Vector2.js'; +import { Vector3 } from '../../math/Vector3.js'; +import { Vector4 } from '../../math/Vector4.js'; + +class Uniform { + constructor(name, value) { + this.name = name; + this.value = value; + + this.boundary = 0; // used to build the uniform buffer according to the STD140 layout + this.itemSize = 0; + + this.offset = 0; // this property is set by WebGPUUniformsGroup and marks the start position in the uniform buffer + } + + setValue(value) { + this.value = value; + } + + getValue() { + return this.value; + } +} + +class NumberUniform extends Uniform { + constructor(name, value = 0) { + super(name, value); + + this.isNumberUniform = true; + + this.boundary = 4; + this.itemSize = 1; + } +} + +class Vector2Uniform extends Uniform { + constructor(name, value = new Vector2()) { + super(name, value); + + this.isVector2Uniform = true; + + this.boundary = 8; + this.itemSize = 2; + } +} + +class Vector3Uniform extends Uniform { + constructor(name, value = new Vector3()) { + super(name, value); + + this.isVector3Uniform = true; + + this.boundary = 16; + this.itemSize = 3; + } +} + +class Vector4Uniform extends Uniform { + constructor(name, value = new Vector4()) { + super(name, value); + + this.isVector4Uniform = true; + + this.boundary = 16; + this.itemSize = 4; + } +} + +class ColorUniform extends Uniform { + constructor(name, value = new Color()) { + super(name, value); + + this.isColorUniform = true; + + this.boundary = 16; + this.itemSize = 3; + } +} + +class Matrix3Uniform extends Uniform { + constructor(name, value = new Matrix3()) { + super(name, value); + + this.isMatrix3Uniform = true; + + this.boundary = 48; + this.itemSize = 12; + } +} + +class Matrix4Uniform extends Uniform { + constructor(name, value = new Matrix4()) { + super(name, value); + + this.isMatrix4Uniform = true; + + this.boundary = 64; + this.itemSize = 16; + } +} + +export { NumberUniform, Vector2Uniform, Vector3Uniform, Vector4Uniform, ColorUniform, Matrix3Uniform, Matrix4Uniform }; diff --git a/src-testing/src/renderers/common/UniformBuffer.ts b/src-testing/src/renderers/common/UniformBuffer.ts new file mode 100644 index 000000000..28aac0d7e --- /dev/null +++ b/src-testing/src/renderers/common/UniformBuffer.ts @@ -0,0 +1,11 @@ +import Buffer from './Buffer.js'; + +class UniformBuffer extends Buffer { + constructor(name, buffer = null) { + super(name, buffer); + + this.isUniformBuffer = true; + } +} + +export default UniformBuffer; diff --git a/src-testing/src/renderers/common/UniformsGroup.ts b/src-testing/src/renderers/common/UniformsGroup.ts new file mode 100644 index 000000000..e2b62671a --- /dev/null +++ b/src-testing/src/renderers/common/UniformsGroup.ts @@ -0,0 +1,277 @@ +import UniformBuffer from './UniformBuffer.js'; +import { GPU_CHUNK_BYTES } from './Constants.js'; + +class UniformsGroup extends UniformBuffer { + constructor(name) { + super(name); + + this.isUniformsGroup = true; + + this._values = null; + + // the order of uniforms in this array must match the order of uniforms in the shader + + this.uniforms = []; + } + + addUniform(uniform) { + this.uniforms.push(uniform); + + return this; + } + + removeUniform(uniform) { + const index = this.uniforms.indexOf(uniform); + + if (index !== -1) { + this.uniforms.splice(index, 1); + } + + return this; + } + + get values() { + if (this._values === null) { + this._values = Array.from(this.buffer); + } + + return this._values; + } + + get buffer() { + let buffer = this._buffer; + + if (buffer === null) { + const byteLength = this.byteLength; + + buffer = new Float32Array(new ArrayBuffer(byteLength)); + + this._buffer = buffer; + } + + return buffer; + } + + get byteLength() { + let offset = 0; // global buffer offset in bytes + + for (let i = 0, l = this.uniforms.length; i < l; i++) { + const uniform = this.uniforms[i]; + + const { boundary, itemSize } = uniform; + + // offset within a single chunk in bytes + + const chunkOffset = offset % GPU_CHUNK_BYTES; + const remainingSizeInChunk = GPU_CHUNK_BYTES - chunkOffset; + + // conformance tests + + if (chunkOffset !== 0 && remainingSizeInChunk - boundary < 0) { + // check for chunk overflow + + offset += GPU_CHUNK_BYTES - chunkOffset; + } else if (chunkOffset % boundary !== 0) { + // check for correct alignment + + offset += chunkOffset % boundary; + } + + uniform.offset = offset / this.bytesPerElement; + + offset += itemSize * this.bytesPerElement; + } + + return Math.ceil(offset / GPU_CHUNK_BYTES) * GPU_CHUNK_BYTES; + } + + update() { + let updated = false; + + for (const uniform of this.uniforms) { + if (this.updateByType(uniform) === true) { + updated = true; + } + } + + return updated; + } + + updateByType(uniform) { + if (uniform.isNumberUniform) return this.updateNumber(uniform); + if (uniform.isVector2Uniform) return this.updateVector2(uniform); + if (uniform.isVector3Uniform) return this.updateVector3(uniform); + if (uniform.isVector4Uniform) return this.updateVector4(uniform); + if (uniform.isColorUniform) return this.updateColor(uniform); + if (uniform.isMatrix3Uniform) return this.updateMatrix3(uniform); + if (uniform.isMatrix4Uniform) return this.updateMatrix4(uniform); + + console.error('THREE.WebGPUUniformsGroup: Unsupported uniform type.', uniform); + } + + updateNumber(uniform) { + let updated = false; + + const a = this.values; + const v = uniform.getValue(); + const offset = uniform.offset; + + if (a[offset] !== v) { + const b = this.buffer; + + b[offset] = a[offset] = v; + updated = true; + } + + return updated; + } + + updateVector2(uniform) { + let updated = false; + + const a = this.values; + const v = uniform.getValue(); + const offset = uniform.offset; + + if (a[offset + 0] !== v.x || a[offset + 1] !== v.y) { + const b = this.buffer; + + b[offset + 0] = a[offset + 0] = v.x; + b[offset + 1] = a[offset + 1] = v.y; + + updated = true; + } + + return updated; + } + + updateVector3(uniform) { + let updated = false; + + const a = this.values; + const v = uniform.getValue(); + const offset = uniform.offset; + + if (a[offset + 0] !== v.x || a[offset + 1] !== v.y || a[offset + 2] !== v.z) { + const b = this.buffer; + + b[offset + 0] = a[offset + 0] = v.x; + b[offset + 1] = a[offset + 1] = v.y; + b[offset + 2] = a[offset + 2] = v.z; + + updated = true; + } + + return updated; + } + + updateVector4(uniform) { + let updated = false; + + const a = this.values; + const v = uniform.getValue(); + const offset = uniform.offset; + + if (a[offset + 0] !== v.x || a[offset + 1] !== v.y || a[offset + 2] !== v.z || a[offset + 4] !== v.w) { + const b = this.buffer; + + b[offset + 0] = a[offset + 0] = v.x; + b[offset + 1] = a[offset + 1] = v.y; + b[offset + 2] = a[offset + 2] = v.z; + b[offset + 3] = a[offset + 3] = v.w; + + updated = true; + } + + return updated; + } + + updateColor(uniform) { + let updated = false; + + const a = this.values; + const c = uniform.getValue(); + const offset = uniform.offset; + + if (a[offset + 0] !== c.r || a[offset + 1] !== c.g || a[offset + 2] !== c.b) { + const b = this.buffer; + + b[offset + 0] = a[offset + 0] = c.r; + b[offset + 1] = a[offset + 1] = c.g; + b[offset + 2] = a[offset + 2] = c.b; + + updated = true; + } + + return updated; + } + + updateMatrix3(uniform) { + let updated = false; + + const a = this.values; + const e = uniform.getValue().elements; + const offset = uniform.offset; + + if ( + a[offset + 0] !== e[0] || + a[offset + 1] !== e[1] || + a[offset + 2] !== e[2] || + a[offset + 4] !== e[3] || + a[offset + 5] !== e[4] || + a[offset + 6] !== e[5] || + a[offset + 8] !== e[6] || + a[offset + 9] !== e[7] || + a[offset + 10] !== e[8] + ) { + const b = this.buffer; + + b[offset + 0] = a[offset + 0] = e[0]; + b[offset + 1] = a[offset + 1] = e[1]; + b[offset + 2] = a[offset + 2] = e[2]; + b[offset + 4] = a[offset + 4] = e[3]; + b[offset + 5] = a[offset + 5] = e[4]; + b[offset + 6] = a[offset + 6] = e[5]; + b[offset + 8] = a[offset + 8] = e[6]; + b[offset + 9] = a[offset + 9] = e[7]; + b[offset + 10] = a[offset + 10] = e[8]; + + updated = true; + } + + return updated; + } + + updateMatrix4(uniform) { + let updated = false; + + const a = this.values; + const e = uniform.getValue().elements; + const offset = uniform.offset; + + if (arraysEqual(a, e, offset) === false) { + const b = this.buffer; + b.set(e, offset); + setArray(a, e, offset); + updated = true; + } + + return updated; + } +} + +function setArray(a, b, offset) { + for (let i = 0, l = b.length; i < l; i++) { + a[offset + i] = b[i]; + } +} + +function arraysEqual(a, b, offset) { + for (let i = 0, l = b.length; i < l; i++) { + if (a[offset + i] !== b[i]) return false; + } + + return true; +} + +export default UniformsGroup; diff --git a/src-testing/src/renderers/common/extras/PMREMGenerator.ts b/src-testing/src/renderers/common/extras/PMREMGenerator.ts new file mode 100644 index 000000000..b317f950c --- /dev/null +++ b/src-testing/src/renderers/common/extras/PMREMGenerator.ts @@ -0,0 +1,657 @@ +import NodeMaterial from '../../../materials/nodes/NodeMaterial.js'; +import { getDirection, blur } from '../../../nodes/pmrem/PMREMUtils.js'; +import { equirectUV } from '../../../nodes/utils/EquirectUVNode.js'; +import { uniform } from '../../../nodes/core/UniformNode.js'; +import { uniformArray } from '../../../nodes/accessors/UniformArrayNode.js'; +import { texture } from '../../../nodes/accessors/TextureNode.js'; +import { cubeTexture } from '../../../nodes/accessors/CubeTextureNode.js'; +import { float, vec3 } from '../../../nodes/tsl/TSLBase.js'; +import { uv } from '../../../nodes/accessors/UV.js'; +import { attribute } from '../../../nodes/core/AttributeNode.js'; + +import { OrthographicCamera } from '../../../cameras/OrthographicCamera.js'; +import { Color } from '../../../math/Color.js'; +import { Vector3 } from '../../../math/Vector3.js'; +import { BufferGeometry } from '../../../core/BufferGeometry.js'; +import { BufferAttribute } from '../../../core/BufferAttribute.js'; +import { RenderTarget } from '../../../core/RenderTarget.js'; +import { Mesh } from '../../../objects/Mesh.js'; +import { PerspectiveCamera } from '../../../cameras/PerspectiveCamera.js'; +import { MeshBasicMaterial } from '../../../materials/MeshBasicMaterial.js'; +import { BoxGeometry } from '../../../geometries/BoxGeometry.js'; +import { + CubeReflectionMapping, + CubeRefractionMapping, + CubeUVReflectionMapping, + LinearFilter, + NoBlending, + RGBAFormat, + HalfFloatType, + BackSide, + LinearSRGBColorSpace, +} from '../../../constants.js'; + +const LOD_MIN = 4; + +// The standard deviations (radians) associated with the extra mips. These are +// chosen to approximate a Trowbridge-Reitz distribution function times the +// geometric shadowing function. These sigma values squared must match the +// variance #defines in cube_uv_reflection_fragment.glsl.js. +const EXTRA_LOD_SIGMA = [0.125, 0.215, 0.35, 0.446, 0.526, 0.582]; + +// The maximum length of the blur for loop. Smaller sigmas will use fewer +// samples and exit early, but not recompile the shader. +const MAX_SAMPLES = 20; + +const _flatCamera = /*@__PURE__*/ new OrthographicCamera(-1, 1, 1, -1, 0, 1); +const _cubeCamera = /*@__PURE__*/ new PerspectiveCamera(90, 1); +const _clearColor = /*@__PURE__*/ new Color(); +let _oldTarget = null; +let _oldActiveCubeFace = 0; +let _oldActiveMipmapLevel = 0; + +// Golden Ratio +const PHI = (1 + Math.sqrt(5)) / 2; +const INV_PHI = 1 / PHI; + +// Vertices of a dodecahedron (except the opposites, which represent the +// same axis), used as axis directions evenly spread on a sphere. +const _axisDirections = [ + /*@__PURE__*/ new Vector3(-PHI, INV_PHI, 0), + /*@__PURE__*/ new Vector3(PHI, INV_PHI, 0), + /*@__PURE__*/ new Vector3(-INV_PHI, 0, PHI), + /*@__PURE__*/ new Vector3(INV_PHI, 0, PHI), + /*@__PURE__*/ new Vector3(0, PHI, -INV_PHI), + /*@__PURE__*/ new Vector3(0, PHI, INV_PHI), + /*@__PURE__*/ new Vector3(-1, 1, -1), + /*@__PURE__*/ new Vector3(1, 1, -1), + /*@__PURE__*/ new Vector3(-1, 1, 1), + /*@__PURE__*/ new Vector3(1, 1, 1), +]; + +// + +// WebGPU Face indices +const _faceLib = [3, 1, 5, 0, 4, 2]; + +const direction = getDirection(uv(), attribute('faceIndex')).normalize(); +const outputDirection = vec3(direction.x, direction.y.negate(), direction.z); + +/** + * This class generates a Prefiltered, Mipmapped Radiance Environment Map + * (PMREM) from a cubeMap environment texture. This allows different levels of + * blur to be quickly accessed based on material roughness. It is packed into a + * special CubeUV format that allows us to perform custom interpolation so that + * we can support nonlinear formats such as RGBE. Unlike a traditional mipmap + * chain, it only goes down to the LOD_MIN level (above), and then creates extra + * even more filtered 'mips' at the same LOD_MIN resolution, associated with + * higher roughness levels. In this way we maintain resolution to smoothly + * interpolate diffuse lighting while limiting sampling computation. + * + * Paper: Fast, Accurate Image-Based Lighting + * https://drive.google.com/file/d/15y8r_UpKlU9SvV4ILb0C3qCPecS8pvLz/view + */ + +class PMREMGenerator { + constructor(renderer) { + this._renderer = renderer; + this._pingPongRenderTarget = null; + + this._lodMax = 0; + this._cubeSize = 0; + this._lodPlanes = []; + this._sizeLods = []; + this._sigmas = []; + this._lodMeshes = []; + + this._blurMaterial = null; + this._cubemapMaterial = null; + this._equirectMaterial = null; + this._backgroundBox = null; + } + + /** + * Generates a PMREM from a supplied Scene, which can be faster than using an + * image if networking bandwidth is low. Optional sigma specifies a blur radius + * in radians to be applied to the scene before PMREM generation. Optional near + * and far planes ensure the scene is rendered in its entirety (the cubeCamera + * is placed at the origin). + */ + fromScene(scene, sigma = 0, near = 0.1, far = 100) { + _oldTarget = this._renderer.getRenderTarget(); + _oldActiveCubeFace = this._renderer.getActiveCubeFace(); + _oldActiveMipmapLevel = this._renderer.getActiveMipmapLevel(); + + this._setSize(256); + + const cubeUVRenderTarget = this._allocateTargets(); + cubeUVRenderTarget.depthBuffer = true; + + this._sceneToCubeUV(scene, near, far, cubeUVRenderTarget); + + if (sigma > 0) { + this._blur(cubeUVRenderTarget, 0, 0, sigma); + } + + this._applyPMREM(cubeUVRenderTarget); + + this._cleanup(cubeUVRenderTarget); + + return cubeUVRenderTarget; + } + + /** + * Generates a PMREM from an equirectangular texture, which can be either LDR + * or HDR. The ideal input image size is 1k (1024 x 512), + * as this matches best with the 256 x 256 cubemap output. + */ + fromEquirectangular(equirectangular, renderTarget = null) { + return this._fromTexture(equirectangular, renderTarget); + } + + /** + * Generates a PMREM from an cubemap texture, which can be either LDR + * or HDR. The ideal input cube size is 256 x 256, + * as this matches best with the 256 x 256 cubemap output. + */ + fromCubemap(cubemap, renderTarget = null) { + return this._fromTexture(cubemap, renderTarget); + } + + /** + * Pre-compiles the cubemap shader. You can get faster start-up by invoking this method during + * your texture's network fetch for increased concurrency. + */ + async compileCubemapShader() { + if (this._cubemapMaterial === null) { + this._cubemapMaterial = _getCubemapMaterial(); + await this._compileMaterial(this._cubemapMaterial); + } + } + + /** + * Pre-compiles the equirectangular shader. You can get faster start-up by invoking this method during + * your texture's network fetch for increased concurrency. + */ + async compileEquirectangularShader() { + if (this._equirectMaterial === null) { + this._equirectMaterial = _getEquirectMaterial(); + await this._compileMaterial(this._equirectMaterial); + } + } + + /** + * Disposes of the PMREMGenerator's internal memory. Note that PMREMGenerator is a static class, + * so you should not need more than one PMREMGenerator object. If you do, calling dispose() on + * one of them will cause any others to also become unusable. + */ + dispose() { + this._dispose(); + + if (this._cubemapMaterial !== null) this._cubemapMaterial.dispose(); + if (this._equirectMaterial !== null) this._equirectMaterial.dispose(); + if (this._backgroundBox !== null) { + this._backgroundBox.geometry.dispose(); + this._backgroundBox.material.dispose(); + } + } + + // private interface + + _setSize(cubeSize) { + this._lodMax = Math.floor(Math.log2(cubeSize)); + this._cubeSize = Math.pow(2, this._lodMax); + } + + _dispose() { + if (this._blurMaterial !== null) this._blurMaterial.dispose(); + + if (this._pingPongRenderTarget !== null) this._pingPongRenderTarget.dispose(); + + for (let i = 0; i < this._lodPlanes.length; i++) { + this._lodPlanes[i].dispose(); + } + } + + _cleanup(outputTarget) { + this._renderer.setRenderTarget(_oldTarget, _oldActiveCubeFace, _oldActiveMipmapLevel); + outputTarget.scissorTest = false; + _setViewport(outputTarget, 0, 0, outputTarget.width, outputTarget.height); + } + + _fromTexture(texture, renderTarget) { + if (texture.mapping === CubeReflectionMapping || texture.mapping === CubeRefractionMapping) { + this._setSize(texture.image.length === 0 ? 16 : texture.image[0].width || texture.image[0].image.width); + } else { + // Equirectangular + + this._setSize(texture.image.width / 4); + } + + _oldTarget = this._renderer.getRenderTarget(); + _oldActiveCubeFace = this._renderer.getActiveCubeFace(); + _oldActiveMipmapLevel = this._renderer.getActiveMipmapLevel(); + + const cubeUVRenderTarget = renderTarget || this._allocateTargets(); + this._textureToCubeUV(texture, cubeUVRenderTarget); + this._applyPMREM(cubeUVRenderTarget); + this._cleanup(cubeUVRenderTarget); + + return cubeUVRenderTarget; + } + + _allocateTargets() { + const width = 3 * Math.max(this._cubeSize, 16 * 7); + const height = 4 * this._cubeSize; + + const params = { + magFilter: LinearFilter, + minFilter: LinearFilter, + generateMipmaps: false, + type: HalfFloatType, + format: RGBAFormat, + colorSpace: LinearSRGBColorSpace, + //depthBuffer: false + }; + + const cubeUVRenderTarget = _createRenderTarget(width, height, params); + + if ( + this._pingPongRenderTarget === null || + this._pingPongRenderTarget.width !== width || + this._pingPongRenderTarget.height !== height + ) { + if (this._pingPongRenderTarget !== null) { + this._dispose(); + } + + this._pingPongRenderTarget = _createRenderTarget(width, height, params); + + const { _lodMax } = this; + ({ + sizeLods: this._sizeLods, + lodPlanes: this._lodPlanes, + sigmas: this._sigmas, + lodMeshes: this._lodMeshes, + } = _createPlanes(_lodMax)); + + this._blurMaterial = _getBlurShader(_lodMax, width, height); + } + + return cubeUVRenderTarget; + } + + async _compileMaterial(material) { + const tmpMesh = new Mesh(this._lodPlanes[0], material); + await this._renderer.compile(tmpMesh, _flatCamera); + } + + _sceneToCubeUV(scene, near, far, cubeUVRenderTarget) { + const cubeCamera = _cubeCamera; + cubeCamera.near = near; + cubeCamera.far = far; + + // px, py, pz, nx, ny, nz + const upSign = [-1, 1, -1, -1, -1, -1]; + const forwardSign = [1, 1, 1, -1, -1, -1]; + + const renderer = this._renderer; + + const originalAutoClear = renderer.autoClear; + + renderer.getClearColor(_clearColor); + + renderer.autoClear = false; + + let backgroundBox = this._backgroundBox; + + if (backgroundBox === null) { + const backgroundMaterial = new MeshBasicMaterial({ + name: 'PMREM.Background', + side: BackSide, + depthWrite: false, + depthTest: false, + }); + + backgroundBox = new Mesh(new BoxGeometry(), backgroundMaterial); + } + + let useSolidColor = false; + const background = scene.background; + + if (background) { + if (background.isColor) { + backgroundBox.material.color.copy(background); + scene.background = null; + useSolidColor = true; + } + } else { + backgroundBox.material.color.copy(_clearColor); + useSolidColor = true; + } + + renderer.setRenderTarget(cubeUVRenderTarget); + + renderer.clear(); + + if (useSolidColor) { + renderer.render(backgroundBox, cubeCamera); + } + + for (let i = 0; i < 6; i++) { + const col = i % 3; + + if (col === 0) { + cubeCamera.up.set(0, upSign[i], 0); + cubeCamera.lookAt(forwardSign[i], 0, 0); + } else if (col === 1) { + cubeCamera.up.set(0, 0, upSign[i]); + cubeCamera.lookAt(0, forwardSign[i], 0); + } else { + cubeCamera.up.set(0, upSign[i], 0); + cubeCamera.lookAt(0, 0, forwardSign[i]); + } + + const size = this._cubeSize; + + _setViewport(cubeUVRenderTarget, col * size, i > 2 ? size : 0, size, size); + + renderer.render(scene, cubeCamera); + } + + renderer.autoClear = originalAutoClear; + scene.background = background; + } + + _textureToCubeUV(texture, cubeUVRenderTarget) { + const renderer = this._renderer; + + const isCubeTexture = texture.mapping === CubeReflectionMapping || texture.mapping === CubeRefractionMapping; + + if (isCubeTexture) { + if (this._cubemapMaterial === null) { + this._cubemapMaterial = _getCubemapMaterial(texture); + } + } else { + if (this._equirectMaterial === null) { + this._equirectMaterial = _getEquirectMaterial(texture); + } + } + + const material = isCubeTexture ? this._cubemapMaterial : this._equirectMaterial; + material.fragmentNode.value = texture; + + const mesh = this._lodMeshes[0]; + mesh.material = material; + + const size = this._cubeSize; + + _setViewport(cubeUVRenderTarget, 0, 0, 3 * size, 2 * size); + + renderer.setRenderTarget(cubeUVRenderTarget); + renderer.render(mesh, _flatCamera); + } + + _applyPMREM(cubeUVRenderTarget) { + const renderer = this._renderer; + const autoClear = renderer.autoClear; + renderer.autoClear = false; + const n = this._lodPlanes.length; + + for (let i = 1; i < n; i++) { + const sigma = Math.sqrt(this._sigmas[i] * this._sigmas[i] - this._sigmas[i - 1] * this._sigmas[i - 1]); + + const poleAxis = _axisDirections[(n - i - 1) % _axisDirections.length]; + + this._blur(cubeUVRenderTarget, i - 1, i, sigma, poleAxis); + } + + renderer.autoClear = autoClear; + } + + /** + * This is a two-pass Gaussian blur for a cubemap. Normally this is done + * vertically and horizontally, but this breaks down on a cube. Here we apply + * the blur latitudinally (around the poles), and then longitudinally (towards + * the poles) to approximate the orthogonally-separable blur. It is least + * accurate at the poles, but still does a decent job. + */ + _blur(cubeUVRenderTarget, lodIn, lodOut, sigma, poleAxis) { + const pingPongRenderTarget = this._pingPongRenderTarget; + + this._halfBlur(cubeUVRenderTarget, pingPongRenderTarget, lodIn, lodOut, sigma, 'latitudinal', poleAxis); + + this._halfBlur(pingPongRenderTarget, cubeUVRenderTarget, lodOut, lodOut, sigma, 'longitudinal', poleAxis); + } + + _halfBlur(targetIn, targetOut, lodIn, lodOut, sigmaRadians, direction, poleAxis) { + const renderer = this._renderer; + const blurMaterial = this._blurMaterial; + + if (direction !== 'latitudinal' && direction !== 'longitudinal') { + console.error('blur direction must be either latitudinal or longitudinal!'); + } + + // Number of standard deviations at which to cut off the discrete approximation. + const STANDARD_DEVIATIONS = 3; + + const blurMesh = this._lodMeshes[lodOut]; + blurMesh.material = blurMaterial; + + const blurUniforms = blurMaterial.uniforms; + + const pixels = this._sizeLods[lodIn] - 1; + const radiansPerPixel = isFinite(sigmaRadians) ? Math.PI / (2 * pixels) : (2 * Math.PI) / (2 * MAX_SAMPLES - 1); + const sigmaPixels = sigmaRadians / radiansPerPixel; + const samples = isFinite(sigmaRadians) ? 1 + Math.floor(STANDARD_DEVIATIONS * sigmaPixels) : MAX_SAMPLES; + + if (samples > MAX_SAMPLES) { + console.warn( + `sigmaRadians, ${sigmaRadians}, is too large and will clip, as it requested ${ + samples + } samples when the maximum is set to ${MAX_SAMPLES}`, + ); + } + + const weights = []; + let sum = 0; + + for (let i = 0; i < MAX_SAMPLES; ++i) { + const x = i / sigmaPixels; + const weight = Math.exp((-x * x) / 2); + weights.push(weight); + + if (i === 0) { + sum += weight; + } else if (i < samples) { + sum += 2 * weight; + } + } + + for (let i = 0; i < weights.length; i++) { + weights[i] = weights[i] / sum; + } + + targetIn.texture.frame = (targetIn.texture.frame || 0) + 1; + + blurUniforms.envMap.value = targetIn.texture; + blurUniforms.samples.value = samples; + blurUniforms.weights.array = weights; + blurUniforms.latitudinal.value = direction === 'latitudinal' ? 1 : 0; + + if (poleAxis) { + blurUniforms.poleAxis.value = poleAxis; + } + + const { _lodMax } = this; + blurUniforms.dTheta.value = radiansPerPixel; + blurUniforms.mipInt.value = _lodMax - lodIn; + + const outputSize = this._sizeLods[lodOut]; + const x = 3 * outputSize * (lodOut > _lodMax - LOD_MIN ? lodOut - _lodMax + LOD_MIN : 0); + const y = 4 * (this._cubeSize - outputSize); + + _setViewport(targetOut, x, y, 3 * outputSize, 2 * outputSize); + renderer.setRenderTarget(targetOut); + renderer.render(blurMesh, _flatCamera); + } +} + +function _createPlanes(lodMax) { + const lodPlanes = []; + const sizeLods = []; + const sigmas = []; + const lodMeshes = []; + + let lod = lodMax; + + const totalLods = lodMax - LOD_MIN + 1 + EXTRA_LOD_SIGMA.length; + + for (let i = 0; i < totalLods; i++) { + const sizeLod = Math.pow(2, lod); + sizeLods.push(sizeLod); + let sigma = 1.0 / sizeLod; + + if (i > lodMax - LOD_MIN) { + sigma = EXTRA_LOD_SIGMA[i - lodMax + LOD_MIN - 1]; + } else if (i === 0) { + sigma = 0; + } + + sigmas.push(sigma); + + const texelSize = 1.0 / (sizeLod - 2); + const min = -texelSize; + const max = 1 + texelSize; + const uv1 = [min, min, max, min, max, max, min, min, max, max, min, max]; + + const cubeFaces = 6; + const vertices = 6; + const positionSize = 3; + const uvSize = 2; + const faceIndexSize = 1; + + const position = new Float32Array(positionSize * vertices * cubeFaces); + const uv = new Float32Array(uvSize * vertices * cubeFaces); + const faceIndex = new Float32Array(faceIndexSize * vertices * cubeFaces); + + for (let face = 0; face < cubeFaces; face++) { + const x = ((face % 3) * 2) / 3 - 1; + const y = face > 2 ? 0 : -1; + const coordinates = [ + x, + y, + 0, + x + 2 / 3, + y, + 0, + x + 2 / 3, + y + 1, + 0, + x, + y, + 0, + x + 2 / 3, + y + 1, + 0, + x, + y + 1, + 0, + ]; + + const faceIdx = _faceLib[face]; + position.set(coordinates, positionSize * vertices * faceIdx); + uv.set(uv1, uvSize * vertices * faceIdx); + const fill = [faceIdx, faceIdx, faceIdx, faceIdx, faceIdx, faceIdx]; + faceIndex.set(fill, faceIndexSize * vertices * faceIdx); + } + + const planes = new BufferGeometry(); + planes.setAttribute('position', new BufferAttribute(position, positionSize)); + planes.setAttribute('uv', new BufferAttribute(uv, uvSize)); + planes.setAttribute('faceIndex', new BufferAttribute(faceIndex, faceIndexSize)); + lodPlanes.push(planes); + lodMeshes.push(new Mesh(planes, null)); + + if (lod > LOD_MIN) { + lod--; + } + } + + return { lodPlanes, sizeLods, sigmas, lodMeshes }; +} + +function _createRenderTarget(width, height, params) { + const cubeUVRenderTarget = new RenderTarget(width, height, params); + cubeUVRenderTarget.texture.mapping = CubeUVReflectionMapping; + cubeUVRenderTarget.texture.name = 'PMREM.cubeUv'; + cubeUVRenderTarget.texture.isPMREMTexture = true; + cubeUVRenderTarget.scissorTest = true; + return cubeUVRenderTarget; +} + +function _setViewport(target, x, y, width, height) { + target.viewport.set(x, y, width, height); + target.scissor.set(x, y, width, height); +} + +function _getMaterial(type) { + const material = new NodeMaterial(); + material.depthTest = false; + material.depthWrite = false; + material.blending = NoBlending; + material.name = `PMREM_${type}`; + + return material; +} + +function _getBlurShader(lodMax, width, height) { + const weights = uniformArray(new Array(MAX_SAMPLES).fill(0)); + const poleAxis = uniform(new Vector3(0, 1, 0)); + const dTheta = uniform(0); + const n = float(MAX_SAMPLES); + const latitudinal = uniform(0); // false, bool + const samples = uniform(1); // int + const envMap = texture(null); + const mipInt = uniform(0); // int + const CUBEUV_TEXEL_WIDTH = float(1 / width); + const CUBEUV_TEXEL_HEIGHT = float(1 / height); + const CUBEUV_MAX_MIP = float(lodMax); + + const materialUniforms = { + n, + latitudinal, + weights, + poleAxis, + outputDirection, + dTheta, + samples, + envMap, + mipInt, + CUBEUV_TEXEL_WIDTH, + CUBEUV_TEXEL_HEIGHT, + CUBEUV_MAX_MIP, + }; + + const material = _getMaterial('blur'); + material.uniforms = materialUniforms; // TODO: Move to outside of the material + material.fragmentNode = blur({ ...materialUniforms, latitudinal: latitudinal.equal(1) }); + + return material; +} + +function _getCubemapMaterial(envTexture) { + const material = _getMaterial('cubemap'); + material.fragmentNode = cubeTexture(envTexture, outputDirection); + + return material; +} + +function _getEquirectMaterial(envTexture) { + const material = _getMaterial('equirect'); + material.fragmentNode = texture(envTexture, equirectUV(outputDirection), 0); + + return material; +} + +export default PMREMGenerator; diff --git a/src-testing/src/renderers/common/nodes/NodeBuilderState.ts b/src-testing/src/renderers/common/nodes/NodeBuilderState.ts new file mode 100644 index 000000000..520a3c918 --- /dev/null +++ b/src-testing/src/renderers/common/nodes/NodeBuilderState.ts @@ -0,0 +1,55 @@ +import BindGroup from '../BindGroup.js'; + +class NodeBuilderState { + constructor( + vertexShader, + fragmentShader, + computeShader, + nodeAttributes, + bindings, + updateNodes, + updateBeforeNodes, + updateAfterNodes, + monitor, + transforms = [], + ) { + this.vertexShader = vertexShader; + this.fragmentShader = fragmentShader; + this.computeShader = computeShader; + this.transforms = transforms; + + this.nodeAttributes = nodeAttributes; + this.bindings = bindings; + + this.updateNodes = updateNodes; + this.updateBeforeNodes = updateBeforeNodes; + this.updateAfterNodes = updateAfterNodes; + + this.monitor = monitor; + + this.usedTimes = 0; + } + + createBindings() { + const bindings = []; + + for (const instanceGroup of this.bindings) { + const shared = instanceGroup.bindings[0].groupNode.shared; + + if (shared !== true) { + const bindingsGroup = new BindGroup(instanceGroup.name, [], instanceGroup.index, instanceGroup); + bindings.push(bindingsGroup); + + for (const instanceBinding of instanceGroup.bindings) { + bindingsGroup.bindings.push(instanceBinding.clone()); + } + } else { + bindings.push(instanceGroup); + } + } + + return bindings; + } +} + +export default NodeBuilderState; diff --git a/src-testing/src/renderers/common/nodes/NodeLibrary.ts b/src-testing/src/renderers/common/nodes/NodeLibrary.ts new file mode 100644 index 000000000..b6738b95a --- /dev/null +++ b/src-testing/src/renderers/common/nodes/NodeLibrary.ts @@ -0,0 +1,76 @@ +class NodeLibrary { + constructor() { + this.lightNodes = new WeakMap(); + this.materialNodes = new Map(); + this.toneMappingNodes = new Map(); + } + + fromMaterial(material) { + if (material.isNodeMaterial) return material; + + let nodeMaterial = null; + + const nodeMaterialClass = this.getMaterialNodeClass(material.type); + + if (nodeMaterialClass !== null) { + nodeMaterial = new nodeMaterialClass(); + + for (const key in material) { + nodeMaterial[key] = material[key]; + } + } + + return nodeMaterial; + } + + addToneMapping(toneMappingNode, toneMapping) { + this.addType(toneMappingNode, toneMapping, this.toneMappingNodes); + } + + getToneMappingFunction(toneMapping) { + return this.toneMappingNodes.get(toneMapping) || null; + } + + getMaterialNodeClass(materialType) { + return this.materialNodes.get(materialType) || null; + } + + addMaterial(materialNodeClass, materialClass) { + this.addType(materialNodeClass, materialClass.type, this.materialNodes); + } + + getLightNodeClass(light) { + return this.lightNodes.get(light) || null; + } + + addLight(lightNodeClass, lightClass) { + this.addClass(lightNodeClass, lightClass, this.lightNodes); + } + + addType(nodeClass, type, library) { + if (library.has(type)) { + console.warn(`Redefinition of node ${type}`); + return; + } + + if (typeof nodeClass !== 'function') throw new Error(`Node class ${nodeClass.name} is not a class.`); + if (typeof type === 'function' || typeof type === 'object') + throw new Error(`Base class ${type} is not a class.`); + + library.set(type, nodeClass); + } + + addClass(nodeClass, baseClass, library) { + if (library.has(baseClass)) { + console.warn(`Redefinition of node ${baseClass.name}`); + return; + } + + if (typeof nodeClass !== 'function') throw new Error(`Node class ${nodeClass.name} is not a class.`); + if (typeof baseClass !== 'function') throw new Error(`Base class ${baseClass.name} is not a class.`); + + library.set(baseClass, nodeClass); + } +} + +export default NodeLibrary; diff --git a/src-testing/src/renderers/common/nodes/NodeSampledTexture.d.ts b/src-testing/src/renderers/common/nodes/NodeSampledTexture.d.ts new file mode 100644 index 000000000..97c3c3adf --- /dev/null +++ b/src-testing/src/renderers/common/nodes/NodeSampledTexture.d.ts @@ -0,0 +1,29 @@ +import TextureNode from "../../../nodes/accessors/TextureNode.js"; +import UniformGroupNode from "../../../nodes/core/UniformGroupNode.js"; +import { SampledTexture } from "../SampledTexture.js"; + +type GPUStorageTextureAccess = "read-only" | "read-write" | "write-only"; + +declare class NodeSampledTexture extends SampledTexture { + textureNode: TextureNode | undefined; + groupNode: UniformGroupNode; + + access: "read-write" | "read-only" | "write-only"; + + constructor( + name: string, + textureNode: TextureNode | undefined, + groupNode: UniformGroupNode, + access?: GPUStorageTextureAccess | null, + ); +} + +declare class NodeSampledCubeTexture extends NodeSampledTexture { + readonly isSampledCubeTexture: true; +} + +declare class NodeSampledTexture3D extends NodeSampledTexture { + readonly isSampledTexture3D = true; +} + +export { NodeSampledCubeTexture, NodeSampledTexture, NodeSampledTexture3D }; diff --git a/src-testing/src/renderers/common/nodes/NodeSampler.d.ts b/src-testing/src/renderers/common/nodes/NodeSampler.d.ts new file mode 100644 index 000000000..60db177d5 --- /dev/null +++ b/src-testing/src/renderers/common/nodes/NodeSampler.d.ts @@ -0,0 +1,12 @@ +import TextureNode from "../../../nodes/accessors/TextureNode.js"; +import UniformGroupNode from "../../../nodes/core/UniformGroupNode.js"; +import Sampler from "../Sampler.js"; + +declare class NodeSampler extends Sampler { + textureNode: TextureNode | undefined; + groupNode: UniformGroupNode; + constructor(name: string, textureNode: TextureNode | undefined, groupNode: UniformGroupNode); + update(): void; +} + +export default NodeSampler; diff --git a/src-testing/src/renderers/common/nodes/NodeUniform.ts b/src-testing/src/renderers/common/nodes/NodeUniform.ts new file mode 100644 index 000000000..659f5a82f --- /dev/null +++ b/src-testing/src/renderers/common/nodes/NodeUniform.ts @@ -0,0 +1,103 @@ +import { + NumberUniform, + Vector2Uniform, + Vector3Uniform, + Vector4Uniform, + ColorUniform, + Matrix3Uniform, + Matrix4Uniform, +} from '../Uniform.js'; + +class NumberNodeUniform extends NumberUniform { + constructor(nodeUniform) { + super(nodeUniform.name, nodeUniform.value); + + this.nodeUniform = nodeUniform; + } + + getValue() { + return this.nodeUniform.value; + } +} + +class Vector2NodeUniform extends Vector2Uniform { + constructor(nodeUniform) { + super(nodeUniform.name, nodeUniform.value); + + this.nodeUniform = nodeUniform; + } + + getValue() { + return this.nodeUniform.value; + } +} + +class Vector3NodeUniform extends Vector3Uniform { + constructor(nodeUniform) { + super(nodeUniform.name, nodeUniform.value); + + this.nodeUniform = nodeUniform; + } + + getValue() { + return this.nodeUniform.value; + } +} + +class Vector4NodeUniform extends Vector4Uniform { + constructor(nodeUniform) { + super(nodeUniform.name, nodeUniform.value); + + this.nodeUniform = nodeUniform; + } + + getValue() { + return this.nodeUniform.value; + } +} + +class ColorNodeUniform extends ColorUniform { + constructor(nodeUniform) { + super(nodeUniform.name, nodeUniform.value); + + this.nodeUniform = nodeUniform; + } + + getValue() { + return this.nodeUniform.value; + } +} + +class Matrix3NodeUniform extends Matrix3Uniform { + constructor(nodeUniform) { + super(nodeUniform.name, nodeUniform.value); + + this.nodeUniform = nodeUniform; + } + + getValue() { + return this.nodeUniform.value; + } +} + +class Matrix4NodeUniform extends Matrix4Uniform { + constructor(nodeUniform) { + super(nodeUniform.name, nodeUniform.value); + + this.nodeUniform = nodeUniform; + } + + getValue() { + return this.nodeUniform.value; + } +} + +export { + NumberNodeUniform, + Vector2NodeUniform, + Vector3NodeUniform, + Vector4NodeUniform, + ColorNodeUniform, + Matrix3NodeUniform, + Matrix4NodeUniform, +}; diff --git a/src-testing/src/renderers/common/nodes/NodeUniformsGroup.ts b/src-testing/src/renderers/common/nodes/NodeUniformsGroup.ts new file mode 100644 index 000000000..d2d92cb20 --- /dev/null +++ b/src-testing/src/renderers/common/nodes/NodeUniformsGroup.ts @@ -0,0 +1,30 @@ +import UniformsGroup from '../UniformsGroup.js'; + +let _id = 0; + +class NodeUniformsGroup extends UniformsGroup { + constructor(name, groupNode) { + super(name); + + this.id = _id++; + this.groupNode = groupNode; + + this.isNodeUniformsGroup = true; + } + + getNodes() { + const nodes = []; + + for (const uniform of this.uniforms) { + const node = uniform.nodeUniform.node; + + if (!node) throw new Error('NodeUniformsGroup: Uniform has no node.'); + + nodes.push(node); + } + + return nodes; + } +} + +export default NodeUniformsGroup; diff --git a/src-testing/src/renderers/common/nodes/Nodes.ts b/src-testing/src/renderers/common/nodes/Nodes.ts new file mode 100644 index 000000000..f409c2b15 --- /dev/null +++ b/src-testing/src/renderers/common/nodes/Nodes.ts @@ -0,0 +1,433 @@ +import DataMap from '../DataMap.js'; +import ChainMap from '../ChainMap.js'; +import NodeBuilderState from './NodeBuilderState.js'; +import { cubeMapNode } from '../../../nodes/utils/CubeMapNode.js'; +import { NodeFrame } from '../../../nodes/Nodes.js'; +import { + objectGroup, + renderGroup, + frameGroup, + cubeTexture, + texture, + rangeFog, + densityFog, + reference, + normalWorld, + pmremTexture, + screenUV, +} from '../../../nodes/TSL.js'; + +import { + CubeUVReflectionMapping, + EquirectangularReflectionMapping, + EquirectangularRefractionMapping, +} from '../../../constants.js'; +import { hashArray } from '../../../nodes/core/NodeUtils.js'; + +const outputNodeMap = new WeakMap(); + +class Nodes extends DataMap { + constructor(renderer, backend) { + super(); + + this.renderer = renderer; + this.backend = backend; + this.nodeFrame = new NodeFrame(); + this.nodeBuilderCache = new Map(); + this.callHashCache = new ChainMap(); + this.groupsData = new ChainMap(); + } + + updateGroup(nodeUniformsGroup) { + const groupNode = nodeUniformsGroup.groupNode; + const name = groupNode.name; + + // objectGroup is every updated + + if (name === objectGroup.name) return true; + + // renderGroup is updated once per render/compute call + + if (name === renderGroup.name) { + const uniformsGroupData = this.get(nodeUniformsGroup); + const renderId = this.nodeFrame.renderId; + + if (uniformsGroupData.renderId !== renderId) { + uniformsGroupData.renderId = renderId; + + return true; + } + + return false; + } + + // frameGroup is updated once per frame + + if (name === frameGroup.name) { + const uniformsGroupData = this.get(nodeUniformsGroup); + const frameId = this.nodeFrame.frameId; + + if (uniformsGroupData.frameId !== frameId) { + uniformsGroupData.frameId = frameId; + + return true; + } + + return false; + } + + // other groups are updated just when groupNode.needsUpdate is true + + const groupChain = [groupNode, nodeUniformsGroup]; + + let groupData = this.groupsData.get(groupChain); + if (groupData === undefined) this.groupsData.set(groupChain, (groupData = {})); + + if (groupData.version !== groupNode.version) { + groupData.version = groupNode.version; + + return true; + } + + return false; + } + + getForRenderCacheKey(renderObject) { + return renderObject.initialCacheKey; + } + + getForRender(renderObject) { + const renderObjectData = this.get(renderObject); + + let nodeBuilderState = renderObjectData.nodeBuilderState; + + if (nodeBuilderState === undefined) { + const { nodeBuilderCache } = this; + + const cacheKey = this.getForRenderCacheKey(renderObject); + + nodeBuilderState = nodeBuilderCache.get(cacheKey); + + if (nodeBuilderState === undefined) { + const nodeBuilder = this.backend.createNodeBuilder(renderObject.object, this.renderer); + nodeBuilder.scene = renderObject.scene; + nodeBuilder.material = renderObject.material; + nodeBuilder.camera = renderObject.camera; + nodeBuilder.context.material = renderObject.material; + nodeBuilder.lightsNode = renderObject.lightsNode; + nodeBuilder.environmentNode = this.getEnvironmentNode(renderObject.scene); + nodeBuilder.fogNode = this.getFogNode(renderObject.scene); + nodeBuilder.clippingContext = renderObject.clippingContext; + nodeBuilder.build(); + + nodeBuilderState = this._createNodeBuilderState(nodeBuilder); + + nodeBuilderCache.set(cacheKey, nodeBuilderState); + } + + nodeBuilderState.usedTimes++; + + renderObjectData.nodeBuilderState = nodeBuilderState; + } + + return nodeBuilderState; + } + + delete(object) { + if (object.isRenderObject) { + const nodeBuilderState = this.get(object).nodeBuilderState; + nodeBuilderState.usedTimes--; + + if (nodeBuilderState.usedTimes === 0) { + this.nodeBuilderCache.delete(this.getForRenderCacheKey(object)); + } + } + + return super.delete(object); + } + + getForCompute(computeNode) { + const computeData = this.get(computeNode); + + let nodeBuilderState = computeData.nodeBuilderState; + + if (nodeBuilderState === undefined) { + const nodeBuilder = this.backend.createNodeBuilder(computeNode, this.renderer); + nodeBuilder.build(); + + nodeBuilderState = this._createNodeBuilderState(nodeBuilder); + + computeData.nodeBuilderState = nodeBuilderState; + } + + return nodeBuilderState; + } + + _createNodeBuilderState(nodeBuilder) { + return new NodeBuilderState( + nodeBuilder.vertexShader, + nodeBuilder.fragmentShader, + nodeBuilder.computeShader, + nodeBuilder.getAttributesArray(), + nodeBuilder.getBindings(), + nodeBuilder.updateNodes, + nodeBuilder.updateBeforeNodes, + nodeBuilder.updateAfterNodes, + nodeBuilder.monitor, + nodeBuilder.transforms, + ); + } + + getEnvironmentNode(scene) { + return scene.environmentNode || this.get(scene).environmentNode || null; + } + + getBackgroundNode(scene) { + return scene.backgroundNode || this.get(scene).backgroundNode || null; + } + + getFogNode(scene) { + return scene.fogNode || this.get(scene).fogNode || null; + } + + getCacheKey(scene, lightsNode) { + const chain = [scene, lightsNode]; + const callId = this.renderer.info.calls; + + let cacheKeyData = this.callHashCache.get(chain); + + if (cacheKeyData === undefined || cacheKeyData.callId !== callId) { + const environmentNode = this.getEnvironmentNode(scene); + const fogNode = this.getFogNode(scene); + + const values = []; + + if (lightsNode) values.push(lightsNode.getCacheKey(true)); + if (environmentNode) values.push(environmentNode.getCacheKey()); + if (fogNode) values.push(fogNode.getCacheKey()); + + values.push(this.renderer.shadowMap.enabled ? 1 : 0); + + cacheKeyData = { + callId, + cacheKey: hashArray(values), + }; + + this.callHashCache.set(chain, cacheKeyData); + } + + return cacheKeyData.cacheKey; + } + + updateScene(scene) { + this.updateEnvironment(scene); + this.updateFog(scene); + this.updateBackground(scene); + } + + get isToneMappingState() { + return this.renderer.getRenderTarget() ? false : true; + } + + updateBackground(scene) { + const sceneData = this.get(scene); + const background = scene.background; + + if (background) { + const forceUpdate = + (scene.backgroundBlurriness === 0 && sceneData.backgroundBlurriness > 0) || + (scene.backgroundBlurriness > 0 && sceneData.backgroundBlurriness === 0); + + if (sceneData.background !== background || forceUpdate) { + let backgroundNode = null; + + if ( + background.isCubeTexture === true || + background.mapping === EquirectangularReflectionMapping || + background.mapping === EquirectangularRefractionMapping || + background.mapping === CubeUVReflectionMapping + ) { + if (scene.backgroundBlurriness > 0 || background.mapping === CubeUVReflectionMapping) { + backgroundNode = pmremTexture(background, normalWorld); + } else { + let envMap; + + if (background.isCubeTexture === true) { + envMap = cubeTexture(background); + } else { + envMap = texture(background); + } + + backgroundNode = cubeMapNode(envMap); + } + } else if (background.isTexture === true) { + backgroundNode = texture(background, screenUV.flipY()).setUpdateMatrix(true); + } else if (background.isColor !== true) { + console.error('WebGPUNodes: Unsupported background configuration.', background); + } + + sceneData.backgroundNode = backgroundNode; + sceneData.background = background; + sceneData.backgroundBlurriness = scene.backgroundBlurriness; + } + } else if (sceneData.backgroundNode) { + delete sceneData.backgroundNode; + delete sceneData.background; + } + } + + updateFog(scene) { + const sceneData = this.get(scene); + const fog = scene.fog; + + if (fog) { + if (sceneData.fog !== fog) { + let fogNode = null; + + if (fog.isFogExp2) { + const color = reference('color', 'color', fog).setGroup(renderGroup); + const density = reference('density', 'float', fog).setGroup(renderGroup); + + fogNode = densityFog(color, density); + } else if (fog.isFog) { + const color = reference('color', 'color', fog).setGroup(renderGroup); + const near = reference('near', 'float', fog).setGroup(renderGroup); + const far = reference('far', 'float', fog).setGroup(renderGroup); + + fogNode = rangeFog(color, near, far); + } else { + console.error('WebGPUNodes: Unsupported fog configuration.', fog); + } + + sceneData.fogNode = fogNode; + sceneData.fog = fog; + } + } else { + delete sceneData.fogNode; + delete sceneData.fog; + } + } + + updateEnvironment(scene) { + const sceneData = this.get(scene); + const environment = scene.environment; + + if (environment) { + if (sceneData.environment !== environment) { + let environmentNode = null; + + if (environment.isCubeTexture === true) { + environmentNode = cubeTexture(environment); + } else if (environment.isTexture === true) { + environmentNode = texture(environment); + } else { + console.error('Nodes: Unsupported environment configuration.', environment); + } + + sceneData.environmentNode = environmentNode; + sceneData.environment = environment; + } + } else if (sceneData.environmentNode) { + delete sceneData.environmentNode; + delete sceneData.environment; + } + } + + getNodeFrame(renderer = this.renderer, scene = null, object = null, camera = null, material = null) { + const nodeFrame = this.nodeFrame; + nodeFrame.renderer = renderer; + nodeFrame.scene = scene; + nodeFrame.object = object; + nodeFrame.camera = camera; + nodeFrame.material = material; + + return nodeFrame; + } + + getNodeFrameForRender(renderObject) { + return this.getNodeFrame( + renderObject.renderer, + renderObject.scene, + renderObject.object, + renderObject.camera, + renderObject.material, + ); + } + + getOutputCacheKey() { + const renderer = this.renderer; + + return renderer.toneMapping + ',' + renderer.currentColorSpace; + } + + hasOutputChange(outputTarget) { + const cacheKey = outputNodeMap.get(outputTarget); + + return cacheKey !== this.getOutputCacheKey(); + } + + getOutputNode(outputTexture) { + const renderer = this.renderer; + const cacheKey = this.getOutputCacheKey(); + + const output = texture(outputTexture, screenUV).renderOutput(renderer.toneMapping, renderer.currentColorSpace); + + outputNodeMap.set(outputTexture, cacheKey); + + return output; + } + + updateBefore(renderObject) { + const nodeBuilder = renderObject.getNodeBuilderState(); + + for (const node of nodeBuilder.updateBeforeNodes) { + // update frame state for each node + + this.getNodeFrameForRender(renderObject).updateBeforeNode(node); + } + } + + updateAfter(renderObject) { + const nodeBuilder = renderObject.getNodeBuilderState(); + + for (const node of nodeBuilder.updateAfterNodes) { + // update frame state for each node + + this.getNodeFrameForRender(renderObject).updateAfterNode(node); + } + } + + updateForCompute(computeNode) { + const nodeFrame = this.getNodeFrame(); + const nodeBuilder = this.getForCompute(computeNode); + + for (const node of nodeBuilder.updateNodes) { + nodeFrame.updateNode(node); + } + } + + updateForRender(renderObject) { + const nodeFrame = this.getNodeFrameForRender(renderObject); + const nodeBuilder = renderObject.getNodeBuilderState(); + + for (const node of nodeBuilder.updateNodes) { + nodeFrame.updateNode(node); + } + } + + needsRefresh(renderObject) { + const nodeFrame = this.getNodeFrameForRender(renderObject); + const monitor = renderObject.getMonitor(); + + return monitor.needsRefresh(renderObject, nodeFrame); + } + + dispose() { + super.dispose(); + + this.nodeFrame = new NodeFrame(); + this.nodeBuilderCache = new Map(); + } +} + +export default Nodes; diff --git a/src-testing/src/renderers/common/nodes/StandardNodeLibrary.d.ts b/src-testing/src/renderers/common/nodes/StandardNodeLibrary.d.ts new file mode 100644 index 000000000..d7db44562 --- /dev/null +++ b/src-testing/src/renderers/common/nodes/StandardNodeLibrary.d.ts @@ -0,0 +1,5 @@ +import NodeLibrary from "./NodeLibrary.js"; +declare class StandardNodeLibrary extends NodeLibrary { + constructor(); +} +export default StandardNodeLibrary; diff --git a/src-testing/src/renderers/shaders/ShaderChunk.d.ts b/src-testing/src/renderers/shaders/ShaderChunk.d.ts new file mode 100644 index 000000000..caf4e39bb --- /dev/null +++ b/src-testing/src/renderers/shaders/ShaderChunk.d.ts @@ -0,0 +1,143 @@ +// Renderers / Shaders ///////////////////////////////////////////////////////////////////// +export const ShaderChunk: { + alphahash_fragment: string; + alphahash_pars_fragment: string; + alphamap_fragment: string; + alphamap_pars_fragment: string; + alphatest_fragment: string; + alphatest_pars_fragment: string; + aomap_fragment: string; + aomap_pars_fragment: string; + batching_pars_vertex: string; + begin_vertex: string; + beginnormal_vertex: string; + bsdfs: string; + iridescence_fragment: string; + bumpmap_pars_fragment: string; + clipping_planes_fragment: string; + clipping_planes_pars_fragment: string; + clipping_planes_pars_vertex: string; + clipping_planes_vertex: string; + color_fragment: string; + color_pars_fragment: string; + color_pars_vertex: string; + color_vertex: string; + common: string; + cube_uv_reflection_fragment: string; + defaultnormal_vertex: string; + displacementmap_pars_vertex: string; + displacementmap_vertex: string; + emissivemap_fragment: string; + emissivemap_pars_fragment: string; + colorspace_fragment: string; + colorspace_pars_fragment: string; + envmap_fragment: string; + envmap_common_pars_fragment: string; + envmap_pars_fragment: string; + envmap_pars_vertex: string; + envmap_physical_pars_fragment: string; + envmap_vertex: string; + fog_vertex: string; + fog_pars_vertex: string; + fog_fragment: string; + fog_pars_fragment: string; + gradientmap_pars_fragment: string; + lightmap_pars_fragment: string; + lights_lambert_fragment: string; + lights_lambert_pars_fragment: string; + lights_pars_begin: string; + lights_toon_fragment: string; + lights_toon_pars_fragment: string; + lights_phong_fragment: string; + lights_phong_pars_fragment: string; + lights_physical_fragment: string; + lights_physical_pars_fragment: string; + lights_fragment_begin: string; + lights_fragment_maps: string; + lights_fragment_end: string; + logdepthbuf_fragment: string; + logdepthbuf_pars_fragment: string; + logdepthbuf_pars_vertex: string; + logdepthbuf_vertex: string; + map_fragment: string; + map_pars_fragment: string; + map_particle_fragment: string; + map_particle_pars_fragment: string; + metalnessmap_fragment: string; + metalnessmap_pars_fragment: string; + morphcolor_vertex: string; + morphnormal_vertex: string; + morphtarget_pars_vertex: string; + morphtarget_vertex: string; + normal_fragment_begin: string; + normal_fragment_maps: string; + normal_pars_fragment: string; + normal_pars_vertex: string; + normal_vertex: string; + normalmap_pars_fragment: string; + clearcoat_normal_fragment_begin: string; + clearcoat_normal_fragment_maps: string; + clearcoat_pars_fragment: string; + iridescence_pars_fragment: string; + opaque_fragment: string; + packing: string; + premultiplied_alpha_fragment: string; + project_vertex: string; + dithering_fragment: string; + dithering_pars_fragment: string; + roughnessmap_fragment: string; + roughnessmap_pars_fragment: string; + shadowmap_pars_fragment: string; + shadowmap_pars_vertex: string; + shadowmap_vertex: string; + shadowmask_pars_fragment: string; + skinbase_vertex: string; + skinning_pars_vertex: string; + skinning_vertex: string; + skinnormal_vertex: string; + specularmap_fragment: string; + specularmap_pars_fragment: string; + tonemapping_fragment: string; + tonemapping_pars_fragment: string; + transmission_fragment: string; + transmission_pars_fragment: string; + uv_pars_fragment: string; + uv_pars_vertex: string; + uv_vertex: string; + worldpos_vertex: string; + + background_vert: string; + background_frag: string; + backgroundCube_vert: string; + backgroundCube_frag: string; + cube_vert: string; + cube_frag: string; + depth_vert: string; + depth_frag: string; + distanceRGBA_vert: string; + distanceRGBA_frag: string; + equirect_vert: string; + equirect_frag: string; + linedashed_vert: string; + linedashed_frag: string; + meshbasic_vert: string; + meshbasic_frag: string; + meshlambert_vert: string; + meshlambert_frag: string; + meshmatcap_vert: string; + meshmatcap_frag: string; + meshnormal_vert: string; + meshnormal_frag: string; + meshphong_vert: string; + meshphong_frag: string; + meshphysical_vert: string; + meshphysical_frag: string; + meshtoon_vert: string; + meshtoon_frag: string; + points_vert: string; + points_frag: string; + shadow_vert: string; + shadow_frag: string; + sprite_vert: string; + sprite_frag: string; +}; diff --git a/src-testing/src/renderers/shaders/ShaderLib.d.ts b/src-testing/src/renderers/shaders/ShaderLib.d.ts new file mode 100644 index 000000000..9a52c4dcd --- /dev/null +++ b/src-testing/src/renderers/shaders/ShaderLib.d.ts @@ -0,0 +1,29 @@ +import { IUniform } from "./UniformsLib.js"; + +export interface ShaderLibShader { + uniforms: { [uniform: string]: IUniform }; + vertexShader: string; + fragmentShader: string; +} + +declare const ShaderLib: { + [name: string]: ShaderLibShader; + basic: ShaderLibShader; + lambert: ShaderLibShader; + phong: ShaderLibShader; + standard: ShaderLibShader; + matcap: ShaderLibShader; + points: ShaderLibShader; + dashed: ShaderLibShader; + depth: ShaderLibShader; + normal: ShaderLibShader; + sprite: ShaderLibShader; + background: ShaderLibShader; + cube: ShaderLibShader; + equirect: ShaderLibShader; + distanceRGBA: ShaderLibShader; + shadow: ShaderLibShader; + physical: ShaderLibShader; +}; + +export { ShaderLib }; diff --git a/src-testing/src/renderers/shaders/UniformsLib.d.ts b/src-testing/src/renderers/shaders/UniformsLib.d.ts new file mode 100644 index 000000000..cb0d808bd --- /dev/null +++ b/src-testing/src/renderers/shaders/UniformsLib.d.ts @@ -0,0 +1,189 @@ +import { Color } from "../../math/Color.js"; +import { Matrix3 } from "../../math/Matrix3.js"; +import { Vector2 } from "../../math/Vector2.js"; + +// eslint-disable-next-line @typescript-eslint/naming-convention +export interface IUniform { + value: TValue; +} + +export const UniformsLib: { + common: { + diffuse: IUniform; + opacity: IUniform; + map: IUniform; + mapTransform: IUniform; + alphaMap: IUniform; + alphaMapTransform: IUniform; + alphaTest: IUniform; + }; + specularmap: { + specularMap: IUniform; + specularMapTransform: IUniform; + }; + envmap: { + envMap: IUniform; + envMapRotation: IUniform; + flipEnvMap: IUniform; + reflectivity: IUniform; + ior: IUniform; + refractRatio: IUniform; + }; + aomap: { + aoMap: IUniform; + aoMapIntensity: IUniform; + aoMapTransform: IUniform; + }; + lightmap: { + lightMap: IUniform; + lightMapIntensity: IUniform; + lightMapTransform: IUniform; + }; + bumpmap: { + bumpMap: IUniform; + bumpMapTransform: IUniform; + bumpScale: IUniform; + }; + normalmap: { + normalMap: IUniform; + normalMapTransform: IUniform; + normalScale: IUniform; + }; + displacementmap: { + displacementMap: IUniform; + displacementMapTransform: IUniform; + displacementScale: IUniform; + displacementBias: IUniform; + }; + emissivemap: { + emissiveMap: IUniform; + emissiveMapTransform: IUniform; + }; + metalnessmap: { + metalnessMap: IUniform; + metalnessMapTransform: IUniform; + }; + roughnessmap: { + roughnessMap: IUniform; + roughnessMapTransform: IUniform; + }; + gradientmap: { + gradientMap: IUniform; + }; + fog: { + fogDensity: IUniform; + fogNear: IUniform; + fogFar: IUniform; + fogColor: IUniform; + }; + lights: { + ambientLightColor: IUniform; + lightProbe: IUniform; + directionalLights: { + value: unknown[]; + properties: { + direction: {}; + color: {}; + }; + }; + directionalLightShadows: { + value: unknown[]; + properties: { + shadowIntensity: number; + shadowBias: {}; + shadowNormalBias: {}; + shadowRadius: {}; + shadowMapSize: {}; + }; + }; + directionalShadowMap: IUniform; + directionalShadowMatrix: IUniform; + spotLights: { + value: unknown[]; + properties: { + color: {}; + position: {}; + direction: {}; + distance: {}; + coneCos: {}; + penumbraCos: {}; + decay: {}; + }; + }; + spotLightShadows: { + value: unknown[]; + properties: { + shadowIntensity: number; + shadowBias: {}; + shadowNormalBias: {}; + shadowRadius: {}; + shadowMapSize: {}; + }; + }; + spotLightMap: IUniform; + spotShadowMap: IUniform; + spotLightMatrix: IUniform; + pointLights: { + value: unknown[]; + properties: { + color: {}; + position: {}; + decay: {}; + distance: {}; + }; + }; + pointLightShadows: { + value: unknown[]; + properties: { + shadowIntensity: number; + shadowBias: {}; + shadowNormalBias: {}; + shadowRadius: {}; + shadowMapSize: {}; + shadowCameraNear: {}; + shadowCameraFar: {}; + }; + }; + pointShadowMap: IUniform; + pointShadowMatrix: IUniform; + hemisphereLights: { + value: unknown[]; + properties: { + direction: {}; + skycolor: {}; + groundColor: {}; + }; + }; + rectAreaLights: { + value: unknown[]; + properties: { + color: {}; + position: {}; + width: {}; + height: {}; + }; + }; + ltc_1: IUniform; + ltc_2: IUniform; + }; + points: { + diffuse: IUniform; + opacity: IUniform; + size: IUniform; + scale: IUniform; + map: IUniform; + alphaMap: IUniform; + alphaTest: IUniform; + uvTransform: IUniform; + }; + sprite: { + diffuse: IUniform; + opacity: IUniform; + center: IUniform; + rotation: IUniform; + map: IUniform; + mapTransform: IUniform; + alphaMap: IUniform; + alphaTest: IUniform; + }; +}; diff --git a/src-testing/src/renderers/shaders/UniformsUtils.d.ts b/src-testing/src/renderers/shaders/UniformsUtils.d.ts new file mode 100644 index 000000000..fe5178d55 --- /dev/null +++ b/src-testing/src/renderers/shaders/UniformsUtils.d.ts @@ -0,0 +1,14 @@ +import { UniformsGroup } from "../../core/UniformsGroup.js"; +import { IUniform } from "./UniformsLib.js"; + +export function cloneUniforms(uniformsSrc: T): T; +export function mergeUniforms(uniforms: Array<{ [uniform: string]: IUniform }>): { [uniform: string]: IUniform }; + +export function cloneUniformsGroups(src: UniformsGroup[]): UniformsGroup[]; + +declare const UniformsUtils: { + clone: typeof cloneUniforms; + merge: typeof mergeUniforms; +}; + +export { UniformsUtils }; diff --git a/src-testing/src/renderers/webgl-fallback/WebGLBackend.ts b/src-testing/src/renderers/webgl-fallback/WebGLBackend.ts new file mode 100644 index 000000000..ccf00b986 --- /dev/null +++ b/src-testing/src/renderers/webgl-fallback/WebGLBackend.ts @@ -0,0 +1,1349 @@ +import GLSLNodeBuilder from './nodes/GLSLNodeBuilder.js'; +import Backend from '../common/Backend.js'; +import { getCacheKey } from '../common/RenderContext.js'; + +import WebGLAttributeUtils from './utils/WebGLAttributeUtils.js'; +import WebGLState from './utils/WebGLState.js'; +import WebGLUtils from './utils/WebGLUtils.js'; +import WebGLTextureUtils from './utils/WebGLTextureUtils.js'; +import WebGLExtensions from './utils/WebGLExtensions.js'; +import WebGLCapabilities from './utils/WebGLCapabilities.js'; +import { GLFeatureName } from './utils/WebGLConstants.js'; +import { WebGLBufferRenderer } from './WebGLBufferRenderer.js'; + +import { warnOnce } from '../../utils.js'; +import { WebGLCoordinateSystem } from '../../constants.js'; + +// + +class WebGLBackend extends Backend { + constructor(parameters = {}) { + super(parameters); + + this.isWebGLBackend = true; + } + + init(renderer) { + super.init(renderer); + + // + + const parameters = this.parameters; + + const glContext = + parameters.context !== undefined ? parameters.context : renderer.domElement.getContext('webgl2'); + + this.gl = glContext; + + this.extensions = new WebGLExtensions(this); + this.capabilities = new WebGLCapabilities(this); + this.attributeUtils = new WebGLAttributeUtils(this); + this.textureUtils = new WebGLTextureUtils(this); + this.bufferRenderer = new WebGLBufferRenderer(this); + + this.state = new WebGLState(this); + this.utils = new WebGLUtils(this); + + this.vaoCache = {}; + this.transformFeedbackCache = {}; + this.discard = false; + this.trackTimestamp = parameters.trackTimestamp === true; + + this.extensions.get('EXT_color_buffer_float'); + this.extensions.get('WEBGL_clip_cull_distance'); + this.extensions.get('OES_texture_float_linear'); + this.extensions.get('EXT_color_buffer_half_float'); + this.extensions.get('WEBGL_multisampled_render_to_texture'); + this.extensions.get('WEBGL_render_shared_exponent'); + this.extensions.get('WEBGL_multi_draw'); + + this.disjoint = this.extensions.get('EXT_disjoint_timer_query_webgl2'); + this.parallel = this.extensions.get('KHR_parallel_shader_compile'); + + this._knownBindings = new WeakSet(); + + this._currentContext = null; + } + + get coordinateSystem() { + return WebGLCoordinateSystem; + } + + async getArrayBufferAsync(attribute) { + return await this.attributeUtils.getArrayBufferAsync(attribute); + } + + async waitForGPU() { + await this.utils._clientWaitAsync(); + } + + initTimestampQuery(renderContext) { + if (!this.disjoint || !this.trackTimestamp) return; + + const renderContextData = this.get(renderContext); + + if (this.queryRunning) { + if (!renderContextData.queryQueue) renderContextData.queryQueue = []; + renderContextData.queryQueue.push(renderContext); + return; + } + + if (renderContextData.activeQuery) { + this.gl.endQuery(this.disjoint.TIME_ELAPSED_EXT); + renderContextData.activeQuery = null; + } + + renderContextData.activeQuery = this.gl.createQuery(); + + if (renderContextData.activeQuery !== null) { + this.gl.beginQuery(this.disjoint.TIME_ELAPSED_EXT, renderContextData.activeQuery); + this.queryRunning = true; + } + } + + // timestamp utils + + prepareTimestampBuffer(renderContext) { + if (!this.disjoint || !this.trackTimestamp) return; + + const renderContextData = this.get(renderContext); + + if (renderContextData.activeQuery) { + this.gl.endQuery(this.disjoint.TIME_ELAPSED_EXT); + + if (!renderContextData.gpuQueries) renderContextData.gpuQueries = []; + renderContextData.gpuQueries.push({ query: renderContextData.activeQuery }); + renderContextData.activeQuery = null; + this.queryRunning = false; + + if (renderContextData.queryQueue && renderContextData.queryQueue.length > 0) { + const nextRenderContext = renderContextData.queryQueue.shift(); + this.initTimestampQuery(nextRenderContext); + } + } + } + + async resolveTimestampAsync(renderContext, type = 'render') { + if (!this.disjoint || !this.trackTimestamp) return; + + const renderContextData = this.get(renderContext); + + if (!renderContextData.gpuQueries) renderContextData.gpuQueries = []; + + for (let i = 0; i < renderContextData.gpuQueries.length; i++) { + const queryInfo = renderContextData.gpuQueries[i]; + const available = this.gl.getQueryParameter(queryInfo.query, this.gl.QUERY_RESULT_AVAILABLE); + const disjoint = this.gl.getParameter(this.disjoint.GPU_DISJOINT_EXT); + + if (available && !disjoint) { + const elapsed = this.gl.getQueryParameter(queryInfo.query, this.gl.QUERY_RESULT); + const duration = Number(elapsed) / 1000000; // Convert nanoseconds to milliseconds + this.gl.deleteQuery(queryInfo.query); + renderContextData.gpuQueries.splice(i, 1); // Remove the processed query + i--; + this.renderer.info.updateTimestamp(type, duration); + } + } + } + + getContext() { + return this.gl; + } + + beginRender(renderContext) { + const { gl } = this; + const renderContextData = this.get(renderContext); + + // + + // + + this.initTimestampQuery(renderContext); + + renderContextData.previousContext = this._currentContext; + this._currentContext = renderContext; + + this._setFramebuffer(renderContext); + + this.clear( + renderContext.clearColor, + renderContext.clearDepth, + renderContext.clearStencil, + renderContext, + false, + ); + + // + if (renderContext.viewport) { + this.updateViewport(renderContext); + } else { + gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); + } + + if (renderContext.scissor) { + const { x, y, width, height } = renderContext.scissorValue; + + gl.scissor(x, renderContext.height - height - y, width, height); + } + + const occlusionQueryCount = renderContext.occlusionQueryCount; + + if (occlusionQueryCount > 0) { + // Get a reference to the array of objects with queries. The renderContextData property + // can be changed by another render pass before the async reading of all previous queries complete + renderContextData.currentOcclusionQueries = renderContextData.occlusionQueries; + renderContextData.currentOcclusionQueryObjects = renderContextData.occlusionQueryObjects; + + renderContextData.lastOcclusionObject = null; + renderContextData.occlusionQueries = new Array(occlusionQueryCount); + renderContextData.occlusionQueryObjects = new Array(occlusionQueryCount); + renderContextData.occlusionQueryIndex = 0; + } + } + + finishRender(renderContext) { + const { gl, state } = this; + const renderContextData = this.get(renderContext); + const previousContext = renderContextData.previousContext; + + const occlusionQueryCount = renderContext.occlusionQueryCount; + + if (occlusionQueryCount > 0) { + if (occlusionQueryCount > renderContextData.occlusionQueryIndex) { + gl.endQuery(gl.ANY_SAMPLES_PASSED); + } + + this.resolveOccludedAsync(renderContext); + } + + const textures = renderContext.textures; + + if (textures !== null) { + for (let i = 0; i < textures.length; i++) { + const texture = textures[i]; + + if (texture.generateMipmaps) { + this.generateMipmaps(texture); + } + } + } + + this._currentContext = previousContext; + + if (renderContext.textures !== null && renderContext.renderTarget) { + const renderTargetContextData = this.get(renderContext.renderTarget); + + const { samples } = renderContext.renderTarget; + + if (samples > 0) { + const fb = renderTargetContextData.framebuffers[renderContext.getCacheKey()]; + + const mask = gl.COLOR_BUFFER_BIT; + + const msaaFrameBuffer = renderTargetContextData.msaaFrameBuffer; + + const textures = renderContext.textures; + + state.bindFramebuffer(gl.READ_FRAMEBUFFER, msaaFrameBuffer); + state.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fb); + + for (let i = 0; i < textures.length; i++) { + // TODO Add support for MRT + + if (renderContext.scissor) { + const { x, y, width, height } = renderContext.scissorValue; + + const viewY = renderContext.height - height - y; + + gl.blitFramebuffer( + x, + viewY, + x + width, + viewY + height, + x, + viewY, + x + width, + viewY + height, + mask, + gl.NEAREST, + ); + gl.invalidateSubFramebuffer( + gl.READ_FRAMEBUFFER, + renderTargetContextData.invalidationArray, + x, + viewY, + width, + height, + ); + } else { + gl.blitFramebuffer( + 0, + 0, + renderContext.width, + renderContext.height, + 0, + 0, + renderContext.width, + renderContext.height, + mask, + gl.NEAREST, + ); + gl.invalidateFramebuffer(gl.READ_FRAMEBUFFER, renderTargetContextData.invalidationArray); + } + } + } + } + + if (previousContext !== null) { + this._setFramebuffer(previousContext); + + if (previousContext.viewport) { + this.updateViewport(previousContext); + } else { + gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); + } + } + + this.prepareTimestampBuffer(renderContext); + } + + resolveOccludedAsync(renderContext) { + const renderContextData = this.get(renderContext); + + // handle occlusion query results + + const { currentOcclusionQueries, currentOcclusionQueryObjects } = renderContextData; + + if (currentOcclusionQueries && currentOcclusionQueryObjects) { + const occluded = new WeakSet(); + const { gl } = this; + + renderContextData.currentOcclusionQueryObjects = null; + renderContextData.currentOcclusionQueries = null; + + const check = () => { + let completed = 0; + + // check all queries and requeue as appropriate + for (let i = 0; i < currentOcclusionQueries.length; i++) { + const query = currentOcclusionQueries[i]; + + if (query === null) continue; + + if (gl.getQueryParameter(query, gl.QUERY_RESULT_AVAILABLE)) { + if (gl.getQueryParameter(query, gl.QUERY_RESULT) > 0) + occluded.add(currentOcclusionQueryObjects[i]); + + currentOcclusionQueries[i] = null; + gl.deleteQuery(query); + + completed++; + } + } + + if (completed < currentOcclusionQueries.length) { + requestAnimationFrame(check); + } else { + renderContextData.occluded = occluded; + } + }; + + check(); + } + } + + isOccluded(renderContext, object) { + const renderContextData = this.get(renderContext); + + return renderContextData.occluded && renderContextData.occluded.has(object); + } + + updateViewport(renderContext) { + const gl = this.gl; + const { x, y, width, height } = renderContext.viewportValue; + + gl.viewport(x, renderContext.height - height - y, width, height); + } + + setScissorTest(boolean) { + const gl = this.gl; + + if (boolean) { + gl.enable(gl.SCISSOR_TEST); + } else { + gl.disable(gl.SCISSOR_TEST); + } + } + + clear(color, depth, stencil, descriptor = null, setFrameBuffer = true) { + const { gl } = this; + + if (descriptor === null) { + const clearColor = this.getClearColor(); + + // premultiply alpha + + clearColor.r *= clearColor.a; + clearColor.g *= clearColor.a; + clearColor.b *= clearColor.a; + + descriptor = { + textures: null, + clearColorValue: clearColor, + }; + } + + // + + let clear = 0; + + if (color) clear |= gl.COLOR_BUFFER_BIT; + if (depth) clear |= gl.DEPTH_BUFFER_BIT; + if (stencil) clear |= gl.STENCIL_BUFFER_BIT; + + if (clear !== 0) { + let clearColor; + + if (descriptor.clearColorValue) { + clearColor = descriptor.clearColorValue; + } else { + clearColor = this.getClearColor(); + + // premultiply alpha + + clearColor.r *= clearColor.a; + clearColor.g *= clearColor.a; + clearColor.b *= clearColor.a; + } + + if (depth) this.state.setDepthMask(true); + + if (descriptor.textures === null) { + gl.clearColor(clearColor.r, clearColor.g, clearColor.b, clearColor.a); + gl.clear(clear); + } else { + if (setFrameBuffer) this._setFramebuffer(descriptor); + + if (color) { + for (let i = 0; i < descriptor.textures.length; i++) { + gl.clearBufferfv(gl.COLOR, i, [clearColor.r, clearColor.g, clearColor.b, clearColor.a]); + } + } + + if (depth && stencil) { + gl.clearBufferfi(gl.DEPTH_STENCIL, 0, 1, 0); + } else if (depth) { + gl.clearBufferfv(gl.DEPTH, 0, [1.0]); + } else if (stencil) { + gl.clearBufferiv(gl.STENCIL, 0, [0]); + } + } + } + } + + beginCompute(computeGroup) { + const { state, gl } = this; + + state.bindFramebuffer(gl.FRAMEBUFFER, null); + this.initTimestampQuery(computeGroup); + } + + compute(computeGroup, computeNode, bindings, pipeline) { + const { state, gl } = this; + + if (!this.discard) { + // required here to handle async behaviour of render.compute() + gl.enable(gl.RASTERIZER_DISCARD); + this.discard = true; + } + + const { programGPU, transformBuffers, attributes } = this.get(pipeline); + + const vaoKey = this._getVaoKey(null, attributes); + + const vaoGPU = this.vaoCache[vaoKey]; + + if (vaoGPU === undefined) { + this._createVao(null, attributes); + } else { + gl.bindVertexArray(vaoGPU); + } + + state.useProgram(programGPU); + + this._bindUniforms(bindings); + + const transformFeedbackGPU = this._getTransformFeedback(transformBuffers); + + gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, transformFeedbackGPU); + gl.beginTransformFeedback(gl.POINTS); + + if (attributes[0].isStorageInstancedBufferAttribute) { + gl.drawArraysInstanced(gl.POINTS, 0, 1, computeNode.count); + } else { + gl.drawArrays(gl.POINTS, 0, computeNode.count); + } + + gl.endTransformFeedback(); + gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null); + + // switch active buffers + + for (let i = 0; i < transformBuffers.length; i++) { + const dualAttributeData = transformBuffers[i]; + + if (dualAttributeData.pbo) { + this.textureUtils.copyBufferToTexture(dualAttributeData.transformBuffer, dualAttributeData.pbo); + } + + dualAttributeData.switchBuffers(); + } + } + + finishCompute(computeGroup) { + const gl = this.gl; + + this.discard = false; + + gl.disable(gl.RASTERIZER_DISCARD); + + this.prepareTimestampBuffer(computeGroup); + + if (this._currentContext) { + this._setFramebuffer(this._currentContext); + } + } + + draw(renderObject /*, info*/) { + const { object, pipeline, material, context } = renderObject; + const { programGPU } = this.get(pipeline); + + const { gl, state } = this; + + const contextData = this.get(context); + + const drawParams = renderObject.getDrawParameters(); + + if (drawParams === null) return; + + // + + this._bindUniforms(renderObject.getBindings()); + + const frontFaceCW = object.isMesh && object.matrixWorld.determinant() < 0; + + state.setMaterial(material, frontFaceCW); + + state.useProgram(programGPU); + + // + + let vaoGPU = renderObject.staticVao; + + if (vaoGPU === undefined) { + const vaoKey = this._getVaoKey(renderObject.getIndex(), renderObject.getAttributes()); + + vaoGPU = this.vaoCache[vaoKey]; + + if (vaoGPU === undefined) { + let staticVao; + + ({ vaoGPU, staticVao } = this._createVao(renderObject.getIndex(), renderObject.getAttributes())); + + if (staticVao) renderObject.staticVao = vaoGPU; + } + } + + gl.bindVertexArray(vaoGPU); + + // + + const index = renderObject.getIndex(); + + // + + const lastObject = contextData.lastOcclusionObject; + + if (lastObject !== object && lastObject !== undefined) { + if (lastObject !== null && lastObject.occlusionTest === true) { + gl.endQuery(gl.ANY_SAMPLES_PASSED); + + contextData.occlusionQueryIndex++; + } + + if (object.occlusionTest === true) { + const query = gl.createQuery(); + + gl.beginQuery(gl.ANY_SAMPLES_PASSED, query); + + contextData.occlusionQueries[contextData.occlusionQueryIndex] = query; + contextData.occlusionQueryObjects[contextData.occlusionQueryIndex] = object; + } + + contextData.lastOcclusionObject = object; + } + + // + const renderer = this.bufferRenderer; + + if (object.isPoints) renderer.mode = gl.POINTS; + else if (object.isLineSegments) renderer.mode = gl.LINES; + else if (object.isLine) renderer.mode = gl.LINE_STRIP; + else if (object.isLineLoop) renderer.mode = gl.LINE_LOOP; + else { + if (material.wireframe === true) { + state.setLineWidth(material.wireframeLinewidth * this.renderer.getPixelRatio()); + renderer.mode = gl.LINES; + } else { + renderer.mode = gl.TRIANGLES; + } + } + + // + + const { vertexCount, instanceCount } = drawParams; + let { firstVertex } = drawParams; + + renderer.object = object; + + if (index !== null) { + firstVertex *= index.array.BYTES_PER_ELEMENT; + + const indexData = this.get(index); + + renderer.index = index.count; + renderer.type = indexData.type; + } else { + renderer.index = 0; + } + + if (object.isBatchedMesh) { + if (object._multiDrawInstances !== null) { + renderer.renderMultiDrawInstances( + object._multiDrawStarts, + object._multiDrawCounts, + object._multiDrawCount, + object._multiDrawInstances, + ); + } else if (!this.hasFeature('WEBGL_multi_draw')) { + warnOnce('THREE.WebGLRenderer: WEBGL_multi_draw not supported.'); + } else { + renderer.renderMultiDraw(object._multiDrawStarts, object._multiDrawCounts, object._multiDrawCount); + } + } else if (instanceCount > 1) { + renderer.renderInstances(firstVertex, vertexCount, instanceCount); + } else { + renderer.render(firstVertex, vertexCount); + } + // + + gl.bindVertexArray(null); + } + + needsRenderUpdate(/*renderObject*/) { + return false; + } + + getRenderCacheKey(/*renderObject*/) { + return ''; + } + + // textures + + createDefaultTexture(texture) { + this.textureUtils.createDefaultTexture(texture); + } + + createTexture(texture, options) { + this.textureUtils.createTexture(texture, options); + } + + updateTexture(texture, options) { + this.textureUtils.updateTexture(texture, options); + } + + generateMipmaps(texture) { + this.textureUtils.generateMipmaps(texture); + } + + destroyTexture(texture) { + this.textureUtils.destroyTexture(texture); + } + + copyTextureToBuffer(texture, x, y, width, height, faceIndex) { + return this.textureUtils.copyTextureToBuffer(texture, x, y, width, height, faceIndex); + } + + createSampler(/*texture*/) { + //console.warn( 'Abstract class.' ); + } + + destroySampler() {} + + // node builder + + createNodeBuilder(object, renderer) { + return new GLSLNodeBuilder(object, renderer); + } + + // program + + createProgram(program) { + const gl = this.gl; + const { stage, code } = program; + + const shader = stage === 'fragment' ? gl.createShader(gl.FRAGMENT_SHADER) : gl.createShader(gl.VERTEX_SHADER); + + gl.shaderSource(shader, code); + gl.compileShader(shader); + + this.set(program, { + shaderGPU: shader, + }); + } + + destroyProgram(/*program*/) { + console.warn('Abstract class.'); + } + + createRenderPipeline(renderObject, promises) { + const gl = this.gl; + const pipeline = renderObject.pipeline; + + // Program + + const { fragmentProgram, vertexProgram } = pipeline; + + const programGPU = gl.createProgram(); + + const fragmentShader = this.get(fragmentProgram).shaderGPU; + const vertexShader = this.get(vertexProgram).shaderGPU; + + gl.attachShader(programGPU, fragmentShader); + gl.attachShader(programGPU, vertexShader); + gl.linkProgram(programGPU); + + this.set(pipeline, { + programGPU, + fragmentShader, + vertexShader, + }); + + if (promises !== null && this.parallel) { + const p = new Promise((resolve /*, reject*/) => { + const parallel = this.parallel; + const checkStatus = () => { + if (gl.getProgramParameter(programGPU, parallel.COMPLETION_STATUS_KHR)) { + this._completeCompile(renderObject, pipeline); + resolve(); + } else { + requestAnimationFrame(checkStatus); + } + }; + + checkStatus(); + }); + + promises.push(p); + + return; + } + + this._completeCompile(renderObject, pipeline); + } + + _handleSource(string, errorLine) { + const lines = string.split('\n'); + const lines2 = []; + + const from = Math.max(errorLine - 6, 0); + const to = Math.min(errorLine + 6, lines.length); + + for (let i = from; i < to; i++) { + const line = i + 1; + lines2.push(`${line === errorLine ? '>' : ' '} ${line}: ${lines[i]}`); + } + + return lines2.join('\n'); + } + + _getShaderErrors(gl, shader, type) { + const status = gl.getShaderParameter(shader, gl.COMPILE_STATUS); + const errors = gl.getShaderInfoLog(shader).trim(); + + if (status && errors === '') return ''; + + const errorMatches = /ERROR: 0:(\d+)/.exec(errors); + if (errorMatches) { + const errorLine = parseInt(errorMatches[1]); + return ( + type.toUpperCase() + + '\n\n' + + errors + + '\n\n' + + this._handleSource(gl.getShaderSource(shader), errorLine) + ); + } else { + return errors; + } + } + + _logProgramError(programGPU, glFragmentShader, glVertexShader) { + if (this.renderer.debug.checkShaderErrors) { + const gl = this.gl; + + const programLog = gl.getProgramInfoLog(programGPU).trim(); + + if (gl.getProgramParameter(programGPU, gl.LINK_STATUS) === false) { + if (typeof this.renderer.debug.onShaderError === 'function') { + this.renderer.debug.onShaderError(gl, programGPU, glVertexShader, glFragmentShader); + } else { + // default error reporting + + const vertexErrors = this._getShaderErrors(gl, glVertexShader, 'vertex'); + const fragmentErrors = this._getShaderErrors(gl, glFragmentShader, 'fragment'); + + console.error( + 'THREE.WebGLProgram: Shader Error ' + + gl.getError() + + ' - ' + + 'VALIDATE_STATUS ' + + gl.getProgramParameter(programGPU, gl.VALIDATE_STATUS) + + '\n\n' + + 'Program Info Log: ' + + programLog + + '\n' + + vertexErrors + + '\n' + + fragmentErrors, + ); + } + } else if (programLog !== '') { + console.warn('THREE.WebGLProgram: Program Info Log:', programLog); + } + } + } + + _completeCompile(renderObject, pipeline) { + const { state, gl } = this; + const pipelineData = this.get(pipeline); + const { programGPU, fragmentShader, vertexShader } = pipelineData; + + if (gl.getProgramParameter(programGPU, gl.LINK_STATUS) === false) { + this._logProgramError(programGPU, fragmentShader, vertexShader); + } + + state.useProgram(programGPU); + + // Bindings + + const bindings = renderObject.getBindings(); + + this._setupBindings(bindings, programGPU); + + // + + this.set(pipeline, { + programGPU, + }); + } + + createComputePipeline(computePipeline, bindings) { + const { state, gl } = this; + + // Program + + const fragmentProgram = { + stage: 'fragment', + code: '#version 300 es\nprecision highp float;\nvoid main() {}', + }; + + this.createProgram(fragmentProgram); + + const { computeProgram } = computePipeline; + + const programGPU = gl.createProgram(); + + const fragmentShader = this.get(fragmentProgram).shaderGPU; + const vertexShader = this.get(computeProgram).shaderGPU; + + const transforms = computeProgram.transforms; + + const transformVaryingNames = []; + const transformAttributeNodes = []; + + for (let i = 0; i < transforms.length; i++) { + const transform = transforms[i]; + + transformVaryingNames.push(transform.varyingName); + transformAttributeNodes.push(transform.attributeNode); + } + + gl.attachShader(programGPU, fragmentShader); + gl.attachShader(programGPU, vertexShader); + + gl.transformFeedbackVaryings(programGPU, transformVaryingNames, gl.SEPARATE_ATTRIBS); + + gl.linkProgram(programGPU); + + if (gl.getProgramParameter(programGPU, gl.LINK_STATUS) === false) { + this._logProgramError(programGPU, fragmentShader, vertexShader); + } + + state.useProgram(programGPU); + + // Bindings + + this._setupBindings(bindings, programGPU); + + const attributeNodes = computeProgram.attributes; + const attributes = []; + const transformBuffers = []; + + for (let i = 0; i < attributeNodes.length; i++) { + const attribute = attributeNodes[i].node.attribute; + + attributes.push(attribute); + + if (!this.has(attribute)) this.attributeUtils.createAttribute(attribute, gl.ARRAY_BUFFER); + } + + for (let i = 0; i < transformAttributeNodes.length; i++) { + const attribute = transformAttributeNodes[i].attribute; + + if (!this.has(attribute)) this.attributeUtils.createAttribute(attribute, gl.ARRAY_BUFFER); + + const attributeData = this.get(attribute); + + transformBuffers.push(attributeData); + } + + // + + this.set(computePipeline, { + programGPU, + transformBuffers, + attributes, + }); + } + + createBindings(bindGroup, bindings) { + if (this._knownBindings.has(bindings) === false) { + this._knownBindings.add(bindings); + + let uniformBuffers = 0; + let textures = 0; + + for (const bindGroup of bindings) { + this.set(bindGroup, { + textures: textures, + uniformBuffers: uniformBuffers, + }); + + for (const binding of bindGroup.bindings) { + if (binding.isUniformBuffer) uniformBuffers++; + if (binding.isSampledTexture) textures++; + } + } + } + + this.updateBindings(bindGroup, bindings); + } + + updateBindings(bindGroup /*, bindings*/) { + const { gl } = this; + + const bindGroupData = this.get(bindGroup); + + let i = bindGroupData.uniformBuffers; + let t = bindGroupData.textures; + + for (const binding of bindGroup.bindings) { + if (binding.isUniformsGroup || binding.isUniformBuffer) { + const data = binding.buffer; + const bufferGPU = gl.createBuffer(); + + gl.bindBuffer(gl.UNIFORM_BUFFER, bufferGPU); + gl.bufferData(gl.UNIFORM_BUFFER, data, gl.DYNAMIC_DRAW); + + this.set(binding, { + index: i++, + bufferGPU, + }); + } else if (binding.isSampledTexture) { + const { textureGPU, glTextureType } = this.get(binding.texture); + + this.set(binding, { + index: t++, + textureGPU, + glTextureType, + }); + } + } + } + + updateBinding(binding) { + const gl = this.gl; + + if (binding.isUniformsGroup || binding.isUniformBuffer) { + const bindingData = this.get(binding); + const bufferGPU = bindingData.bufferGPU; + const data = binding.buffer; + + gl.bindBuffer(gl.UNIFORM_BUFFER, bufferGPU); + gl.bufferData(gl.UNIFORM_BUFFER, data, gl.DYNAMIC_DRAW); + } + } + + // attributes + + createIndexAttribute(attribute) { + const gl = this.gl; + + this.attributeUtils.createAttribute(attribute, gl.ELEMENT_ARRAY_BUFFER); + } + + createAttribute(attribute) { + if (this.has(attribute)) return; + + const gl = this.gl; + + this.attributeUtils.createAttribute(attribute, gl.ARRAY_BUFFER); + } + + createStorageAttribute(attribute) { + if (this.has(attribute)) return; + + const gl = this.gl; + + this.attributeUtils.createAttribute(attribute, gl.ARRAY_BUFFER); + } + + updateAttribute(attribute) { + this.attributeUtils.updateAttribute(attribute); + } + + destroyAttribute(attribute) { + this.attributeUtils.destroyAttribute(attribute); + } + + updateSize() { + //console.warn( 'Abstract class.' ); + } + + hasFeature(name) { + const keysMatching = Object.keys(GLFeatureName).filter(key => GLFeatureName[key] === name); + + const extensions = this.extensions; + + for (let i = 0; i < keysMatching.length; i++) { + if (extensions.has(keysMatching[i])) return true; + } + + return false; + } + + getMaxAnisotropy() { + return this.capabilities.getMaxAnisotropy(); + } + + copyTextureToTexture(srcTexture, dstTexture, srcRegion, dstPosition, level) { + this.textureUtils.copyTextureToTexture(srcTexture, dstTexture, srcRegion, dstPosition, level); + } + + copyFramebufferToTexture(texture, renderContext, rectangle) { + this.textureUtils.copyFramebufferToTexture(texture, renderContext, rectangle); + } + + _setFramebuffer(descriptor) { + const { gl, state } = this; + + let currentFrameBuffer = null; + + if (descriptor.textures !== null) { + const renderTarget = descriptor.renderTarget; + const renderTargetContextData = this.get(renderTarget); + const { samples, depthBuffer, stencilBuffer } = renderTarget; + + const isCube = renderTarget.isWebGLCubeRenderTarget === true; + + let msaaFb = renderTargetContextData.msaaFrameBuffer; + let depthRenderbuffer = renderTargetContextData.depthRenderbuffer; + + const cacheKey = getCacheKey(descriptor); + + let fb; + + if (isCube) { + renderTargetContextData.cubeFramebuffers || (renderTargetContextData.cubeFramebuffers = {}); + + fb = renderTargetContextData.cubeFramebuffers[cacheKey]; + } else { + renderTargetContextData.framebuffers || (renderTargetContextData.framebuffers = {}); + + fb = renderTargetContextData.framebuffers[cacheKey]; + } + + if (fb === undefined) { + fb = gl.createFramebuffer(); + + state.bindFramebuffer(gl.FRAMEBUFFER, fb); + + const textures = descriptor.textures; + + if (isCube) { + renderTargetContextData.cubeFramebuffers[cacheKey] = fb; + + const { textureGPU } = this.get(textures[0]); + + const cubeFace = this.renderer._activeCubeFace; + + gl.framebufferTexture2D( + gl.FRAMEBUFFER, + gl.COLOR_ATTACHMENT0, + gl.TEXTURE_CUBE_MAP_POSITIVE_X + cubeFace, + textureGPU, + 0, + ); + } else { + renderTargetContextData.framebuffers[cacheKey] = fb; + + for (let i = 0; i < textures.length; i++) { + const texture = textures[i]; + const textureData = this.get(texture); + textureData.renderTarget = descriptor.renderTarget; + textureData.cacheKey = cacheKey; // required for copyTextureToTexture() + + const attachment = gl.COLOR_ATTACHMENT0 + i; + + gl.framebufferTexture2D(gl.FRAMEBUFFER, attachment, gl.TEXTURE_2D, textureData.textureGPU, 0); + } + + state.drawBuffers(descriptor, fb); + } + + if (descriptor.depthTexture !== null) { + const textureData = this.get(descriptor.depthTexture); + const depthStyle = stencilBuffer ? gl.DEPTH_STENCIL_ATTACHMENT : gl.DEPTH_ATTACHMENT; + textureData.renderTarget = descriptor.renderTarget; + textureData.cacheKey = cacheKey; // required for copyTextureToTexture() + + gl.framebufferTexture2D(gl.FRAMEBUFFER, depthStyle, gl.TEXTURE_2D, textureData.textureGPU, 0); + } + } + + if (samples > 0) { + if (msaaFb === undefined) { + const invalidationArray = []; + + msaaFb = gl.createFramebuffer(); + + state.bindFramebuffer(gl.FRAMEBUFFER, msaaFb); + + const msaaRenderbuffers = []; + + const textures = descriptor.textures; + + for (let i = 0; i < textures.length; i++) { + msaaRenderbuffers[i] = gl.createRenderbuffer(); + + gl.bindRenderbuffer(gl.RENDERBUFFER, msaaRenderbuffers[i]); + + invalidationArray.push(gl.COLOR_ATTACHMENT0 + i); + + if (depthBuffer) { + const depthStyle = stencilBuffer ? gl.DEPTH_STENCIL_ATTACHMENT : gl.DEPTH_ATTACHMENT; + invalidationArray.push(depthStyle); + } + + const texture = descriptor.textures[i]; + const textureData = this.get(texture); + + gl.renderbufferStorageMultisample( + gl.RENDERBUFFER, + samples, + textureData.glInternalFormat, + descriptor.width, + descriptor.height, + ); + gl.framebufferRenderbuffer( + gl.FRAMEBUFFER, + gl.COLOR_ATTACHMENT0 + i, + gl.RENDERBUFFER, + msaaRenderbuffers[i], + ); + } + + renderTargetContextData.msaaFrameBuffer = msaaFb; + renderTargetContextData.msaaRenderbuffers = msaaRenderbuffers; + + if (depthRenderbuffer === undefined) { + depthRenderbuffer = gl.createRenderbuffer(); + this.textureUtils.setupRenderBufferStorage(depthRenderbuffer, descriptor); + + renderTargetContextData.depthRenderbuffer = depthRenderbuffer; + + const depthStyle = stencilBuffer ? gl.DEPTH_STENCIL_ATTACHMENT : gl.DEPTH_ATTACHMENT; + invalidationArray.push(depthStyle); + } + + renderTargetContextData.invalidationArray = invalidationArray; + } + + currentFrameBuffer = renderTargetContextData.msaaFrameBuffer; + } else { + currentFrameBuffer = fb; + } + } + + state.bindFramebuffer(gl.FRAMEBUFFER, currentFrameBuffer); + } + + _getVaoKey(index, attributes) { + let key = []; + + if (index !== null) { + const indexData = this.get(index); + + key += ':' + indexData.id; + } + + for (let i = 0; i < attributes.length; i++) { + const attributeData = this.get(attributes[i]); + + key += ':' + attributeData.id; + } + + return key; + } + + _createVao(index, attributes) { + const { gl } = this; + + const vaoGPU = gl.createVertexArray(); + let key = ''; + + let staticVao = true; + + gl.bindVertexArray(vaoGPU); + + if (index !== null) { + const indexData = this.get(index); + + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexData.bufferGPU); + + key += ':' + indexData.id; + } + + for (let i = 0; i < attributes.length; i++) { + const attribute = attributes[i]; + const attributeData = this.get(attribute); + + key += ':' + attributeData.id; + + gl.bindBuffer(gl.ARRAY_BUFFER, attributeData.bufferGPU); + gl.enableVertexAttribArray(i); + + if (attribute.isStorageBufferAttribute || attribute.isStorageInstancedBufferAttribute) staticVao = false; + + let stride, offset; + + if (attribute.isInterleavedBufferAttribute === true) { + stride = attribute.data.stride * attributeData.bytesPerElement; + offset = attribute.offset * attributeData.bytesPerElement; + } else { + stride = 0; + offset = 0; + } + + if (attributeData.isInteger) { + gl.vertexAttribIPointer(i, attribute.itemSize, attributeData.type, stride, offset); + } else { + gl.vertexAttribPointer(i, attribute.itemSize, attributeData.type, attribute.normalized, stride, offset); + } + + if (attribute.isInstancedBufferAttribute && !attribute.isInterleavedBufferAttribute) { + gl.vertexAttribDivisor(i, attribute.meshPerAttribute); + } else if (attribute.isInterleavedBufferAttribute && attribute.data.isInstancedInterleavedBuffer) { + gl.vertexAttribDivisor(i, attribute.data.meshPerAttribute); + } + } + + gl.bindBuffer(gl.ARRAY_BUFFER, null); + + this.vaoCache[key] = vaoGPU; + + return { vaoGPU, staticVao }; + } + + _getTransformFeedback(transformBuffers) { + let key = ''; + + for (let i = 0; i < transformBuffers.length; i++) { + key += ':' + transformBuffers[i].id; + } + + let transformFeedbackGPU = this.transformFeedbackCache[key]; + + if (transformFeedbackGPU !== undefined) { + return transformFeedbackGPU; + } + + const { gl } = this; + + transformFeedbackGPU = gl.createTransformFeedback(); + + gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, transformFeedbackGPU); + + for (let i = 0; i < transformBuffers.length; i++) { + const attributeData = transformBuffers[i]; + + gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, i, attributeData.transformBuffer); + } + + gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null); + + this.transformFeedbackCache[key] = transformFeedbackGPU; + + return transformFeedbackGPU; + } + + _setupBindings(bindings, programGPU) { + const gl = this.gl; + + for (const bindGroup of bindings) { + for (const binding of bindGroup.bindings) { + const bindingData = this.get(binding); + const index = bindingData.index; + + if (binding.isUniformsGroup || binding.isUniformBuffer) { + const location = gl.getUniformBlockIndex(programGPU, binding.name); + gl.uniformBlockBinding(programGPU, location, index); + } else if (binding.isSampledTexture) { + const location = gl.getUniformLocation(programGPU, binding.name); + gl.uniform1i(location, index); + } + } + } + } + + _bindUniforms(bindings) { + const { gl, state } = this; + + for (const bindGroup of bindings) { + for (const binding of bindGroup.bindings) { + const bindingData = this.get(binding); + const index = bindingData.index; + + if (binding.isUniformsGroup || binding.isUniformBuffer) { + // TODO USE bindBufferRange to group multiple uniform buffers + state.bindBufferBase(gl.UNIFORM_BUFFER, index, bindingData.bufferGPU); + } else if (binding.isSampledTexture) { + state.bindTexture(bindingData.glTextureType, bindingData.textureGPU, gl.TEXTURE0 + index); + } + } + } + } +} + +export default WebGLBackend; diff --git a/src-testing/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.ts b/src-testing/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.ts new file mode 100644 index 000000000..b1e720647 --- /dev/null +++ b/src-testing/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.ts @@ -0,0 +1,812 @@ +import { GLSLNodeParser, NodeBuilder, TextureNode, vectorComponents } from '../../../nodes/Nodes.js'; + +import NodeUniformBuffer from '../../common/nodes/NodeUniformBuffer.js'; +import NodeUniformsGroup from '../../common/nodes/NodeUniformsGroup.js'; + +import { + NodeSampledTexture, + NodeSampledCubeTexture, + NodeSampledTexture3D, +} from '../../common/nodes/NodeSampledTexture.js'; + +import { + NoColorSpace, + ByteType, + ShortType, + RGBAIntegerFormat, + RGBIntegerFormat, + RedIntegerFormat, + RGIntegerFormat, + UnsignedByteType, + UnsignedIntType, + UnsignedShortType, + RedFormat, + RGFormat, + IntType, + RGBFormat, + RGBAFormat, + FloatType, +} from '../../../constants.js'; +import { DataTexture } from '../../../textures/DataTexture.js'; + +const glslMethods = { + atan2: 'atan', + textureDimensions: 'textureSize', + equals: 'equal', +}; + +const precisionLib = { + low: 'lowp', + medium: 'mediump', + high: 'highp', +}; + +const supports = { + swizzleAssign: true, + storageBuffer: false, +}; + +const defaultPrecisions = ` +precision highp float; +precision highp int; +precision highp sampler2D; +precision highp sampler3D; +precision highp samplerCube; +precision highp sampler2DArray; + +precision highp usampler2D; +precision highp usampler3D; +precision highp usamplerCube; +precision highp usampler2DArray; + +precision highp isampler2D; +precision highp isampler3D; +precision highp isamplerCube; +precision highp isampler2DArray; + +precision lowp sampler2DShadow; +`; + +class GLSLNodeBuilder extends NodeBuilder { + constructor(object, renderer) { + super(object, renderer, new GLSLNodeParser()); + + this.uniformGroups = {}; + this.transforms = []; + this.extensions = {}; + + this.useComparisonMethod = true; + } + + needsColorSpaceToLinearSRGB(texture) { + return texture.isVideoTexture === true && texture.colorSpace !== NoColorSpace; + } + + getMethod(method) { + return glslMethods[method] || method; + } + + getOutputStructName() { + return ''; + } + + buildFunctionCode(shaderNode) { + const layout = shaderNode.layout; + const flowData = this.flowShaderNode(shaderNode); + + const parameters = []; + + for (const input of layout.inputs) { + parameters.push(this.getType(input.type) + ' ' + input.name); + } + + // + + const code = `${this.getType(layout.type)} ${layout.name}( ${parameters.join(', ')} ) { + + ${flowData.vars} + +${flowData.code} + return ${flowData.result}; + +}`; + + // + + return code; + } + + setupPBO(storageBufferNode) { + const attribute = storageBufferNode.value; + + if (attribute.pbo === undefined) { + const originalArray = attribute.array; + const numElements = attribute.count * attribute.itemSize; + + const { itemSize } = attribute; + + const isInteger = attribute.array.constructor.name.toLowerCase().includes('int'); + + let format = isInteger ? RedIntegerFormat : RedFormat; + + if (itemSize === 2) { + format = isInteger ? RGIntegerFormat : RGFormat; + } else if (itemSize === 3) { + format = isInteger ? RGBIntegerFormat : RGBFormat; + } else if (itemSize === 4) { + format = isInteger ? RGBAIntegerFormat : RGBAFormat; + } + + const typeMap = { + Float32Array: FloatType, + Uint8Array: UnsignedByteType, + Uint16Array: UnsignedShortType, + Uint32Array: UnsignedIntType, + Int8Array: ByteType, + Int16Array: ShortType, + Int32Array: IntType, + Uint8ClampedArray: UnsignedByteType, + }; + + const width = Math.pow(2, Math.ceil(Math.log2(Math.sqrt(numElements / itemSize)))); + let height = Math.ceil(numElements / itemSize / width); + if (width * height * itemSize < numElements) height++; // Ensure enough space + + const newSize = width * height * itemSize; + + const newArray = new originalArray.constructor(newSize); + + newArray.set(originalArray, 0); + + attribute.array = newArray; + + const pboTexture = new DataTexture( + attribute.array, + width, + height, + format, + typeMap[attribute.array.constructor.name] || FloatType, + ); + pboTexture.needsUpdate = true; + pboTexture.isPBOTexture = true; + + const pbo = new TextureNode(pboTexture, null, null); + pbo.setPrecision('high'); + + attribute.pboNode = pbo; + attribute.pbo = pbo.value; + + this.getUniformFromNode(attribute.pboNode, 'texture', this.shaderStage, this.context.label); + } + } + + getPropertyName(node, shaderStage = this.shaderStage) { + if (node.isNodeUniform && node.node.isTextureNode !== true && node.node.isBufferNode !== true) { + return shaderStage.charAt(0) + '_' + node.name; + } + + return super.getPropertyName(node, shaderStage); + } + + generatePBO(storageArrayElementNode) { + const { node, indexNode } = storageArrayElementNode; + const attribute = node.value; + + if (this.renderer.backend.has(attribute)) { + const attributeData = this.renderer.backend.get(attribute); + attributeData.pbo = attribute.pbo; + } + + const nodeUniform = this.getUniformFromNode(attribute.pboNode, 'texture', this.shaderStage, this.context.label); + const textureName = this.getPropertyName(nodeUniform); + + this.increaseUsage(indexNode); // force cache generate to be used as index in x,y + const indexSnippet = indexNode.build(this, 'uint'); + + const elementNodeData = this.getDataFromNode(storageArrayElementNode); + + let propertyName = elementNodeData.propertyName; + + if (propertyName === undefined) { + // property element + + const nodeVar = this.getVarFromNode(storageArrayElementNode); + + propertyName = this.getPropertyName(nodeVar); + + // property size + + const bufferNodeData = this.getDataFromNode(node); + + let propertySizeName = bufferNodeData.propertySizeName; + + if (propertySizeName === undefined) { + propertySizeName = propertyName + 'Size'; + + this.getVarFromNode(node, propertySizeName, 'uint'); + + this.addLineFlowCode( + `${propertySizeName} = uint( textureSize( ${textureName}, 0 ).x )`, + storageArrayElementNode, + ); + + bufferNodeData.propertySizeName = propertySizeName; + } + + // + + const { itemSize } = attribute; + + const channel = '.' + vectorComponents.join('').slice(0, itemSize); + const uvSnippet = `ivec2(${indexSnippet} % ${propertySizeName}, ${indexSnippet} / ${propertySizeName})`; + + const snippet = this.generateTextureLoad(null, textureName, uvSnippet, null, '0'); + + // + + let prefix = 'vec4'; + + if (attribute.pbo.type === UnsignedIntType) { + prefix = 'uvec4'; + } else if (attribute.pbo.type === IntType) { + prefix = 'ivec4'; + } + + this.addLineFlowCode(`${propertyName} = ${prefix}(${snippet})${channel}`, storageArrayElementNode); + + elementNodeData.propertyName = propertyName; + } + + return propertyName; + } + + generateTextureLoad(texture, textureProperty, uvIndexSnippet, depthSnippet, levelSnippet = '0') { + if (depthSnippet) { + return `texelFetch( ${textureProperty}, ivec3( ${uvIndexSnippet}, ${depthSnippet} ), ${levelSnippet} )`; + } else { + return `texelFetch( ${textureProperty}, ${uvIndexSnippet}, ${levelSnippet} )`; + } + } + + generateTexture(texture, textureProperty, uvSnippet, depthSnippet) { + if (texture.isDepthTexture) { + return `texture( ${textureProperty}, ${uvSnippet} ).x`; + } else { + if (depthSnippet) uvSnippet = `vec3( ${uvSnippet}, ${depthSnippet} )`; + + return `texture( ${textureProperty}, ${uvSnippet} )`; + } + } + + generateTextureLevel(texture, textureProperty, uvSnippet, levelSnippet) { + return `textureLod( ${textureProperty}, ${uvSnippet}, ${levelSnippet} )`; + } + + generateTextureBias(texture, textureProperty, uvSnippet, biasSnippet) { + return `texture( ${textureProperty}, ${uvSnippet}, ${biasSnippet} )`; + } + + generateTextureGrad(texture, textureProperty, uvSnippet, gradSnippet) { + return `textureGrad( ${textureProperty}, ${uvSnippet}, ${gradSnippet[0]}, ${gradSnippet[1]} )`; + } + + generateTextureCompare( + texture, + textureProperty, + uvSnippet, + compareSnippet, + depthSnippet, + shaderStage = this.shaderStage, + ) { + if (shaderStage === 'fragment') { + return `texture( ${textureProperty}, vec3( ${uvSnippet}, ${compareSnippet} ) )`; + } else { + console.error( + `WebGPURenderer: THREE.DepthTexture.compareFunction() does not support ${shaderStage} shader.`, + ); + } + } + + getVars(shaderStage) { + const snippets = []; + + const vars = this.vars[shaderStage]; + + if (vars !== undefined) { + for (const variable of vars) { + snippets.push(`${this.getVar(variable.type, variable.name)};`); + } + } + + return snippets.join('\n\t'); + } + + getUniforms(shaderStage) { + const uniforms = this.uniforms[shaderStage]; + + const bindingSnippets = []; + const uniformGroups = {}; + + for (const uniform of uniforms) { + let snippet = null; + let group = false; + + if (uniform.type === 'texture') { + const texture = uniform.node.value; + + let typePrefix = ''; + + if (texture.isDataTexture === true) { + if (texture.type === UnsignedIntType) { + typePrefix = 'u'; + } else if (texture.type === IntType) { + typePrefix = 'i'; + } + } + + if (texture.compareFunction) { + snippet = `sampler2DShadow ${uniform.name};`; + } else if (texture.isDataArrayTexture === true || texture.isCompressedArrayTexture === true) { + snippet = `${typePrefix}sampler2DArray ${uniform.name};`; + } else { + snippet = `${typePrefix}sampler2D ${uniform.name};`; + } + } else if (uniform.type === 'cubeTexture') { + snippet = `samplerCube ${uniform.name};`; + } else if (uniform.type === 'texture3D') { + snippet = `sampler3D ${uniform.name};`; + } else if (uniform.type === 'buffer') { + const bufferNode = uniform.node; + const bufferType = this.getType(bufferNode.bufferType); + const bufferCount = bufferNode.bufferCount; + + const bufferCountSnippet = bufferCount > 0 ? bufferCount : ''; + snippet = `${bufferNode.name} {\n\t${bufferType} ${uniform.name}[${bufferCountSnippet}];\n};\n`; + } else { + const vectorType = this.getVectorType(uniform.type); + + snippet = `${vectorType} ${this.getPropertyName(uniform, shaderStage)};`; + + group = true; + } + + const precision = uniform.node.precision; + + if (precision !== null) { + snippet = precisionLib[precision] + ' ' + snippet; + } + + if (group) { + snippet = '\t' + snippet; + + const groupName = uniform.groupNode.name; + const groupSnippets = uniformGroups[groupName] || (uniformGroups[groupName] = []); + + groupSnippets.push(snippet); + } else { + snippet = 'uniform ' + snippet; + + bindingSnippets.push(snippet); + } + } + + let output = ''; + + for (const name in uniformGroups) { + const groupSnippets = uniformGroups[name]; + + output += this._getGLSLUniformStruct(shaderStage + '_' + name, groupSnippets.join('\n')) + '\n'; + } + + output += bindingSnippets.join('\n'); + + return output; + } + + getTypeFromAttribute(attribute) { + let nodeType = super.getTypeFromAttribute(attribute); + + if (/^[iu]/.test(nodeType) && attribute.gpuType !== IntType) { + let dataAttribute = attribute; + + if (attribute.isInterleavedBufferAttribute) dataAttribute = attribute.data; + + const array = dataAttribute.array; + + if ((array instanceof Uint32Array || array instanceof Int32Array) === false) { + nodeType = nodeType.slice(1); + } + } + + return nodeType; + } + + getAttributes(shaderStage) { + let snippet = ''; + + if (shaderStage === 'vertex' || shaderStage === 'compute') { + const attributes = this.getAttributesArray(); + + let location = 0; + + for (const attribute of attributes) { + snippet += `layout( location = ${location++} ) in ${attribute.type} ${attribute.name};\n`; + } + } + + return snippet; + } + + getStructMembers(struct) { + const snippets = []; + const members = struct.getMemberTypes(); + + for (let i = 0; i < members.length; i++) { + const member = members[i]; + snippets.push(`layout( location = ${i} ) out ${member} m${i};`); + } + + return snippets.join('\n'); + } + + getStructs(shaderStage) { + const snippets = []; + const structs = this.structs[shaderStage]; + + if (structs.length === 0) { + return 'layout( location = 0 ) out vec4 fragColor;\n'; + } + + for (let index = 0, length = structs.length; index < length; index++) { + const struct = structs[index]; + + let snippet = '\n'; + snippet += this.getStructMembers(struct); + snippet += '\n'; + + snippets.push(snippet); + } + + return snippets.join('\n\n'); + } + + getVaryings(shaderStage) { + let snippet = ''; + + const varyings = this.varyings; + + if (shaderStage === 'vertex' || shaderStage === 'compute') { + for (const varying of varyings) { + if (shaderStage === 'compute') varying.needsInterpolation = true; + const type = varying.type; + const flat = type.includes('int') || type.includes('uv') || type.includes('iv') ? 'flat ' : ''; + + snippet += `${flat}${varying.needsInterpolation ? 'out' : '/*out*/'} ${type} ${varying.name};\n`; + } + } else if (shaderStage === 'fragment') { + for (const varying of varyings) { + if (varying.needsInterpolation) { + const type = varying.type; + const flat = type.includes('int') || type.includes('uv') || type.includes('iv') ? 'flat ' : ''; + + snippet += `${flat}in ${type} ${varying.name};\n`; + } + } + } + + return snippet; + } + + getVertexIndex() { + return 'uint( gl_VertexID )'; + } + + getInstanceIndex() { + return 'uint( gl_InstanceID )'; + } + + getInvocationLocalIndex() { + const workgroupSize = this.object.workgroupSize; + + const size = workgroupSize.reduce((acc, curr) => acc * curr, 1); + + return `uint( gl_InstanceID ) % ${size}u`; + } + + getDrawIndex() { + const extensions = this.renderer.backend.extensions; + + if (extensions.has('WEBGL_multi_draw')) { + return 'uint( gl_DrawID )'; + } + + return null; + } + + getFrontFacing() { + return 'gl_FrontFacing'; + } + + getFragCoord() { + return 'gl_FragCoord.xy'; + } + + getFragDepth() { + return 'gl_FragDepth'; + } + + enableExtension(name, behavior, shaderStage = this.shaderStage) { + const map = this.extensions[shaderStage] || (this.extensions[shaderStage] = new Map()); + + if (map.has(name) === false) { + map.set(name, { + name, + behavior, + }); + } + } + + getExtensions(shaderStage) { + const snippets = []; + + if (shaderStage === 'vertex') { + const ext = this.renderer.backend.extensions; + const isBatchedMesh = this.object.isBatchedMesh; + + if (isBatchedMesh && ext.has('WEBGL_multi_draw')) { + this.enableExtension('GL_ANGLE_multi_draw', 'require', shaderStage); + } + } + + const extensions = this.extensions[shaderStage]; + + if (extensions !== undefined) { + for (const { name, behavior } of extensions.values()) { + snippets.push(`#extension ${name} : ${behavior}`); + } + } + + return snippets.join('\n'); + } + + isAvailable(name) { + let result = supports[name]; + + if (result === undefined) { + if (name === 'float32Filterable') { + const extensions = this.renderer.backend.extensions; + + if (extensions.has('OES_texture_float_linear')) { + extensions.get('OES_texture_float_linear'); + result = true; + } else { + result = false; + } + } + + supports[name] = result; + } + + return result; + } + + isFlipY() { + return true; + } + + registerTransform(varyingName, attributeNode) { + this.transforms.push({ varyingName, attributeNode }); + } + + getTransforms(/* shaderStage */) { + const transforms = this.transforms; + + let snippet = ''; + + for (let i = 0; i < transforms.length; i++) { + const transform = transforms[i]; + + const attributeName = this.getPropertyName(transform.attributeNode); + + snippet += `${transform.varyingName} = ${attributeName};\n\t`; + } + + return snippet; + } + + _getGLSLUniformStruct(name, vars) { + return ` +layout( std140 ) uniform ${name} { +${vars} +};`; + } + + _getGLSLVertexCode(shaderData) { + return `#version 300 es + +${this.getSignature()} + +// extensions +${shaderData.extensions} + +// precision +${defaultPrecisions} + +// uniforms +${shaderData.uniforms} + +// varyings +${shaderData.varyings} + +// attributes +${shaderData.attributes} + +// codes +${shaderData.codes} + +void main() { + + // vars + ${shaderData.vars} + + // transforms + ${shaderData.transforms} + + // flow + ${shaderData.flow} + + gl_PointSize = 1.0; + +} +`; + } + + _getGLSLFragmentCode(shaderData) { + return `#version 300 es + +${this.getSignature()} + +// precision +${defaultPrecisions} + +// uniforms +${shaderData.uniforms} + +// varyings +${shaderData.varyings} + +// codes +${shaderData.codes} + +${shaderData.structs} + +void main() { + + // vars + ${shaderData.vars} + + // flow + ${shaderData.flow} + +} +`; + } + + buildCode() { + const shadersData = this.material !== null ? { fragment: {}, vertex: {} } : { compute: {} }; + + this.sortBindingGroups(); + + for (const shaderStage in shadersData) { + let flow = '// code\n\n'; + flow += this.flowCode[shaderStage]; + + const flowNodes = this.flowNodes[shaderStage]; + const mainNode = flowNodes[flowNodes.length - 1]; + + for (const node of flowNodes) { + const flowSlotData = this.getFlowData(node /*, shaderStage*/); + const slotName = node.name; + + if (slotName) { + if (flow.length > 0) flow += '\n'; + + flow += `\t// flow -> ${slotName}\n\t`; + } + + flow += `${flowSlotData.code}\n\t`; + + if (node === mainNode && shaderStage !== 'compute') { + flow += '// result\n\t'; + + if (shaderStage === 'vertex') { + flow += 'gl_Position = '; + flow += `${flowSlotData.result};`; + } else if (shaderStage === 'fragment') { + if (!node.outputNode.isOutputStructNode) { + flow += 'fragColor = '; + flow += `${flowSlotData.result};`; + } + } + } + } + + const stageData = shadersData[shaderStage]; + + stageData.extensions = this.getExtensions(shaderStage); + stageData.uniforms = this.getUniforms(shaderStage); + stageData.attributes = this.getAttributes(shaderStage); + stageData.varyings = this.getVaryings(shaderStage); + stageData.vars = this.getVars(shaderStage); + stageData.structs = this.getStructs(shaderStage); + stageData.codes = this.getCodes(shaderStage); + stageData.transforms = this.getTransforms(shaderStage); + stageData.flow = flow; + } + + if (this.material !== null) { + this.vertexShader = this._getGLSLVertexCode(shadersData.vertex); + this.fragmentShader = this._getGLSLFragmentCode(shadersData.fragment); + } else { + this.computeShader = this._getGLSLVertexCode(shadersData.compute); + } + } + + getUniformFromNode(node, type, shaderStage, name = null) { + const uniformNode = super.getUniformFromNode(node, type, shaderStage, name); + const nodeData = this.getDataFromNode(node, shaderStage, this.globalCache); + + let uniformGPU = nodeData.uniformGPU; + + if (uniformGPU === undefined) { + const group = node.groupNode; + const groupName = group.name; + + const bindings = this.getBindGroupArray(groupName, shaderStage); + + if (type === 'texture') { + uniformGPU = new NodeSampledTexture(uniformNode.name, uniformNode.node, group); + bindings.push(uniformGPU); + } else if (type === 'cubeTexture') { + uniformGPU = new NodeSampledCubeTexture(uniformNode.name, uniformNode.node, group); + bindings.push(uniformGPU); + } else if (type === 'texture3D') { + uniformGPU = new NodeSampledTexture3D(uniformNode.name, uniformNode.node, group); + bindings.push(uniformGPU); + } else if (type === 'buffer') { + node.name = `NodeBuffer_${node.id}`; + uniformNode.name = `buffer${node.id}`; + + const buffer = new NodeUniformBuffer(node, group); + buffer.name = node.name; + + bindings.push(buffer); + + uniformGPU = buffer; + } else { + const uniformsStage = this.uniformGroups[shaderStage] || (this.uniformGroups[shaderStage] = {}); + + let uniformsGroup = uniformsStage[groupName]; + + if (uniformsGroup === undefined) { + uniformsGroup = new NodeUniformsGroup(shaderStage + '_' + groupName, group); + //uniformsGroup.setVisibility( gpuShaderStageLib[ shaderStage ] ); + + uniformsStage[groupName] = uniformsGroup; + + bindings.push(uniformsGroup); + } + + uniformGPU = this.getNodeUniform(uniformNode, type); + + uniformsGroup.addUniform(uniformGPU); + } + + nodeData.uniformGPU = uniformGPU; + } + + return uniformNode; + } +} + +export default GLSLNodeBuilder; diff --git a/src-testing/src/renderers/webgl/WebGLAttributes.d.ts b/src-testing/src/renderers/webgl/WebGLAttributes.d.ts new file mode 100644 index 000000000..8f4a9757b --- /dev/null +++ b/src-testing/src/renderers/webgl/WebGLAttributes.d.ts @@ -0,0 +1,21 @@ +import { BufferAttribute } from "../../core/BufferAttribute.js"; +import { GLBufferAttribute } from "../../core/GLBufferAttribute.js"; +import { InterleavedBufferAttribute } from "../../core/InterleavedBufferAttribute.js"; + +export class WebGLAttributes { + constructor(gl: WebGLRenderingContext | WebGL2RenderingContext); + + get(attribute: BufferAttribute | InterleavedBufferAttribute | GLBufferAttribute): + | { + buffer: WebGLBuffer; + type: number; + bytesPerElement: number; + version: number; + size: number; + } + | undefined; + + remove(attribute: BufferAttribute | InterleavedBufferAttribute | GLBufferAttribute): void; + + update(attribute: BufferAttribute | InterleavedBufferAttribute | GLBufferAttribute, bufferType: number): void; +} diff --git a/src-testing/src/renderers/webgl/WebGLBindingStates.d.ts b/src-testing/src/renderers/webgl/WebGLBindingStates.d.ts new file mode 100644 index 000000000..0b96de770 --- /dev/null +++ b/src-testing/src/renderers/webgl/WebGLBindingStates.d.ts @@ -0,0 +1,26 @@ +import { BufferAttribute } from "../../core/BufferAttribute.js"; +import { BufferGeometry } from "../../core/BufferGeometry.js"; +import { Object3D } from "../../core/Object3D.js"; +import { Material } from "../../materials/Material.js"; +import { WebGLAttributes } from "./WebGLAttributes.js"; +import { WebGLProgram } from "./WebGLProgram.js"; + +export class WebGLBindingStates { + constructor(gl: WebGLRenderingContext, attributes: WebGLAttributes); + + setup( + object: Object3D, + material: Material, + program: WebGLProgram, + geometry: BufferGeometry, + index: BufferAttribute, + ): void; + reset(): void; + resetDefaultState(): void; + dispose(): void; + releaseStatesOfGeometry(): void; + releaseStatesOfProgram(): void; + initAttributes(): void; + enableAttribute(attribute: number): void; + disableUnusedAttributes(): void; +} diff --git a/src-testing/src/renderers/webgl/WebGLBufferRenderer.d.ts b/src-testing/src/renderers/webgl/WebGLBufferRenderer.d.ts new file mode 100644 index 000000000..c75f74745 --- /dev/null +++ b/src-testing/src/renderers/webgl/WebGLBufferRenderer.d.ts @@ -0,0 +1,21 @@ +import { WebGLExtensions } from "./WebGLExtensions.js"; +import { WebGLInfo } from "./WebGLInfo.js"; + +export class WebGLBufferRenderer { + constructor( + gl: WebGLRenderingContext, + extensions: WebGLExtensions, + info: WebGLInfo, + ); + + setMode: (value: any) => void; + render: (start: any, count: number) => void; + renderInstances: (start: any, count: number, primcount: number) => void; + renderMultiDraw: (starts: Int32Array, counts: Int32Array, drawCount: number) => void; + renderMultiDrawInstances: ( + starts: Int32Array, + counts: Int32Array, + drawCount: number, + primcount: Int32Array, + ) => void; +} diff --git a/src-testing/src/renderers/webgl/WebGLCapabilities.d.ts b/src-testing/src/renderers/webgl/WebGLCapabilities.d.ts new file mode 100644 index 000000000..c36a9b0f2 --- /dev/null +++ b/src-testing/src/renderers/webgl/WebGLCapabilities.d.ts @@ -0,0 +1,48 @@ +import { PixelFormat, TextureDataType } from "../../constants.js"; + +export interface WebGLCapabilitiesParameters { + /** + * shader precision. Can be "highp", "mediump" or "lowp". + */ + precision?: string | undefined; + + /** + * default is false. + */ + logarithmicDepthBuffer?: boolean | undefined; + + /** + * default is false. + */ + reverseDepthBuffer?: boolean | undefined; +} + +export class WebGLCapabilities { + constructor(gl: WebGLRenderingContext, extensions: any, parameters: WebGLCapabilitiesParameters); + + readonly isWebGL2: boolean; + + getMaxAnisotropy: () => number; + getMaxPrecision: (precision: string) => string; + + textureFormatReadable: (textureFormat: PixelFormat) => boolean; + textureTypeReadable: (textureType: TextureDataType) => boolean; + + precision: string; + logarithmicDepthBuffer: boolean; + reverseDepthBuffer: boolean; + + maxTextures: number; + maxVertexTextures: number; + maxTextureSize: number; + maxCubemapSize: number; + + maxAttributes: number; + maxVertexUniforms: number; + maxVaryings: number; + maxFragmentUniforms: number; + + vertexTextures: boolean; + + maxSamples: number; +} diff --git a/src-testing/src/renderers/webgl/WebGLClipping.d.ts b/src-testing/src/renderers/webgl/WebGLClipping.d.ts new file mode 100644 index 000000000..167a16b35 --- /dev/null +++ b/src-testing/src/renderers/webgl/WebGLClipping.d.ts @@ -0,0 +1,26 @@ +import { Camera } from "../../cameras/Camera.js"; +import { Material } from "../../materials/Material.js"; +import { Plane } from "../../math/Plane.js"; +import { WebGLProperties } from "./WebGLProperties.js"; + +export class WebGLClipping { + constructor(properties: WebGLProperties); + + uniform: { value: any; needsUpdate: boolean }; + + /** + * @default 0 + */ + numPlanes: number; + + /** + * @default 0 + */ + numIntersection: number; + + init(planes: any[], enableLocalClipping: boolean): boolean; + beginShadows(): void; + endShadows(): void; + setGlobalState(planes: Plane[], camera: Camera): void; + setState(material: Material, camera: Camera, useCache: boolean): void; +} diff --git a/src-testing/src/renderers/webgl/WebGLCubeMaps.d.ts b/src-testing/src/renderers/webgl/WebGLCubeMaps.d.ts new file mode 100644 index 000000000..32cda3f61 --- /dev/null +++ b/src-testing/src/renderers/webgl/WebGLCubeMaps.d.ts @@ -0,0 +1,8 @@ +import { WebGLRenderer } from "../WebGLRenderer.js"; + +export class WebGLCubeMaps { + constructor(renderer: WebGLRenderer); + + get(texture: any): any; + dispose(): void; +} diff --git a/src-testing/src/renderers/webgl/WebGLCubeUVMaps.d.ts b/src-testing/src/renderers/webgl/WebGLCubeUVMaps.d.ts new file mode 100644 index 000000000..e94246325 --- /dev/null +++ b/src-testing/src/renderers/webgl/WebGLCubeUVMaps.d.ts @@ -0,0 +1,9 @@ +import { Texture } from "../../textures/Texture.js"; +import { WebGLRenderer } from "../WebGLRenderer.js"; + +export class WebGLCubeUVMaps { + constructor(renderer: WebGLRenderer); + + get(texture: T): T extends Texture ? Texture : T; + dispose(): void; +} diff --git a/src-testing/src/renderers/webgl/WebGLExtensions.d.ts b/src-testing/src/renderers/webgl/WebGLExtensions.d.ts new file mode 100644 index 000000000..0f0c0bf4b --- /dev/null +++ b/src-testing/src/renderers/webgl/WebGLExtensions.d.ts @@ -0,0 +1,7 @@ +export class WebGLExtensions { + constructor(gl: WebGLRenderingContext); + + has(name: string): boolean; + init(): void; + get(name: string): any; +} diff --git a/src-testing/src/renderers/webgl/WebGLGeometries.d.ts b/src-testing/src/renderers/webgl/WebGLGeometries.d.ts new file mode 100644 index 000000000..422249f37 --- /dev/null +++ b/src-testing/src/renderers/webgl/WebGLGeometries.d.ts @@ -0,0 +1,13 @@ +import { BufferAttribute } from "../../core/BufferAttribute.js"; +import { BufferGeometry } from "../../core/BufferGeometry.js"; +import { Object3D } from "../../core/Object3D.js"; +import { WebGLAttributes } from "./WebGLAttributes.js"; +import { WebGLInfo } from "./WebGLInfo.js"; + +export class WebGLGeometries { + constructor(gl: WebGLRenderingContext, attributes: WebGLAttributes, info: WebGLInfo); + + get(object: Object3D, geometry: BufferGeometry): BufferGeometry; + update(geometry: BufferGeometry): void; + getWireframeAttribute(geometry: BufferGeometry): BufferAttribute; +} diff --git a/src-testing/src/renderers/webgl/WebGLIndexedBufferRenderer.d.ts b/src-testing/src/renderers/webgl/WebGLIndexedBufferRenderer.d.ts new file mode 100644 index 000000000..8e016e847 --- /dev/null +++ b/src-testing/src/renderers/webgl/WebGLIndexedBufferRenderer.d.ts @@ -0,0 +1,15 @@ +export class WebGLIndexedBufferRenderer { + constructor(gl: WebGLRenderingContext, extensions: any, info: any); + + setMode: (value: any) => void; + setIndex: (index: any) => void; + render: (start: any, count: number) => void; + renderInstances: (start: any, count: number, primcount: number) => void; + renderMultiDraw: (starts: Int32Array, counts: Int32Array, drawCount: number) => void; + renderMultiDrawInstances: ( + starts: Int32Array, + counts: Int32Array, + drawCount: number, + primcount: Int32Array, + ) => void; +} diff --git a/src-testing/src/renderers/webgl/WebGLInfo.d.ts b/src-testing/src/renderers/webgl/WebGLInfo.d.ts new file mode 100644 index 000000000..952ff6f9f --- /dev/null +++ b/src-testing/src/renderers/webgl/WebGLInfo.d.ts @@ -0,0 +1,39 @@ +import { WebGLProgram } from "./WebGLProgram.js"; + +/** + * An object with a series of statistical information about the graphics board memory and the rendering process. + */ +export class WebGLInfo { + constructor(gl: WebGLRenderingContext); + + /** + * @default true + */ + autoReset: boolean; + + /** + * @default { geometries: 0, textures: 0 } + */ + memory: { + geometries: number; + textures: number; + }; + + /** + * @default null + */ + programs: WebGLProgram[] | null; + + /** + * @default { frame: 0, calls: 0, triangles: 0, points: 0, lines: 0 } + */ + render: { + calls: number; + frame: number; + lines: number; + points: number; + triangles: number; + }; + update(count: number, mode: number, instanceCount: number): void; + reset(): void; +} diff --git a/src-testing/src/renderers/webgl/WebGLLights.d.ts b/src-testing/src/renderers/webgl/WebGLLights.d.ts new file mode 100644 index 000000000..4c01422e8 --- /dev/null +++ b/src-testing/src/renderers/webgl/WebGLLights.d.ts @@ -0,0 +1,49 @@ +import { WebGLExtensions } from "./WebGLExtensions.js"; + +export interface WebGLLightsState { + version: number; + + hash: { + directionalLength: number; + pointLength: number; + spotLength: number; + rectAreaLength: number; + hemiLength: number; + + numDirectionalShadows: number; + numPointShadows: number; + numSpotShadows: number; + numSpotMaps: number; + + numLightProbes: number; + }; + + ambient: number[]; + probe: any[]; + directional: any[]; + directionalShadow: any[]; + directionalShadowMap: any[]; + directionalShadowMatrix: any[]; + spot: any[]; + spotShadow: any[]; + spotShadowMap: any[]; + spotShadowMatrix: any[]; + rectArea: any[]; + point: any[]; + pointShadow: any[]; + pointShadowMap: any[]; + pointShadowMatrix: any[]; + hemi: any[]; + numSpotLightShadowsWithMaps: number; + numLightProbes: number; +} + +export class WebGLLights { + constructor(extensions: WebGLExtensions); + + state: WebGLLightsState; + + get(light: any): any; + setup(lights: any): void; + setupView(lights: any, camera: any): void; +} diff --git a/src-testing/src/renderers/webgl/WebGLObjects.d.ts b/src-testing/src/renderers/webgl/WebGLObjects.d.ts new file mode 100644 index 000000000..aeb0356f7 --- /dev/null +++ b/src-testing/src/renderers/webgl/WebGLObjects.d.ts @@ -0,0 +1,6 @@ +export class WebGLObjects { + constructor(gl: WebGLRenderingContext, geometries: any, attributes: any, info: any); + + update(object: any): any; + dispose(): void; +} diff --git a/src-testing/src/renderers/webgl/WebGLProgram.d.ts b/src-testing/src/renderers/webgl/WebGLProgram.d.ts new file mode 100644 index 000000000..b3e5d6fd8 --- /dev/null +++ b/src-testing/src/renderers/webgl/WebGLProgram.d.ts @@ -0,0 +1,30 @@ +import { WebGLRenderer } from "../WebGLRenderer.js"; +import { WebGLUniforms } from "./WebGLUniforms.js"; + +export class WebGLProgram { + constructor(renderer: WebGLRenderer, cacheKey: string, parameters: object); + + name: string; + id: number; + cacheKey: string; // unique identifier for this program, used for looking up compiled programs from cache. + + /** + * @default 1 + */ + usedTimes: number; + program: any; + vertexShader: WebGLShader; + fragmentShader: WebGLShader; + /** + * @deprecated Use {@link WebGLProgram#getUniforms getUniforms()} instead. + */ + uniforms: any; + /** + * @deprecated Use {@link WebGLProgram#getAttributes getAttributes()} instead. + */ + attributes: any; + + getUniforms(): WebGLUniforms; + getAttributes(): any; + destroy(): void; +} diff --git a/src-testing/src/renderers/webgl/WebGLPrograms.d.ts b/src-testing/src/renderers/webgl/WebGLPrograms.d.ts new file mode 100644 index 000000000..8f5999f06 --- /dev/null +++ b/src-testing/src/renderers/webgl/WebGLPrograms.d.ts @@ -0,0 +1,233 @@ +import { Combine, DepthPackingStrategies, GLSLVersion, Mapping, ShadowMapType, ToneMapping } from "../../constants.js"; +import { Object3D } from "../../core/Object3D.js"; +import { Light } from "../../lights/Light.js"; +import { Material } from "../../materials/Material.js"; +import { Scene } from "../../scenes/Scene.js"; +import { IUniform } from "../shaders/UniformsLib.js"; +import { WebGLRenderer } from "../WebGLRenderer.js"; +import { WebGLBindingStates } from "./WebGLBindingStates.js"; +import { WebGLCapabilities } from "./WebGLCapabilities.js"; +import { WebGLClipping } from "./WebGLClipping.js"; +import { WebGLCubeMaps } from "./WebGLCubeMaps.js"; +import { WebGLExtensions } from "./WebGLExtensions.js"; +import { WebGLLightsState } from "./WebGLLights.js"; +import { WebGLProgram } from "./WebGLProgram.js"; + +export interface WebGLProgramParameters { + shaderID: string; + shaderType: string; + shaderName: string; + + vertexShader: string; + fragmentShader: string; + defines: { [define: string]: string | number | boolean } | undefined; + + customVertexShaderID: string | undefined; + customFragmentShaderID: string | undefined; + + isRawShaderMaterial: boolean; + glslVersion: GLSLVersion | null | undefined; + + precision: "lowp" | "mediump" | "highp"; + + batching: boolean; + batchingColor: boolean; + instancing: boolean; + instancingColor: boolean; + instancingMorph: boolean; + + supportsVertexTextures: boolean; + outputColorSpace: string; + alphaToCoverage: boolean; + + map: boolean; + matcap: boolean; + envMap: boolean; + envMapMode: Mapping | false; + envMapCubeUVHeight: number | null; + aoMap: boolean; + lightMap: boolean; + bumpMap: boolean; + normalMap: boolean; + displacementMap: boolean; + emissiveMap: boolean; + + normalMapObjectSpace: boolean; + normalMapTangentSpace: boolean; + + metalnessMap: boolean; + roughnessMap: boolean; + + anisotropy: boolean; + anisotropyMap: boolean; + + clearcoat: boolean; + clearcoatMap: boolean; + clearcoatNormalMap: boolean; + clearcoatRoughnessMap: boolean; + + dispersion: boolean; + + iridescence: boolean; + iridescenceMap: boolean; + iridescenceThicknessMap: boolean; + + sheen: boolean; + sheenColorMap: boolean; + sheenRoughnessMap: boolean; + + specularMap: boolean; + specularColorMap: boolean; + specularIntensityMap: boolean; + + transmission: boolean; + transmissionMap: boolean; + thicknessMap: boolean; + + gradientMap: boolean; + + opaque: boolean; + + alphaMap: boolean; + alphaTest: boolean; + alphaHash: boolean; + + combine: Combine | undefined; + + // + + mapUv: string | false; + aoMapUv: string | false; + lightMapUv: string | false; + bumpMapUv: string | false; + normalMapUv: string | false; + displacementMapUv: string | false; + emissiveMapUv: string | false; + + metalnessMapUv: string | false; + roughnessMapUv: string | false; + + anisotropyMapUv: string | false; + + clearcoatMapUv: string | false; + clearcoatNormalMapUv: string | false; + clearcoatRoughnessMapUv: string | false; + + iridescenceMapUv: string | false; + iridescenceThicknessMapUv: string | false; + + sheenColorMapUv: string | false; + sheenRoughnessMapUv: string | false; + + specularMapUv: string | false; + specularColorMapUv: string | false; + specularIntensityMapUv: string | false; + + transmissionMapUv: string | false; + thicknessMapUv: string | false; + + alphaMapUv: string | false; + + // + + vertexTangents: boolean; + vertexColors: boolean; + vertexAlphas: boolean; + vertexUv1s: boolean; + vertexUv2s: boolean; + vertexUv3s: boolean; + + pointsUvs: boolean; + + fog: boolean; + useFog: boolean; + fogExp2: boolean; + + flatShading: boolean; + + sizeAttenuation: boolean; + logarithmicDepthBuffer: boolean; + reverseDepthBuffer: boolean; + + skinning: boolean; + + morphTargets: boolean; + morphNormals: boolean; + morphColors: boolean; + morphTargetsCount: number; + morphTextureStride: number; + + numDirLights: number; + numPointLights: number; + numSpotLights: number; + numSpotLightMaps: number; + numRectAreaLights: number; + numHemiLights: number; + + numDirLightShadows: number; + numPointLightShadows: number; + numSpotLightShadows: number; + numSpotLightShadowsWithMaps: number; + + numLightProbes: number; + + numClippingPlanes: number; + numClipIntersection: number; + + dithering: boolean; + + shadowMapEnabled: boolean; + shadowMapType: ShadowMapType; + + toneMapping: ToneMapping; + + decodeVideoTexture: boolean; + decodeVideoTextureEmissive: boolean; + + premultipliedAlpha: boolean; + + doubleSided: boolean; + flipSided: boolean; + + useDepthPacking: boolean; + depthPacking: DepthPackingStrategies | 0; + + index0AttributeName: string | undefined; + + extensionClipCullDistance: boolean; + extensionMultiDraw: boolean; + + rendererExtensionParallelShaderCompile: boolean; + + customProgramCacheKey: string; +} + +export interface WebGLProgramParametersWithUniforms extends WebGLProgramParameters { + uniforms: { [uniform: string]: IUniform }; +} + +export class WebGLPrograms { + constructor( + renderer: WebGLRenderer, + cubemaps: WebGLCubeMaps, + extensions: WebGLExtensions, + capabilities: WebGLCapabilities, + bindingStates: WebGLBindingStates, + clipping: WebGLClipping, + ); + + programs: WebGLProgram[]; + + getParameters( + material: Material, + lights: WebGLLightsState, + shadows: Light[], + scene: Scene, + object: Object3D, + ): WebGLProgramParameters; + + getProgramCacheKey(parameters: WebGLProgramParameters): string; + getUniforms(material: Material): { [uniform: string]: IUniform }; + acquireProgram(parameters: WebGLProgramParametersWithUniforms, cacheKey: string): WebGLProgram; + releaseProgram(program: WebGLProgram): void; +} diff --git a/src-testing/src/renderers/webgl/WebGLProperties.d.ts b/src-testing/src/renderers/webgl/WebGLProperties.d.ts new file mode 100644 index 000000000..adcf01ec9 --- /dev/null +++ b/src-testing/src/renderers/webgl/WebGLProperties.d.ts @@ -0,0 +1,9 @@ +export class WebGLProperties { + constructor(); + + has: (object: unknown) => boolean; + get: (object: unknown) => unknown; + remove: (object: unknown) => void; + update: (object: unknown, key: unknown, value: unknown) => unknown; + dispose: () => void; +} diff --git a/src-testing/src/renderers/webgl/WebGLRenderLists.d.ts b/src-testing/src/renderers/webgl/WebGLRenderLists.d.ts new file mode 100644 index 000000000..0f16a4287 --- /dev/null +++ b/src-testing/src/renderers/webgl/WebGLRenderLists.d.ts @@ -0,0 +1,66 @@ +import { Camera } from "../../cameras/Camera.js"; +import { BufferGeometry } from "../../core/BufferGeometry.js"; +import { Object3D } from "../../core/Object3D.js"; +import { Material } from "../../materials/Material.js"; +import { Group } from "../../objects/Group.js"; +import { Scene } from "../../scenes/Scene.js"; +import { WebGLProgram } from "./WebGLProgram.js"; +import { WebGLProperties } from "./WebGLProperties.js"; + +export interface RenderItem { + id: number; + object: Object3D; + geometry: BufferGeometry | null; + material: Material; + program: WebGLProgram; + groupOrder: number; + renderOrder: number; + z: number; + group: Group | null; +} + +export class WebGLRenderList { + constructor(properties: WebGLProperties); + + /** + * @default [] + */ + opaque: RenderItem[]; + + /** + * @default [] + */ + transparent: RenderItem[]; + + /** + * @default [] + */ + transmissive: RenderItem[]; + + init(): void; + push( + object: Object3D, + geometry: BufferGeometry | null, + material: Material, + groupOrder: number, + z: number, + group: Group | null, + ): void; + unshift( + object: Object3D, + geometry: BufferGeometry | null, + material: Material, + groupOrder: number, + z: number, + group: Group | null, + ): void; + sort(opaqueSort: (a: any, b: any) => number, transparentSort: (a: any, b: any) => number): void; + finish(): void; +} + +export class WebGLRenderLists { + constructor(properties: WebGLProperties); + + dispose(): void; + get(scene: Scene, renderCallDepth: number): WebGLRenderList; +} diff --git a/src-testing/src/renderers/webgl/WebGLShader.d.ts b/src-testing/src/renderers/webgl/WebGLShader.d.ts new file mode 100644 index 000000000..5704fb88e --- /dev/null +++ b/src-testing/src/renderers/webgl/WebGLShader.d.ts @@ -0,0 +1 @@ +export function WebGLShader(gl: WebGLRenderingContext, type: string, string: string): WebGLShader; diff --git a/src-testing/src/renderers/webgl/WebGLShadowMap.d.ts b/src-testing/src/renderers/webgl/WebGLShadowMap.d.ts new file mode 100644 index 000000000..8368fdee7 --- /dev/null +++ b/src-testing/src/renderers/webgl/WebGLShadowMap.d.ts @@ -0,0 +1,38 @@ +import { Camera } from "../../cameras/Camera.js"; +import { ShadowMapType } from "../../constants.js"; +import { Light } from "../../lights/Light.js"; +import { Scene } from "../../scenes/Scene.js"; +import { WebGLRenderer } from "../WebGLRenderer.js"; +import { WebGLCapabilities } from "./WebGLCapabilities.js"; +import { WebGLObjects } from "./WebGLObjects.js"; + +export class WebGLShadowMap { + constructor(_renderer: WebGLRenderer, _objects: WebGLObjects, _capabilities: WebGLCapabilities); + + /** + * @default false + */ + enabled: boolean; + + /** + * @default true + */ + autoUpdate: boolean; + + /** + * @default false + */ + needsUpdate: boolean; + + /** + * @default THREE.PCFShadowMap + */ + type: ShadowMapType; + + render(shadowsArray: Light[], scene: Scene, camera: Camera): void; + + /** + * @deprecated Use {@link Material#shadowSide} instead. + */ + cullFace: any; +} diff --git a/src-testing/src/renderers/webgl/WebGLState.d.ts b/src-testing/src/renderers/webgl/WebGLState.d.ts new file mode 100644 index 000000000..13d4850e9 --- /dev/null +++ b/src-testing/src/renderers/webgl/WebGLState.d.ts @@ -0,0 +1,116 @@ +import { + Blending, + BlendingDstFactor, + BlendingEquation, + BlendingSrcFactor, + CullFace, + DepthModes, +} from "../../constants.js"; +import { Material } from "../../materials/Material.js"; +import { Vector4 } from "../../math/Vector4.js"; +import { WebGLRenderTarget } from "../WebGLRenderTarget.js"; + +export class WebGLColorBuffer { + constructor(); + + setMask(colorMask: boolean): void; + setLocked(lock: boolean): void; + setClear(r: number, g: number, b: number, a: number, premultipliedAlpha: boolean): void; + reset(): void; +} + +export class WebGLDepthBuffer { + constructor(); + + setTest(depthTest: boolean): void; + setMask(depthMask: boolean): void; + setFunc(depthFunc: DepthModes): void; + setLocked(lock: boolean): void; + setClear(depth: number): void; + reset(): void; +} + +export class WebGLStencilBuffer { + constructor(); + + setTest(stencilTest: boolean): void; + setMask(stencilMask: number): void; + setFunc(stencilFunc: number, stencilRef: number, stencilMask: number): void; + setOp(stencilFail: number, stencilZFail: number, stencilZPass: number): void; + setLocked(lock: boolean): void; + setClear(stencil: number): void; + reset(): void; +} + +export class WebGLState { + constructor(gl: WebGLRenderingContext); + + buffers: { + color: WebGLColorBuffer; + depth: WebGLDepthBuffer; + stencil: WebGLStencilBuffer; + }; + + enable(id: number): void; + disable(id: number): void; + bindFramebuffer(target: number, framebuffer: WebGLFramebuffer | null): void; + drawBuffers(renderTarget: WebGLRenderTarget | null, framebuffer: WebGLFramebuffer | null): void; + useProgram(program: any): boolean; + setBlending( + blending: Blending, + blendEquation?: BlendingEquation, + blendSrc?: BlendingSrcFactor, + blendDst?: BlendingDstFactor, + blendEquationAlpha?: BlendingEquation, + blendSrcAlpha?: BlendingSrcFactor, + blendDstAlpha?: BlendingDstFactor, + premultiplyAlpha?: boolean, + ): void; + setMaterial(material: Material, frontFaceCW: boolean): void; + setFlipSided(flipSided: boolean): void; + setCullFace(cullFace: CullFace): void; + setLineWidth(width: number): void; + setPolygonOffset(polygonoffset: boolean, factor?: number, units?: number): void; + setScissorTest(scissorTest: boolean): void; + activeTexture(webglSlot: number): void; + bindTexture(webglType: number, webglTexture: any): void; + unbindTexture(): void; + // Same interface as https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/compressedTexImage2D + compressedTexImage2D( + target: number, + level: number, + internalformat: number, + width: number, + height: number, + border: number, + data: ArrayBufferView, + ): void; + // Same interface as https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/texImage2D + texImage2D( + target: number, + level: number, + internalformat: number, + width: number, + height: number, + border: number, + format: number, + type: number, + pixels: ArrayBufferView | null, + ): void; + texImage2D(target: number, level: number, internalformat: number, format: number, type: number, source: any): void; + texImage3D( + target: number, + level: number, + internalformat: number, + width: number, + height: number, + depth: number, + border: number, + format: number, + type: number, + pixels: any, + ): void; + scissor(scissor: Vector4): void; + viewport(viewport: Vector4): void; + reset(): void; +} diff --git a/src-testing/src/renderers/webgl/WebGLTextures.d.ts b/src-testing/src/renderers/webgl/WebGLTextures.d.ts new file mode 100644 index 000000000..031866dee --- /dev/null +++ b/src-testing/src/renderers/webgl/WebGLTextures.d.ts @@ -0,0 +1,30 @@ +import { WebGLCapabilities } from "./WebGLCapabilities.js"; +import { WebGLExtensions } from "./WebGLExtensions.js"; +import { WebGLInfo } from "./WebGLInfo.js"; +import { WebGLProperties } from "./WebGLProperties.js"; +import { WebGLState } from "./WebGLState.js"; +import { WebGLUtils } from "./WebGLUtils.js"; + +export class WebGLTextures { + constructor( + gl: WebGLRenderingContext, + extensions: WebGLExtensions, + state: WebGLState, + properties: WebGLProperties, + capabilities: WebGLCapabilities, + utils: WebGLUtils, + info: WebGLInfo, + ); + + allocateTextureUnit(): void; + resetTextureUnits(): void; + setTexture2D(texture: any, slot: number): void; + setTexture2DArray(texture: any, slot: number): void; + setTexture3D(texture: any, slot: number): void; + setTextureCube(texture: any, slot: number): void; + setupRenderTarget(renderTarget: any): void; + updateRenderTargetMipmap(renderTarget: any): void; + updateMultisampleRenderTarget(renderTarget: any): void; + safeSetTexture2D(texture: any, slot: number): void; + safeSetTextureCube(texture: any, slot: number): void; +} diff --git a/src-testing/src/renderers/webgl/WebGLUniforms.d.ts b/src-testing/src/renderers/webgl/WebGLUniforms.d.ts new file mode 100644 index 000000000..925b5e4bf --- /dev/null +++ b/src-testing/src/renderers/webgl/WebGLUniforms.d.ts @@ -0,0 +1,12 @@ +import { WebGLProgram } from "./WebGLProgram.js"; +import { WebGLTextures } from "./WebGLTextures.js"; + +export class WebGLUniforms { + constructor(gl: WebGLRenderingContext, program: WebGLProgram); + + setValue(gl: WebGLRenderingContext, name: string, value: any, textures: WebGLTextures): void; + setOptional(gl: WebGLRenderingContext, object: any, name: string): void; + + static upload(gl: WebGLRenderingContext, seq: any, values: any[], textures: WebGLTextures): void; + static seqWithValue(seq: any, values: any[]): any[]; +} diff --git a/src-testing/src/renderers/webgl/WebGLUniformsGroups.d.ts b/src-testing/src/renderers/webgl/WebGLUniformsGroups.d.ts new file mode 100644 index 000000000..a5e052c1f --- /dev/null +++ b/src-testing/src/renderers/webgl/WebGLUniformsGroups.d.ts @@ -0,0 +1,17 @@ +import { UniformsGroup } from "../../core/UniformsGroup.js"; + +import { WebGLCapabilities } from "./WebGLCapabilities.js"; +import { WebGLInfo } from "./WebGLInfo.js"; +import { WebGLProgram } from "./WebGLProgram.js"; +import { WebGLState } from "./WebGLState.js"; + +export function WebGLUniformsGroups( + gl: WebGLRenderingContext, + info: WebGLInfo, + capabilities: WebGLCapabilities, + state: WebGLState, +): { + dispose: () => void; + update: (uniformsGroup: UniformsGroup, program: WebGLProgram) => void; + bind: (uniformsGroup: UniformsGroup, program: WebGLProgram) => void; +}; diff --git a/src-testing/src/renderers/webgl/WebGLUtils.d.ts b/src-testing/src/renderers/webgl/WebGLUtils.d.ts new file mode 100644 index 000000000..53011bfe6 --- /dev/null +++ b/src-testing/src/renderers/webgl/WebGLUtils.d.ts @@ -0,0 +1,11 @@ +import { CompressedPixelFormat, PixelFormat, TextureDataType } from "../../constants.js"; +import { WebGLExtensions } from "./WebGLExtensions.js"; + +export class WebGLUtils { + constructor( + gl: WebGLRenderingContext | WebGL2RenderingContext, + extensions: WebGLExtensions, + ); + + convert(p: PixelFormat | CompressedPixelFormat | TextureDataType, colorSpace?: string): number | null; +} diff --git a/src-testing/src/renderers/webgpu/WebGPUBackend.ts b/src-testing/src/renderers/webgpu/WebGPUBackend.ts new file mode 100644 index 000000000..930197a02 --- /dev/null +++ b/src-testing/src/renderers/webgpu/WebGPUBackend.ts @@ -0,0 +1,1297 @@ +/*// debugger tools +import 'https://greggman.github.io/webgpu-avoid-redundant-state-setting/webgpu-check-redundant-state-setting.js'; +//*/ + +import { + GPUFeatureName, + GPULoadOp, + GPUStoreOp, + GPUIndexFormat, + GPUTextureViewDimension, +} from './utils/WebGPUConstants.js'; + +import WGSLNodeBuilder from './nodes/WGSLNodeBuilder.js'; +import Backend from '../common/Backend.js'; + +import WebGPUUtils from './utils/WebGPUUtils.js'; +import WebGPUAttributeUtils from './utils/WebGPUAttributeUtils.js'; +import WebGPUBindingUtils from './utils/WebGPUBindingUtils.js'; +import WebGPUPipelineUtils from './utils/WebGPUPipelineUtils.js'; +import WebGPUTextureUtils from './utils/WebGPUTextureUtils.js'; + +import { WebGPUCoordinateSystem } from '../../constants.js'; + +// + +class WebGPUBackend extends Backend { + constructor(parameters = {}) { + super(parameters); + + this.isWebGPUBackend = true; + + // some parameters require default values other than "undefined" + this.parameters.alpha = parameters.alpha === undefined ? true : parameters.alpha; + + this.parameters.requiredLimits = parameters.requiredLimits === undefined ? {} : parameters.requiredLimits; + + this.trackTimestamp = parameters.trackTimestamp === true; + + this.device = null; + this.context = null; + this.colorBuffer = null; + this.defaultRenderPassdescriptor = null; + + this.utils = new WebGPUUtils(this); + this.attributeUtils = new WebGPUAttributeUtils(this); + this.bindingUtils = new WebGPUBindingUtils(this); + this.pipelineUtils = new WebGPUPipelineUtils(this); + this.textureUtils = new WebGPUTextureUtils(this); + this.occludedResolveCache = new Map(); + } + + async init(renderer) { + await super.init(renderer); + + // + + const parameters = this.parameters; + + // create the device if it is not passed with parameters + + let device; + + if (parameters.device === undefined) { + const adapterOptions = { + powerPreference: parameters.powerPreference, + }; + + const adapter = await navigator.gpu.requestAdapter(adapterOptions); + + if (adapter === null) { + throw new Error('WebGPUBackend: Unable to create WebGPU adapter.'); + } + + // feature support + + const features = Object.values(GPUFeatureName); + + const supportedFeatures = []; + + for (const name of features) { + if (adapter.features.has(name)) { + supportedFeatures.push(name); + } + } + + const deviceDescriptor = { + requiredFeatures: supportedFeatures, + requiredLimits: parameters.requiredLimits, + }; + + device = await adapter.requestDevice(deviceDescriptor); + } else { + device = parameters.device; + } + + const context = + parameters.context !== undefined ? parameters.context : renderer.domElement.getContext('webgpu'); + + this.device = device; + this.context = context; + + const alphaMode = parameters.alpha ? 'premultiplied' : 'opaque'; + + this.trackTimestamp = this.trackTimestamp && this.hasFeature(GPUFeatureName.TimestampQuery); + + this.context.configure({ + device: this.device, + format: this.utils.getPreferredCanvasFormat(), + usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.COPY_SRC, + alphaMode: alphaMode, + }); + + this.updateSize(); + } + + get coordinateSystem() { + return WebGPUCoordinateSystem; + } + + async getArrayBufferAsync(attribute) { + return await this.attributeUtils.getArrayBufferAsync(attribute); + } + + getContext() { + return this.context; + } + + _getDefaultRenderPassDescriptor() { + let descriptor = this.defaultRenderPassdescriptor; + + if (descriptor === null) { + const renderer = this.renderer; + + descriptor = { + colorAttachments: [ + { + view: null, + }, + ], + }; + + if (this.renderer.depth === true || this.renderer.stencil === true) { + descriptor.depthStencilAttachment = { + view: this.textureUtils.getDepthBuffer(renderer.depth, renderer.stencil).createView(), + }; + } + + const colorAttachment = descriptor.colorAttachments[0]; + + if (this.renderer.samples > 0) { + colorAttachment.view = this.colorBuffer.createView(); + } else { + colorAttachment.resolveTarget = undefined; + } + + this.defaultRenderPassdescriptor = descriptor; + } + + const colorAttachment = descriptor.colorAttachments[0]; + + if (this.renderer.samples > 0) { + colorAttachment.resolveTarget = this.context.getCurrentTexture().createView(); + } else { + colorAttachment.view = this.context.getCurrentTexture().createView(); + } + + return descriptor; + } + + _getRenderPassDescriptor(renderContext) { + const renderTarget = renderContext.renderTarget; + const renderTargetData = this.get(renderTarget); + + let descriptors = renderTargetData.descriptors; + + if ( + descriptors === undefined || + renderTargetData.width !== renderTarget.width || + renderTargetData.height !== renderTarget.height || + renderTargetData.activeMipmapLevel !== renderTarget.activeMipmapLevel || + renderTargetData.samples !== renderTarget.samples + ) { + descriptors = {}; + + renderTargetData.descriptors = descriptors; + + // dispose + + const onDispose = () => { + renderTarget.removeEventListener('dispose', onDispose); + + this.delete(renderTarget); + }; + + renderTarget.addEventListener('dispose', onDispose); + } + + const cacheKey = renderContext.getCacheKey(); + + let descriptor = descriptors[cacheKey]; + + if (descriptor === undefined) { + const textures = renderContext.textures; + const colorAttachments = []; + + for (let i = 0; i < textures.length; i++) { + const textureData = this.get(textures[i]); + + const textureView = textureData.texture.createView({ + baseMipLevel: renderContext.activeMipmapLevel, + mipLevelCount: 1, + baseArrayLayer: renderContext.activeCubeFace, + dimension: GPUTextureViewDimension.TwoD, + }); + + let view, resolveTarget; + + if (textureData.msaaTexture !== undefined) { + view = textureData.msaaTexture.createView(); + resolveTarget = textureView; + } else { + view = textureView; + resolveTarget = undefined; + } + + colorAttachments.push({ + view, + resolveTarget, + loadOp: GPULoadOp.Load, + storeOp: GPUStoreOp.Store, + }); + } + + descriptor = { + colorAttachments, + }; + + if (renderContext.depth) { + const depthTextureData = this.get(renderContext.depthTexture); + + const depthStencilAttachment = { + view: depthTextureData.texture.createView(), + }; + descriptor.depthStencilAttachment = depthStencilAttachment; + } + + descriptors[cacheKey] = descriptor; + + renderTargetData.width = renderTarget.width; + renderTargetData.height = renderTarget.height; + renderTargetData.samples = renderTarget.samples; + renderTargetData.activeMipmapLevel = renderTarget.activeMipmapLevel; + } + + return descriptor; + } + + beginRender(renderContext) { + const renderContextData = this.get(renderContext); + + const device = this.device; + const occlusionQueryCount = renderContext.occlusionQueryCount; + + let occlusionQuerySet; + + if (occlusionQueryCount > 0) { + if (renderContextData.currentOcclusionQuerySet) renderContextData.currentOcclusionQuerySet.destroy(); + if (renderContextData.currentOcclusionQueryBuffer) renderContextData.currentOcclusionQueryBuffer.destroy(); + + // Get a reference to the array of objects with queries. The renderContextData property + // can be changed by another render pass before the buffer.mapAsyc() completes. + renderContextData.currentOcclusionQuerySet = renderContextData.occlusionQuerySet; + renderContextData.currentOcclusionQueryBuffer = renderContextData.occlusionQueryBuffer; + renderContextData.currentOcclusionQueryObjects = renderContextData.occlusionQueryObjects; + + // + + occlusionQuerySet = device.createQuerySet({ type: 'occlusion', count: occlusionQueryCount }); + + renderContextData.occlusionQuerySet = occlusionQuerySet; + renderContextData.occlusionQueryIndex = 0; + renderContextData.occlusionQueryObjects = new Array(occlusionQueryCount); + + renderContextData.lastOcclusionObject = null; + } + + let descriptor; + + if (renderContext.textures === null) { + descriptor = this._getDefaultRenderPassDescriptor(); + } else { + descriptor = this._getRenderPassDescriptor(renderContext); + } + + this.initTimestampQuery(renderContext, descriptor); + + descriptor.occlusionQuerySet = occlusionQuerySet; + + const depthStencilAttachment = descriptor.depthStencilAttachment; + + if (renderContext.textures !== null) { + const colorAttachments = descriptor.colorAttachments; + + for (let i = 0; i < colorAttachments.length; i++) { + const colorAttachment = colorAttachments[i]; + + if (renderContext.clearColor) { + colorAttachment.clearValue = i === 0 ? renderContext.clearColorValue : { r: 0, g: 0, b: 0, a: 1 }; + colorAttachment.loadOp = GPULoadOp.Clear; + colorAttachment.storeOp = GPUStoreOp.Store; + } else { + colorAttachment.loadOp = GPULoadOp.Load; + colorAttachment.storeOp = GPUStoreOp.Store; + } + } + } else { + const colorAttachment = descriptor.colorAttachments[0]; + + if (renderContext.clearColor) { + colorAttachment.clearValue = renderContext.clearColorValue; + colorAttachment.loadOp = GPULoadOp.Clear; + colorAttachment.storeOp = GPUStoreOp.Store; + } else { + colorAttachment.loadOp = GPULoadOp.Load; + colorAttachment.storeOp = GPUStoreOp.Store; + } + } + + // + + if (renderContext.depth) { + if (renderContext.clearDepth) { + depthStencilAttachment.depthClearValue = renderContext.clearDepthValue; + depthStencilAttachment.depthLoadOp = GPULoadOp.Clear; + depthStencilAttachment.depthStoreOp = GPUStoreOp.Store; + } else { + depthStencilAttachment.depthLoadOp = GPULoadOp.Load; + depthStencilAttachment.depthStoreOp = GPUStoreOp.Store; + } + } + + if (renderContext.stencil) { + if (renderContext.clearStencil) { + depthStencilAttachment.stencilClearValue = renderContext.clearStencilValue; + depthStencilAttachment.stencilLoadOp = GPULoadOp.Clear; + depthStencilAttachment.stencilStoreOp = GPUStoreOp.Store; + } else { + depthStencilAttachment.stencilLoadOp = GPULoadOp.Load; + depthStencilAttachment.stencilStoreOp = GPUStoreOp.Store; + } + } + + // + + const encoder = device.createCommandEncoder({ label: 'renderContext_' + renderContext.id }); + const currentPass = encoder.beginRenderPass(descriptor); + + // + + renderContextData.descriptor = descriptor; + renderContextData.encoder = encoder; + renderContextData.currentPass = currentPass; + renderContextData.currentSets = { attributes: {}, bindingGroups: [], pipeline: null, index: null }; + renderContextData.renderBundles = []; + + // + + if (renderContext.viewport) { + this.updateViewport(renderContext); + } + + if (renderContext.scissor) { + const { x, y, width, height } = renderContext.scissorValue; + + currentPass.setScissorRect(x, y, width, height); + } + } + + finishRender(renderContext) { + const renderContextData = this.get(renderContext); + const occlusionQueryCount = renderContext.occlusionQueryCount; + + if (renderContextData.renderBundles.length > 0) { + renderContextData.currentPass.executeBundles(renderContextData.renderBundles); + } + + if (occlusionQueryCount > renderContextData.occlusionQueryIndex) { + renderContextData.currentPass.endOcclusionQuery(); + } + + renderContextData.currentPass.end(); + + if (occlusionQueryCount > 0) { + const bufferSize = occlusionQueryCount * 8; // 8 byte entries for query results + + // + + let queryResolveBuffer = this.occludedResolveCache.get(bufferSize); + + if (queryResolveBuffer === undefined) { + queryResolveBuffer = this.device.createBuffer({ + size: bufferSize, + usage: GPUBufferUsage.QUERY_RESOLVE | GPUBufferUsage.COPY_SRC, + }); + + this.occludedResolveCache.set(bufferSize, queryResolveBuffer); + } + + // + + const readBuffer = this.device.createBuffer({ + size: bufferSize, + usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ, + }); + + // two buffers required here - WebGPU doesn't allow usage of QUERY_RESOLVE & MAP_READ to be combined + renderContextData.encoder.resolveQuerySet( + renderContextData.occlusionQuerySet, + 0, + occlusionQueryCount, + queryResolveBuffer, + 0, + ); + renderContextData.encoder.copyBufferToBuffer(queryResolveBuffer, 0, readBuffer, 0, bufferSize); + + renderContextData.occlusionQueryBuffer = readBuffer; + + // + + this.resolveOccludedAsync(renderContext); + } + + this.prepareTimestampBuffer(renderContext, renderContextData.encoder); + + this.device.queue.submit([renderContextData.encoder.finish()]); + + // + + if (renderContext.textures !== null) { + const textures = renderContext.textures; + + for (let i = 0; i < textures.length; i++) { + const texture = textures[i]; + + if (texture.generateMipmaps === true) { + this.textureUtils.generateMipmaps(texture); + } + } + } + } + + isOccluded(renderContext, object) { + const renderContextData = this.get(renderContext); + + return renderContextData.occluded && renderContextData.occluded.has(object); + } + + async resolveOccludedAsync(renderContext) { + const renderContextData = this.get(renderContext); + + // handle occlusion query results + + const { currentOcclusionQueryBuffer, currentOcclusionQueryObjects } = renderContextData; + + if (currentOcclusionQueryBuffer && currentOcclusionQueryObjects) { + const occluded = new WeakSet(); + + renderContextData.currentOcclusionQueryObjects = null; + renderContextData.currentOcclusionQueryBuffer = null; + + await currentOcclusionQueryBuffer.mapAsync(GPUMapMode.READ); + + const buffer = currentOcclusionQueryBuffer.getMappedRange(); + const results = new BigUint64Array(buffer); + + for (let i = 0; i < currentOcclusionQueryObjects.length; i++) { + if (results[i] !== BigInt(0)) { + occluded.add(currentOcclusionQueryObjects[i]); + } + } + + currentOcclusionQueryBuffer.destroy(); + + renderContextData.occluded = occluded; + } + } + + updateViewport(renderContext) { + const { currentPass } = this.get(renderContext); + const { x, y, width, height, minDepth, maxDepth } = renderContext.viewportValue; + + currentPass.setViewport(x, y, width, height, minDepth, maxDepth); + } + + clear(color, depth, stencil, renderTargetData = null) { + const device = this.device; + const renderer = this.renderer; + + let colorAttachments = []; + + let depthStencilAttachment; + let clearValue; + + let supportsDepth; + let supportsStencil; + + if (color) { + const clearColor = this.getClearColor(); + + if (this.renderer.alpha === true) { + // premultiply alpha + + const a = clearColor.a; + + clearValue = { r: clearColor.r * a, g: clearColor.g * a, b: clearColor.b * a, a: a }; + } else { + clearValue = { r: clearColor.r, g: clearColor.g, b: clearColor.b, a: clearColor.a }; + } + } + + if (renderTargetData === null) { + supportsDepth = renderer.depth; + supportsStencil = renderer.stencil; + + const descriptor = this._getDefaultRenderPassDescriptor(); + + if (color) { + colorAttachments = descriptor.colorAttachments; + + const colorAttachment = colorAttachments[0]; + + colorAttachment.clearValue = clearValue; + colorAttachment.loadOp = GPULoadOp.Clear; + colorAttachment.storeOp = GPUStoreOp.Store; + } + + if (supportsDepth || supportsStencil) { + depthStencilAttachment = descriptor.depthStencilAttachment; + } + } else { + supportsDepth = renderTargetData.depth; + supportsStencil = renderTargetData.stencil; + + if (color) { + for (const texture of renderTargetData.textures) { + const textureData = this.get(texture); + const textureView = textureData.texture.createView(); + + let view, resolveTarget; + + if (textureData.msaaTexture !== undefined) { + view = textureData.msaaTexture.createView(); + resolveTarget = textureView; + } else { + view = textureView; + resolveTarget = undefined; + } + + colorAttachments.push({ + view, + resolveTarget, + clearValue, + loadOp: GPULoadOp.Clear, + storeOp: GPUStoreOp.Store, + }); + } + } + + if (supportsDepth || supportsStencil) { + const depthTextureData = this.get(renderTargetData.depthTexture); + + depthStencilAttachment = { + view: depthTextureData.texture.createView(), + }; + } + } + + // + + if (supportsDepth) { + if (depth) { + depthStencilAttachment.depthLoadOp = GPULoadOp.Clear; + depthStencilAttachment.depthClearValue = renderer.getClearDepth(); + depthStencilAttachment.depthStoreOp = GPUStoreOp.Store; + } else { + depthStencilAttachment.depthLoadOp = GPULoadOp.Load; + depthStencilAttachment.depthStoreOp = GPUStoreOp.Store; + } + } + + // + + if (supportsStencil) { + if (stencil) { + depthStencilAttachment.stencilLoadOp = GPULoadOp.Clear; + depthStencilAttachment.stencilClearValue = renderer.getClearStencil(); + depthStencilAttachment.stencilStoreOp = GPUStoreOp.Store; + } else { + depthStencilAttachment.stencilLoadOp = GPULoadOp.Load; + depthStencilAttachment.stencilStoreOp = GPUStoreOp.Store; + } + } + + // + + const encoder = device.createCommandEncoder({}); + const currentPass = encoder.beginRenderPass({ + colorAttachments, + depthStencilAttachment, + }); + + currentPass.end(); + + device.queue.submit([encoder.finish()]); + } + + // compute + + beginCompute(computeGroup) { + const groupGPU = this.get(computeGroup); + + const descriptor = {}; + + this.initTimestampQuery(computeGroup, descriptor); + + groupGPU.cmdEncoderGPU = this.device.createCommandEncoder(); + + groupGPU.passEncoderGPU = groupGPU.cmdEncoderGPU.beginComputePass(descriptor); + } + + compute(computeGroup, computeNode, bindings, pipeline) { + const { passEncoderGPU } = this.get(computeGroup); + + // pipeline + + const pipelineGPU = this.get(pipeline).pipeline; + passEncoderGPU.setPipeline(pipelineGPU); + + // bind groups + + for (let i = 0, l = bindings.length; i < l; i++) { + const bindGroup = bindings[i]; + const bindingsData = this.get(bindGroup); + + passEncoderGPU.setBindGroup(i, bindingsData.group); + } + + const maxComputeWorkgroupsPerDimension = this.device.limits.maxComputeWorkgroupsPerDimension; + + const computeNodeData = this.get(computeNode); + + if (computeNodeData.dispatchSize === undefined) computeNodeData.dispatchSize = { x: 0, y: 1, z: 1 }; + + const { dispatchSize } = computeNodeData; + + if (computeNode.dispatchCount > maxComputeWorkgroupsPerDimension) { + dispatchSize.x = Math.min(computeNode.dispatchCount, maxComputeWorkgroupsPerDimension); + dispatchSize.y = Math.ceil(computeNode.dispatchCount / maxComputeWorkgroupsPerDimension); + } else { + dispatchSize.x = computeNode.dispatchCount; + } + + passEncoderGPU.dispatchWorkgroups(dispatchSize.x, dispatchSize.y, dispatchSize.z); + } + + finishCompute(computeGroup) { + const groupData = this.get(computeGroup); + + groupData.passEncoderGPU.end(); + + this.prepareTimestampBuffer(computeGroup, groupData.cmdEncoderGPU); + + this.device.queue.submit([groupData.cmdEncoderGPU.finish()]); + } + + async waitForGPU() { + await this.device.queue.onSubmittedWorkDone(); + } + + // render object + + draw(renderObject, info) { + const { object, context, pipeline } = renderObject; + const bindings = renderObject.getBindings(); + const renderContextData = this.get(context); + const pipelineGPU = this.get(pipeline).pipeline; + const currentSets = renderContextData.currentSets; + const passEncoderGPU = renderContextData.currentPass; + + const drawParams = renderObject.getDrawParameters(); + + if (drawParams === null) return; + + // pipeline + + if (currentSets.pipeline !== pipelineGPU) { + passEncoderGPU.setPipeline(pipelineGPU); + + currentSets.pipeline = pipelineGPU; + } + + // bind groups + + const currentBindingGroups = currentSets.bindingGroups; + + for (let i = 0, l = bindings.length; i < l; i++) { + const bindGroup = bindings[i]; + const bindingsData = this.get(bindGroup); + + if (currentBindingGroups[bindGroup.index] !== bindGroup.id) { + passEncoderGPU.setBindGroup(bindGroup.index, bindingsData.group); + currentBindingGroups[bindGroup.index] = bindGroup.id; + } + } + + // attributes + + const index = renderObject.getIndex(); + + const hasIndex = index !== null; + + // index + + if (hasIndex === true) { + if (currentSets.index !== index) { + const buffer = this.get(index).buffer; + const indexFormat = index.array instanceof Uint16Array ? GPUIndexFormat.Uint16 : GPUIndexFormat.Uint32; + + passEncoderGPU.setIndexBuffer(buffer, indexFormat); + + currentSets.index = index; + } + } + + // vertex buffers + + const vertexBuffers = renderObject.getVertexBuffers(); + + for (let i = 0, l = vertexBuffers.length; i < l; i++) { + const vertexBuffer = vertexBuffers[i]; + + if (currentSets.attributes[i] !== vertexBuffer) { + const buffer = this.get(vertexBuffer).buffer; + passEncoderGPU.setVertexBuffer(i, buffer); + + currentSets.attributes[i] = vertexBuffer; + } + } + + // occlusion queries - handle multiple consecutive draw calls for an object + + if (renderContextData.occlusionQuerySet !== undefined) { + const lastObject = renderContextData.lastOcclusionObject; + + if (lastObject !== object) { + if (lastObject !== null && lastObject.occlusionTest === true) { + passEncoderGPU.endOcclusionQuery(); + renderContextData.occlusionQueryIndex++; + } + + if (object.occlusionTest === true) { + passEncoderGPU.beginOcclusionQuery(renderContextData.occlusionQueryIndex); + renderContextData.occlusionQueryObjects[renderContextData.occlusionQueryIndex] = object; + } + + renderContextData.lastOcclusionObject = object; + } + } + + // draw + + if (object.isBatchedMesh === true) { + const starts = object._multiDrawStarts; + const counts = object._multiDrawCounts; + const drawCount = object._multiDrawCount; + const drawInstances = object._multiDrawInstances; + + const bytesPerElement = hasIndex ? index.array.BYTES_PER_ELEMENT : 1; + + for (let i = 0; i < drawCount; i++) { + const count = drawInstances ? drawInstances[i] : 1; + const firstInstance = count > 1 ? 0 : i; + + passEncoderGPU.drawIndexed(counts[i], count, starts[i] / bytesPerElement, 0, firstInstance); + } + } else if (hasIndex === true) { + const { vertexCount: indexCount, instanceCount, firstVertex: firstIndex } = drawParams; + + const indirect = renderObject.getIndirect(); + + if (indirect !== null) { + const buffer = this.get(indirect).buffer; + + passEncoderGPU.drawIndexedIndirect(buffer, 0); + } else { + passEncoderGPU.drawIndexed(indexCount, instanceCount, firstIndex, 0, 0); + } + + info.update(object, indexCount, instanceCount); + } else { + const { vertexCount, instanceCount, firstVertex } = drawParams; + + const indirect = renderObject.getIndirect(); + + if (indirect !== null) { + const buffer = this.get(indirect).buffer; + + passEncoderGPU.drawIndirect(buffer, 0); + } else { + passEncoderGPU.draw(vertexCount, instanceCount, firstVertex, 0); + } + + info.update(object, vertexCount, instanceCount); + } + } + + // cache key + + needsRenderUpdate(renderObject) { + const data = this.get(renderObject); + + const { object, material } = renderObject; + + const utils = this.utils; + + const sampleCount = utils.getSampleCountRenderContext(renderObject.context); + const colorSpace = utils.getCurrentColorSpace(renderObject.context); + const colorFormat = utils.getCurrentColorFormat(renderObject.context); + const depthStencilFormat = utils.getCurrentDepthStencilFormat(renderObject.context); + const primitiveTopology = utils.getPrimitiveTopology(object, material); + + let needsUpdate = false; + + if ( + data.material !== material || + data.materialVersion !== material.version || + data.transparent !== material.transparent || + data.blending !== material.blending || + data.premultipliedAlpha !== material.premultipliedAlpha || + data.blendSrc !== material.blendSrc || + data.blendDst !== material.blendDst || + data.blendEquation !== material.blendEquation || + data.blendSrcAlpha !== material.blendSrcAlpha || + data.blendDstAlpha !== material.blendDstAlpha || + data.blendEquationAlpha !== material.blendEquationAlpha || + data.colorWrite !== material.colorWrite || + data.depthWrite !== material.depthWrite || + data.depthTest !== material.depthTest || + data.depthFunc !== material.depthFunc || + data.stencilWrite !== material.stencilWrite || + data.stencilFunc !== material.stencilFunc || + data.stencilFail !== material.stencilFail || + data.stencilZFail !== material.stencilZFail || + data.stencilZPass !== material.stencilZPass || + data.stencilFuncMask !== material.stencilFuncMask || + data.stencilWriteMask !== material.stencilWriteMask || + data.side !== material.side || + data.alphaToCoverage !== material.alphaToCoverage || + data.sampleCount !== sampleCount || + data.colorSpace !== colorSpace || + data.colorFormat !== colorFormat || + data.depthStencilFormat !== depthStencilFormat || + data.primitiveTopology !== primitiveTopology || + data.clippingContextCacheKey !== renderObject.clippingContext.cacheKey + ) { + data.material = material; + data.materialVersion = material.version; + data.transparent = material.transparent; + data.blending = material.blending; + data.premultipliedAlpha = material.premultipliedAlpha; + data.blendSrc = material.blendSrc; + data.blendDst = material.blendDst; + data.blendEquation = material.blendEquation; + data.blendSrcAlpha = material.blendSrcAlpha; + data.blendDstAlpha = material.blendDstAlpha; + data.blendEquationAlpha = material.blendEquationAlpha; + data.colorWrite = material.colorWrite; + data.depthWrite = material.depthWrite; + data.depthTest = material.depthTest; + data.depthFunc = material.depthFunc; + data.stencilWrite = material.stencilWrite; + data.stencilFunc = material.stencilFunc; + data.stencilFail = material.stencilFail; + data.stencilZFail = material.stencilZFail; + data.stencilZPass = material.stencilZPass; + data.stencilFuncMask = material.stencilFuncMask; + data.stencilWriteMask = material.stencilWriteMask; + data.side = material.side; + data.alphaToCoverage = material.alphaToCoverage; + data.sampleCount = sampleCount; + data.colorSpace = colorSpace; + data.colorFormat = colorFormat; + data.depthStencilFormat = depthStencilFormat; + data.primitiveTopology = primitiveTopology; + data.clippingContextCacheKey = renderObject.clippingContext.cacheKey; + + needsUpdate = true; + } + + return needsUpdate; + } + + getRenderCacheKey(renderObject) { + const { object, material } = renderObject; + + const utils = this.utils; + const renderContext = renderObject.context; + + return [ + material.transparent, + material.blending, + material.premultipliedAlpha, + material.blendSrc, + material.blendDst, + material.blendEquation, + material.blendSrcAlpha, + material.blendDstAlpha, + material.blendEquationAlpha, + material.colorWrite, + material.depthWrite, + material.depthTest, + material.depthFunc, + material.stencilWrite, + material.stencilFunc, + material.stencilFail, + material.stencilZFail, + material.stencilZPass, + material.stencilFuncMask, + material.stencilWriteMask, + material.side, + utils.getSampleCountRenderContext(renderContext), + utils.getCurrentColorSpace(renderContext), + utils.getCurrentColorFormat(renderContext), + utils.getCurrentDepthStencilFormat(renderContext), + utils.getPrimitiveTopology(object, material), + renderObject.getGeometryCacheKey(), + renderObject.clippingContext.cacheKey, + ].join(); + } + + // textures + + createSampler(texture) { + this.textureUtils.createSampler(texture); + } + + destroySampler(texture) { + this.textureUtils.destroySampler(texture); + } + + createDefaultTexture(texture) { + this.textureUtils.createDefaultTexture(texture); + } + + createTexture(texture, options) { + this.textureUtils.createTexture(texture, options); + } + + updateTexture(texture, options) { + this.textureUtils.updateTexture(texture, options); + } + + generateMipmaps(texture) { + this.textureUtils.generateMipmaps(texture); + } + + destroyTexture(texture) { + this.textureUtils.destroyTexture(texture); + } + + copyTextureToBuffer(texture, x, y, width, height, faceIndex) { + return this.textureUtils.copyTextureToBuffer(texture, x, y, width, height, faceIndex); + } + + initTimestampQuery(renderContext, descriptor) { + if (!this.trackTimestamp) return; + + const renderContextData = this.get(renderContext); + + if (!renderContextData.timeStampQuerySet) { + // Create a GPUQuerySet which holds 2 timestamp query results: one for the + // beginning and one for the end of compute pass execution. + const timeStampQuerySet = this.device.createQuerySet({ type: 'timestamp', count: 2 }); + + const timestampWrites = { + querySet: timeStampQuerySet, + beginningOfPassWriteIndex: 0, // Write timestamp in index 0 when pass begins. + endOfPassWriteIndex: 1, // Write timestamp in index 1 when pass ends. + }; + + Object.assign(descriptor, { + timestampWrites, + }); + + renderContextData.timeStampQuerySet = timeStampQuerySet; + } + } + + // timestamp utils + + prepareTimestampBuffer(renderContext, encoder) { + if (!this.trackTimestamp) return; + + const renderContextData = this.get(renderContext); + + const size = 2 * BigInt64Array.BYTES_PER_ELEMENT; + + if (renderContextData.currentTimestampQueryBuffers === undefined) { + renderContextData.currentTimestampQueryBuffers = { + resolveBuffer: this.device.createBuffer({ + label: 'timestamp resolve buffer', + size: size, + usage: GPUBufferUsage.QUERY_RESOLVE | GPUBufferUsage.COPY_SRC, + }), + resultBuffer: this.device.createBuffer({ + label: 'timestamp result buffer', + size: size, + usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ, + }), + isMappingPending: false, + }; + } + + const { resolveBuffer, resultBuffer, isMappingPending } = renderContextData.currentTimestampQueryBuffers; + + if (isMappingPending === true) return; + + encoder.resolveQuerySet(renderContextData.timeStampQuerySet, 0, 2, resolveBuffer, 0); + encoder.copyBufferToBuffer(resolveBuffer, 0, resultBuffer, 0, size); + } + + async resolveTimestampAsync(renderContext, type = 'render') { + if (!this.trackTimestamp) return; + + const renderContextData = this.get(renderContext); + + if (renderContextData.currentTimestampQueryBuffers === undefined) return; + + const { resultBuffer, isMappingPending } = renderContextData.currentTimestampQueryBuffers; + + if (isMappingPending === true) return; + + renderContextData.currentTimestampQueryBuffers.isMappingPending = true; + + resultBuffer.mapAsync(GPUMapMode.READ).then(() => { + const times = new BigUint64Array(resultBuffer.getMappedRange()); + const duration = Number(times[1] - times[0]) / 1000000; + + this.renderer.info.updateTimestamp(type, duration); + + resultBuffer.unmap(); + + renderContextData.currentTimestampQueryBuffers.isMappingPending = false; + }); + } + + // node builder + + createNodeBuilder(object, renderer) { + return new WGSLNodeBuilder(object, renderer); + } + + // program + + createProgram(program) { + const programGPU = this.get(program); + + programGPU.module = { + module: this.device.createShaderModule({ code: program.code, label: program.stage }), + entryPoint: 'main', + }; + } + + destroyProgram(program) { + this.delete(program); + } + + // pipelines + + createRenderPipeline(renderObject, promises) { + this.pipelineUtils.createRenderPipeline(renderObject, promises); + } + + createComputePipeline(computePipeline, bindings) { + this.pipelineUtils.createComputePipeline(computePipeline, bindings); + } + + beginBundle(renderContext) { + const renderContextData = this.get(renderContext); + + renderContextData._currentPass = renderContextData.currentPass; + renderContextData._currentSets = renderContextData.currentSets; + + renderContextData.currentSets = { attributes: {}, bindingGroups: [], pipeline: null, index: null }; + renderContextData.currentPass = this.pipelineUtils.createBundleEncoder(renderContext); + } + + finishBundle(renderContext, bundle) { + const renderContextData = this.get(renderContext); + + const bundleEncoder = renderContextData.currentPass; + const bundleGPU = bundleEncoder.finish(); + + this.get(bundle).bundleGPU = bundleGPU; + + // restore render pass state + + renderContextData.currentSets = renderContextData._currentSets; + renderContextData.currentPass = renderContextData._currentPass; + } + + addBundle(renderContext, bundle) { + const renderContextData = this.get(renderContext); + + renderContextData.renderBundles.push(this.get(bundle).bundleGPU); + } + + // bindings + + createBindings(bindGroup) { + this.bindingUtils.createBindings(bindGroup); + } + + updateBindings(bindGroup) { + this.bindingUtils.createBindings(bindGroup); + } + + updateBinding(binding) { + this.bindingUtils.updateBinding(binding); + } + + // attributes + + createIndexAttribute(attribute) { + this.attributeUtils.createAttribute( + attribute, + GPUBufferUsage.INDEX | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST, + ); + } + + createAttribute(attribute) { + this.attributeUtils.createAttribute( + attribute, + GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST, + ); + } + + createStorageAttribute(attribute) { + this.attributeUtils.createAttribute( + attribute, + GPUBufferUsage.STORAGE | GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST, + ); + } + + createIndirectStorageAttribute(attribute) { + this.attributeUtils.createAttribute( + attribute, + GPUBufferUsage.STORAGE | GPUBufferUsage.INDIRECT | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST, + ); + } + + updateAttribute(attribute) { + this.attributeUtils.updateAttribute(attribute); + } + + destroyAttribute(attribute) { + this.attributeUtils.destroyAttribute(attribute); + } + + // canvas + + updateSize() { + this.colorBuffer = this.textureUtils.getColorBuffer(); + this.defaultRenderPassdescriptor = null; + } + + // utils public + + getMaxAnisotropy() { + return 16; + } + + hasFeature(name) { + return this.device.features.has(name); + } + + copyTextureToTexture(srcTexture, dstTexture, srcRegion = null, dstPosition = null, level = 0) { + let dstX = 0; + let dstY = 0; + let dstLayer = 0; + + let srcX = 0; + let srcY = 0; + let srcLayer = 0; + + let srcWidth = srcTexture.image.width; + let srcHeight = srcTexture.image.height; + + if (srcRegion !== null) { + srcX = srcRegion.x; + srcY = srcRegion.y; + srcLayer = srcRegion.z || 0; + srcWidth = srcRegion.width; + srcHeight = srcRegion.height; + } + + if (dstPosition !== null) { + dstX = dstPosition.x; + dstY = dstPosition.y; + dstLayer = dstPosition.z || 0; + } + + const encoder = this.device.createCommandEncoder({ + label: 'copyTextureToTexture_' + srcTexture.id + '_' + dstTexture.id, + }); + + const sourceGPU = this.get(srcTexture).texture; + const destinationGPU = this.get(dstTexture).texture; + + encoder.copyTextureToTexture( + { + texture: sourceGPU, + mipLevel: level, + origin: { x: srcX, y: srcY, z: srcLayer }, + }, + { + texture: destinationGPU, + mipLevel: level, + origin: { x: dstX, y: dstY, z: dstLayer }, + }, + [srcWidth, srcHeight, 1], + ); + + this.device.queue.submit([encoder.finish()]); + } + + copyFramebufferToTexture(texture, renderContext, rectangle) { + const renderContextData = this.get(renderContext); + + const { encoder, descriptor } = renderContextData; + + let sourceGPU = null; + + if (renderContext.renderTarget) { + if (texture.isDepthTexture) { + sourceGPU = this.get(renderContext.depthTexture).texture; + } else { + sourceGPU = this.get(renderContext.textures[0]).texture; + } + } else { + if (texture.isDepthTexture) { + sourceGPU = this.textureUtils.getDepthBuffer(renderContext.depth, renderContext.stencil); + } else { + sourceGPU = this.context.getCurrentTexture(); + } + } + + const destinationGPU = this.get(texture).texture; + + if (sourceGPU.format !== destinationGPU.format) { + console.error( + 'WebGPUBackend: copyFramebufferToTexture: Source and destination formats do not match.', + sourceGPU.format, + destinationGPU.format, + ); + + return; + } + + renderContextData.currentPass.end(); + + encoder.copyTextureToTexture( + { + texture: sourceGPU, + origin: { x: rectangle.x, y: rectangle.y, z: 0 }, + }, + { + texture: destinationGPU, + }, + [rectangle.z, rectangle.w], + ); + + if (texture.generateMipmaps) this.textureUtils.generateMipmaps(texture); + + for (let i = 0; i < descriptor.colorAttachments.length; i++) { + descriptor.colorAttachments[i].loadOp = GPULoadOp.Load; + } + + if (renderContext.depth) descriptor.depthStencilAttachment.depthLoadOp = GPULoadOp.Load; + if (renderContext.stencil) descriptor.depthStencilAttachment.stencilLoadOp = GPULoadOp.Load; + + renderContextData.currentPass = encoder.beginRenderPass(descriptor); + renderContextData.currentSets = { attributes: {}, bindingGroups: [], pipeline: null, index: null }; + } +} + +export default WebGPUBackend; diff --git a/src-testing/src/renderers/webgpu/WebGPURenderer.Nodes.d.ts b/src-testing/src/renderers/webgpu/WebGPURenderer.Nodes.d.ts new file mode 100644 index 000000000..b9eb0ddeb --- /dev/null +++ b/src-testing/src/renderers/webgpu/WebGPURenderer.Nodes.d.ts @@ -0,0 +1,12 @@ +import Renderer, { RendererParameters } from "../common/Renderer.js"; +import { WebGPUBackendParameters } from "./WebGPUBackend.js"; + +export interface WebGPURendererParameters extends RendererParameters, WebGPUBackendParameters { + forceWebGL?: boolean | undefined; +} + +export default class WebGPURenderer extends Renderer { + readonly isWebGPURenderer: true; + + constructor(parameters?: WebGPURendererParameters); +} diff --git a/src-testing/src/renderers/webgpu/WebGPURenderer.ts b/src-testing/src/renderers/webgpu/WebGPURenderer.ts new file mode 100644 index 000000000..1b4e424f4 --- /dev/null +++ b/src-testing/src/renderers/webgpu/WebGPURenderer.ts @@ -0,0 +1,46 @@ +import Renderer from '../common/Renderer.js'; +import WebGLBackend from '../webgl-fallback/WebGLBackend.js'; +import WebGPUBackend from './WebGPUBackend.js'; +import StandardNodeLibrary from './nodes/StandardNodeLibrary.js'; +/* +const debugHandler = { + + get: function ( target, name ) { + + // Add |update + if ( /^(create|destroy)/.test( name ) ) console.log( 'WebGPUBackend.' + name ); + + return target[ name ]; + + } + +}; +*/ +class WebGPURenderer extends Renderer { + constructor(parameters = {}) { + let BackendClass; + + if (parameters.forceWebGL) { + BackendClass = WebGLBackend; + } else { + BackendClass = WebGPUBackend; + + parameters.getFallback = () => { + console.warn('THREE.WebGPURenderer: WebGPU is not available, running under WebGL2 backend.'); + + return new WebGLBackend(parameters); + }; + } + + const backend = new BackendClass(parameters); + + //super( new Proxy( backend, debugHandler ) ); + super(backend, parameters); + + this.library = new StandardNodeLibrary(); + + this.isWebGPURenderer = true; + } +} + +export default WebGPURenderer; diff --git a/src-testing/src/renderers/webgpu/nodes/BasicNodeLibrary.ts b/src-testing/src/renderers/webgpu/nodes/BasicNodeLibrary.ts new file mode 100644 index 000000000..665bffa32 --- /dev/null +++ b/src-testing/src/renderers/webgpu/nodes/BasicNodeLibrary.ts @@ -0,0 +1,61 @@ +import NodeLibrary from '../../common/nodes/NodeLibrary.js'; + +// Lights +import { PointLight } from '../../../lights/PointLight.js'; +import { PointLightNode } from '../../../nodes/Nodes.js'; +import { DirectionalLight } from '../../../lights/DirectionalLight.js'; +import { DirectionalLightNode } from '../../../nodes/Nodes.js'; +import { RectAreaLight } from '../../../lights/RectAreaLight.js'; +import { RectAreaLightNode } from '../../../nodes/Nodes.js'; +import { SpotLight } from '../../../lights/SpotLight.js'; +import { SpotLightNode } from '../../../nodes/Nodes.js'; +import { AmbientLight } from '../../../lights/AmbientLight.js'; +import { AmbientLightNode } from '../../../nodes/Nodes.js'; +import { HemisphereLight } from '../../../lights/HemisphereLight.js'; +import { HemisphereLightNode } from '../../../nodes/Nodes.js'; +import { LightProbe } from '../../../lights/LightProbe.js'; +import { LightProbeNode } from '../../../nodes/Nodes.js'; +import IESSpotLight from '../../../lights/webgpu/IESSpotLight.js'; +import { IESSpotLightNode } from '../../../nodes/Nodes.js'; + +// Tone Mapping +import { + LinearToneMapping, + ReinhardToneMapping, + CineonToneMapping, + ACESFilmicToneMapping, + AgXToneMapping, + NeutralToneMapping, +} from '../../../constants.js'; +import { + linearToneMapping, + reinhardToneMapping, + cineonToneMapping, + acesFilmicToneMapping, + agxToneMapping, + neutralToneMapping, +} from '../../../nodes/display/ToneMappingFunctions.js'; + +class BasicNodeLibrary extends NodeLibrary { + constructor() { + super(); + + this.addLight(PointLightNode, PointLight); + this.addLight(DirectionalLightNode, DirectionalLight); + this.addLight(RectAreaLightNode, RectAreaLight); + this.addLight(SpotLightNode, SpotLight); + this.addLight(AmbientLightNode, AmbientLight); + this.addLight(HemisphereLightNode, HemisphereLight); + this.addLight(LightProbeNode, LightProbe); + this.addLight(IESSpotLightNode, IESSpotLight); + + this.addToneMapping(linearToneMapping, LinearToneMapping); + this.addToneMapping(reinhardToneMapping, ReinhardToneMapping); + this.addToneMapping(cineonToneMapping, CineonToneMapping); + this.addToneMapping(acesFilmicToneMapping, ACESFilmicToneMapping); + this.addToneMapping(agxToneMapping, AgXToneMapping); + this.addToneMapping(neutralToneMapping, NeutralToneMapping); + } +} + +export default BasicNodeLibrary; diff --git a/src-testing/src/renderers/webgpu/nodes/StandardNodeLibrary.ts b/src-testing/src/renderers/webgpu/nodes/StandardNodeLibrary.ts new file mode 100644 index 000000000..bca482b4d --- /dev/null +++ b/src-testing/src/renderers/webgpu/nodes/StandardNodeLibrary.ts @@ -0,0 +1,107 @@ +import NodeLibrary from '../../common/nodes/NodeLibrary.js'; + +// Materials +import { MeshPhongMaterial } from '../../../materials/MeshPhongMaterial.js'; +import MeshPhongNodeMaterial from '../../../materials/nodes/MeshPhongNodeMaterial.js'; +import { MeshStandardMaterial } from '../../../materials/MeshStandardMaterial.js'; +import MeshStandardNodeMaterial from '../../../materials/nodes/MeshStandardNodeMaterial.js'; +import { MeshPhysicalMaterial } from '../../../materials/MeshPhysicalMaterial.js'; +import MeshPhysicalNodeMaterial from '../../../materials/nodes/MeshPhysicalNodeMaterial.js'; +import { MeshToonMaterial } from '../../../materials/MeshToonMaterial.js'; +import MeshToonNodeMaterial from '../../../materials/nodes/MeshToonNodeMaterial.js'; +import { MeshBasicMaterial } from '../../../materials/MeshBasicMaterial.js'; +import MeshBasicNodeMaterial from '../../../materials/nodes/MeshBasicNodeMaterial.js'; +import { MeshLambertMaterial } from '../../../materials/MeshLambertMaterial.js'; +import MeshLambertNodeMaterial from '../../../materials/nodes/MeshLambertNodeMaterial.js'; +import { MeshNormalMaterial } from '../../../materials/MeshNormalMaterial.js'; +import MeshNormalNodeMaterial from '../../../materials/nodes/MeshNormalNodeMaterial.js'; +import { MeshMatcapMaterial } from '../../../materials/MeshMatcapMaterial.js'; +import MeshMatcapNodeMaterial from '../../../materials/nodes/MeshMatcapNodeMaterial.js'; +import { LineBasicMaterial } from '../../../materials/LineBasicMaterial.js'; +import LineBasicNodeMaterial from '../../../materials/nodes/LineBasicNodeMaterial.js'; +import { LineDashedMaterial } from '../../../materials/LineDashedMaterial.js'; +import LineDashedNodeMaterial from '../../../materials/nodes/LineDashedNodeMaterial.js'; +import { PointsMaterial } from '../../../materials/PointsMaterial.js'; +import PointsNodeMaterial from '../../../materials/nodes/PointsNodeMaterial.js'; +import { SpriteMaterial } from '../../../materials/SpriteMaterial.js'; +import SpriteNodeMaterial from '../../../materials/nodes/SpriteNodeMaterial.js'; +import { ShadowMaterial } from '../../../materials/ShadowMaterial.js'; +import ShadowNodeMaterial from '../../../materials/nodes/ShadowNodeMaterial.js'; +//import { MeshDepthMaterial } from '../../../materials/MeshDepthMaterial.js'; +//import MeshDepthNodeMaterial from '../../../materials/nodes/MeshDepthNodeMaterial.js'; +//import { MeshDistanceMaterial } from '../../../materials/MeshDistanceMaterial.js'; +//import MeshDistanceNodeMaterial from '../../../materials/nodes/MeshDistanceNodeMaterial.js'; + +// Lights +import { PointLight } from '../../../lights/PointLight.js'; +import { PointLightNode } from '../../../nodes/Nodes.js'; +import { DirectionalLight } from '../../../lights/DirectionalLight.js'; +import { DirectionalLightNode } from '../../../nodes/Nodes.js'; +import { RectAreaLight } from '../../../lights/RectAreaLight.js'; +import { RectAreaLightNode } from '../../../nodes/Nodes.js'; +import { SpotLight } from '../../../lights/SpotLight.js'; +import { SpotLightNode } from '../../../nodes/Nodes.js'; +import { AmbientLight } from '../../../lights/AmbientLight.js'; +import { AmbientLightNode } from '../../../nodes/Nodes.js'; +import { HemisphereLight } from '../../../lights/HemisphereLight.js'; +import { HemisphereLightNode } from '../../../nodes/Nodes.js'; +import { LightProbe } from '../../../lights/LightProbe.js'; +import { LightProbeNode } from '../../../nodes/Nodes.js'; +import IESSpotLight from '../../../lights/webgpu/IESSpotLight.js'; +import { IESSpotLightNode } from '../../../nodes/Nodes.js'; + +// Tone Mapping +import { + LinearToneMapping, + ReinhardToneMapping, + CineonToneMapping, + ACESFilmicToneMapping, + AgXToneMapping, + NeutralToneMapping, +} from '../../../constants.js'; +import { + linearToneMapping, + reinhardToneMapping, + cineonToneMapping, + acesFilmicToneMapping, + agxToneMapping, + neutralToneMapping, +} from '../../../nodes/display/ToneMappingFunctions.js'; + +class StandardNodeLibrary extends NodeLibrary { + constructor() { + super(); + + this.addMaterial(MeshPhongNodeMaterial, MeshPhongMaterial); + this.addMaterial(MeshStandardNodeMaterial, MeshStandardMaterial); + this.addMaterial(MeshPhysicalNodeMaterial, MeshPhysicalMaterial); + this.addMaterial(MeshToonNodeMaterial, MeshToonMaterial); + this.addMaterial(MeshBasicNodeMaterial, MeshBasicMaterial); + this.addMaterial(MeshLambertNodeMaterial, MeshLambertMaterial); + this.addMaterial(MeshNormalNodeMaterial, MeshNormalMaterial); + this.addMaterial(MeshMatcapNodeMaterial, MeshMatcapMaterial); + this.addMaterial(LineBasicNodeMaterial, LineBasicMaterial); + this.addMaterial(LineDashedNodeMaterial, LineDashedMaterial); + this.addMaterial(PointsNodeMaterial, PointsMaterial); + this.addMaterial(SpriteNodeMaterial, SpriteMaterial); + this.addMaterial(ShadowNodeMaterial, ShadowMaterial); + + this.addLight(PointLightNode, PointLight); + this.addLight(DirectionalLightNode, DirectionalLight); + this.addLight(RectAreaLightNode, RectAreaLight); + this.addLight(SpotLightNode, SpotLight); + this.addLight(AmbientLightNode, AmbientLight); + this.addLight(HemisphereLightNode, HemisphereLight); + this.addLight(LightProbeNode, LightProbe); + this.addLight(IESSpotLightNode, IESSpotLight); + + this.addToneMapping(linearToneMapping, LinearToneMapping); + this.addToneMapping(reinhardToneMapping, ReinhardToneMapping); + this.addToneMapping(cineonToneMapping, CineonToneMapping); + this.addToneMapping(acesFilmicToneMapping, ACESFilmicToneMapping); + this.addToneMapping(agxToneMapping, AgXToneMapping); + this.addToneMapping(neutralToneMapping, NeutralToneMapping); + } +} + +export default StandardNodeLibrary; diff --git a/src-testing/src/renderers/webgpu/nodes/WGSLNodeBuilder.ts b/src-testing/src/renderers/webgpu/nodes/WGSLNodeBuilder.ts new file mode 100644 index 000000000..dc3aa7280 --- /dev/null +++ b/src-testing/src/renderers/webgpu/nodes/WGSLNodeBuilder.ts @@ -0,0 +1,1178 @@ +import NodeUniformsGroup from '../../common/nodes/NodeUniformsGroup.js'; + +import NodeSampler from '../../common/nodes/NodeSampler.js'; +import { + NodeSampledTexture, + NodeSampledCubeTexture, + NodeSampledTexture3D, +} from '../../common/nodes/NodeSampledTexture.js'; + +import NodeUniformBuffer from '../../common/nodes/NodeUniformBuffer.js'; +import NodeStorageBuffer from '../../common/nodes/NodeStorageBuffer.js'; + +import { NodeBuilder, CodeNode } from '../../../nodes/Nodes.js'; + +import { getFormat } from '../utils/WebGPUTextureUtils.js'; + +import WGSLNodeParser from './WGSLNodeParser.js'; +import { GPUBufferBindingType, GPUStorageTextureAccess } from '../utils/WebGPUConstants.js'; + +import { NoColorSpace, FloatType } from '../../../constants.js'; + +// GPUShaderStage is not defined in browsers not supporting WebGPU +const GPUShaderStage = self.GPUShaderStage; + +const gpuShaderStageLib = { + vertex: GPUShaderStage ? GPUShaderStage.VERTEX : 1, + fragment: GPUShaderStage ? GPUShaderStage.FRAGMENT : 2, + compute: GPUShaderStage ? GPUShaderStage.COMPUTE : 4, +}; + +const supports = { + instance: true, + swizzleAssign: false, + storageBuffer: true, +}; + +const wgslFnOpLib = { + '^^': 'tsl_xor', +}; + +const wgslTypeLib = { + float: 'f32', + int: 'i32', + uint: 'u32', + bool: 'bool', + color: 'vec3', + + vec2: 'vec2', + ivec2: 'vec2', + uvec2: 'vec2', + bvec2: 'vec2', + + vec3: 'vec3', + ivec3: 'vec3', + uvec3: 'vec3', + bvec3: 'vec3', + + vec4: 'vec4', + ivec4: 'vec4', + uvec4: 'vec4', + bvec4: 'vec4', + + mat2: 'mat2x2', + mat3: 'mat3x3', + mat4: 'mat4x4', +}; + +const wgslPolyfill = { + tsl_xor: new CodeNode('fn tsl_xor( a : bool, b : bool ) -> bool { return ( a || b ) && !( a && b ); }'), + mod_float: new CodeNode('fn tsl_mod_float( x : f32, y : f32 ) -> f32 { return x - y * floor( x / y ); }'), + mod_vec2: new CodeNode('fn tsl_mod_vec2( x : vec2f, y : vec2f ) -> vec2f { return x - y * floor( x / y ); }'), + mod_vec3: new CodeNode('fn tsl_mod_vec3( x : vec3f, y : vec3f ) -> vec3f { return x - y * floor( x / y ); }'), + mod_vec4: new CodeNode('fn tsl_mod_vec4( x : vec4f, y : vec4f ) -> vec4f { return x - y * floor( x / y ); }'), + equals_bool: new CodeNode('fn tsl_equals_bool( a : bool, b : bool ) -> bool { return a == b; }'), + equals_bvec2: new CodeNode( + 'fn tsl_equals_bvec2( a : vec2f, b : vec2f ) -> vec2 { return vec2( a.x == b.x, a.y == b.y ); }', + ), + equals_bvec3: new CodeNode( + 'fn tsl_equals_bvec3( a : vec3f, b : vec3f ) -> vec3 { return vec3( a.x == b.x, a.y == b.y, a.z == b.z ); }', + ), + equals_bvec4: new CodeNode( + 'fn tsl_equals_bvec4( a : vec4f, b : vec4f ) -> vec4 { return vec4( a.x == b.x, a.y == b.y, a.z == b.z, a.w == b.w ); }', + ), + repeatWrapping: new CodeNode(` +fn tsl_repeatWrapping( uv : vec2, dimension : vec2 ) -> vec2 { + + let uvScaled = vec2( uv * vec2( dimension ) ); + + return ( ( uvScaled % dimension ) + dimension ) % dimension; + +} +`), + biquadraticTexture: new CodeNode(` +fn tsl_biquadraticTexture( map : texture_2d, coord : vec2f, level : i32 ) -> vec4f { + + let iRes = vec2i( textureDimensions( map, level ) ); + let res = vec2f( iRes ); + + let uvScaled = coord * res; + let uvWrapping = ( ( uvScaled % res ) + res ) % res; + + // https://www.shadertoy.com/view/WtyXRy + + let uv = uvWrapping - 0.5; + let iuv = floor( uv ); + let f = fract( uv ); + + let rg1 = textureLoad( map, vec2i( iuv + vec2( 0.5, 0.5 ) ) % iRes, level ); + let rg2 = textureLoad( map, vec2i( iuv + vec2( 1.5, 0.5 ) ) % iRes, level ); + let rg3 = textureLoad( map, vec2i( iuv + vec2( 0.5, 1.5 ) ) % iRes, level ); + let rg4 = textureLoad( map, vec2i( iuv + vec2( 1.5, 1.5 ) ) % iRes, level ); + + return mix( mix( rg1, rg2, f.x ), mix( rg3, rg4, f.x ), f.y ); + +} +`), +}; + +const wgslMethods = { + dFdx: 'dpdx', + dFdy: '- dpdy', + mod_float: 'tsl_mod_float', + mod_vec2: 'tsl_mod_vec2', + mod_vec3: 'tsl_mod_vec3', + mod_vec4: 'tsl_mod_vec4', + equals_bool: 'tsl_equals_bool', + equals_bvec2: 'tsl_equals_bvec2', + equals_bvec3: 'tsl_equals_bvec3', + equals_bvec4: 'tsl_equals_bvec4', + inversesqrt: 'inverseSqrt', + bitcast: 'bitcast', +}; + +// WebGPU issue: does not support pow() with negative base on Windows + +if (/Windows/g.test(navigator.userAgent)) { + wgslPolyfill.pow_float = new CodeNode( + 'fn tsl_pow_float( a : f32, b : f32 ) -> f32 { return select( -pow( -a, b ), pow( a, b ), a > 0.0 ); }', + ); + wgslPolyfill.pow_vec2 = new CodeNode( + 'fn tsl_pow_vec2( a : vec2f, b : vec2f ) -> vec2f { return vec2f( tsl_pow_float( a.x, b.x ), tsl_pow_float( a.y, b.y ) ); }', + [wgslPolyfill.pow_float], + ); + wgslPolyfill.pow_vec3 = new CodeNode( + 'fn tsl_pow_vec3( a : vec3f, b : vec3f ) -> vec3f { return vec3f( tsl_pow_float( a.x, b.x ), tsl_pow_float( a.y, b.y ), tsl_pow_float( a.z, b.z ) ); }', + [wgslPolyfill.pow_float], + ); + wgslPolyfill.pow_vec4 = new CodeNode( + 'fn tsl_pow_vec4( a : vec4f, b : vec4f ) -> vec4f { return vec4f( tsl_pow_float( a.x, b.x ), tsl_pow_float( a.y, b.y ), tsl_pow_float( a.z, b.z ), tsl_pow_float( a.w, b.w ) ); }', + [wgslPolyfill.pow_float], + ); + + wgslMethods.pow_float = 'tsl_pow_float'; + wgslMethods.pow_vec2 = 'tsl_pow_vec2'; + wgslMethods.pow_vec3 = 'tsl_pow_vec3'; + wgslMethods.pow_vec4 = 'tsl_pow_vec4'; +} + +// + +let diagnostics = ''; + +if (/Firefox|Deno/g.test(navigator.userAgent) !== true) { + diagnostics += 'diagnostic( off, derivative_uniformity );\n'; +} + +// + +class WGSLNodeBuilder extends NodeBuilder { + constructor(object, renderer) { + super(object, renderer, new WGSLNodeParser()); + + this.uniformGroups = {}; + + this.builtins = {}; + + this.directives = {}; + + this.scopedArrays = new Map(); + } + + needsToWorkingColorSpace(texture) { + return texture.isVideoTexture === true && texture.colorSpace !== NoColorSpace; + } + + _generateTextureSample(texture, textureProperty, uvSnippet, depthSnippet, shaderStage = this.shaderStage) { + if (shaderStage === 'fragment') { + if (depthSnippet) { + return `textureSample( ${textureProperty}, ${textureProperty}_sampler, ${uvSnippet}, ${depthSnippet} )`; + } else { + return `textureSample( ${textureProperty}, ${textureProperty}_sampler, ${uvSnippet} )`; + } + } else if (this.isFilteredTexture(texture)) { + return this.generateFilteredTexture(texture, textureProperty, uvSnippet); + } else { + return this.generateTextureLod(texture, textureProperty, uvSnippet, '0'); + } + } + + _generateVideoSample(textureProperty, uvSnippet, shaderStage = this.shaderStage) { + if (shaderStage === 'fragment') { + return `textureSampleBaseClampToEdge( ${textureProperty}, ${textureProperty}_sampler, vec2( ${uvSnippet}.x, 1.0 - ${uvSnippet}.y ) )`; + } else { + console.error(`WebGPURenderer: THREE.VideoTexture does not support ${shaderStage} shader.`); + } + } + + _generateTextureSampleLevel( + texture, + textureProperty, + uvSnippet, + levelSnippet, + depthSnippet, + shaderStage = this.shaderStage, + ) { + if (shaderStage === 'fragment' && this.isUnfilterable(texture) === false) { + return `textureSampleLevel( ${textureProperty}, ${textureProperty}_sampler, ${uvSnippet}, ${levelSnippet} )`; + } else if (this.isFilteredTexture(texture)) { + return this.generateFilteredTexture(texture, textureProperty, uvSnippet, levelSnippet); + } else { + return this.generateTextureLod(texture, textureProperty, uvSnippet, levelSnippet); + } + } + + generateFilteredTexture(texture, textureProperty, uvSnippet, levelSnippet = '0') { + this._include('biquadraticTexture'); + + return `tsl_biquadraticTexture( ${textureProperty}, ${uvSnippet}, i32( ${levelSnippet} ) )`; + } + + generateTextureLod(texture, textureProperty, uvSnippet, levelSnippet = '0') { + this._include('repeatWrapping'); + + const dimension = + texture.isMultisampleRenderTargetTexture === true + ? `textureDimensions( ${textureProperty} )` + : `textureDimensions( ${textureProperty}, 0 )`; + + return `textureLoad( ${textureProperty}, tsl_repeatWrapping( ${uvSnippet}, ${dimension} ), i32( ${levelSnippet} ) )`; + } + + generateTextureLoad(texture, textureProperty, uvIndexSnippet, depthSnippet, levelSnippet = '0u') { + if (depthSnippet) { + return `textureLoad( ${textureProperty}, ${uvIndexSnippet}, ${depthSnippet}, ${levelSnippet} )`; + } else { + return `textureLoad( ${textureProperty}, ${uvIndexSnippet}, ${levelSnippet} )`; + } + } + + generateTextureStore(texture, textureProperty, uvIndexSnippet, valueSnippet) { + return `textureStore( ${textureProperty}, ${uvIndexSnippet}, ${valueSnippet} )`; + } + + isUnfilterable(texture) { + return ( + this.getComponentTypeFromTexture(texture) !== 'float' || + (!this.isAvailable('float32Filterable') && texture.isDataTexture === true && texture.type === FloatType) || + texture.isMultisampleRenderTargetTexture === true + ); + } + + generateTexture(texture, textureProperty, uvSnippet, depthSnippet, shaderStage = this.shaderStage) { + let snippet = null; + + if (texture.isVideoTexture === true) { + snippet = this._generateVideoSample(textureProperty, uvSnippet, shaderStage); + } else if (this.isUnfilterable(texture)) { + snippet = this.generateTextureLod(texture, textureProperty, uvSnippet, '0', depthSnippet, shaderStage); + } else { + snippet = this._generateTextureSample(texture, textureProperty, uvSnippet, depthSnippet, shaderStage); + } + + return snippet; + } + + generateTextureGrad( + texture, + textureProperty, + uvSnippet, + gradSnippet, + depthSnippet, + shaderStage = this.shaderStage, + ) { + if (shaderStage === 'fragment') { + // TODO handle i32 or u32 --> uvSnippet, array_index: A, ddx, ddy + return `textureSampleGrad( ${textureProperty}, ${textureProperty}_sampler, ${uvSnippet}, ${gradSnippet[0]}, ${gradSnippet[1]} )`; + } else { + console.error(`WebGPURenderer: THREE.TextureNode.gradient() does not support ${shaderStage} shader.`); + } + } + + generateTextureCompare( + texture, + textureProperty, + uvSnippet, + compareSnippet, + depthSnippet, + shaderStage = this.shaderStage, + ) { + if (shaderStage === 'fragment') { + return `textureSampleCompare( ${textureProperty}, ${textureProperty}_sampler, ${uvSnippet}, ${compareSnippet} )`; + } else { + console.error( + `WebGPURenderer: THREE.DepthTexture.compareFunction() does not support ${shaderStage} shader.`, + ); + } + } + + generateTextureLevel( + texture, + textureProperty, + uvSnippet, + levelSnippet, + depthSnippet, + shaderStage = this.shaderStage, + ) { + let snippet = null; + + if (texture.isVideoTexture === true) { + snippet = this._generateVideoSample(textureProperty, uvSnippet, shaderStage); + } else { + snippet = this._generateTextureSampleLevel( + texture, + textureProperty, + uvSnippet, + levelSnippet, + depthSnippet, + shaderStage, + ); + } + + return snippet; + } + + generateTextureBias( + texture, + textureProperty, + uvSnippet, + biasSnippet, + depthSnippet, + shaderStage = this.shaderStage, + ) { + if (shaderStage === 'fragment') { + return `textureSampleBias( ${textureProperty}, ${textureProperty}_sampler, ${uvSnippet}, ${biasSnippet} )`; + } else { + console.error(`WebGPURenderer: THREE.TextureNode.biasNode does not support ${shaderStage} shader.`); + } + } + + getPropertyName(node, shaderStage = this.shaderStage) { + if (node.isNodeVarying === true && node.needsInterpolation === true) { + if (shaderStage === 'vertex') { + return `varyings.${node.name}`; + } + } else if (node.isNodeUniform === true) { + const name = node.name; + const type = node.type; + + if (type === 'texture' || type === 'cubeTexture' || type === 'storageTexture' || type === 'texture3D') { + return name; + } else if (type === 'buffer' || type === 'storageBuffer' || type === 'indirectStorageBuffer') { + return `NodeBuffer_${node.id}.${name}`; + } else { + return node.groupNode.name + '.' + name; + } + } + + return super.getPropertyName(node); + } + + getOutputStructName() { + return 'output'; + } + + _getUniformGroupCount(shaderStage) { + return Object.keys(this.uniforms[shaderStage]).length; + } + + getFunctionOperator(op) { + const fnOp = wgslFnOpLib[op]; + + if (fnOp !== undefined) { + this._include(fnOp); + + return fnOp; + } + + return null; + } + + getStorageAccess(node) { + if (node.isStorageTextureNode) { + switch (node.access) { + case GPUStorageTextureAccess.ReadOnly: + return 'read'; + + case GPUStorageTextureAccess.WriteOnly: + return 'write'; + + default: + return 'read_write'; + } + } else { + switch (node.access) { + case GPUBufferBindingType.Storage: + return 'read_write'; + + case GPUBufferBindingType.ReadOnlyStorage: + return 'read'; + + default: + return 'write'; + } + } + } + + getUniformFromNode(node, type, shaderStage, name = null) { + const uniformNode = super.getUniformFromNode(node, type, shaderStage, name); + const nodeData = this.getDataFromNode(node, shaderStage, this.globalCache); + + if (nodeData.uniformGPU === undefined) { + let uniformGPU; + + const group = node.groupNode; + const groupName = group.name; + + const bindings = this.getBindGroupArray(groupName, shaderStage); + + if (type === 'texture' || type === 'cubeTexture' || type === 'storageTexture' || type === 'texture3D') { + let texture = null; + + if (type === 'texture' || type === 'storageTexture') { + texture = new NodeSampledTexture( + uniformNode.name, + uniformNode.node, + group, + node.access ? node.access : null, + ); + } else if (type === 'cubeTexture') { + texture = new NodeSampledCubeTexture( + uniformNode.name, + uniformNode.node, + group, + node.access ? node.access : null, + ); + } else if (type === 'texture3D') { + texture = new NodeSampledTexture3D( + uniformNode.name, + uniformNode.node, + group, + node.access ? node.access : null, + ); + } + + texture.store = node.isStorageTextureNode === true; + texture.setVisibility(gpuShaderStageLib[shaderStage]); + + if ( + shaderStage === 'fragment' && + this.isUnfilterable(node.value) === false && + texture.store === false + ) { + const sampler = new NodeSampler(`${uniformNode.name}_sampler`, uniformNode.node, group); + sampler.setVisibility(gpuShaderStageLib[shaderStage]); + + bindings.push(sampler, texture); + + uniformGPU = [sampler, texture]; + } else { + bindings.push(texture); + + uniformGPU = [texture]; + } + } else if (type === 'buffer' || type === 'storageBuffer' || type === 'indirectStorageBuffer') { + const bufferClass = type === 'buffer' ? NodeUniformBuffer : NodeStorageBuffer; + + const buffer = new bufferClass(node, group); + buffer.setVisibility(gpuShaderStageLib[shaderStage]); + + bindings.push(buffer); + + uniformGPU = buffer; + } else { + const uniformsStage = this.uniformGroups[shaderStage] || (this.uniformGroups[shaderStage] = {}); + + let uniformsGroup = uniformsStage[groupName]; + + if (uniformsGroup === undefined) { + uniformsGroup = new NodeUniformsGroup(groupName, group); + uniformsGroup.setVisibility(gpuShaderStageLib[shaderStage]); + + uniformsStage[groupName] = uniformsGroup; + + bindings.push(uniformsGroup); + } + + uniformGPU = this.getNodeUniform(uniformNode, type); + + uniformsGroup.addUniform(uniformGPU); + } + + nodeData.uniformGPU = uniformGPU; + } + + return uniformNode; + } + + getBuiltin(name, property, type, shaderStage = this.shaderStage) { + const map = this.builtins[shaderStage] || (this.builtins[shaderStage] = new Map()); + + if (map.has(name) === false) { + map.set(name, { + name, + property, + type, + }); + } + + return property; + } + + hasBuiltin(name, shaderStage = this.shaderStage) { + return this.builtins[shaderStage] !== undefined && this.builtins[shaderStage].has(name); + } + + getVertexIndex() { + if (this.shaderStage === 'vertex') { + return this.getBuiltin('vertex_index', 'vertexIndex', 'u32', 'attribute'); + } + + return 'vertexIndex'; + } + + buildFunctionCode(shaderNode) { + const layout = shaderNode.layout; + const flowData = this.flowShaderNode(shaderNode); + + const parameters = []; + + for (const input of layout.inputs) { + parameters.push(input.name + ' : ' + this.getType(input.type)); + } + + // + + let code = `fn ${layout.name}( ${parameters.join(', ')} ) -> ${this.getType(layout.type)} { +${flowData.vars} +${flowData.code} +`; + + if (flowData.result) { + code += `\treturn ${flowData.result};\n`; + } + + code += '\n}\n'; + + // + + return code; + } + + getInstanceIndex() { + if (this.shaderStage === 'vertex') { + return this.getBuiltin('instance_index', 'instanceIndex', 'u32', 'attribute'); + } + + return 'instanceIndex'; + } + + getInvocationLocalIndex() { + return this.getBuiltin('local_invocation_index', 'invocationLocalIndex', 'u32', 'attribute'); + } + + getSubgroupSize() { + this.enableSubGroups(); + + return this.getBuiltin('subgroup_size', 'subgroupSize', 'u32', 'attribute'); + } + + getInvocationSubgroupIndex() { + this.enableSubGroups(); + + return this.getBuiltin('subgroup_invocation_id', 'invocationSubgroupIndex', 'u32', 'attribute'); + } + + getSubgroupIndex() { + this.enableSubGroups(); + + return this.getBuiltin('subgroup_id', 'subgroupIndex', 'u32', 'attribute'); + } + + getDrawIndex() { + return null; + } + + getFrontFacing() { + return this.getBuiltin('front_facing', 'isFront', 'bool'); + } + + getFragCoord() { + return this.getBuiltin('position', 'fragCoord', 'vec4') + '.xy'; + } + + getFragDepth() { + return 'output.' + this.getBuiltin('frag_depth', 'depth', 'f32', 'output'); + } + + isFlipY() { + return false; + } + + enableDirective(name, shaderStage = this.shaderStage) { + const stage = this.directives[shaderStage] || (this.directives[shaderStage] = new Set()); + stage.add(name); + } + + getDirectives(shaderStage) { + const snippets = []; + const directives = this.directives[shaderStage]; + + if (directives !== undefined) { + for (const directive of directives) { + snippets.push(`enable ${directive};`); + } + } + + return snippets.join('\n'); + } + + enableSubGroups() { + this.enableDirective('subgroups'); + } + + enableSubgroupsF16() { + this.enableDirective('subgroups-f16'); + } + + enableClipDistances() { + this.enableDirective('clip_distances'); + } + + enableShaderF16() { + this.enableDirective('f16'); + } + + enableDualSourceBlending() { + this.enableDirective('dual_source_blending'); + } + + getBuiltins(shaderStage) { + const snippets = []; + const builtins = this.builtins[shaderStage]; + + if (builtins !== undefined) { + for (const { name, property, type } of builtins.values()) { + snippets.push(`@builtin( ${name} ) ${property} : ${type}`); + } + } + + return snippets.join(',\n\t'); + } + + getScopedArray(name, scope, bufferType, bufferCount) { + if (this.scopedArrays.has(name) === false) { + this.scopedArrays.set(name, { + name, + scope, + bufferType, + bufferCount, + }); + } + + return name; + } + + getScopedArrays(shaderStage) { + if (shaderStage !== 'compute') { + return; + } + + const snippets = []; + + for (const { name, scope, bufferType, bufferCount } of this.scopedArrays.values()) { + const type = this.getType(bufferType); + + snippets.push(`var<${scope}> ${name}: array< ${type}, ${bufferCount} >;`); + } + + return snippets.join('\n'); + } + + getAttributes(shaderStage) { + const snippets = []; + + if (shaderStage === 'compute') { + this.getBuiltin('global_invocation_id', 'id', 'vec3', 'attribute'); + this.getBuiltin('workgroup_id', 'workgroupId', 'vec3', 'attribute'); + this.getBuiltin('local_invocation_id', 'localId', 'vec3', 'attribute'); + this.getBuiltin('num_workgroups', 'numWorkgroups', 'vec3', 'attribute'); + + if (this.renderer.hasFeature('subgroups')) { + this.enableDirective('subgroups', shaderStage); + this.getBuiltin('subgroup_size', 'subgroupSize', 'u32', 'attribute'); + } + } + + if (shaderStage === 'vertex' || shaderStage === 'compute') { + const builtins = this.getBuiltins('attribute'); + + if (builtins) snippets.push(builtins); + + const attributes = this.getAttributesArray(); + + for (let index = 0, length = attributes.length; index < length; index++) { + const attribute = attributes[index]; + const name = attribute.name; + const type = this.getType(attribute.type); + + snippets.push(`@location( ${index} ) ${name} : ${type}`); + } + } + + return snippets.join(',\n\t'); + } + + getStructMembers(struct) { + const snippets = []; + const members = struct.getMemberTypes(); + + for (let i = 0; i < members.length; i++) { + const member = members[i]; + snippets.push(`\t@location( ${i} ) m${i} : ${member}`); + } + + const builtins = this.getBuiltins('output'); + + if (builtins) snippets.push('\t' + builtins); + + return snippets.join(',\n'); + } + + getStructs(shaderStage) { + const snippets = []; + const structs = this.structs[shaderStage]; + + for (let index = 0, length = structs.length; index < length; index++) { + const struct = structs[index]; + const name = struct.name; + + let snippet = `\struct ${name} {\n`; + snippet += this.getStructMembers(struct); + snippet += '\n}'; + + snippets.push(snippet); + + snippets.push(`\nvar output : ${name};\n\n`); + } + + return snippets.join('\n\n'); + } + + getVar(type, name) { + return `var ${name} : ${this.getType(type)}`; + } + + getVars(shaderStage) { + const snippets = []; + const vars = this.vars[shaderStage]; + + if (vars !== undefined) { + for (const variable of vars) { + snippets.push(`\t${this.getVar(variable.type, variable.name)};`); + } + } + + return `\n${snippets.join('\n')}\n`; + } + + getVaryings(shaderStage) { + const snippets = []; + + if (shaderStage === 'vertex') { + this.getBuiltin('position', 'Vertex', 'vec4', 'vertex'); + } + + if (shaderStage === 'vertex' || shaderStage === 'fragment') { + const varyings = this.varyings; + const vars = this.vars[shaderStage]; + + for (let index = 0; index < varyings.length; index++) { + const varying = varyings[index]; + + if (varying.needsInterpolation) { + let attributesSnippet = `@location( ${index} )`; + + if (/^(int|uint|ivec|uvec)/.test(varying.type)) { + attributesSnippet += ' @interpolate( flat )'; + } + + snippets.push(`${attributesSnippet} ${varying.name} : ${this.getType(varying.type)}`); + } else if (shaderStage === 'vertex' && vars.includes(varying) === false) { + vars.push(varying); + } + } + } + + const builtins = this.getBuiltins(shaderStage); + + if (builtins) snippets.push(builtins); + + const code = snippets.join(',\n\t'); + + return shaderStage === 'vertex' ? this._getWGSLStruct('VaryingsStruct', '\t' + code) : code; + } + + getUniforms(shaderStage) { + const uniforms = this.uniforms[shaderStage]; + + const bindingSnippets = []; + const bufferSnippets = []; + const structSnippets = []; + const uniformGroups = {}; + + for (const uniform of uniforms) { + const groupName = uniform.groupNode.name; + const uniformIndexes = this.bindingsIndexes[groupName]; + + if ( + uniform.type === 'texture' || + uniform.type === 'cubeTexture' || + uniform.type === 'storageTexture' || + uniform.type === 'texture3D' + ) { + const texture = uniform.node.value; + + if ( + shaderStage === 'fragment' && + this.isUnfilterable(texture) === false && + uniform.node.isStorageTextureNode !== true + ) { + if (texture.isDepthTexture === true && texture.compareFunction !== null) { + bindingSnippets.push( + `@binding( ${uniformIndexes.binding++} ) @group( ${uniformIndexes.group} ) var ${uniform.name}_sampler : sampler_comparison;`, + ); + } else { + bindingSnippets.push( + `@binding( ${uniformIndexes.binding++} ) @group( ${uniformIndexes.group} ) var ${uniform.name}_sampler : sampler;`, + ); + } + } + + let textureType; + + let multisampled = ''; + + if (texture.isMultisampleRenderTargetTexture === true) { + multisampled = '_multisampled'; + } + + if (texture.isCubeTexture === true) { + textureType = 'texture_cube'; + } else if (texture.isDataArrayTexture === true || texture.isCompressedArrayTexture === true) { + textureType = 'texture_2d_array'; + } else if (texture.isDepthTexture === true) { + textureType = `texture_depth${multisampled}_2d`; + } else if (texture.isVideoTexture === true) { + textureType = 'texture_external'; + } else if (texture.isData3DTexture === true) { + textureType = 'texture_3d'; + } else if (uniform.node.isStorageTextureNode === true) { + const format = getFormat(texture); + const access = this.getStorageAccess(uniform.node); + + textureType = `texture_storage_2d<${format}, ${access}>`; + } else { + const componentPrefix = this.getComponentTypeFromTexture(texture).charAt(0); + + textureType = `texture${multisampled}_2d<${componentPrefix}32>`; + } + + bindingSnippets.push( + `@binding( ${uniformIndexes.binding++} ) @group( ${uniformIndexes.group} ) var ${uniform.name} : ${textureType};`, + ); + } else if ( + uniform.type === 'buffer' || + uniform.type === 'storageBuffer' || + uniform.type === 'indirectStorageBuffer' + ) { + const bufferNode = uniform.node; + const bufferType = this.getType(bufferNode.bufferType); + const bufferCount = bufferNode.bufferCount; + + const bufferCountSnippet = bufferCount > 0 && uniform.type === 'buffer' ? ', ' + bufferCount : ''; + const bufferTypeSnippet = bufferNode.isAtomic ? `atomic<${bufferType}>` : `${bufferType}`; + const bufferSnippet = `\t${uniform.name} : array< ${bufferTypeSnippet}${bufferCountSnippet} >\n`; + const bufferAccessMode = bufferNode.isStorageBufferNode + ? `storage, ${this.getStorageAccess(bufferNode)}` + : 'uniform'; + + bufferSnippets.push( + this._getWGSLStructBinding( + 'NodeBuffer_' + bufferNode.id, + bufferSnippet, + bufferAccessMode, + uniformIndexes.binding++, + uniformIndexes.group, + ), + ); + } else { + const vectorType = this.getType(this.getVectorType(uniform.type)); + const groupName = uniform.groupNode.name; + + const group = + uniformGroups[groupName] || + (uniformGroups[groupName] = { + index: uniformIndexes.binding++, + id: uniformIndexes.group, + snippets: [], + }); + + group.snippets.push(`\t${uniform.name} : ${vectorType}`); + } + } + + for (const name in uniformGroups) { + const group = uniformGroups[name]; + + structSnippets.push( + this._getWGSLStructBinding(name, group.snippets.join(',\n'), 'uniform', group.index, group.id), + ); + } + + let code = bindingSnippets.join('\n'); + code += bufferSnippets.join('\n'); + code += structSnippets.join('\n'); + + return code; + } + + buildCode() { + const shadersData = this.material !== null ? { fragment: {}, vertex: {} } : { compute: {} }; + + this.sortBindingGroups(); + + for (const shaderStage in shadersData) { + const stageData = shadersData[shaderStage]; + stageData.uniforms = this.getUniforms(shaderStage); + stageData.attributes = this.getAttributes(shaderStage); + stageData.varyings = this.getVaryings(shaderStage); + stageData.structs = this.getStructs(shaderStage); + stageData.vars = this.getVars(shaderStage); + stageData.codes = this.getCodes(shaderStage); + stageData.directives = this.getDirectives(shaderStage); + stageData.scopedArrays = this.getScopedArrays(shaderStage); + + // + + let flow = '// code\n\n'; + flow += this.flowCode[shaderStage]; + + const flowNodes = this.flowNodes[shaderStage]; + const mainNode = flowNodes[flowNodes.length - 1]; + + const outputNode = mainNode.outputNode; + const isOutputStruct = outputNode !== undefined && outputNode.isOutputStructNode === true; + + for (const node of flowNodes) { + const flowSlotData = this.getFlowData(node /*, shaderStage*/); + const slotName = node.name; + + if (slotName) { + if (flow.length > 0) flow += '\n'; + + flow += `\t// flow -> ${slotName}\n\t`; + } + + flow += `${flowSlotData.code}\n\t`; + + if (node === mainNode && shaderStage !== 'compute') { + flow += '// result\n\n\t'; + + if (shaderStage === 'vertex') { + flow += `varyings.Vertex = ${flowSlotData.result};`; + } else if (shaderStage === 'fragment') { + if (isOutputStruct) { + stageData.returnType = outputNode.nodeType; + + flow += `return ${flowSlotData.result};`; + } else { + let structSnippet = '\t@location(0) color: vec4'; + + const builtins = this.getBuiltins('output'); + + if (builtins) structSnippet += ',\n\t' + builtins; + + stageData.returnType = 'OutputStruct'; + stageData.structs += this._getWGSLStruct('OutputStruct', structSnippet); + stageData.structs += '\nvar output : OutputStruct;\n\n'; + + flow += `output.color = ${flowSlotData.result};\n\n\treturn output;`; + } + } + } + } + + stageData.flow = flow; + } + + if (this.material !== null) { + this.vertexShader = this._getWGSLVertexCode(shadersData.vertex); + this.fragmentShader = this._getWGSLFragmentCode(shadersData.fragment); + } else { + this.computeShader = this._getWGSLComputeCode( + shadersData.compute, + (this.object.workgroupSize || [64]).join(', '), + ); + } + } + + getMethod(method, output = null) { + let wgslMethod; + + if (output !== null) { + wgslMethod = this._getWGSLMethod(method + '_' + output); + } + + if (wgslMethod === undefined) { + wgslMethod = this._getWGSLMethod(method); + } + + return wgslMethod || method; + } + + getType(type) { + return wgslTypeLib[type] || type; + } + + isAvailable(name) { + let result = supports[name]; + + if (result === undefined) { + if (name === 'float32Filterable') { + result = this.renderer.hasFeature('float32-filterable'); + } + + supports[name] = result; + } + + return result; + } + + _getWGSLMethod(method) { + if (wgslPolyfill[method] !== undefined) { + this._include(method); + } + + return wgslMethods[method]; + } + + _include(name) { + const codeNode = wgslPolyfill[name]; + codeNode.build(this); + + if (this.currentFunctionNode !== null) { + this.currentFunctionNode.includes.push(codeNode); + } + + return codeNode; + } + + _getWGSLVertexCode(shaderData) { + return `${this.getSignature()} +// directives +${shaderData.directives} + +// uniforms +${shaderData.uniforms} + +// varyings +${shaderData.varyings} +var varyings : VaryingsStruct; + +// codes +${shaderData.codes} + +@vertex +fn main( ${shaderData.attributes} ) -> VaryingsStruct { + + // vars + ${shaderData.vars} + + // flow + ${shaderData.flow} + + return varyings; + +} +`; + } + + _getWGSLFragmentCode(shaderData) { + return `${this.getSignature()} +// global +${diagnostics} + +// uniforms +${shaderData.uniforms} + +// structs +${shaderData.structs} + +// codes +${shaderData.codes} + +@fragment +fn main( ${shaderData.varyings} ) -> ${shaderData.returnType} { + + // vars + ${shaderData.vars} + + // flow + ${shaderData.flow} + +} +`; + } + + _getWGSLComputeCode(shaderData, workgroupSize) { + return `${this.getSignature()} +// directives +${shaderData.directives} + +// system +var instanceIndex : u32; + +// locals +${shaderData.scopedArrays} + +// uniforms +${shaderData.uniforms} + +// codes +${shaderData.codes} + +@compute @workgroup_size( ${workgroupSize} ) +fn main( ${shaderData.attributes} ) { + + // system + instanceIndex = id.x + id.y * numWorkgroups.x * u32(${workgroupSize}) + id.z * numWorkgroups.x * numWorkgroups.y * u32(${workgroupSize}); + + // vars + ${shaderData.vars} + + // flow + ${shaderData.flow} + +} +`; + } + + _getWGSLStruct(name, vars) { + return ` +struct ${name} { +${vars} +};`; + } + + _getWGSLStructBinding(name, vars, access, binding = 0, group = 0) { + const structName = name + 'Struct'; + const structSnippet = this._getWGSLStruct(structName, vars); + + return `${structSnippet} +@binding( ${binding} ) @group( ${group} ) +var<${access}> ${name} : ${structName};`; + } +} + +export default WGSLNodeBuilder; diff --git a/src-testing/src/renderers/webgpu/nodes/WGSLNodeFunction.ts b/src-testing/src/renderers/webgpu/nodes/WGSLNodeFunction.ts new file mode 100644 index 000000000..33b0d2688 --- /dev/null +++ b/src-testing/src/renderers/webgpu/nodes/WGSLNodeFunction.ts @@ -0,0 +1,142 @@ +import NodeFunction from '../../../nodes/core/NodeFunction.js'; +import NodeFunctionInput from '../../../nodes/core/NodeFunctionInput.js'; + +const declarationRegexp = /^[fn]*\s*([a-z_0-9]+)?\s*\(([\s\S]*?)\)\s*[\-\>]*\s*([a-z_0-9]+(?:<[\s\S]+?>)?)/i; +const propertiesRegexp = /([a-z_0-9]+)\s*:\s*([a-z_0-9]+(?:<[\s\S]+?>)?)/gi; + +const wgslTypeLib = { + f32: 'float', + i32: 'int', + u32: 'uint', + bool: 'bool', + + 'vec2': 'vec2', + 'vec2': 'ivec2', + 'vec2': 'uvec2', + 'vec2': 'bvec2', + + vec2f: 'vec2', + vec2i: 'ivec2', + vec2u: 'uvec2', + vec2b: 'bvec2', + + 'vec3': 'vec3', + 'vec3': 'ivec3', + 'vec3': 'uvec3', + 'vec3': 'bvec3', + + vec3f: 'vec3', + vec3i: 'ivec3', + vec3u: 'uvec3', + vec3b: 'bvec3', + + 'vec4': 'vec4', + 'vec4': 'ivec4', + 'vec4': 'uvec4', + 'vec4': 'bvec4', + + vec4f: 'vec4', + vec4i: 'ivec4', + vec4u: 'uvec4', + vec4b: 'bvec4', + + 'mat2x2': 'mat2', + mat2x2f: 'mat2', + + 'mat3x3': 'mat3', + mat3x3f: 'mat3', + + 'mat4x4': 'mat4', + mat4x4f: 'mat4', + + sampler: 'sampler', + + texture_1d: 'texture', + + texture_2d: 'texture', + texture_2d_array: 'texture', + texture_multisampled_2d: 'cubeTexture', + + texture_depth_2d: 'depthTexture', + + texture_3d: 'texture3D', + + texture_cube: 'cubeTexture', + texture_cube_array: 'cubeTexture', + + texture_storage_1d: 'storageTexture', + texture_storage_2d: 'storageTexture', + texture_storage_2d_array: 'storageTexture', + texture_storage_3d: 'storageTexture', +}; + +const parse = source => { + source = source.trim(); + + const declaration = source.match(declarationRegexp); + + if (declaration !== null && declaration.length === 4) { + const inputsCode = declaration[2]; + const propsMatches = []; + let match = null; + + while ((match = propertiesRegexp.exec(inputsCode)) !== null) { + propsMatches.push({ name: match[1], type: match[2] }); + } + + // Process matches to correctly pair names and types + const inputs = []; + for (let i = 0; i < propsMatches.length; i++) { + const { name, type } = propsMatches[i]; + + let resolvedType = type; + + if (resolvedType.startsWith('texture')) { + resolvedType = type.split('<')[0]; + } else if (resolvedType.startsWith('ptr')) { + resolvedType = 'pointer'; + } + + resolvedType = wgslTypeLib[resolvedType] || resolvedType; + + inputs.push(new NodeFunctionInput(resolvedType, name)); + } + + const blockCode = source.substring(declaration[0].length); + const outputType = declaration[3] || 'void'; + + const name = declaration[1] !== undefined ? declaration[1] : ''; + const type = wgslTypeLib[outputType] || outputType; + + return { + type, + inputs, + name, + inputsCode, + blockCode, + outputType, + }; + } else { + throw new Error('FunctionNode: Function is not a WGSL code.'); + } +}; + +class WGSLNodeFunction extends NodeFunction { + constructor(source) { + const { type, inputs, name, inputsCode, blockCode, outputType } = parse(source); + + super(type, inputs, name); + + this.inputsCode = inputsCode; + this.blockCode = blockCode; + this.outputType = outputType; + } + + getCode(name = this.name) { + const outputType = this.outputType !== 'void' ? '-> ' + this.outputType : ''; + + return `fn ${name} ( ${this.inputsCode.trim()} ) ${outputType}` + this.blockCode; + } +} + +export default WGSLNodeFunction; diff --git a/src-testing/src/renderers/webgpu/nodes/WGSLNodeParser.ts b/src-testing/src/renderers/webgpu/nodes/WGSLNodeParser.ts new file mode 100644 index 000000000..c32133df4 --- /dev/null +++ b/src-testing/src/renderers/webgpu/nodes/WGSLNodeParser.ts @@ -0,0 +1,10 @@ +import NodeParser from '../../../nodes/core/NodeParser.js'; +import WGSLNodeFunction from './WGSLNodeFunction.js'; + +class WGSLNodeParser extends NodeParser { + parseFunction(source) { + return new WGSLNodeFunction(source); + } +} + +export default WGSLNodeParser; diff --git a/src-testing/src/renderers/webgpu/utils/WebGPUConstants.d.ts b/src-testing/src/renderers/webgpu/utils/WebGPUConstants.d.ts new file mode 100644 index 000000000..baa36f901 --- /dev/null +++ b/src-testing/src/renderers/webgpu/utils/WebGPUConstants.d.ts @@ -0,0 +1,328 @@ +export enum GPUPrimitiveTopology { + PointList = "point-list", + LineList = "line-list", + LineStrip = "line-strip", + TriangleList = "triangle-list", + TriangleStrip = "triangle-strip", +} + +export enum GPUCompareFunction { + Never = "never", + Less = "less", + Equal = "equal", + LessEqual = "less-equal", + Greater = "greater", + NotEqual = "not-equal", + GreaterEqual = "greater-equal", + Always = "always", +} + +export enum GPUStoreOp { + Store = "store", + Discard = "discard", +} + +export enum GPULoadOp { + Load = "load", + Clear = "clear", +} + +export enum GPUFrontFace { + CCW = "ccw", + CW = "cw", +} + +export enum GPUCullMode { + None = "none", + Front = "front", + Back = "back", +} + +export enum GPUIndexFormat { + Uint16 = "uint16", + Uint32 = "uint32", +} + +export enum GPUVertexFormat { + Uint8x2 = "uint8x2", + Uint8x4 = "uint8x4", + Sint8x2 = "sint8x2", + Sint8x4 = "sint8x4", + Unorm8x2 = "unorm8x2", + Unorm8x4 = "unorm8x4", + Snorm8x2 = "snorm8x2", + Snorm8x4 = "snorm8x4", + Uint16x2 = "uint16x2", + Uint16x4 = "uint16x4", + Sint16x2 = "sint16x2", + Sint16x4 = "sint16x4", + Unorm16x2 = "unorm16x2", + Unorm16x4 = "unorm16x4", + Snorm16x2 = "snorm16x2", + Snorm16x4 = "snorm16x4", + Float16x2 = "float16x2", + Float16x4 = "float16x4", + Float32 = "float32", + Float32x2 = "float32x2", + Float32x3 = "float32x3", + Float32x4 = "float32x4", + Uint32 = "uint32", + Uint32x2 = "uint32x2", + Uint32x3 = "uint32x3", + Uint32x4 = "uint32x4", + Sint32 = "sint32", + Sint32x2 = "sint32x2", + Sint32x3 = "sint32x3", + Sint32x4 = "sint32x4", +} + +export enum GPUTextureFormat { + // 8-bit formats + + R8Unorm = "r8unorm", + R8Snorm = "r8snorm", + R8Uint = "r8uint", + R8Sint = "r8sint", + + // 16-bit formats + + R16Uint = "r16uint", + R16Sint = "r16sint", + R16Float = "r16float", + RG8Unorm = "rg8unorm", + RG8Snorm = "rg8snorm", + RG8Uint = "rg8uint", + RG8Sint = "rg8sint", + + // 32-bit formats + + R32Uint = "r32uint", + R32Sint = "r32sint", + R32Float = "r32float", + RG16Uint = "rg16uint", + RG16Sint = "rg16sint", + RG16Float = "rg16float", + RGBA8Unorm = "rgba8unorm", + RGBA8UnormSRGB = "rgba8unorm-srgb", + RGBA8Snorm = "rgba8snorm", + RGBA8Uint = "rgba8uint", + RGBA8Sint = "rgba8sint", + BGRA8Unorm = "bgra8unorm", + BGRA8UnormSRGB = "bgra8unorm-srgb", + // Packed 32-bit formats + RGB9E5UFloat = "rgb9e5ufloat", + RGB10A2Unorm = "rgb10a2unorm", + RG11B10uFloat = "rgb10a2unorm", + + // 64-bit formats + + RG32Uint = "rg32uint", + RG32Sint = "rg32sint", + RG32Float = "rg32float", + RGBA16Uint = "rgba16uint", + RGBA16Sint = "rgba16sint", + RGBA16Float = "rgba16float", + + // 128-bit formats + + RGBA32Uint = "rgba32uint", + RGBA32Sint = "rgba32sint", + RGBA32Float = "rgba32float", + + // Depth and stencil formats + + Stencil8 = "stencil8", + Depth16Unorm = "depth16unorm", + Depth24Plus = "depth24plus", + Depth24PlusStencil8 = "depth24plus-stencil8", + Depth32Float = "depth32float", + + // 'depth32float-stencil8' extension + + Depth32FloatStencil8 = "depth32float-stencil8", + + // BC compressed formats usable if 'texture-compression-bc' is both + // supported by the device/user agent and enabled in requestDevice. + + BC1RGBAUnorm = "bc1-rgba-unorm", + BC1RGBAUnormSRGB = "bc1-rgba-unorm-srgb", + BC2RGBAUnorm = "bc2-rgba-unorm", + BC2RGBAUnormSRGB = "bc2-rgba-unorm-srgb", + BC3RGBAUnorm = "bc3-rgba-unorm", + BC3RGBAUnormSRGB = "bc3-rgba-unorm-srgb", + BC4RUnorm = "bc4-r-unorm", + BC4RSnorm = "bc4-r-snorm", + BC5RGUnorm = "bc5-rg-unorm", + BC5RGSnorm = "bc5-rg-snorm", + BC6HRGBUFloat = "bc6h-rgb-ufloat", + BC6HRGBFloat = "bc6h-rgb-float", + BC7RGBAUnorm = "bc7-rgba-unorm", + BC7RGBAUnormSRGB = "bc7-rgba-srgb", + + // ETC2 compressed formats usable if 'texture-compression-etc2' is both + // supported by the device/user agent and enabled in requestDevice. + + ETC2RGB8Unorm = "etc2-rgb8unorm", + ETC2RGB8UnormSRGB = "etc2-rgb8unorm-srgb", + ETC2RGB8A1Unorm = "etc2-rgb8a1unorm", + ETC2RGB8A1UnormSRGB = "etc2-rgb8a1unorm-srgb", + ETC2RGBA8Unorm = "etc2-rgba8unorm", + ETC2RGBA8UnormSRGB = "etc2-rgba8unorm-srgb", + EACR11Unorm = "eac-r11unorm", + EACR11Snorm = "eac-r11snorm", + EACRG11Unorm = "eac-rg11unorm", + EACRG11Snorm = "eac-rg11snorm", + + // ASTC compressed formats usable if 'texture-compression-astc' is both + // supported by the device/user agent and enabled in requestDevice. + + ASTC4x4Unorm = "astc-4x4-unorm", + ASTC4x4UnormSRGB = "astc-4x4-unorm-srgb", + ASTC5x4Unorm = "astc-5x4-unorm", + ASTC5x4UnormSRGB = "astc-5x4-unorm-srgb", + ASTC5x5Unorm = "astc-5x5-unorm", + ASTC5x5UnormSRGB = "astc-5x5-unorm-srgb", + ASTC6x5Unorm = "astc-6x5-unorm", + ASTC6x5UnormSRGB = "astc-6x5-unorm-srgb", + ASTC6x6Unorm = "astc-6x6-unorm", + ASTC6x6UnormSRGB = "astc-6x6-unorm-srgb", + ASTC8x5Unorm = "astc-8x5-unorm", + ASTC8x5UnormSRGB = "astc-8x5-unorm-srgb", + ASTC8x6Unorm = "astc-8x6-unorm", + ASTC8x6UnormSRGB = "astc-8x6-unorm-srgb", + ASTC8x8Unorm = "astc-8x8-unorm", + ASTC8x8UnormSRGB = "astc-8x8-unorm-srgb", + ASTC10x5Unorm = "astc-10x5-unorm", + ASTC10x5UnormSRGB = "astc-10x5-unorm-srgb", + ASTC10x6Unorm = "astc-10x6-unorm", + ASTC10x6UnormSRGB = "astc-10x6-unorm-srgb", + ASTC10x8Unorm = "astc-10x8-unorm", + ASTC10x8UnormSRGB = "astc-10x8-unorm-srgb", + ASTC10x10Unorm = "astc-10x10-unorm", + ASTC10x10UnormSRGB = "astc-10x10-unorm-srgb", + ASTC12x10Unorm = "astc-12x10-unorm", + ASTC12x10UnormSRGB = "astc-12x10-unorm-srgb", + ASTC12x12Unorm = "astc-12x12-unorm", + ASTC12x12UnormSRGB = "astc-12x12-unorm-srgb", +} + +export enum GPUAddressMode { + ClampToEdge = "clamp-to-edge", + Repeat = "repeat", + MirrorRepeat = "mirror-repeat", +} + +export enum GPUFilterMode { + Linear = "linear", + Nearest = "nearest", +} + +export enum GPUBlendFactor { + Zero = "zero", + One = "one", + Src = "src", + OneMinusSrc = "one-minus-src", + SrcAlpha = "src-alpha", + OneMinusSrcAlpha = "one-minus-src-alpha", + Dst = "dst", + OneMinusDstColor = "one-minus-dst", + DstAlpha = "dst-alpha", + OneMinusDstAlpha = "one-minus-dst-alpha", + SrcAlphaSaturated = "src-alpha-saturated", + Constant = "constant", + OneMinusConstant = "one-minus-constant", +} + +export enum GPUBlendOperation { + Add = "add", + Subtract = "subtract", + ReverseSubtract = "reverse-subtract", + Min = "min", + Max = "max", +} + +export enum GPUColorWriteFlags { + None = 0, + Red = 0x1, + Green = 0x2, + Blue = 0x4, + Alpha = 0x8, + All = 0xF, +} + +export enum GPUStencilOperation { + Keep = "keep", + Zero = "zero", + Replace = "replace", + Invert = "invert", + IncrementClamp = "increment-clamp", + DecrementClamp = "decrement-clamp", + IncrementWrap = "increment-wrap", + DecrementWrap = "decrement-wrap", +} + +export enum GPUBufferBindingType { + Uniform = "uniform", + Storage = "storage", + ReadOnlyStorage = "read-only-storage", +} + +export enum GPUStorageTextureAccess { + WriteOnly = "write-only", + ReadOnly = "read-only", + ReadWrite = "read-write", +} + +export enum GPUSamplerBindingType { + Filtering = "filtering", + NonFiltering = "non-filtering", + Comparison = "comparison", +} + +export enum GPUTextureSampleType { + Float = "float", + UnfilterableFloat = "unfilterable-float", + Depth = "depth", + SInt = "sint", + UInt = "uint", +} + +export enum GPUTextureDimension { + OneD = "1d", + TwoD = "2d", + ThreeD = "3d", +} + +export enum GPUTextureViewDimension { + OneD = "1d", + TwoD = "2d", + TwoDArray = "2d-array", + Cube = "cube", + CubeArray = "cube-array", + ThreeD = "3d", +} + +export enum GPUTextureAspect { + All = "all", + StencilOnly = "stencil-only", + DepthOnly = "depth-only", +} + +export enum GPUInputStepMode { + Vertex = "vertex", + Instance = "instance", +} + +export enum GPUFeatureName { + DepthClipControl = "depth-clip-control", + Depth32FloatStencil8 = "depth32float-stencil8", + TextureCompressionBC = "texture-compression-bc", + TextureCompressionETC2 = "texture-compression-etc2", + TextureCompressionASTC = "texture-compression-astc", + TimestampQuery = "timestamp-query", + IndirectFirstInstance = "indirect-first-instance", + ShaderF16 = "shader-f16", + RG11B10UFloat = "rg11b10ufloat-renderable", + BGRA8UNormStorage = "bgra8unorm-storage", + Float32Filterable = "float32-filterable", +} diff --git a/src-testing/src/renderers/webxr/WebXRController.d.ts b/src-testing/src/renderers/webxr/WebXRController.d.ts new file mode 100644 index 000000000..956a036b4 --- /dev/null +++ b/src-testing/src/renderers/webxr/WebXRController.d.ts @@ -0,0 +1,63 @@ +import { Object3DEventMap } from "../../core/Object3D.js"; +import { Vector3 } from "../../math/Vector3.js"; +import { Group } from "../../objects/Group.js"; + +export type XRControllerEventType = XRSessionEventType | XRInputSourceEventType | "disconnected" | "connected"; + +export class XRJointSpace extends Group { + readonly jointRadius: number | undefined; +} + +export type XRHandJoints = Record; + +export interface XRHandInputState { + pinching: boolean; +} + +export interface WebXRSpaceEventMap extends Object3DEventMap { + select: { data: XRInputSource }; + selectstart: { data: XRInputSource }; + selectend: { data: XRInputSource }; + squeeze: { data: XRInputSource }; + squeezestart: { data: XRInputSource }; + squeezeend: { data: XRInputSource }; + + connected: { data: XRInputSource }; + disconnected: { data: XRInputSource }; + + pinchend: { handedness: XRHandedness; target: WebXRController }; // This Event break the THREE.EventDispatcher contract, replacing the target to the wrong instance. + pinchstart: { handedness: XRHandedness; target: WebXRController }; // This Event break the THREE.EventDispatcher contract, replacing the target to the wrong instance. + + move: {}; +} + +export class XRHandSpace extends Group { + readonly joints: Partial; + readonly inputState: XRHandInputState; +} + +export class XRTargetRaySpace extends Group { + hasLinearVelocity: boolean; + readonly linearVelocity: Vector3; + hasAngularVelocity: boolean; + readonly angularVelocity: Vector3; +} + +export class XRGripSpace extends Group { + hasLinearVelocity: boolean; + readonly linearVelocity: Vector3; + hasAngularVelocity: boolean; + readonly angularVelocity: Vector3; +} + +export class WebXRController { + constructor(); + + getHandSpace(): XRHandSpace; + getTargetRaySpace(): XRTargetRaySpace; + getGripSpace(): XRGripSpace; + dispatchEvent(event: { type: XRControllerEventType; data?: XRInputSource }): this; + connect(inputSource: XRInputSource): this; + disconnect(inputSource: XRInputSource): this; + update(inputSource: XRInputSource, frame: XRFrame, referenceSpace: XRReferenceSpace): this; +} diff --git a/src-testing/src/renderers/webxr/WebXRDepthSensing.d.ts b/src-testing/src/renderers/webxr/WebXRDepthSensing.d.ts new file mode 100644 index 000000000..23914f679 --- /dev/null +++ b/src-testing/src/renderers/webxr/WebXRDepthSensing.d.ts @@ -0,0 +1,22 @@ +import { Mesh } from "../../objects/Mesh.js"; +import { Texture } from "../../textures/Texture.js"; +import { WebGLRenderer } from "../WebGLRenderer.js"; +import { WebXRArrayCamera } from "./WebXRManager.js"; + +export class WebXRDepthSensing { + texture: Texture | null; + mesh: Mesh | null; + + depthNear: number; + depthFar: number; + + constructor(); + + init(renderer: WebGLRenderer, depthData: XRWebGLDepthInformation, renderState: XRRenderState): void; + + getMesh(cameraXR: WebXRArrayCamera): Mesh | null; + + reset(): void; + + getDepthTexture(): Texture | null; +} diff --git a/src-testing/src/renderers/webxr/WebXRManager.d.ts b/src-testing/src/renderers/webxr/WebXRManager.d.ts new file mode 100644 index 000000000..4b2073101 --- /dev/null +++ b/src-testing/src/renderers/webxr/WebXRManager.d.ts @@ -0,0 +1,85 @@ +/// + +import { ArrayCamera } from "../../cameras/ArrayCamera.js"; +import { PerspectiveCamera } from "../../cameras/PerspectiveCamera.js"; +import { EventDispatcher } from "../../core/EventDispatcher.js"; +import { Vector4 } from "../../math/Vector4.js"; +import { Mesh } from "../../objects/Mesh.js"; +import { Texture } from "../../textures/Texture.js"; +import { WebGLRenderer } from "../WebGLRenderer.js"; +import { XRGripSpace, XRHandSpace, XRTargetRaySpace } from "./WebXRController.js"; + +export type WebXRCamera = PerspectiveCamera & { viewport: Vector4 }; +export type WebXRArrayCamera = Omit & { cameras: [WebXRCamera, WebXRCamera] }; + +export interface WebXRManagerEventMap { + sessionstart: {}; + sessionend: {}; + planeadded: { data: XRPlane }; + planeremoved: { data: XRPlane }; + planechanged: { data: XRPlane }; + planesdetected: { data: XRPlaneSet }; +} + +export class WebXRManager extends EventDispatcher { + /** + * @default true + */ + cameraAutoUpdate: boolean; + + /** + * @default false + */ + enabled: boolean; + + /** + * @default false + */ + isPresenting: boolean; + + constructor(renderer: WebGLRenderer, gl: WebGLRenderingContext); + + getController: (index: number) => XRTargetRaySpace; + + getControllerGrip: (index: number) => XRGripSpace; + + getHand: (index: number) => XRHandSpace; + + setFramebufferScaleFactor: (value: number) => void; + + setReferenceSpaceType: (value: XRReferenceSpaceType) => void; + + getReferenceSpace: () => XRReferenceSpace | null; + + setReferenceSpace: (value: XRReferenceSpace) => void; + + getBaseLayer: () => XRWebGLLayer | XRProjectionLayer; + + getBinding: () => XRWebGLBinding; + + getFrame: () => XRFrame; + + getSession: () => XRSession | null; + + setSession: (value: XRSession | null) => Promise; + + getEnvironmentBlendMode: () => XREnvironmentBlendMode | undefined; + + getDepthTexture: () => Texture | null; + + updateCamera: (camera: PerspectiveCamera) => void; + + getCamera: () => WebXRArrayCamera; + + getFoveation: () => number | undefined; + + setFoveation: (value: number) => void; + + hasDepthSensing: () => boolean; + + getDepthSensingMesh: () => Mesh | null; + + setAnimationLoop: (callback: XRFrameRequestCallback | null) => void; + + dispose: () => void; +} diff --git a/src-testing/src/scenes/Fog.d.ts b/src-testing/src/scenes/Fog.d.ts new file mode 100644 index 000000000..fc0f18019 --- /dev/null +++ b/src-testing/src/scenes/Fog.d.ts @@ -0,0 +1,77 @@ +import { Color, ColorRepresentation } from "../math/Color.js"; + +export interface FogJSON { + type: string; + name: string; + color: number; + near: number; + far: number; +} + +/** + * This class contains the parameters that define linear fog, i.e., that grows linearly denser with the distance. + * @example + * ```typescript + * const scene = new THREE.Scene(); + * scene.fog = new THREE.Fog(0xcccccc, 10, 15); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/scenes/Fog | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/scenes/Fog.js | Source} + */ +export class Fog { + /** + * The color parameter is passed to the {@link THREE.Color | Color} constructor to set the color property + * @remarks + * Color can be a hexadecimal integer or a CSS-style string. + * @param color + * @param near Expects a `Float` + * @param far Expects a `Float` + */ + constructor(color: ColorRepresentation, near?: number, far?: number); + + /** + * Read-only flag to check if a given object is of type {@link Fog}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isFog: true; + + /** + * Optional name of the object + * @remarks _(doesn't need to be unique)_. + * @defaultValue `""` + */ + name: string; + + /** + * Fog color. + * @remarks If set to black, far away objects will be rendered black. + */ + color: Color; + + /** + * The minimum distance to start applying fog. + * @remarks Objects that are less than **near** units from the active camera won't be affected by fog. + * @defaultValue `1` + * @remarks Expects a `Float` + */ + near: number; + + /** + * The maximum distance at which fog stops being calculated and applied. + * @remarks Objects that are more than **far** units away from the active camera won't be affected by fog. + * @defaultValue `1000` + * @remarks Expects a `Float` + */ + far: number; + + /** + * Returns a new {@link Fog} instance with the same parameters as this one. + */ + clone(): Fog; + + /** + * Return {@link Fog} data in JSON format. + */ + toJSON(): FogJSON; +} diff --git a/src-testing/src/scenes/FogExp2.d.ts b/src-testing/src/scenes/FogExp2.d.ts new file mode 100644 index 000000000..af00981e6 --- /dev/null +++ b/src-testing/src/scenes/FogExp2.d.ts @@ -0,0 +1,66 @@ +import { Color, ColorRepresentation } from "../math/Color.js"; + +export interface FogExp2JSON { + type: string; + name: string; + color: number; + density: number; +} + +/** + * This class contains the parameters that define exponential squared fog, which gives a clear view near the camera and a faster than exponentially densening fog farther from the camera. + * @example + * ```typescript + * const scene = new THREE.Scene(); + * scene.fog = new THREE.FogExp2(0xcccccc, 0.002); + * ``` + * @see Example: {@link https://threejs.org/examples/#webgl_geometry_terrain | webgl geometry terrain} + * @see {@link https://threejs.org/docs/index.html#api/en/scenes/FogExp2 | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/scenes/FogExp2.js | Source} + */ +export class FogExp2 { + /** + * The color parameter is passed to the {@link THREE.Color | Color} constructor to set the color property + * @remarks Color can be a hexadecimal integer or a CSS-style string. + * @param color + * @param density Expects a `Float` + */ + constructor(color: ColorRepresentation, density?: number); + + /** + * Read-only flag to check if a given object is of type {@link FogExp2}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isFogExp2: true; + + /** + * Optional name of the object + * @remarks _(doesn't need to be unique)_. + * @defaultValue `""` + */ + name: string; + + /** + * Fog color. + * @remarks If set to black, far away objects will be rendered black. + */ + color: Color; + + /** + * Defines how fast the fog will grow dense. + * @defaultValue `0.00025` + * @remarks Expects a `Float` + */ + density: number; + + /** + * Returns a new {@link FogExp2} instance with the same parameters as this one. + */ + clone(): FogExp2; + + /** + * Return {@link FogExp2} data in JSON format. + */ + toJSON(): FogExp2JSON; +} diff --git a/src-testing/src/scenes/Scene.d.ts b/src-testing/src/scenes/Scene.d.ts new file mode 100644 index 000000000..c2f43afd7 --- /dev/null +++ b/src-testing/src/scenes/Scene.d.ts @@ -0,0 +1,118 @@ +import { JSONMeta, Object3D, Object3DJSON, Object3DJSONObject } from "../core/Object3D.js"; +import { Material } from "../materials/Material.js"; +import { Color } from "../math/Color.js"; +import { Euler, EulerTuple } from "../math/Euler.js"; +import { CubeTexture } from "../textures/CubeTexture.js"; +import { Texture } from "../textures/Texture.js"; +import { Fog, FogJSON } from "./Fog.js"; +import { FogExp2, FogExp2JSON } from "./FogExp2.js"; + +export interface SceneJSONObject extends Object3DJSONObject { + fog?: FogJSON | FogExp2JSON; + + backgroundBlurriness?: number; + backgroundIntensity?: number; + backgroundRotation: EulerTuple; + + environmentIntensity?: number; + environmentRotation: EulerTuple; +} + +export interface SceneJSON extends Object3DJSON { + object: SceneJSONObject; +} + +/** + * Scenes allow you to set up what and where is to be rendered by three.js + * @remarks + * This is where you place objects, lights and cameras. + * @see Example: {@link https://threejs.org/examples/#webgl_multiple_scenes_comparison | webgl multiple scenes comparison} + * @see {@link https://threejs.org/docs/index.html#manual/en/introduction/Creating-a-scene | Manual: Creating a scene} + * @see {@link https://threejs.org/docs/index.html#api/en/scenes/Scene | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/scenes/Scene.js | Source} + */ +export class Scene extends Object3D { + /** + * Create a new {@link Scene} object. + */ + constructor(); + + /** + * Read-only flag to check if a given object is of type {@link Scene}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isScene: true; + + /** + * @defaultValue `Scene` + */ + type: "Scene"; + + /** + * A {@link Fog | fog} instance defining the type of fog that affects everything rendered in the scene. + * @defaultValue `null` + */ + fog: Fog | FogExp2 | null; + + /** + * Sets the blurriness of the background. Only influences environment maps assigned to {@link THREE.Scene.background | Scene.background}. + * @defaultValue `0` + * @remarks Expects a `Float` between `0` and `1`. + */ + backgroundBlurriness: number; + + /** + * Attenuates the color of the background. Only applies to background textures. + * @defaultValue `1` + * @remarks Expects a `Float` + */ + backgroundIntensity: number; + + /** + * Forces everything in the {@link Scene} to be rendered with the defined material. + * @defaultValue `null` + */ + overrideMaterial: Material | null; + + /** + * Defines the background of the scene. + * @remarks Valid inputs are: + * - A {@link THREE.Color | Color} for defining a uniform colored background. + * - A {@link THREE.Texture | Texture} for defining a (flat) textured background. + * - Texture cubes ({@link THREE.CubeTexture | CubeTexture}) or equirectangular textures for defining a skybox. + * @defaultValue `null` + */ + background: Color | Texture | CubeTexture | null; + + /** + * The rotation of the background in radians. Only influences environment maps assigned to {@link .background}. + * Default is `(0,0,0)`. + */ + backgroundRotation: Euler; + + /** + * Sets the environment map for all physical materials in the scene. + * However, it's not possible to overwrite an existing texture assigned to {@link THREE.MeshStandardMaterial.envMap | MeshStandardMaterial.envMap}. + * @defaultValue `null` + */ + environment: Texture | null; + + /** + * Attenuates the color of the environment. Only influences environment maps assigned to {@link Scene.environment}. + * @default 1 + */ + environmentIntensity: number; + + /** + * The rotation of the environment map in radians. Only influences physical materials in the scene when + * {@link .environment} is used. Default is `(0,0,0)`. + */ + environmentRotation: Euler; + + /** + * Convert the {@link Scene} to three.js {@link https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 | JSON Object/Scene format}. + * @param meta Object containing metadata such as textures or images for the scene. + */ + toJSON(meta?: JSONMeta): SceneJSON; +} diff --git a/src-testing/src/textures/CanvasTexture.d.ts b/src-testing/src/textures/CanvasTexture.d.ts new file mode 100644 index 000000000..6445338fa --- /dev/null +++ b/src-testing/src/textures/CanvasTexture.d.ts @@ -0,0 +1,51 @@ +import { + MagnificationTextureFilter, + Mapping, + MinificationTextureFilter, + PixelFormat, + TextureDataType, + Wrapping, +} from "../constants.js"; +import { OffscreenCanvas, Texture } from "./Texture.js"; + +/** + * Creates a texture from a {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas | canvas element}. + * @remarks + * This is almost the same as the base {@link Texture | Texture} class, + * except that it sets {@link Texture.needsUpdate | needsUpdate} to `true` immediately. + * @see {@link THREE.Texture | Texture} + * @see {@link https://threejs.org/docs/index.html#api/en/textures/CanvasTexture | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/textures/CanvasTexture.js | Source} + */ +export class CanvasTexture extends Texture { + /** + * This creates a new {@link THREE.CanvasTexture | CanvasTexture} object. + * @param canvas The HTML canvas element from which to load the texture. + * @param mapping See {@link Texture.mapping | .mapping}. Default {@link THREE.Texture.DEFAULT_MAPPING} + * @param wrapS See {@link Texture.wrapS | .wrapS}. Default {@link THREE.ClampToEdgeWrapping} + * @param wrapT See {@link Texture.wrapT | .wrapT}. Default {@link THREE.ClampToEdgeWrapping} + * @param magFilter See {@link Texture.magFilter | .magFilter}. Default {@link THREE.LinearFilter} + * @param minFilter See {@link Texture.minFilter | .minFilter}. Default {@link THREE.LinearMipmapLinearFilter} + * @param format See {@link Texture.format | .format}. Default {@link THREE.RGBAFormat} + * @param type See {@link Texture.type | .type}. Default {@link THREE.UnsignedByteType} + * @param anisotropy See {@link Texture.anisotropy | .anisotropy}. Default {@link THREE.Texture.DEFAULT_ANISOTROPY} + */ + constructor( + canvas: TexImageSource | OffscreenCanvas, + mapping?: Mapping, + wrapS?: Wrapping, + wrapT?: Wrapping, + magFilter?: MagnificationTextureFilter, + minFilter?: MinificationTextureFilter, + format?: PixelFormat, + type?: TextureDataType, + anisotropy?: number, + ); + + /** + * Read-only flag to check if a given object is of type {@link CanvasTexture}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isCanvasTexture: true; +} diff --git a/src-testing/src/textures/CompressedArrayTexture.d.ts b/src-testing/src/textures/CompressedArrayTexture.d.ts new file mode 100644 index 000000000..e46c3d478 --- /dev/null +++ b/src-testing/src/textures/CompressedArrayTexture.d.ts @@ -0,0 +1,68 @@ +import { CompressedPixelFormat, TextureDataType, Wrapping } from "../constants.js"; +import { CompressedTexture, CompressedTextureMipmap } from "./CompressedTexture.js"; + +/** + * Creates an texture 2D array based on data in compressed form, for example from a + * {@link https://en.wikipedia.org/wiki/DirectDraw_Surface | DDS} file. + * @remarks For use with the {@link THREE.CompressedTextureLoader | CompressedTextureLoader}. + * @see {@link https://threejs.org/docs/index.html#api/en/textures/CompressedArrayTexture | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/textures/CompressedArrayTexture.js | Source} + */ +export class CompressedArrayTexture extends CompressedTexture { + /** + * Read-only flag to check if a given object is of type {@link CompressedArrayTexture}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isCompressedArrayTexture: true; + + /** + * Overridden with a object containing width and height. + * @override + */ + get image(): { width: number; height: number; depth: number }; + set image(value: { width: number; height: number; depth: number }); + + /** + * This defines how the texture is wrapped in the depth direction. + * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} + * @defaultValue {@link THREE.ClampToEdgeWrapping} + */ + wrapR: Wrapping; + + /** + * A set of all layers which need to be updated in the texture. See {@link CompressedArrayTexture.addLayerUpdate}. + */ + layerUpdates: Set; + + /** + * Create a new instance of {@link CompressedArrayTexture} + * @param mipmaps The mipmaps array should contain objects with data, width and height. The mipmaps should be of the + * correct format and type. + * @param width The width of the biggest mipmap. + * @param height The height of the biggest mipmap. + * @param depth The number of layers of the 2D array texture + * @param format The format used in the mipmaps. See {@link THREE.CompressedPixelFormat}. + * @param type See {@link Texture.type | .type}. Default {@link THREE.UnsignedByteType} + */ + constructor( + mipmaps: CompressedTextureMipmap[], + width: number, + height: number, + depth: number, + format: CompressedPixelFormat, + type?: TextureDataType, + ); + + /** + * Describes that a specific layer of the texture needs to be updated. Normally when {@link Texture.needsUpdate} is + * set to true, the entire compressed texture array is sent to the GPU. Marking specific layers will only transmit + * subsets of all mipmaps associated with a specific depth in the array which is often much more performant. + */ + addLayerUpdate(layerIndex: number): void; + + /** + * Resets the layer updates registry. See {@link CompressedArrayTexture.addLayerUpdate}. + */ + clearLayoutUpdates(): void; +} diff --git a/src-testing/src/textures/CompressedCubeTexture.d.ts b/src-testing/src/textures/CompressedCubeTexture.d.ts new file mode 100644 index 000000000..9c72145a0 --- /dev/null +++ b/src-testing/src/textures/CompressedCubeTexture.d.ts @@ -0,0 +1,13 @@ +import { CompressedPixelFormat, TextureDataType } from "../constants.js"; +import { CompressedTexture } from "./CompressedTexture.js"; + +export class CompressedCubeTexture extends CompressedTexture { + readonly isCompressedCubeTexture: true; + readonly isCubeTexture: true; + + constructor( + images: Array<{ width: number; height: number }>, + format?: CompressedPixelFormat, + type?: TextureDataType, + ); +} diff --git a/src-testing/src/textures/CompressedTexture.d.ts b/src-testing/src/textures/CompressedTexture.d.ts new file mode 100644 index 000000000..33ec5b17d --- /dev/null +++ b/src-testing/src/textures/CompressedTexture.d.ts @@ -0,0 +1,94 @@ +import { + CompressedPixelFormat, + MagnificationTextureFilter, + Mapping, + MinificationTextureFilter, + TextureDataType, + Wrapping, +} from "../constants.js"; +import { TypedArray } from "../core/BufferAttribute.js"; +import { Texture } from "./Texture.js"; + +export interface CompressedTextureMipmap { + data: TypedArray; + width: number; + height: number; +} + +/** + * Creates a texture based on data in compressed form, for example from a {@link https://en.wikipedia.org/wiki/DirectDraw_Surface | DDS} file. + * @remarks For use with the {@link THREE.CompressedTextureLoader | CompressedTextureLoader}. + * @see {@link https://threejs.org/docs/index.html#api/en/textures/CompressedTexture | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/textures/CompressedTexture.js | Source} + */ +export class CompressedTexture extends Texture { + /** + * This creates a new {@link THREE.CompressedTexture | CompressedTexture} object. + * @param mipmaps The mipmaps array should contain objects with data, width and height. The mipmaps should be of the + * correct format and type. + * @param width The width of the biggest mipmap. + * @param height The height of the biggest mipmap. + * @param format The format used in the mipmaps. See {@link THREE.CompressedPixelFormat}. + * @param type See {@link Texture.type | .type}. Default {@link THREE.UnsignedByteType} + * @param mapping See {@link Texture.mapping | .mapping}. Default {@link THREE.Texture.DEFAULT_MAPPING} + * @param wrapS See {@link Texture.wrapS | .wrapS}. Default {@link THREE.ClampToEdgeWrapping} + * @param wrapT See {@link Texture.wrapT | .wrapT}. Default {@link THREE.ClampToEdgeWrapping} + * @param magFilter See {@link Texture.magFilter | .magFilter}. Default {@link THREE.LinearFilter} + * @param minFilter See {@link Texture.minFilter | .minFilter}. Default {@link THREE.LinearMipmapLinearFilter} + * @param anisotropy See {@link Texture.anisotropy | .anisotropy}. Default {@link THREE.Texture.DEFAULT_ANISOTROPY} + * @param colorSpace See {@link Texture.colorSpace .colorSpace}. Default {@link NoColorSpace} + */ + constructor( + mipmaps?: CompressedTextureMipmap[], + width?: number, + height?: number, + format?: CompressedPixelFormat, + type?: TextureDataType, + mapping?: Mapping, + wrapS?: Wrapping, + wrapT?: Wrapping, + magFilter?: MagnificationTextureFilter, + minFilter?: MinificationTextureFilter, + anisotropy?: number, + colorSpace?: string, + ); + + /** + * Read-only flag to check if a given object is of type {@link CompressedTexture}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isCompressedTexture: true; + + /** + * Overridden with a object containing width and height. + * @override + */ + get image(): { width: number; height: number }; + set image(value: { width: number; height: number }); + + /** + * The mipmaps array should contain objects with data, width and height. The mipmaps should be of the correct + * format and type. + */ + mipmaps: CompressedTextureMipmap[] | undefined; + + /** + * @override + * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} + * @see {@link THREE.CompressedPixelFormat} + */ + format: CompressedPixelFormat; + + /** + * @override No flipping for cube textures. (also flipping doesn't work for compressed textures) + * @defaultValue `false` + */ + flipY: boolean; + + /** + * @override Can't generate mipmaps for compressed textures. mips must be embedded in DDS files + * @defaultValue `false` + */ + generateMipmaps: boolean; +} diff --git a/src-testing/src/textures/CubeTexture.d.ts b/src-testing/src/textures/CubeTexture.d.ts new file mode 100644 index 000000000..f5808aaf9 --- /dev/null +++ b/src-testing/src/textures/CubeTexture.d.ts @@ -0,0 +1,89 @@ +import { + CubeTextureMapping, + MagnificationTextureFilter, + MinificationTextureFilter, + PixelFormat, + TextureDataType, + Wrapping, +} from "../constants.js"; +import { Texture } from "./Texture.js"; + +/** + * Creates a cube texture made up of six images. + * @remarks + * {@link CubeTexture} is almost equivalent in functionality and usage to {@link Texture}. + * The only differences are that the images are an array of _6_ images as opposed to a single image, + * and the mapping options are {@link THREE.CubeReflectionMapping} (default) or {@link THREE.CubeRefractionMapping} + * @example + * ```typescript + * const loader = new THREE.CubeTextureLoader(); + * loader.setPath('textures/cube/pisa/'); + * const textureCube = loader.load(['px.png', 'nx.png', 'py.png', 'ny.png', 'pz.png', 'nz.png']); + * const material = new THREE.MeshBasicMaterial({ + * color: 0xffffff, + * envMap: textureCube + * }); + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/textures/CubeTexture | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/textures/CubeTexture.js | Source} + */ +export class CubeTexture extends Texture { + /** + * This creates a new {@link THREE.CubeTexture | CubeTexture} object. + * @param images + * @param mapping See {@link CubeTexture.mapping | .mapping}. Default {@link THREE.CubeReflectionMapping} + * @param wrapS See {@link Texture.wrapS | .wrapS}. Default {@link THREE.ClampToEdgeWrapping} + * @param wrapT See {@link Texture.wrapT | .wrapT}. Default {@link THREE.ClampToEdgeWrapping} + * @param magFilter See {@link Texture.magFilter | .magFilter}. Default {@link THREE.LinearFilter} + * @param minFilter See {@link Texture.minFilter | .minFilter}. Default {@link THREE.LinearMipmapLinearFilter} + * @param format See {@link Texture.format | .format}. Default {@link THREE.RGBAFormat} + * @param type See {@link Texture.type | .type}. Default {@link THREE.UnsignedByteType} + * @param anisotropy See {@link Texture.anisotropy | .anisotropy}. Default {@link THREE.Texture.DEFAULT_ANISOTROPY} + * @param colorSpace See {@link Texture.colorSpace | .colorSpace}. Default {@link NoColorSpace} + */ + constructor( + images?: any[], // HTMLImageElement or HTMLCanvasElement + mapping?: CubeTextureMapping, + wrapS?: Wrapping, + wrapT?: Wrapping, + magFilter?: MagnificationTextureFilter, + minFilter?: MinificationTextureFilter, + format?: PixelFormat, + type?: TextureDataType, + anisotropy?: number, + colorSpace?: string, + ); + + /** + * Read-only flag to check if a given object is of type {@link CubeTexture}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isCubeTexture: true; + + /** + * An image object, typically created using the {@link THREE.CubeTextureLoader.load | CubeTextureLoader.load()} method. + * @see {@link Texture.image} + */ + get image(): any; + set image(data: any); + + /** + * An image object, typically created using the {@link THREE.CubeTextureLoader.load | CubeTextureLoader.load()} method. + * @see {@link Texture.image} + */ + get images(): any; + set images(data: any); + + /** + * @inheritDoc + * @defaultValue {@link THREE.CubeReflectionMapping} + */ + mapping: CubeTextureMapping; + + /** + * @inheritDoc + * @defaultValue `false` + */ + flipY: boolean; +} diff --git a/src-testing/src/textures/Data3DTexture.d.ts b/src-testing/src/textures/Data3DTexture.d.ts new file mode 100644 index 000000000..9e5986eed --- /dev/null +++ b/src-testing/src/textures/Data3DTexture.d.ts @@ -0,0 +1,96 @@ +import { MagnificationTextureFilter, MinificationTextureFilter, Wrapping } from "../constants.js"; +import { Texture } from "./Texture.js"; +import { Texture3DImageData } from "./types.js"; + +/** + * Creates a three-dimensional texture from raw data, with parameters to divide it into width, height, and depth + * @example + * ```typescript + * This creates a[name] with repeating data, 0 to 255 + * // create a buffer with some data + * const sizeX = 64; + * const sizeY = 64; + * const sizeZ = 64; + * const data = new Uint8Array(sizeX * sizeY * sizeZ); + * let i = 0; + * for (let z = 0; z & lt; sizeZ; z++) { + * for (let y = 0; y & lt; sizeY; y++) { + * for (let x = 0; x & lt; sizeX; x++) { + * data[i] = i % 256; + * i++; + * } + * } + * } + * // use the buffer to create the texture + * const texture = new THREE.Data3DTexture(data, sizeX, sizeY, sizeZ); + * texture.needsUpdate = true; + * ``` + * @see Example: {@link https://threejs.org/examples/#webgl2_materials_texture3d | WebGL2 / materials / texture3d} + * @see Example: {@link https://threejs.org/examples/#webgl2_materials_texture3d_partialupdate | WebGL2 / materials / texture3d / partialupdate} + * @see Example: {@link https://threejs.org/examples/#webgl2_volume_cloud | WebGL2 / volume / cloud} + * @see Example: {@link https://threejs.org/examples/#webgl2_volume_perlin | WebGL2 / volume / perlin} + * @see {@link https://threejs.org/docs/index.html#api/en/textures/Data3DTexture | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/textures/Data3DTexture.js | Source} + */ +export class Data3DTexture extends Texture { + /** + * Create a new instance of {@link Data3DTexture} + * @param data {@link https://developer.mozilla.org/en-US/docs/Web/API/ArrayBufferView | ArrayBufferView} of the texture. Default `null`. + * @param width Width of the texture. Default `1`. + * @param height Height of the texture. Default `1`. + * @param depth Depth of the texture. Default `1`. + */ + constructor(data?: BufferSource | null, width?: number, height?: number, depth?: number); + + /** + * Read-only flag to check if a given object is of type {@link Data3DTexture}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isData3DTexture: true; + + /** + * Overridden with a record type holding data, width and height and depth. + * @override + */ + get image(): Texture3DImageData; + set image(data: Texture3DImageData); + + /** + * @override + * @defaultValue {@link THREE.NearestFilter} + */ + magFilter: MagnificationTextureFilter; + + /** + * @override + * @defaultValue {@link THREE.NearestFilter} + */ + minFilter: MinificationTextureFilter; + + /** + * @override + * @defaultValue {@link THREE.ClampToEdgeWrapping} + */ + wrapR: Wrapping; + + /** + * @override + * @defaultValue `false` + */ + flipY: boolean; + + /** + * @override + * @defaultValue `false` + */ + generateMipmaps: boolean; + + /** + * @override + * @defaultValue `1` + */ + unpackAlignment: number; +} + +export {}; diff --git a/src-testing/src/textures/DataArrayTexture.d.ts b/src-testing/src/textures/DataArrayTexture.d.ts new file mode 100644 index 000000000..d3a82c1e8 --- /dev/null +++ b/src-testing/src/textures/DataArrayTexture.d.ts @@ -0,0 +1,123 @@ +import { MagnificationTextureFilter, MinificationTextureFilter } from "../constants.js"; +import { Texture } from "./Texture.js"; +import { Texture3DImageData } from "./types.js"; + +/** + * Creates an array of textures directly from raw data, width and height and depth + * @example + * ```typescript + * This creates a[name] where each texture has a different color. + * // create a buffer with color data + * const width = 512; + * const height = 512; + * const depth = 100; + * const size = width * height; + * const data = new Uint8Array(4 * size * depth); + * for (let i = 0; i & lt; depth; i++) { + * const color = new THREE.Color(Math.random(), Math.random(), Math.random()); + * const r = Math.floor(color.r * 255); + * const g = Math.floor(color.g * 255); + * const b = Math.floor(color.b * 255); + * for (let j = 0; j & lt; size; j++) { + * const stride = (i * size + j) * 4; + * data[stride] = r; + * data[stride + 1] = g; + * data[stride + 2] = b; + * data[stride + 3] = 255; + * } + * } + * // used the buffer to create a [name] + * const texture = new THREE.DataArrayTexture(data, width, height, depth); + * texture.needsUpdate = true; + * ``` + * @see Example: {@link https://threejs.org/examples/#webgl2_materials_texture2darray | WebGL2 / materials / texture2darray} + * @see Example: {@link https://threejs.org/examples/#webgl2_rendertarget_texture2darray | WebGL2 / rendertarget / texture2darray} + * @see {@link https://threejs.org/docs/index.html#api/en/textures/DataArrayTexture | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/textures/DataArrayTexture.js | Source} + */ +export class DataArrayTexture extends Texture { + /** + * Read-only flag to check if a given object is of type {@link DataArrayTexture}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isDataArrayTexture: true; + + /** + * Overridden with a record type holding data, width and height and depth. + * @override + */ + get image(): Texture3DImageData; + set image(data: Texture3DImageData); + + /** + * @override + * @defaultValue {@link THREE.NearestFilter} + */ + magFilter: MagnificationTextureFilter; + + /** + * @override + * @defaultValue {@link THREE.NearestFilter} + */ + minFilter: MinificationTextureFilter; + + /** + * @override + * @defaultValue {@link THREE.ClampToEdgeWrapping} + */ + wrapR: boolean; + + /** + * @override + * @defaultValue `false` + */ + generateMipmaps: boolean; + + /** + * @override + * @defaultValue `false` + */ + flipY: boolean; + + /** + * @override + * @defaultValue `1` + */ + unpackAlignment: number; + + /** + * A set of all layers which need to be updated in the texture. See {@link DataArrayTexture.addLayerUpdate}. + */ + layerUpdates: Set; + + /** + * This creates a new {@link THREE.DataArrayTexture | DataArrayTexture} object. + * @remarks The interpretation of the data depends on {@link format} and {@link type}. + * @remarks If the {@link type} is {@link THREE.UnsignedByteType}, a {@link Uint8Array} will be useful for addressing the texel data + * @remarks If the {@link format} is {@link THREE.RGBAFormat}, data needs four values for one texel; Red, Green, Blue and Alpha (typically the opacity). + * @remarks For the packed {@link type | types}, {@link THREE.UnsignedShort4444Type} and {@link THREE.UnsignedShort5551Type} + * all color components of one texel can be addressed as bitfields within an integer element of a {@link Uint16Array}. + * @remarks In order to use the {@link type | types} {@link THREE.FloatType} and {@link THREE.HalfFloatType}, + * the WebGL implementation must support the respective extensions _OES_texture_float_ and _OES_texture_half_float_ + * @remarks In order to use {@link THREE.LinearFilter} for component-wise, bilinear interpolation of the texels based on these types, + * the WebGL extensions _OES_texture_float_linear_ or _OES_texture_half_float_linear_ must also be present. + * @param data {@link https://developer.mozilla.org/en-US/docs/Web/API/ArrayBufferView | ArrayBufferView} of the texture. Default `null`. + * @param width Width of the texture. Default `1`. + * @param height Height of the texture. Default `1`. + * @param depth Depth of the texture. Default `1`. + */ + constructor(data?: BufferSource | null, width?: number, height?: number, depth?: number); + + /** + * Describes that a specific layer of the texture needs to be updated. Normally when {@link Texture.needsUpdate} is + * set to true, the entire compressed texture array is sent to the GPU. Marking specific layers will only transmit + * subsets of all mipmaps associated with a specific depth in the array which is often much more performant. + */ + addLayerUpdate(layerIndex: number): void; + + /** + * Resets the layer updates registry. See {@link DataArrayTexture.addLayerUpdate}. + */ + clearLayoutUpdates(): void; +} diff --git a/src-testing/src/textures/DataTexture.d.ts b/src-testing/src/textures/DataTexture.d.ts new file mode 100644 index 000000000..605450990 --- /dev/null +++ b/src-testing/src/textures/DataTexture.d.ts @@ -0,0 +1,112 @@ +import { + MagnificationTextureFilter, + Mapping, + MinificationTextureFilter, + PixelFormat, + TextureDataType, + Wrapping, +} from "../constants.js"; +import { Texture } from "./Texture.js"; +import { TextureImageData } from "./types.js"; + +/** + * Creates a texture directly from raw data, width and height. + * @example + * ```typescript + * // create a buffer with color data + * const width = 512; + * const height = 512; + * const size = width * height; + * const data = new Uint8Array(4 * size); + * const color = new THREE.Color(0xffffff); + * const r = Math.floor(color.r * 255); + * const g = Math.floor(color.g * 255); + * const b = Math.floor(color.b * 255); + * for (let i = 0; i & lt; size; i++) { + * const stride = i * 4; + * data[stride] = r; + * data[stride + 1] = g; + * data[stride + 2] = b; + * data[stride + 3] = 255; + * } + * // used the buffer to create a [name] + * const texture = new THREE.DataTexture(data, width, height); + * texture.needsUpdate = true; + * ``` + * @see {@link https://threejs.org/docs/index.html#api/en/textures/DataTexture | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/textures/DataTexture.js | Source} + */ +export class DataTexture extends Texture { + /** + * @param data {@link https://developer.mozilla.org/en-US/docs/Web/API/ArrayBufferView | ArrayBufferView} of the texture. Default `null`. + * @param width Width of the texture. Default `1`. + * @param height Height of the texture. Default `1`. + * @param format See {@link Texture.format | .format}. Default {@link THREE.RGBAFormat} + * @param type See {@link Texture.type | .type}. Default {@link THREE.UnsignedByteType} + * @param mapping See {@link Texture.mapping | .mapping}. Default {@link THREE.Texture.DEFAULT_MAPPING} + * @param wrapS See {@link Texture.wrapS | .wrapS}. Default {@link THREE.ClampToEdgeWrapping} + * @param wrapT See {@link Texture.wrapT | .wrapT}. Default {@link THREE.ClampToEdgeWrapping} + * @param magFilter See {@link Texture.magFilter | .magFilter}. Default {@link THREE.NearestFilter} + * @param minFilter See {@link Texture.minFilter | .minFilter}. Default {@link THREE.NearestFilter} + * @param anisotropy See {@link Texture.anisotropy | .anisotropy}. Default {@link THREE.Texture.DEFAULT_ANISOTROPY} + * @param colorSpace See {@link Texture.colorSpace | .colorSpace}. Default {@link NoColorSpace} + */ + constructor( + data?: BufferSource | null, + width?: number, + height?: number, + format?: PixelFormat, + type?: TextureDataType, + mapping?: Mapping, + wrapS?: Wrapping, + wrapT?: Wrapping, + magFilter?: MagnificationTextureFilter, + minFilter?: MinificationTextureFilter, + anisotropy?: number, + colorSpace?: string, + ); + + /** + * Read-only flag to check if a given object is of type {@link DataTexture}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isDataTexture: true; + + /** + * Overridden with a record type holding data, width and height and depth. + * @override + */ + get image(): TextureImageData; + set image(value: TextureImageData); + + /** + * @override + * @defaultValue {@link THREE.NearestFilter} + */ + magFilter: MagnificationTextureFilter; + + /** + * @override + * @defaultValue {@link THREE.NearestFilter} + */ + minFilter: MinificationTextureFilter; + + /** + * @override + * @defaultValue `false` + */ + flipY: boolean; + + /** + * @override + * @defaultValue `false` + */ + generateMipmaps: boolean; + + /** + * @override + * @defaultValue `1` + */ + unpackAlignment: number; +} diff --git a/src-testing/src/textures/DepthTexture.d.ts b/src-testing/src/textures/DepthTexture.d.ts new file mode 100644 index 000000000..f524e91cc --- /dev/null +++ b/src-testing/src/textures/DepthTexture.d.ts @@ -0,0 +1,104 @@ +import { + DepthTexturePixelFormat, + MagnificationTextureFilter, + Mapping, + MinificationTextureFilter, + TextureComparisonFunction, + TextureDataType, + Wrapping, +} from "../constants.js"; +import { Texture } from "./Texture.js"; + +/** + * This class can be used to automatically save the depth information of a rendering into a texture + * @see Example: {@link https://threejs.org/examples/#webgl_depth_texture | depth / texture} + * @see {@link https://threejs.org/docs/index.html#api/en/textures/DepthTexture | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/textures/DepthTexture.js | Source} + */ +export class DepthTexture extends Texture { + /** + * Create a new instance of {@link DepthTexture} + * @param width Width of the texture. + * @param height Height of the texture. + * @param type See {@link Texture.type | .type}. Default {@link THREE.UnsignedByteType} or {@link THREE.UnsignedInt248Type} + * @param mapping See {@link Texture.mapping | .mapping}. Default {@link THREE.Texture.DEFAULT_MAPPING} + * @param wrapS See {@link Texture.wrapS | .wrapS}. Default {@link THREE.ClampToEdgeWrapping} + * @param wrapT See {@link Texture.wrapT | .wrapT}. Default {@link THREE.ClampToEdgeWrapping} + * @param magFilter See {@link Texture.magFilter | .magFilter}. Default {@link THREE.NearestFilter} + * @param minFilter See {@link Texture.minFilter | .minFilter}. Default {@link THREE.NearestFilter} + * @param anisotropy See {@link Texture.anisotropy | .anisotropy}. Default {@link THREE.Texture.DEFAULT_ANISOTROPY} + * @param format See {@link DepthTexture.format | .format}. Default {@link THREE.DepthFormat} + */ + constructor( + width: number, + height: number, + type?: TextureDataType, + mapping?: Mapping, + wrapS?: Wrapping, + wrapT?: Wrapping, + magFilter?: MagnificationTextureFilter, + minFilter?: MinificationTextureFilter, + anisotropy?: number, + format?: DepthTexturePixelFormat, + ); + + /** + * Read-only flag to check if a given object is of type {@link DepthTexture}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isDepthTexture: true; + + /** + * Overridden with a record type holding width and height. + * @override + */ + get image(): { width: number; height: number }; + set image(value: { width: number; height: number }); + + /** + * @override + * @defaultValue `false` + */ + flipY: boolean; + + /** + * @override + * @defaultValue {@link THREE.NearestFilter} + */ + magFilter: MagnificationTextureFilter; + + /** + * @override + * @defaultValue {@link THREE.NearestFilter} + */ + minFilter: MinificationTextureFilter; + + /** + * @override Depth textures do not use mipmaps. + * @defaultValue `false` + */ + generateMipmaps: boolean; + + /** + * @override + * @see {@link Texture.format | Texture.format} + * @defaultValue {@link THREE.DepthFormat}. + */ + format: DepthTexturePixelFormat; + + /** + * @override + * @defaultValue {@link THREE.UnsignedByteType} when {@link format | .format} === {@link THREE.DepthFormat} + * @defaultValue {@link THREE.UnsignedInt248Type} when {@link format | .format} === {@link THREE.DepthStencilFormat} + */ + type: TextureDataType; + + /** + * This is used to define the comparison function used when comparing texels in the depth texture to the value in + * the depth buffer. Default is `null` which means comparison is disabled. + * + * See {@link THREE.TextureComparisonFunction} for functions. + */ + compareFunction: TextureComparisonFunction | null; +} diff --git a/src-testing/src/textures/FramebufferTexture.d.ts b/src-testing/src/textures/FramebufferTexture.d.ts new file mode 100644 index 000000000..ad54c5175 --- /dev/null +++ b/src-testing/src/textures/FramebufferTexture.d.ts @@ -0,0 +1,62 @@ +import { MagnificationTextureFilter, MinificationTextureFilter } from "../constants.js"; +import { Texture } from "./Texture.js"; + +/** + * This class can only be used in combination with {@link THREE.WebGLRenderer.copyFramebufferToTexture | WebGLRenderer.copyFramebufferToTexture()}. + * @example + * ```typescript + * const pixelRatio = window.devicePixelRatio; + * const textureSize = 128 * pixelRatio; + * + * // instantiate a framebuffer texture + * const frameTexture = new FramebufferTexture( textureSize, textureSize, RGBAFormat ); + * + * // calculate start position for copying part of the frame data + * const vector = new Vector2(); + * vector.x = ( window.innerWidth * pixelRatio / 2 ) - ( textureSize / 2 ); + * vector.y = ( window.innerHeight * pixelRatio / 2 ) - ( textureSize / 2 ); + * + * // render the scene + * renderer.clear(); + * renderer.render( scene, camera ); + * + * // copy part of the rendered frame into the framebuffer texture + * renderer.copyFramebufferToTexture( frameTexture, vector ); + * ``` + * @see Example: {@link https://threejs.org/examples/#webgl_framebuffer_texture | webgl_framebuffer_texture} + * @see {@link https://threejs.org/docs/index.html#api/en/textures/FramebufferTexture | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/textures/FramebufferTexture.js | Source} + */ +export class FramebufferTexture extends Texture { + /** + * Create a new instance of {@link FramebufferTexture} + * @param width The width of the texture. + * @param height The height of the texture. + */ + constructor(width: number, height: number); + + /** + * Read-only flag to check if a given object is of type {@link FramebufferTexture}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isFramebufferTexture: true; + + /** + * @override + * @defaultValue {@link THREE.NearestFilter} + */ + magFilter: MagnificationTextureFilter; + + /** + * @override + * @defaultValue {@link THREE.NearestFilter} + */ + minFilter: MinificationTextureFilter; + + /** + * @override + * @defaultValue `false` + */ + generateMipmaps: boolean; +} diff --git a/src-testing/src/textures/Source.d.ts b/src-testing/src/textures/Source.d.ts new file mode 100644 index 000000000..404d1d8a1 --- /dev/null +++ b/src-testing/src/textures/Source.d.ts @@ -0,0 +1,75 @@ +export type SerializedImage = + | string + | { + data: number[]; + width: number; + height: number; + type: string; + }; + +export class SourceJSON { + uuid: string; + url: SerializedImage | SerializedImage[]; +} + +/** + * Represents the data {@link Source} of a texture. + * @see {@link https://threejs.org/docs/index.html#api/en/textures/Source | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/textures/Source.js | Source} + */ +export class Source { + /** + * Create a new instance of {@link Source} + * @param data The data definition of a texture. Default `null` + */ + constructor(data: any); + + /** + * Flag to check if a given object is of type {@link Source}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isSource: true; + + readonly id: number; + + /** + * The actual data of a texture. + * @remarks The type of this property depends on the texture that uses this instance. + */ + data: any; + + /** + * This property is only relevant when {@link .needsUpdate} is set to `true` and provides more control on how + * texture data should be processed. + * When `dataReady` is set to `false`, the engine performs the memory allocation (if necessary) but does not + * transfer the data into the GPU memory. + * @default true + */ + dataReady: boolean; + + /** + * When the property is set to `true`, the engine allocates the memory for the texture (if necessary) and triggers + * the actual texture upload to the GPU next time the source is used. + */ + set needsUpdate(value: boolean); + + /** + * {@link http://en.wikipedia.org/wiki/Universally_unique_identifier | UUID} of this object instance. + * @remarks This gets automatically assigned and shouldn't be edited. + */ + uuid: string; + + /** + * This starts at `0` and counts how many times {@link needsUpdate | .needsUpdate} is set to `true`. + * @remarks Expects a `Integer` + * @defaultValue `0` + */ + version: number; + + /** + * Convert the data {@link Source} to three.js {@link https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 | JSON Object/Scene format}. + * @param meta Optional object containing metadata. + */ + toJSON(meta?: string | {}): SourceJSON; +} diff --git a/src-testing/src/textures/Texture.d.ts b/src-testing/src/textures/Texture.d.ts new file mode 100644 index 000000000..2dc33c5d1 --- /dev/null +++ b/src-testing/src/textures/Texture.d.ts @@ -0,0 +1,476 @@ +import { + AnyMapping, + AnyPixelFormat, + MagnificationTextureFilter, + Mapping, + MinificationTextureFilter, + PixelFormat, + PixelFormatGPU, + TextureDataType, + Wrapping, +} from "../constants.js"; +import { EventDispatcher } from "../core/EventDispatcher.js"; +import { Matrix3 } from "../math/Matrix3.js"; +import { Vector2 } from "../math/Vector2.js"; +import { CompressedTextureMipmap } from "./CompressedTexture.js"; +import { CubeTexture } from "./CubeTexture.js"; +import { Source } from "./Source.js"; + +export interface TextureJSON { + metadata: { version: number; type: string; generator: string }; + + uuid: string; + name: string; + + image: string; + + mapping: AnyMapping; + channel: number; + + repeat: [x: number, y: number]; + offset: [x: number, y: number]; + center: [x: number, y: number]; + rotation: number; + + wrap: [wrapS: number, wrapT: number]; + + format: AnyPixelFormat; + internalFormat: PixelFormatGPU | null; + type: TextureDataType; + colorSpace: string; + + minFilter: MinificationTextureFilter; + magFilter: MagnificationTextureFilter; + anisotropy: number; + + flipY: boolean; + + generateMipmaps: boolean; + premultiplyAlpha: boolean; + unpackAlignment: number; + + userData?: Record; +} + +/** Shim for OffscreenCanvas. */ +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface OffscreenCanvas extends EventTarget {} + +/** + * Create a {@link Texture} to apply to a surface or as a reflection or refraction map. + * @remarks + * After the initial use of a texture, its **dimensions**, {@link format}, and {@link type} cannot be changed + * Instead, call {@link dispose | .dispose()} on the {@link Texture} and instantiate a new {@link Texture}. + * @example + * ```typescript + * // load a texture, set wrap mode to repeat + * const texture = new THREE.TextureLoader().load("textures/water.jpg"); + * texture.wrapS = THREE.RepeatWrapping; + * texture.wrapT = THREE.RepeatWrapping; + * texture.repeat.set(4, 4); + * ``` + * @see Example: {@link https://threejs.org/examples/#webgl_materials_texture_filters | webgl materials texture filters} + * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} + * @see {@link https://threejs.org/docs/index.html#api/en/textures/Texture | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/Textures/Texture.js | Source} + */ +export class Texture extends EventDispatcher<{ dispose: {} }> { + /** + * This creates a new {@link THREE.Texture | Texture} object. + * @param image See {@link Texture.image | .image}. Default {@link THREE.Texture.DEFAULT_IMAGE} + * @param mapping See {@link Texture.mapping | .mapping}. Default {@link THREE.Texture.DEFAULT_MAPPING} + * @param wrapS See {@link Texture.wrapS | .wrapS}. Default {@link THREE.ClampToEdgeWrapping} + * @param wrapT See {@link Texture.wrapT | .wrapT}. Default {@link THREE.ClampToEdgeWrapping} + * @param magFilter See {@link Texture.magFilter | .magFilter}. Default {@link THREE.LinearFilter} + * @param minFilter See {@link Texture.minFilter | .minFilter}. Default {@link THREE.LinearMipmapLinearFilter} + * @param format See {@link Texture.format | .format}. Default {@link THREE.RGBAFormat} + * @param type See {@link Texture.type | .type}. Default {@link THREE.UnsignedByteType} + * @param anisotropy See {@link Texture.anisotropy | .anisotropy}. Default {@link THREE.Texture.DEFAULT_ANISOTROPY} + * @param colorSpace See {@link Texture.colorSpace | .colorSpace}. Default {@link THREE.NoColorSpace} + */ + constructor( + image?: TexImageSource | OffscreenCanvas, + mapping?: Mapping, + wrapS?: Wrapping, + wrapT?: Wrapping, + magFilter?: MagnificationTextureFilter, + minFilter?: MinificationTextureFilter, + format?: PixelFormat, + type?: TextureDataType, + anisotropy?: number, + colorSpace?: string, + ); + + /** + * @deprecated + */ + constructor( + image: TexImageSource | OffscreenCanvas, + mapping: Mapping, + wrapS: Wrapping, + wrapT: Wrapping, + magFilter: MagnificationTextureFilter, + minFilter: MinificationTextureFilter, + format: PixelFormat, + type: TextureDataType, + anisotropy: number, + ); + + /** + * Read-only flag to check if a given object is of type {@link Texture}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isTexture: true; + + /** + * Unique number for this {@link Texture} instance. + * @remarks Note that ids are assigned in chronological order: 1, 2, 3, ..., incrementing by one for each new object. + * @remarks Expects a `Integer` + */ + readonly id: number; + + /** + * {@link http://en.wikipedia.org/wiki/Universally_unique_identifier | UUID} of this object instance. + * @remarks This gets automatically assigned and shouldn't be edited. + */ + uuid: string; + + /** + * Optional name of the object + * @remarks _(doesn't need to be unique)_. + * @defaultValue `""` + */ + name: string; + + /** + * The data definition of a texture. A reference to the data source can be shared across textures. + * This is often useful in context of spritesheets where multiple textures render the same data + * but with different {@link Texture} transformations. + */ + source: Source; + + /** + * An image object, typically created using the {@link THREE.TextureLoader.load | TextureLoader.load()} method. + * @remarks This can be any image (e.g., PNG, JPG, GIF, DDS) or video (e.g., MP4, OGG/OGV) type supported by three.js. + * @remarks To use video as a {@link Texture} you need to have a playing HTML5 video element as a source + * for your {@link Texture} image and continuously update this {@link Texture} + * as long as video is playing - the {@link THREE.VideoTexture | VideoTexture} class handles this automatically. + */ + get image(): any; + set image(data: any); + + /** + * Array of user-specified mipmaps + * @defaultValue `[]` + */ + mipmaps: CompressedTextureMipmap[] | CubeTexture[] | HTMLCanvasElement[] | undefined; + + /** + * How the image is applied to the object. + * @remarks All {@link Texture} types except {@link THREE.CubeTexture} expect the _values_ be {@link THREE.Mapping} + * @remarks {@link CubeTexture} expect the _values_ be {@link THREE.CubeTextureMapping} + * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} + * @defaultValue _value of_ {@link THREE.Texture.DEFAULT_MAPPING} + */ + mapping: AnyMapping; + + /** + * Lets you select the uv attribute to map the texture to. `0` for `uv`, `1` for `uv1`, `2` for `uv2` and `3` for + * `uv3`. + */ + channel: number; + + /** + * This defines how the {@link Texture} is wrapped *horizontally* and corresponds to **U** in UV mapping. + * @remarks for **WEBGL1** - tiling of images in textures only functions if image dimensions are powers of two + * (2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, ...) in terms of pixels. + * Individual dimensions need not be equal, but each must be a power of two. This is a limitation of WebGL1, not three.js. + * **WEBGL2** does not have this limitation. + * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} + * @see {@link wrapT} + * @see {@link repeat} + * @defaultValue {@link THREE.ClampToEdgeWrapping} + */ + wrapS: Wrapping; + + /** + * This defines how the {@link Texture} is wrapped *vertically* and corresponds to **V** in UV mapping. + * @remarks for **WEBGL1** - tiling of images in textures only functions if image dimensions are powers of two + * (2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, ...) in terms of pixels. + * Individual dimensions need not be equal, but each must be a power of two. This is a limitation of WebGL1, not three.js. + * **WEBGL2** does not have this limitation. + * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} + * @see {@link wrapS} + * @see {@link repeat} + * @defaultValue {@link THREE.ClampToEdgeWrapping} + */ + wrapT: Wrapping; + + /** + * How the {@link Texture} is sampled when a texel covers more than one pixel. + * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} + * @see {@link minFilter} + * @see {@link THREE.MagnificationTextureFilter} + * @defaultValue {@link THREE.LinearFilter} + */ + magFilter: MagnificationTextureFilter; + + /** + * How the {@link Texture} is sampled when a texel covers less than one pixel. + * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} + * @see {@link magFilter} + * @see {@link THREE.MinificationTextureFilter} + * @defaultValue {@link THREE.LinearMipmapLinearFilter} + */ + minFilter: MinificationTextureFilter; + + /** + * The number of samples taken along the axis through the pixel that has the highest density of texels. + * @remarks A higher value gives a less blurry result than a basic mipmap, at the cost of more {@link Texture} samples being used. + * @remarks Use {@link THREE.WebGLCapabilities.getMaxAnisotropy() | renderer.capabilities.getMaxAnisotropy()} to find the maximum valid anisotropy value for the GPU; + * @remarks This value is usually a power of 2. + * @default _value of_ {@link THREE.Texture.DEFAULT_ANISOTROPY}. That is normally `1`. + */ + anisotropy: number; + + /** + * These define how elements of a 2D texture, or texels, are read by shaders. + * @remarks All {@link Texture} types except {@link THREE.DepthTexture} and {@link THREE.CompressedPixelFormat} expect the _values_ be {@link THREE.PixelFormat} + * @remarks {@link DepthTexture} expect the _values_ be {@link THREE.CubeTextureMapping} + * @remarks {@link CompressedPixelFormat} expect the _values_ be {@link THREE.CubeTextureMapping} + * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} + * @see {@link THREE.PixelFormat} + * @defaultValue {@link THREE.RGBAFormat}. + */ + format: AnyPixelFormat; + + /** + * This must correspond to the {@link Texture.format | .format}. + * @remarks {@link THREE.UnsignedByteType}, is the type most used by Texture formats. + * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} + * @see {@link THREE.TextureDataType} + * @defaultValue {@link THREE.UnsignedByteType} + */ + type: TextureDataType; + + /** + * The GPU Pixel Format allows the developer to specify how the data is going to be stored on the GPU. + * @remarks Compatible only with {@link WebGL2RenderingContext | WebGL 2 Rendering Context}. + * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} + * @defaultValue The default value is obtained using a combination of {@link Texture.format | .format} and {@link Texture.type | .type}. + */ + internalFormat: PixelFormatGPU | null; + + /** + * The uv-transform matrix for the texture. + * @remarks + * When {@link Texture.matrixAutoUpdate | .matrixAutoUpdate} property is `true`. + * Will be updated by the renderer from the properties: + * - {@link Texture.offset | .offset} + * - {@link Texture.repeat | .repeat} + * - {@link Texture.rotation | .rotation} + * - {@link Texture.center | .center} + * @remarks + * When {@link Texture.matrixAutoUpdate | .matrixAutoUpdate} property is `false`. + * This matrix may be set manually. + * @see {@link matrixAutoUpdate | .matrixAutoUpdate} + * @defaultValue `new THREE.Matrix3()` + */ + matrix: Matrix3; + + /** + * Whether is to update the texture's uv-transform {@link matrix | .matrix}. + * @remarks Set this to `false` if you are specifying the uv-transform {@link matrix} directly. + * @see {@link matrix | .matrix} + * @defaultValue `true` + */ + matrixAutoUpdate: boolean; + + /** + * How much a single repetition of the texture is offset from the beginning, in each direction **U** and **V**. + * @remarks Typical range is `0.0` to `1.0`. + * @defaultValue `new THREE.Vector2(0, 0)` + */ + offset: Vector2; + + /** + * How many times the texture is repeated across the surface, in each direction **U** and **V**. + * @remarks + * If repeat is set greater than `1` in either direction, the corresponding *Wrap* parameter should + * also be set to {@link THREE.RepeatWrapping} or {@link THREE.MirroredRepeatWrapping} to achieve the desired tiling effect. + * @see {@link wrapS} + * @see {@link wrapT} + * @defaultValue `new THREE.Vector2( 1, 1 )` + */ + repeat: Vector2; + + /** + * The point around which rotation occurs. + * @remarks A value of `(0.5, 0.5)` corresponds to the center of the texture. + * @defaultValue `new THREE.Vector2( 0, 0 )`, _lower left._ + */ + center: Vector2; + + /** + * How much the texture is rotated around the center point, in radians. + * @remarks Positive values are counter-clockwise. + * @defaultValue `0` + */ + rotation: number; + + /** + * Whether to generate mipmaps, _(if possible)_ for a texture. + * @remarks Set this to false if you are creating mipmaps manually. + * @defaultValue true + */ + generateMipmaps: boolean; + + /** + * If set to `true`, the alpha channel, if present, is multiplied into the color channels when the texture is uploaded to the GPU. + * @remarks + * Note that this property has no effect for {@link https://developer.mozilla.org/en-US/docs/Web/API/ImageBitmap | ImageBitmap}. + * You need to configure on bitmap creation instead. See {@link THREE.ImageBitmapLoader | ImageBitmapLoader}. + * @see {@link THREE.ImageBitmapLoader | ImageBitmapLoader}. + * @defaultValue `false` + */ + premultiplyAlpha: boolean; + + /** + * If set to `true`, the texture is flipped along the vertical axis when uploaded to the GPU. + * @remarks + * Note that this property has no effect for {@link https://developer.mozilla.org/en-US/docs/Web/API/ImageBitmap | ImageBitmap}. + * You need to configure on bitmap creation instead. See {@link THREE.ImageBitmapLoader | ImageBitmapLoader}. + * @see {@link THREE.ImageBitmapLoader | ImageBitmapLoader}. + * @defaultValue `true` + */ + flipY: boolean; + + /** + * Specifies the alignment requirements for the start of each pixel row in memory. + * @remarks + * The allowable values are: + * - `1` (byte-alignment) + * - `2` (rows aligned to even-numbered bytes) + * - `4` (word-alignment) + * - `8` (rows start on double-word boundaries). + * @see {@link http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml | glPixelStorei} for more information. + * @defaultValue `4` + */ + unpackAlignment: number; // TODO Fix typing to only allow the expected values. + + /** + * The {@link Textures | {@link Texture} constants} page for details of other color spaces. + * @remarks + * Textures containing color data should be annotated with {@link SRGBColorSpace THREE.SRGBColorSpace} or + * {@link LinearSRGBColorSpace THREE.LinearSRGBColorSpace}. + * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} + * @see {@link THREE.TextureDataType} + * @defaultValue {@link THREE.NoColorSpace} + */ + colorSpace: string; + + /** + * Indicates whether a texture belongs to a render target or not + * @defaultValue `false` + */ + isRenderTargetTexture: boolean; + + /** + * An object that can be used to store custom data about the texture. + * @remarks It should not hold references to functions as these will not be cloned. + * @defaultValue `{}` + */ + userData: Record; + + /** + * This starts at `0` and counts how many times {@link needsUpdate | .needsUpdate} is set to `true`. + * @remarks Expects a `Integer` + * @defaultValue `0` + */ + version: number; + + /** + * Indicates whether this texture should be processed by PMREMGenerator or not (only relevant for render target + * textures) + */ + pmremVersion: number; + + /** + * Set this to `true` to trigger an update next time the texture is used. Particularly important for setting the wrap mode. + */ + set needsUpdate(value: boolean); + + /** + * Indicates whether this texture should be processed by {@link THREE.PMREMGenerator} or not. + * @remarks Only relevant for render target textures. + * @defaultValue `false` + */ + set needsPMREMUpdate(value: boolean); + + /** + * The Global default value for {@link anisotropy | .anisotropy}. + * @defaultValue `1`. + */ + static DEFAULT_ANISOTROPY: number; + + /** + * The Global default value for {@link Texture.image | .image}. + * @defaultValue `null`. + */ + static DEFAULT_IMAGE: any; + + /** + * The Global default value for {@link mapping | .mapping}. + * @defaultValue {@link THREE.UVMapping} + */ + static DEFAULT_MAPPING: Mapping; + + /** + * A callback function, called when the texture is updated _(e.g., when needsUpdate has been set to true and then the texture is used)_. + */ + onUpdate: () => void; + + /** + * Transform the **UV** based on the value of this texture's + * {@link offset | .offset}, + * {@link repeat | .repeat}, + * {@link wrapS | .wrapS}, + * {@link wrapT | .wrapT} and + * {@link flipY | .flipY} properties. + * @param uv + */ + transformUv(uv: Vector2): Vector2; + + /** + * Update the texture's **UV-transform** {@link matrix | .matrix} from the texture properties + * {@link offset | .offset}, + * {@link repeat | .repeat}, + * {@link rotation | .rotation} and + * {@link center | .center}. + */ + updateMatrix(): void; + + /** + * Make copy of the texture + * @remarks Note this is not a **"deep copy"**, the image is shared + * @remarks + * Besides, cloning a texture does not automatically mark it for a texture upload + * You have to set {@link needsUpdate | .needsUpdate} to `true` as soon as it's image property (the data source) is fully loaded or ready. + */ + clone(): this; + + copy(source: Texture): this; + + /** + * Convert the texture to three.js {@link https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 | JSON Object/Scene format}. + * @param meta Optional object containing metadata. + */ + toJSON(meta?: string | {}): TextureJSON; + + /** + * Frees the GPU-related resources allocated by this instance + * @remarks Call this method whenever this instance is no longer used in your app. + */ + dispose(): void; +} diff --git a/src-testing/src/textures/VideoTexture.d.ts b/src-testing/src/textures/VideoTexture.d.ts new file mode 100644 index 000000000..31dc5d456 --- /dev/null +++ b/src-testing/src/textures/VideoTexture.d.ts @@ -0,0 +1,90 @@ +import { + MagnificationTextureFilter, + Mapping, + MinificationTextureFilter, + PixelFormat, + TextureDataType, + Wrapping, +} from "../constants.js"; +import { Texture } from "./Texture.js"; + +/** + * Creates a texture for use with a video. + * @remarks + * Note: After the initial use of a texture, the video cannot be changed + * Instead, call {@link dispose | .dispose()} on the texture and instantiate a new one. + * @example + * ```typescript + * // assuming you have created a HTML video element with id="video" + * const video = document.getElementById('video'); + * const texture = new THREE.VideoTexture(video); + * ``` + * @see Example: {@link https://threejs.org/examples/#webgl_materials_video | materials / video} + * @see Example: {@link https://threejs.org/examples/#webgl_materials_video_webcam | materials / video / webcam} + * @see Example: {@link https://threejs.org/examples/#webgl_video_kinect | video / kinect} + * @see Example: {@link https://threejs.org/examples/#webgl_video_panorama_equirectangular | video / panorama / equirectangular} + * @see Example: {@link https://threejs.org/examples/#webxr_vr_video | vr / video} + * @see {@link https://threejs.org/docs/index.html#api/en/textures/VideoTexture | Official Documentation} + * @see {@link https://github.com/mrdoob/three.js/blob/master/src/textures/VideoTexture.js | Source} + */ +export class VideoTexture extends Texture { + /** + * Create a new instance of {@link VideoTexture} + * @param video The video element to use as the texture. + * @param mapping See {@link Texture.mapping | .mapping}. Default {@link THREE.Texture.DEFAULT_MAPPING} + * @param wrapS See {@link Texture.wrapS | .wrapS}. Default {@link THREE.ClampToEdgeWrapping} + * @param wrapT See {@link Texture.wrapT | .wrapT}. Default {@link THREE.ClampToEdgeWrapping} + * @param magFilter See {@link Texture.magFilter | .magFilter}. Default {@link THREE.LinearFilter} + * @param minFilter See {@link Texture.minFilter | .minFilter}. Default {@link THREE.LinearFilter} + * @param format See {@link Texture.format | .format}. Default {@link THREE.RGBAFormat} + * @param type See {@link Texture.type | .type}. Default {@link THREE.UnsignedByteType} + * @param anisotropy See {@link Texture.anisotropy | .anisotropy}. Default {@link THREE.Texture.DEFAULT_ANISOTROPY} + */ + constructor( + video: HTMLVideoElement, + mapping?: Mapping, + wrapS?: Wrapping, + wrapT?: Wrapping, + magFilter?: MagnificationTextureFilter, + minFilter?: MinificationTextureFilter, + format?: PixelFormat, + type?: TextureDataType, + anisotropy?: number, + ); + + /** + * Read-only flag to check if a given object is of type {@link VideoTexture}. + * @remarks This is a _constant_ value + * @defaultValue `true` + */ + readonly isVideoTexture: true; + + /** + * @override + * @defaultValue {@link THREE.LinearFilter} + */ + magFilter: MagnificationTextureFilter; + + /** + * @override + * @defaultValue {@link THREE.LinearFilter} + */ + minFilter: MinificationTextureFilter; + + /** + * @override + * @defaultValue `false` + */ + generateMipmaps: boolean; + + /** + * @override + * You will **not** need to set this manually here as it is handled by the {@link update | update()} method. + */ + set needsUpdate(value: boolean); + + /** + * This is called automatically and sets {@link needsUpdate | .needsUpdate } to `true` every time a new frame is available. + */ + update(): void; +} diff --git a/src-testing/src/textures/types.d.ts b/src-testing/src/textures/types.d.ts new file mode 100644 index 000000000..86b7f2fd2 --- /dev/null +++ b/src-testing/src/textures/types.d.ts @@ -0,0 +1,9 @@ +export interface TextureImageData { + data: Uint8Array | Uint8ClampedArray; + height: number; + width: number; +} + +export interface Texture3DImageData extends TextureImageData { + depth: number; +} diff --git a/src-testing/src/utils.d.ts b/src-testing/src/utils.d.ts new file mode 100644 index 000000000..3fda1cfda --- /dev/null +++ b/src-testing/src/utils.d.ts @@ -0,0 +1,3 @@ +export function createCanvasElement(): HTMLCanvasElement; + +export function probeAsync(gl: WebGLRenderingContext, sync: WebGLSync, interval: number): Promise; From cc0f623341c72caeee559ee3eb913433b60cfeaa Mon Sep 17 00:00:00 2001 From: Nathan Bierema Date: Sun, 10 Nov 2024 17:19:36 -0500 Subject: [PATCH 6/7] Update patch and delete src --- src-testing/changes.patch | 9 +- src-testing/src/Three.Legacy.d.ts | 20 - src-testing/src/Three.WebGPU.Nodes.d.ts | 205 --- src-testing/src/Three.WebGPU.d.ts | 206 --- src-testing/src/Three.d.ts | 214 --- .../src/animation/AnimationAction.d.ts | 86 - src-testing/src/animation/AnimationClip.d.ts | 59 - src-testing/src/animation/AnimationMixer.d.ts | 39 - .../src/animation/AnimationObjectGroup.d.ts | 17 - src-testing/src/animation/AnimationUtils.d.ts | 60 - src-testing/src/animation/KeyframeTrack.d.ts | 55 - .../src/animation/PropertyBinding.d.ts | 43 - src-testing/src/animation/PropertyMixer.d.ts | 17 - .../tracks/BooleanKeyframeTrack.d.ts | 10 - .../animation/tracks/ColorKeyframeTrack.d.ts | 11 - .../animation/tracks/NumberKeyframeTrack.d.ts | 11 - .../tracks/QuaternionKeyframeTrack.d.ts | 11 - .../animation/tracks/StringKeyframeTrack.d.ts | 10 - .../animation/tracks/VectorKeyframeTrack.d.ts | 11 - src-testing/src/audio/Audio.d.ts | 273 ---- src-testing/src/audio/AudioAnalyser.d.ts | 58 - src-testing/src/audio/AudioContext.d.ts | 19 - src-testing/src/audio/AudioListener.d.ts | 96 -- src-testing/src/audio/PositionalAudio.d.ts | 101 -- src-testing/src/cameras/ArrayCamera.d.ts | 32 - src-testing/src/cameras/Camera.d.ts | 74 - src-testing/src/cameras/CubeCamera.d.ts | 68 - .../src/cameras/OrthographicCamera.d.ts | 174 -- .../src/cameras/PerspectiveCamera.d.ts | 254 --- src-testing/src/cameras/StereoCamera.d.ts | 50 - src-testing/src/constants.d.ts | 918 ----------- src-testing/src/core/BufferAttribute.d.ts | 622 ------- src-testing/src/core/BufferGeometry.d.ts | 433 ----- src-testing/src/core/Clock.d.ts | 72 - src-testing/src/core/EventDispatcher.d.ts | 82 - src-testing/src/core/GLBufferAttribute.d.ts | 121 -- .../src/core/InstancedBufferAttribute.d.ts | 32 - .../src/core/InstancedBufferGeometry.d.ts | 37 - .../src/core/InstancedInterleavedBuffer.d.ts | 22 - src-testing/src/core/InterleavedBuffer.d.ts | 150 -- .../src/core/InterleavedBufferAttribute.d.ts | 201 --- src-testing/src/core/Layers.d.ts | 72 - src-testing/src/core/Object3D.d.ts | 674 -------- src-testing/src/core/Raycaster.d.ts | 208 --- src-testing/src/core/RenderTarget.d.ts | 95 -- src-testing/src/core/Uniform.d.ts | 38 - src-testing/src/core/UniformsGroup.d.ts | 33 - src-testing/src/extras/Controls.d.ts | 54 - src-testing/src/extras/DataUtils.d.ts | 22 - src-testing/src/extras/Earcut.d.ts | 15 - src-testing/src/extras/ImageUtils.d.ts | 32 - src-testing/src/extras/PMREMGenerator.d.ts | 82 - src-testing/src/extras/ShapeUtils.d.ts | 25 - src-testing/src/extras/TextureUtils.d.ts | 42 - src-testing/src/extras/core/Curve.d.ts | 162 -- src-testing/src/extras/core/CurvePath.d.ts | 77 - .../src/extras/core/Interpolations.d.ts | 36 - src-testing/src/extras/core/Path.d.ts | 166 -- src-testing/src/extras/core/Shape.d.ts | 86 - src-testing/src/extras/core/ShapePath.d.ts | 98 -- src-testing/src/extras/curves/ArcCurve.d.ts | 41 - .../src/extras/curves/CatmullRomCurve3.d.ts | 77 - .../src/extras/curves/CubicBezierCurve.d.ts | 72 - .../src/extras/curves/CubicBezierCurve3.d.ts | 72 - src-testing/src/extras/curves/Curves.d.ts | 10 - .../src/extras/curves/EllipseCurve.d.ts | 115 -- src-testing/src/extras/curves/LineCurve.d.ts | 42 - src-testing/src/extras/curves/LineCurve3.d.ts | 42 - .../extras/curves/QuadraticBezierCurve.d.ts | 64 - .../extras/curves/QuadraticBezierCurve3.d.ts | 64 - .../src/extras/curves/SplineCurve.d.ts | 52 - src-testing/src/geometries/BoxGeometry.d.ts | 59 - .../src/geometries/CapsuleGeometry.d.ts | 48 - .../src/geometries/CircleGeometry.d.ts | 51 - src-testing/src/geometries/ConeGeometry.d.ts | 64 - .../src/geometries/CylinderGeometry.d.ts | 64 - .../src/geometries/DodecahedronGeometry.d.ts | 25 - src-testing/src/geometries/EdgesGeometry.d.ts | 41 - .../src/geometries/ExtrudeGeometry.d.ts | 152 -- src-testing/src/geometries/Geometries.d.ts | 21 - .../src/geometries/IcosahedronGeometry.d.ts | 26 - src-testing/src/geometries/LatheGeometry.d.ts | 55 - .../src/geometries/OctahedronGeometry.d.ts | 25 - src-testing/src/geometries/PlaneGeometry.d.ts | 48 - .../src/geometries/PolyhedronGeometry.d.ts | 54 - src-testing/src/geometries/RingGeometry.d.ts | 59 - src-testing/src/geometries/ShapeGeometry.d.ts | 53 - .../src/geometries/SphereGeometry.d.ts | 67 - .../src/geometries/TetrahedronGeometry.d.ts | 25 - src-testing/src/geometries/TorusGeometry.d.ts | 49 - .../src/geometries/TorusKnotGeometry.d.ts | 59 - src-testing/src/geometries/TubeGeometry.d.ts | 86 - .../src/geometries/WireframeGeometry.d.ts | 40 - src-testing/src/helpers/ArrowHelper.d.ts | 93 -- src-testing/src/helpers/AxesHelper.d.ts | 50 - src-testing/src/helpers/Box3Helper.d.ts | 44 - src-testing/src/helpers/BoxHelper.d.ts | 64 - src-testing/src/helpers/CameraHelper.d.ts | 80 - .../src/helpers/DirectionalLightHelper.d.ts | 81 - src-testing/src/helpers/GridHelper.d.ts | 47 - .../src/helpers/HemisphereLightHelper.d.ts | 72 - src-testing/src/helpers/PlaneHelper.d.ts | 50 - src-testing/src/helpers/PointLightHelper.d.ts | 73 - src-testing/src/helpers/PolarGridHelper.d.ts | 55 - src-testing/src/helpers/SkeletonHelper.d.ts | 78 - src-testing/src/helpers/SpotLightHelper.d.ts | 77 - src-testing/src/lights/AmbientLight.d.ts | 36 - src-testing/src/lights/DirectionalLight.d.ts | 103 -- .../src/lights/DirectionalLightShadow.d.ts | 73 - src-testing/src/lights/HemisphereLight.d.ts | 61 - src-testing/src/lights/Light.d.ts | 82 - src-testing/src/lights/LightProbe.d.ts | 47 - src-testing/src/lights/LightShadow.d.ts | 169 -- src-testing/src/lights/PointLight.d.ts | 102 -- src-testing/src/lights/PointLightShadow.d.ts | 22 - src-testing/src/lights/RectAreaLight.d.ts | 82 - src-testing/src/lights/SpotLight.d.ts | 164 -- src-testing/src/lights/SpotLightShadow.d.ts | 72 - .../src/lights/webgpu/IESSpotLight.d.ts | 6 - src-testing/src/loaders/AnimationLoader.d.ts | 9 - src-testing/src/loaders/AudioLoader.d.ts | 6 - .../src/loaders/BufferGeometryLoader.d.ts | 10 - src-testing/src/loaders/Cache.d.ts | 21 - .../src/loaders/CompressedTextureLoader.d.ts | 14 - .../src/loaders/CubeTextureLoader.d.ts | 14 - .../src/loaders/DataTextureLoader.d.ts | 14 - src-testing/src/loaders/FileLoader.d.ts | 19 - .../src/loaders/ImageBitmapLoader.d.ts | 22 - src-testing/src/loaders/ImageLoader.d.ts | 17 - src-testing/src/loaders/Loader.d.ts | 50 - src-testing/src/loaders/LoaderUtils.d.ts | 10 - src-testing/src/loaders/LoadingManager.d.ts | 69 - src-testing/src/loaders/MaterialLoader.d.ts | 21 - src-testing/src/loaders/ObjectLoader.d.ts | 35 - src-testing/src/loaders/TextureLoader.d.ts | 18 - src-testing/src/loaders/nodes/NodeLoader.d.ts | 21 - .../src/loaders/nodes/NodeMaterialLoader.d.ts | 11 - .../src/loaders/nodes/NodeObjectLoader.d.ts | 22 - .../src/materials/LineBasicMaterial.d.ts | 55 - .../src/materials/LineDashedMaterial.d.ts | 35 - src-testing/src/materials/Material.d.ts | 629 -------- src-testing/src/materials/Materials.d.ts | 18 - .../src/materials/MeshBasicMaterial.d.ts | 134 -- .../src/materials/MeshDepthMaterial.d.ts | 71 - .../src/materials/MeshDistanceMaterial.d.ts | 57 - .../src/materials/MeshLambertMaterial.d.ts | 199 --- .../src/materials/MeshMatcapMaterial.d.ts | 112 -- .../src/materials/MeshNormalMaterial.d.ts | 88 - .../src/materials/MeshPhongMaterial.d.ts | 223 --- .../src/materials/MeshPhysicalMaterial.d.ts | 231 --- .../src/materials/MeshStandardMaterial.d.ts | 213 --- .../src/materials/MeshToonMaterial.d.ts | 173 -- src-testing/src/materials/PointsMaterial.d.ts | 56 - .../src/materials/RawShaderMaterial.d.ts | 12 - src-testing/src/materials/ShaderMaterial.d.ts | 162 -- src-testing/src/materials/ShadowMaterial.d.ts | 34 - src-testing/src/materials/SpriteMaterial.d.ts | 61 - .../nodes/InstancedPointsNodeMaterial.d.ts | 33 - .../materials/nodes/Line2NodeMaterial.d.ts | 53 - .../nodes/LineBasicNodeMaterial.d.ts | 22 - .../nodes/LineDashedNodeMaterial.d.ts | 29 - .../nodes/MeshBasicNodeMaterial.d.ts | 36 - .../nodes/MeshLambertNodeMaterial.d.ts | 49 - .../nodes/MeshMatcapNodeMaterial.d.ts | 32 - .../nodes/MeshNormalNodeMaterial.d.ts | 28 - .../nodes/MeshPhongNodeMaterial.d.ts | 56 - .../nodes/MeshPhysicalNodeMaterial.d.ts | 93 -- .../materials/nodes/MeshSSSNodeMaterial.d.ts | 16 - .../nodes/MeshStandardNodeMaterial.d.ts | 56 - .../materials/nodes/MeshToonNodeMaterial.d.ts | 42 - .../src/materials/nodes/NodeMaterial.ts | 535 ------- .../src/materials/nodes/NodeMaterials.d.ts | 18 - .../materials/nodes/PointsNodeMaterial.d.ts | 21 - .../materials/nodes/ShadowNodeMaterial.d.ts | 17 - .../materials/nodes/SpriteNodeMaterial.d.ts | 26 - .../materials/nodes/VolumeNodeMaterial.d.ts | 10 - .../nodes/manager/NodeMaterialObserver.ts | 308 ---- src-testing/src/math/Box2.d.ts | 48 - src-testing/src/math/Box3.d.ts | 66 - src-testing/src/math/Color.d.ts | 375 ----- src-testing/src/math/ColorManagement.d.ts | 49 - src-testing/src/math/Cylindrical.d.ts | 26 - src-testing/src/math/Euler.d.ts | 50 - src-testing/src/math/Frustum.d.ts | 30 - src-testing/src/math/Interpolant.d.ts | 10 - src-testing/src/math/Line3.d.ts | 29 - src-testing/src/math/MathUtils.d.ts | 137 -- src-testing/src/math/Matrix2.d.ts | 53 - src-testing/src/math/Matrix3.d.ts | 184 --- src-testing/src/math/Matrix4.d.ts | 284 ---- src-testing/src/math/Plane.d.ts | 47 - src-testing/src/math/Quaternion.d.ts | 189 --- src-testing/src/math/Ray.d.ts | 60 - src-testing/src/math/Sphere.d.ts | 47 - src-testing/src/math/Spherical.d.ts | 27 - src-testing/src/math/SphericalHarmonics3.d.ts | 50 - src-testing/src/math/Triangle.d.ts | 110 -- src-testing/src/math/Vector2.d.ts | 321 ---- src-testing/src/math/Vector3.d.ts | 301 ---- src-testing/src/math/Vector4.d.ts | 239 --- .../math/interpolants/CubicInterpolant.d.ts | 7 - .../interpolants/DiscreteInterpolant.d.ts | 7 - .../math/interpolants/LinearInterpolant.d.ts | 7 - .../QuaternionLinearInterpolant.d.ts | 7 - src-testing/src/nodes/Nodes.ts | 144 -- src-testing/src/nodes/TSL.d.ts | 156 -- .../src/nodes/accessors/AccessorsUtils.d.ts | 9 - .../src/nodes/accessors/BatchNode.d.ts | 13 - .../src/nodes/accessors/Bitangent.d.ts | 9 - .../nodes/accessors/BufferAttributeNode.ts | 135 -- .../src/nodes/accessors/BufferNode.d.ts | 17 - src-testing/src/nodes/accessors/Camera.d.ts | 14 - .../src/nodes/accessors/ClippingNode.d.ts | 16 - .../src/nodes/accessors/CubeTextureNode.d.ts | 28 - .../src/nodes/accessors/InstanceNode.d.ts | 13 - .../src/nodes/accessors/MaterialNode.d.ts | 129 -- .../nodes/accessors/MaterialProperties.d.ts | 4 - .../accessors/MaterialReferenceNode.d.ts | 15 - .../src/nodes/accessors/ModelNode.d.ts | 24 - .../accessors/ModelViewProjectionNode.d.ts | 8 - .../src/nodes/accessors/MorphNode.d.ts | 15 - src-testing/src/nodes/accessors/Normal.d.ts | 25 - .../src/nodes/accessors/Object3DNode.d.ts | 22 - .../src/nodes/accessors/PointUVNode.d.ts | 10 - src-testing/src/nodes/accessors/Position.d.ts | 10 - .../nodes/accessors/ReferenceBaseNode.d.ts | 27 - .../src/nodes/accessors/ReferenceNode.d.ts | 29 - .../src/nodes/accessors/ReflectVector.d.ts | 9 - .../accessors/RendererReferenceNode.d.ts | 15 - .../src/nodes/accessors/SceneNode.d.ts | 20 - .../src/nodes/accessors/SkinningNode.d.ts | 30 - .../nodes/accessors/StorageBufferNode.d.ts | 38 - .../nodes/accessors/StorageTextureNode.d.ts | 40 - src-testing/src/nodes/accessors/Tangent.d.ts | 12 - .../src/nodes/accessors/Texture3DNode.d.ts | 17 - .../src/nodes/accessors/TextureBicubic.d.ts | 4 - .../src/nodes/accessors/TextureNode.ts | 370 ----- .../src/nodes/accessors/TextureSizeNode.d.ts | 18 - src-testing/src/nodes/accessors/UV.d.ts | 4 - .../src/nodes/accessors/UniformArrayNode.d.ts | 30 - .../src/nodes/accessors/UserDataNode.d.ts | 15 - .../src/nodes/accessors/VelocityNode.d.ts | 20 - .../src/nodes/accessors/VertexColorNode.d.ts | 12 - src-testing/src/nodes/code/CodeNode.ts | 68 - .../src/nodes/code/ExpressionNode.d.ts | 9 - .../src/nodes/code/FunctionCallNode.d.ts | 25 - src-testing/src/nodes/code/FunctionNode.ts | 87 - .../src/nodes/code/ScriptableNode.d.ts | 22 - .../src/nodes/code/ScriptableValueNode.d.ts | 10 - src-testing/src/nodes/core/AssignNode.d.ts | 18 - src-testing/src/nodes/core/AttributeNode.d.ts | 16 - src-testing/src/nodes/core/BypassNode.d.ts | 18 - src-testing/src/nodes/core/CacheNode.d.ts | 20 - src-testing/src/nodes/core/ConstNode.d.ts | 9 - src-testing/src/nodes/core/ContextNode.ts | 61 - src-testing/src/nodes/core/IndexNode.d.ts | 28 - src-testing/src/nodes/core/InputNode.ts | 67 - src-testing/src/nodes/core/LightingModel.d.ts | 46 - src-testing/src/nodes/core/MRTNode.d.ts | 24 - src-testing/src/nodes/core/Node.ts | 401 ----- src-testing/src/nodes/core/NodeAttribute.ts | 11 - src-testing/src/nodes/core/NodeBuilder.ts | 1208 -------------- src-testing/src/nodes/core/NodeCache.ts | 26 - src-testing/src/nodes/core/NodeCode.ts | 11 - src-testing/src/nodes/core/NodeFrame.ts | 127 -- src-testing/src/nodes/core/NodeFunction.ts | 16 - .../src/nodes/core/NodeFunctionInput.d.ts | 7 - src-testing/src/nodes/core/NodeParser.ts | 7 - src-testing/src/nodes/core/NodeUniform.ts | 27 - src-testing/src/nodes/core/NodeUtils.ts | 171 -- src-testing/src/nodes/core/NodeVar.ts | 10 - src-testing/src/nodes/core/NodeVarying.ts | 13 - .../src/nodes/core/OutputStructNode.d.ts | 12 - src-testing/src/nodes/core/ParameterNode.d.ts | 12 - src-testing/src/nodes/core/PropertyNode.d.ts | 43 - src-testing/src/nodes/core/StackNode.ts | 89 - src-testing/src/nodes/core/StructTypeNode.ts | 20 - src-testing/src/nodes/core/TempNode.d.ts | 10 - src-testing/src/nodes/core/UniformGroup.d.ts | 7 - .../src/nodes/core/UniformGroupNode.ts | 47 - src-testing/src/nodes/core/UniformNode.ts | 91 -- src-testing/src/nodes/core/VarNode.d.ts | 31 - src-testing/src/nodes/core/VaryingNode.d.ts | 21 - src-testing/src/nodes/core/constants.ts | 28 - src-testing/src/nodes/display/BlendMode.d.ts | 10 - .../src/nodes/display/BumpMapNode.d.ts | 16 - .../src/nodes/display/ColorAdjustment.d.ts | 56 - .../nodes/display/ColorSpaceFunctions.d.ts | 6 - .../src/nodes/display/ColorSpaceNode.d.ts | 60 - .../src/nodes/display/FrontFacingNode.d.ts | 12 - .../src/nodes/display/NormalMapNode.d.ts | 17 - src-testing/src/nodes/display/PassNode.d.ts | 71 - .../src/nodes/display/PosterizeNode.d.ts | 14 - .../src/nodes/display/RenderOutputNode.d.ts | 28 - src-testing/src/nodes/display/ScreenNode.d.ts | 48 - .../nodes/display/ToneMappingFunctions.d.ts | 14 - .../src/nodes/display/ToneMappingNode.d.ts | 32 - .../nodes/display/ToonOutlinePassNode.d.ts | 24 - .../src/nodes/display/ViewportDepthNode.d.ts | 36 - .../display/ViewportDepthTextureNode.d.ts | 14 - .../display/ViewportSharedTextureNode.d.ts | 14 - .../nodes/display/ViewportTextureNode.d.ts | 28 - src-testing/src/nodes/fog/FogExp2Node.d.ts | 14 - src-testing/src/nodes/fog/FogNode.ts | 38 - src-testing/src/nodes/fog/FogRangeNode.d.ts | 19 - .../src/nodes/functions/BSDF/BRDF_GGX.d.ts | 15 - .../nodes/functions/BSDF/BRDF_Lambert.d.ts | 7 - .../src/nodes/functions/BSDF/BRDF_Sheen.d.ts | 7 - .../src/nodes/functions/BSDF/DFGApprox.d.ts | 11 - .../src/nodes/functions/BSDF/D_GGX.d.ts | 10 - .../functions/BSDF/D_GGX_Anisotropic.d.ts | 10 - .../src/nodes/functions/BSDF/F_Schlick.d.ts | 7 - src-testing/src/nodes/functions/BSDF/LTC.d.ts | 9 - .../nodes/functions/BSDF/Schlick_to_F0.d.ts | 10 - .../functions/BSDF/V_GGX_SmithCorrelated.d.ts | 11 - .../V_GGX_SmithCorrelated_Anisotropic.d.ts | 16 - .../nodes/functions/BasicLightingModel.d.ts | 7 - .../nodes/functions/PhongLightingModel.d.ts | 7 - .../functions/PhysicalLightingModel.d.ts | 30 - .../src/nodes/functions/ShadowMaskModel.d.ts | 9 - .../nodes/functions/ToonLightingModel.d.ts | 4 - .../material/getGeometryRoughness.d.ts | 6 - .../functions/material/getRoughness.d.ts | 7 - .../functions/material/getShIrradianceAt.d.ts | 6 - src-testing/src/nodes/geometry/RangeNode.d.ts | 19 - src-testing/src/nodes/gpgpu/ComputeNode.ts | 75 - src-testing/src/nodes/lighting/AONode.d.ts | 8 - .../src/nodes/lighting/AmbientLightNode.d.ts | 8 - .../src/nodes/lighting/AnalyticLightNode.d.ts | 8 - .../nodes/lighting/BasicEnvironmentNode.d.ts | 10 - .../src/nodes/lighting/BasicLightMapNode.d.ts | 8 - .../nodes/lighting/DirectionalLightNode.d.ts | 8 - .../src/nodes/lighting/EnvironmentNode.ts | 114 -- .../nodes/lighting/HemisphereLightNode.d.ts | 13 - .../src/nodes/lighting/IESSpotLightNode.d.ts | 5 - .../src/nodes/lighting/IrradianceNode.d.ts | 8 - src-testing/src/nodes/lighting/LightNode.d.ts | 18 - .../src/nodes/lighting/LightProbeNode.d.ts | 11 - .../src/nodes/lighting/LightUtils.d.ts | 9 - .../src/nodes/lighting/LightingContextNode.ts | 57 - .../src/nodes/lighting/LightingNode.d.ts | 7 - src-testing/src/nodes/lighting/LightsNode.ts | 200 --- .../src/nodes/lighting/PointLightNode.d.ts | 20 - .../src/nodes/lighting/RectAreaLightNode.d.ts | 21 - .../src/nodes/lighting/ShadowNode.d.ts | 12 - .../src/nodes/lighting/SpotLightNode.d.ts | 15 - .../src/nodes/materialx/MaterialXNodes.d.ts | 107 -- .../src/nodes/materialx/lib/mx_hsv.d.ts | 6 - .../src/nodes/materialx/lib/mx_noise.d.ts | 359 ----- .../materialx/lib/mx_transform_color.d.ts | 4 - .../src/nodes/math/ConditionalNode.d.ts | 39 - src-testing/src/nodes/math/Hash.d.ts | 4 - src-testing/src/nodes/math/MathNode.d.ts | 273 ---- src-testing/src/nodes/math/MathUtils.d.ts | 6 - src-testing/src/nodes/math/OperatorNode.d.ts | 97 -- src-testing/src/nodes/math/TriNoise3D.d.ts | 12 - .../src/nodes/parsers/GLSLNodeFunction.d.ts | 9 - .../src/nodes/parsers/GLSLNodeParser.d.ts | 8 - src-testing/src/nodes/pmrem/PMREMNode.d.ts | 22 - src-testing/src/nodes/pmrem/PMREMUtils.d.ts | 28 - src-testing/src/nodes/procedural/Checker.d.ts | 4 - src-testing/src/nodes/tsl/TSLBase.d.ts | 21 - src-testing/src/nodes/tsl/TSLCore.ts | 533 ------ .../src/nodes/utils/ArrayElementNode.d.ts | 9 - src-testing/src/nodes/utils/ConvertNode.d.ts | 7 - src-testing/src/nodes/utils/CubeMapNode.d.ts | 13 - src-testing/src/nodes/utils/Discard.d.ts | 11 - .../src/nodes/utils/EquirectUVNode.d.ts | 8 - .../nodes/utils/FunctionOverloadingNode.d.ts | 13 - src-testing/src/nodes/utils/JoinNode.d.ts | 10 - src-testing/src/nodes/utils/LoopNode.d.ts | 22 - src-testing/src/nodes/utils/MatcapUVNode.d.ts | 8 - .../src/nodes/utils/MaxMipLevelNode.d.ts | 14 - src-testing/src/nodes/utils/Oscillators.d.ts | 7 - src-testing/src/nodes/utils/Packing.d.ts | 5 - .../src/nodes/utils/PostProcessingUtils.d.ts | 45 - src-testing/src/nodes/utils/RTTNode.d.ts | 45 - .../src/nodes/utils/ReflectorNode.d.ts | 45 - src-testing/src/nodes/utils/RemapNode.d.ts | 36 - src-testing/src/nodes/utils/RotateNode.d.ts | 15 - src-testing/src/nodes/utils/SetNode.d.ts | 11 - src-testing/src/nodes/utils/SplitNode.d.ts | 15 - .../src/nodes/utils/SpriteSheetUVNode.d.ts | 16 - src-testing/src/nodes/utils/SpriteUtils.d.ts | 6 - .../nodes/utils/StorageArrayElementNode.d.ts | 19 - src-testing/src/nodes/utils/Timer.d.ts | 21 - .../nodes/utils/TriplanarTexturesNode.d.ts | 36 - src-testing/src/nodes/utils/UVUtils.d.ts | 14 - .../src/nodes/utils/ViewportUtils.d.ts | 4 - src-testing/src/objects/BatchedMesh.d.ts | 275 ---- src-testing/src/objects/Bone.d.ts | 36 - src-testing/src/objects/Group.d.ts | 37 - src-testing/src/objects/InstancedMesh.d.ts | 179 --- src-testing/src/objects/LOD.d.ts | 111 -- src-testing/src/objects/Line.d.ts | 87 - src-testing/src/objects/LineLoop.d.ts | 40 - src-testing/src/objects/LineSegments.d.ts | 41 - src-testing/src/objects/Mesh.d.ts | 94 -- src-testing/src/objects/Points.d.ts | 66 - src-testing/src/objects/Skeleton.d.ts | 120 -- src-testing/src/objects/SkinnedMesh.d.ts | 160 -- src-testing/src/objects/Sprite.d.ts | 65 - .../src/renderers/WebGL3DRenderTarget.d.ts | 29 - .../src/renderers/WebGLArrayRenderTarget.d.ts | 29 - .../src/renderers/WebGLCubeRenderTarget.d.ts | 18 - .../src/renderers/WebGLRenderTarget.d.ts | 8 - src-testing/src/renderers/WebGLRenderer.d.ts | 558 ------- src-testing/src/renderers/common/Animation.ts | 38 - .../src/renderers/common/Attributes.ts | 56 - src-testing/src/renderers/common/Backend.ts | 170 -- .../src/renderers/common/Background.ts | 133 -- src-testing/src/renderers/common/BindGroup.ts | 14 - src-testing/src/renderers/common/Binding.ts | 17 - src-testing/src/renderers/common/Bindings.ts | 160 -- src-testing/src/renderers/common/Buffer.ts | 28 - .../src/renderers/common/BufferUtils.ts | 23 - .../src/renderers/common/BundleGroup.ts | 20 - src-testing/src/renderers/common/ChainMap.ts | 43 - .../src/renderers/common/ClippingContext.ts | 136 -- src-testing/src/renderers/common/Color4.ts | 27 - .../src/renderers/common/ComputePipeline.ts | 13 - src-testing/src/renderers/common/Constants.ts | 15 - .../src/renderers/common/CubeRenderTarget.ts | 71 - src-testing/src/renderers/common/DataMap.ts | 38 - .../src/renderers/common/Geometries.ts | 199 --- .../IndirectStorageBufferAttribute.d.ts | 10 - src-testing/src/renderers/common/Info.ts | 95 -- .../src/renderers/common/Lighting.d.ts | 15 - src-testing/src/renderers/common/Pipeline.ts | 9 - src-testing/src/renderers/common/Pipelines.ts | 270 ---- .../src/renderers/common/PostProcessing.d.ts | 21 - .../renderers/common/PostProcessingUtils.d.ts | 66 - .../src/renderers/common/ProgrammableStage.ts | 16 - .../src/renderers/common/QuadMesh.d.ts | 16 - .../src/renderers/common/RenderBundle.ts | 12 - .../src/renderers/common/RenderBundles.ts | 28 - .../src/renderers/common/RenderContext.ts | 56 - .../src/renderers/common/RenderContexts.ts | 47 - .../src/renderers/common/RenderList.ts | 142 -- .../src/renderers/common/RenderLists.ts | 30 - .../src/renderers/common/RenderObject.ts | 350 ---- .../src/renderers/common/RenderObjects.ts | 107 -- .../src/renderers/common/RenderPipeline.ts | 12 - src-testing/src/renderers/common/Renderer.ts | 1425 ----------------- .../src/renderers/common/SampledTexture.ts | 68 - src-testing/src/renderers/common/Sampler.ts | 14 - .../src/renderers/common/StorageBuffer.ts | 13 - .../common/StorageBufferAttribute.d.ts | 7 - .../StorageInstancedBufferAttribute.d.ts | 8 - .../src/renderers/common/StorageTexture.d.ts | 5 - src-testing/src/renderers/common/Textures.ts | 294 ---- src-testing/src/renderers/common/Uniform.ts | 105 -- .../src/renderers/common/UniformBuffer.ts | 11 - .../src/renderers/common/UniformsGroup.ts | 277 ---- .../renderers/common/extras/PMREMGenerator.ts | 657 -------- .../common/nodes/NodeBuilderState.ts | 55 - .../src/renderers/common/nodes/NodeLibrary.ts | 76 - .../common/nodes/NodeSampledTexture.d.ts | 29 - .../renderers/common/nodes/NodeSampler.d.ts | 12 - .../src/renderers/common/nodes/NodeUniform.ts | 103 -- .../common/nodes/NodeUniformsGroup.ts | 30 - .../src/renderers/common/nodes/Nodes.ts | 433 ----- .../common/nodes/StandardNodeLibrary.d.ts | 5 - .../src/renderers/shaders/ShaderChunk.d.ts | 143 -- .../src/renderers/shaders/ShaderLib.d.ts | 29 - .../src/renderers/shaders/UniformsLib.d.ts | 189 --- .../src/renderers/shaders/UniformsUtils.d.ts | 14 - .../renderers/webgl-fallback/WebGLBackend.ts | 1349 ---------------- .../webgl-fallback/nodes/GLSLNodeBuilder.ts | 812 ---------- .../src/renderers/webgl/WebGLAttributes.d.ts | 21 - .../renderers/webgl/WebGLBindingStates.d.ts | 26 - .../renderers/webgl/WebGLBufferRenderer.d.ts | 21 - .../renderers/webgl/WebGLCapabilities.d.ts | 48 - .../src/renderers/webgl/WebGLClipping.d.ts | 26 - .../src/renderers/webgl/WebGLCubeMaps.d.ts | 8 - .../src/renderers/webgl/WebGLCubeUVMaps.d.ts | 9 - .../src/renderers/webgl/WebGLExtensions.d.ts | 7 - .../src/renderers/webgl/WebGLGeometries.d.ts | 13 - .../webgl/WebGLIndexedBufferRenderer.d.ts | 15 - .../src/renderers/webgl/WebGLInfo.d.ts | 39 - .../src/renderers/webgl/WebGLLights.d.ts | 49 - .../src/renderers/webgl/WebGLObjects.d.ts | 6 - .../src/renderers/webgl/WebGLProgram.d.ts | 30 - .../src/renderers/webgl/WebGLPrograms.d.ts | 233 --- .../src/renderers/webgl/WebGLProperties.d.ts | 9 - .../src/renderers/webgl/WebGLRenderLists.d.ts | 66 - .../src/renderers/webgl/WebGLShader.d.ts | 1 - .../src/renderers/webgl/WebGLShadowMap.d.ts | 38 - .../src/renderers/webgl/WebGLState.d.ts | 116 -- .../src/renderers/webgl/WebGLTextures.d.ts | 30 - .../src/renderers/webgl/WebGLUniforms.d.ts | 12 - .../renderers/webgl/WebGLUniformsGroups.d.ts | 17 - .../src/renderers/webgl/WebGLUtils.d.ts | 11 - .../src/renderers/webgpu/WebGPUBackend.ts | 1297 --------------- .../webgpu/WebGPURenderer.Nodes.d.ts | 12 - .../src/renderers/webgpu/WebGPURenderer.ts | 46 - .../webgpu/nodes/BasicNodeLibrary.ts | 61 - .../webgpu/nodes/StandardNodeLibrary.ts | 107 -- .../renderers/webgpu/nodes/WGSLNodeBuilder.ts | 1178 -------------- .../webgpu/nodes/WGSLNodeFunction.ts | 142 -- .../renderers/webgpu/nodes/WGSLNodeParser.ts | 10 - .../webgpu/utils/WebGPUConstants.d.ts | 328 ---- .../src/renderers/webxr/WebXRController.d.ts | 63 - .../renderers/webxr/WebXRDepthSensing.d.ts | 22 - .../src/renderers/webxr/WebXRManager.d.ts | 85 - src-testing/src/scenes/Fog.d.ts | 77 - src-testing/src/scenes/FogExp2.d.ts | 66 - src-testing/src/scenes/Scene.d.ts | 118 -- src-testing/src/textures/CanvasTexture.d.ts | 51 - .../src/textures/CompressedArrayTexture.d.ts | 68 - .../src/textures/CompressedCubeTexture.d.ts | 13 - .../src/textures/CompressedTexture.d.ts | 94 -- src-testing/src/textures/CubeTexture.d.ts | 89 - src-testing/src/textures/Data3DTexture.d.ts | 96 -- .../src/textures/DataArrayTexture.d.ts | 123 -- src-testing/src/textures/DataTexture.d.ts | 112 -- src-testing/src/textures/DepthTexture.d.ts | 104 -- .../src/textures/FramebufferTexture.d.ts | 62 - src-testing/src/textures/Source.d.ts | 75 - src-testing/src/textures/Texture.d.ts | 476 ------ src-testing/src/textures/VideoTexture.d.ts | 90 -- src-testing/src/textures/types.d.ts | 9 - src-testing/src/utils.d.ts | 3 - 523 files changed, 4 insertions(+), 42355 deletions(-) delete mode 100644 src-testing/src/Three.Legacy.d.ts delete mode 100644 src-testing/src/Three.WebGPU.Nodes.d.ts delete mode 100644 src-testing/src/Three.WebGPU.d.ts delete mode 100644 src-testing/src/Three.d.ts delete mode 100644 src-testing/src/animation/AnimationAction.d.ts delete mode 100644 src-testing/src/animation/AnimationClip.d.ts delete mode 100644 src-testing/src/animation/AnimationMixer.d.ts delete mode 100644 src-testing/src/animation/AnimationObjectGroup.d.ts delete mode 100644 src-testing/src/animation/AnimationUtils.d.ts delete mode 100644 src-testing/src/animation/KeyframeTrack.d.ts delete mode 100644 src-testing/src/animation/PropertyBinding.d.ts delete mode 100644 src-testing/src/animation/PropertyMixer.d.ts delete mode 100644 src-testing/src/animation/tracks/BooleanKeyframeTrack.d.ts delete mode 100644 src-testing/src/animation/tracks/ColorKeyframeTrack.d.ts delete mode 100644 src-testing/src/animation/tracks/NumberKeyframeTrack.d.ts delete mode 100644 src-testing/src/animation/tracks/QuaternionKeyframeTrack.d.ts delete mode 100644 src-testing/src/animation/tracks/StringKeyframeTrack.d.ts delete mode 100644 src-testing/src/animation/tracks/VectorKeyframeTrack.d.ts delete mode 100644 src-testing/src/audio/Audio.d.ts delete mode 100644 src-testing/src/audio/AudioAnalyser.d.ts delete mode 100644 src-testing/src/audio/AudioContext.d.ts delete mode 100644 src-testing/src/audio/AudioListener.d.ts delete mode 100644 src-testing/src/audio/PositionalAudio.d.ts delete mode 100644 src-testing/src/cameras/ArrayCamera.d.ts delete mode 100644 src-testing/src/cameras/Camera.d.ts delete mode 100644 src-testing/src/cameras/CubeCamera.d.ts delete mode 100644 src-testing/src/cameras/OrthographicCamera.d.ts delete mode 100644 src-testing/src/cameras/PerspectiveCamera.d.ts delete mode 100644 src-testing/src/cameras/StereoCamera.d.ts delete mode 100644 src-testing/src/constants.d.ts delete mode 100644 src-testing/src/core/BufferAttribute.d.ts delete mode 100644 src-testing/src/core/BufferGeometry.d.ts delete mode 100644 src-testing/src/core/Clock.d.ts delete mode 100644 src-testing/src/core/EventDispatcher.d.ts delete mode 100644 src-testing/src/core/GLBufferAttribute.d.ts delete mode 100644 src-testing/src/core/InstancedBufferAttribute.d.ts delete mode 100644 src-testing/src/core/InstancedBufferGeometry.d.ts delete mode 100644 src-testing/src/core/InstancedInterleavedBuffer.d.ts delete mode 100644 src-testing/src/core/InterleavedBuffer.d.ts delete mode 100644 src-testing/src/core/InterleavedBufferAttribute.d.ts delete mode 100644 src-testing/src/core/Layers.d.ts delete mode 100644 src-testing/src/core/Object3D.d.ts delete mode 100644 src-testing/src/core/Raycaster.d.ts delete mode 100644 src-testing/src/core/RenderTarget.d.ts delete mode 100644 src-testing/src/core/Uniform.d.ts delete mode 100644 src-testing/src/core/UniformsGroup.d.ts delete mode 100644 src-testing/src/extras/Controls.d.ts delete mode 100644 src-testing/src/extras/DataUtils.d.ts delete mode 100644 src-testing/src/extras/Earcut.d.ts delete mode 100644 src-testing/src/extras/ImageUtils.d.ts delete mode 100644 src-testing/src/extras/PMREMGenerator.d.ts delete mode 100644 src-testing/src/extras/ShapeUtils.d.ts delete mode 100644 src-testing/src/extras/TextureUtils.d.ts delete mode 100644 src-testing/src/extras/core/Curve.d.ts delete mode 100644 src-testing/src/extras/core/CurvePath.d.ts delete mode 100644 src-testing/src/extras/core/Interpolations.d.ts delete mode 100644 src-testing/src/extras/core/Path.d.ts delete mode 100644 src-testing/src/extras/core/Shape.d.ts delete mode 100644 src-testing/src/extras/core/ShapePath.d.ts delete mode 100644 src-testing/src/extras/curves/ArcCurve.d.ts delete mode 100644 src-testing/src/extras/curves/CatmullRomCurve3.d.ts delete mode 100644 src-testing/src/extras/curves/CubicBezierCurve.d.ts delete mode 100644 src-testing/src/extras/curves/CubicBezierCurve3.d.ts delete mode 100644 src-testing/src/extras/curves/Curves.d.ts delete mode 100644 src-testing/src/extras/curves/EllipseCurve.d.ts delete mode 100644 src-testing/src/extras/curves/LineCurve.d.ts delete mode 100644 src-testing/src/extras/curves/LineCurve3.d.ts delete mode 100644 src-testing/src/extras/curves/QuadraticBezierCurve.d.ts delete mode 100644 src-testing/src/extras/curves/QuadraticBezierCurve3.d.ts delete mode 100644 src-testing/src/extras/curves/SplineCurve.d.ts delete mode 100644 src-testing/src/geometries/BoxGeometry.d.ts delete mode 100644 src-testing/src/geometries/CapsuleGeometry.d.ts delete mode 100644 src-testing/src/geometries/CircleGeometry.d.ts delete mode 100644 src-testing/src/geometries/ConeGeometry.d.ts delete mode 100644 src-testing/src/geometries/CylinderGeometry.d.ts delete mode 100644 src-testing/src/geometries/DodecahedronGeometry.d.ts delete mode 100644 src-testing/src/geometries/EdgesGeometry.d.ts delete mode 100644 src-testing/src/geometries/ExtrudeGeometry.d.ts delete mode 100644 src-testing/src/geometries/Geometries.d.ts delete mode 100644 src-testing/src/geometries/IcosahedronGeometry.d.ts delete mode 100644 src-testing/src/geometries/LatheGeometry.d.ts delete mode 100644 src-testing/src/geometries/OctahedronGeometry.d.ts delete mode 100644 src-testing/src/geometries/PlaneGeometry.d.ts delete mode 100644 src-testing/src/geometries/PolyhedronGeometry.d.ts delete mode 100644 src-testing/src/geometries/RingGeometry.d.ts delete mode 100644 src-testing/src/geometries/ShapeGeometry.d.ts delete mode 100644 src-testing/src/geometries/SphereGeometry.d.ts delete mode 100644 src-testing/src/geometries/TetrahedronGeometry.d.ts delete mode 100644 src-testing/src/geometries/TorusGeometry.d.ts delete mode 100644 src-testing/src/geometries/TorusKnotGeometry.d.ts delete mode 100644 src-testing/src/geometries/TubeGeometry.d.ts delete mode 100644 src-testing/src/geometries/WireframeGeometry.d.ts delete mode 100644 src-testing/src/helpers/ArrowHelper.d.ts delete mode 100644 src-testing/src/helpers/AxesHelper.d.ts delete mode 100644 src-testing/src/helpers/Box3Helper.d.ts delete mode 100644 src-testing/src/helpers/BoxHelper.d.ts delete mode 100644 src-testing/src/helpers/CameraHelper.d.ts delete mode 100644 src-testing/src/helpers/DirectionalLightHelper.d.ts delete mode 100644 src-testing/src/helpers/GridHelper.d.ts delete mode 100644 src-testing/src/helpers/HemisphereLightHelper.d.ts delete mode 100644 src-testing/src/helpers/PlaneHelper.d.ts delete mode 100644 src-testing/src/helpers/PointLightHelper.d.ts delete mode 100644 src-testing/src/helpers/PolarGridHelper.d.ts delete mode 100644 src-testing/src/helpers/SkeletonHelper.d.ts delete mode 100644 src-testing/src/helpers/SpotLightHelper.d.ts delete mode 100644 src-testing/src/lights/AmbientLight.d.ts delete mode 100644 src-testing/src/lights/DirectionalLight.d.ts delete mode 100644 src-testing/src/lights/DirectionalLightShadow.d.ts delete mode 100644 src-testing/src/lights/HemisphereLight.d.ts delete mode 100644 src-testing/src/lights/Light.d.ts delete mode 100644 src-testing/src/lights/LightProbe.d.ts delete mode 100644 src-testing/src/lights/LightShadow.d.ts delete mode 100644 src-testing/src/lights/PointLight.d.ts delete mode 100644 src-testing/src/lights/PointLightShadow.d.ts delete mode 100644 src-testing/src/lights/RectAreaLight.d.ts delete mode 100644 src-testing/src/lights/SpotLight.d.ts delete mode 100644 src-testing/src/lights/SpotLightShadow.d.ts delete mode 100644 src-testing/src/lights/webgpu/IESSpotLight.d.ts delete mode 100644 src-testing/src/loaders/AnimationLoader.d.ts delete mode 100644 src-testing/src/loaders/AudioLoader.d.ts delete mode 100644 src-testing/src/loaders/BufferGeometryLoader.d.ts delete mode 100644 src-testing/src/loaders/Cache.d.ts delete mode 100644 src-testing/src/loaders/CompressedTextureLoader.d.ts delete mode 100644 src-testing/src/loaders/CubeTextureLoader.d.ts delete mode 100644 src-testing/src/loaders/DataTextureLoader.d.ts delete mode 100644 src-testing/src/loaders/FileLoader.d.ts delete mode 100644 src-testing/src/loaders/ImageBitmapLoader.d.ts delete mode 100644 src-testing/src/loaders/ImageLoader.d.ts delete mode 100644 src-testing/src/loaders/Loader.d.ts delete mode 100644 src-testing/src/loaders/LoaderUtils.d.ts delete mode 100644 src-testing/src/loaders/LoadingManager.d.ts delete mode 100644 src-testing/src/loaders/MaterialLoader.d.ts delete mode 100644 src-testing/src/loaders/ObjectLoader.d.ts delete mode 100644 src-testing/src/loaders/TextureLoader.d.ts delete mode 100644 src-testing/src/loaders/nodes/NodeLoader.d.ts delete mode 100644 src-testing/src/loaders/nodes/NodeMaterialLoader.d.ts delete mode 100644 src-testing/src/loaders/nodes/NodeObjectLoader.d.ts delete mode 100644 src-testing/src/materials/LineBasicMaterial.d.ts delete mode 100644 src-testing/src/materials/LineDashedMaterial.d.ts delete mode 100644 src-testing/src/materials/Material.d.ts delete mode 100644 src-testing/src/materials/Materials.d.ts delete mode 100644 src-testing/src/materials/MeshBasicMaterial.d.ts delete mode 100644 src-testing/src/materials/MeshDepthMaterial.d.ts delete mode 100644 src-testing/src/materials/MeshDistanceMaterial.d.ts delete mode 100644 src-testing/src/materials/MeshLambertMaterial.d.ts delete mode 100644 src-testing/src/materials/MeshMatcapMaterial.d.ts delete mode 100644 src-testing/src/materials/MeshNormalMaterial.d.ts delete mode 100644 src-testing/src/materials/MeshPhongMaterial.d.ts delete mode 100644 src-testing/src/materials/MeshPhysicalMaterial.d.ts delete mode 100644 src-testing/src/materials/MeshStandardMaterial.d.ts delete mode 100644 src-testing/src/materials/MeshToonMaterial.d.ts delete mode 100644 src-testing/src/materials/PointsMaterial.d.ts delete mode 100644 src-testing/src/materials/RawShaderMaterial.d.ts delete mode 100644 src-testing/src/materials/ShaderMaterial.d.ts delete mode 100644 src-testing/src/materials/ShadowMaterial.d.ts delete mode 100644 src-testing/src/materials/SpriteMaterial.d.ts delete mode 100644 src-testing/src/materials/nodes/InstancedPointsNodeMaterial.d.ts delete mode 100644 src-testing/src/materials/nodes/Line2NodeMaterial.d.ts delete mode 100644 src-testing/src/materials/nodes/LineBasicNodeMaterial.d.ts delete mode 100644 src-testing/src/materials/nodes/LineDashedNodeMaterial.d.ts delete mode 100644 src-testing/src/materials/nodes/MeshBasicNodeMaterial.d.ts delete mode 100644 src-testing/src/materials/nodes/MeshLambertNodeMaterial.d.ts delete mode 100644 src-testing/src/materials/nodes/MeshMatcapNodeMaterial.d.ts delete mode 100644 src-testing/src/materials/nodes/MeshNormalNodeMaterial.d.ts delete mode 100644 src-testing/src/materials/nodes/MeshPhongNodeMaterial.d.ts delete mode 100644 src-testing/src/materials/nodes/MeshPhysicalNodeMaterial.d.ts delete mode 100644 src-testing/src/materials/nodes/MeshSSSNodeMaterial.d.ts delete mode 100644 src-testing/src/materials/nodes/MeshStandardNodeMaterial.d.ts delete mode 100644 src-testing/src/materials/nodes/MeshToonNodeMaterial.d.ts delete mode 100644 src-testing/src/materials/nodes/NodeMaterial.ts delete mode 100644 src-testing/src/materials/nodes/NodeMaterials.d.ts delete mode 100644 src-testing/src/materials/nodes/PointsNodeMaterial.d.ts delete mode 100644 src-testing/src/materials/nodes/ShadowNodeMaterial.d.ts delete mode 100644 src-testing/src/materials/nodes/SpriteNodeMaterial.d.ts delete mode 100644 src-testing/src/materials/nodes/VolumeNodeMaterial.d.ts delete mode 100644 src-testing/src/materials/nodes/manager/NodeMaterialObserver.ts delete mode 100644 src-testing/src/math/Box2.d.ts delete mode 100644 src-testing/src/math/Box3.d.ts delete mode 100644 src-testing/src/math/Color.d.ts delete mode 100644 src-testing/src/math/ColorManagement.d.ts delete mode 100644 src-testing/src/math/Cylindrical.d.ts delete mode 100644 src-testing/src/math/Euler.d.ts delete mode 100644 src-testing/src/math/Frustum.d.ts delete mode 100644 src-testing/src/math/Interpolant.d.ts delete mode 100644 src-testing/src/math/Line3.d.ts delete mode 100644 src-testing/src/math/MathUtils.d.ts delete mode 100644 src-testing/src/math/Matrix2.d.ts delete mode 100644 src-testing/src/math/Matrix3.d.ts delete mode 100644 src-testing/src/math/Matrix4.d.ts delete mode 100644 src-testing/src/math/Plane.d.ts delete mode 100644 src-testing/src/math/Quaternion.d.ts delete mode 100644 src-testing/src/math/Ray.d.ts delete mode 100644 src-testing/src/math/Sphere.d.ts delete mode 100644 src-testing/src/math/Spherical.d.ts delete mode 100644 src-testing/src/math/SphericalHarmonics3.d.ts delete mode 100644 src-testing/src/math/Triangle.d.ts delete mode 100644 src-testing/src/math/Vector2.d.ts delete mode 100644 src-testing/src/math/Vector3.d.ts delete mode 100644 src-testing/src/math/Vector4.d.ts delete mode 100644 src-testing/src/math/interpolants/CubicInterpolant.d.ts delete mode 100644 src-testing/src/math/interpolants/DiscreteInterpolant.d.ts delete mode 100644 src-testing/src/math/interpolants/LinearInterpolant.d.ts delete mode 100644 src-testing/src/math/interpolants/QuaternionLinearInterpolant.d.ts delete mode 100644 src-testing/src/nodes/Nodes.ts delete mode 100644 src-testing/src/nodes/TSL.d.ts delete mode 100644 src-testing/src/nodes/accessors/AccessorsUtils.d.ts delete mode 100644 src-testing/src/nodes/accessors/BatchNode.d.ts delete mode 100644 src-testing/src/nodes/accessors/Bitangent.d.ts delete mode 100644 src-testing/src/nodes/accessors/BufferAttributeNode.ts delete mode 100644 src-testing/src/nodes/accessors/BufferNode.d.ts delete mode 100644 src-testing/src/nodes/accessors/Camera.d.ts delete mode 100644 src-testing/src/nodes/accessors/ClippingNode.d.ts delete mode 100644 src-testing/src/nodes/accessors/CubeTextureNode.d.ts delete mode 100644 src-testing/src/nodes/accessors/InstanceNode.d.ts delete mode 100644 src-testing/src/nodes/accessors/MaterialNode.d.ts delete mode 100644 src-testing/src/nodes/accessors/MaterialProperties.d.ts delete mode 100644 src-testing/src/nodes/accessors/MaterialReferenceNode.d.ts delete mode 100644 src-testing/src/nodes/accessors/ModelNode.d.ts delete mode 100644 src-testing/src/nodes/accessors/ModelViewProjectionNode.d.ts delete mode 100644 src-testing/src/nodes/accessors/MorphNode.d.ts delete mode 100644 src-testing/src/nodes/accessors/Normal.d.ts delete mode 100644 src-testing/src/nodes/accessors/Object3DNode.d.ts delete mode 100644 src-testing/src/nodes/accessors/PointUVNode.d.ts delete mode 100644 src-testing/src/nodes/accessors/Position.d.ts delete mode 100644 src-testing/src/nodes/accessors/ReferenceBaseNode.d.ts delete mode 100644 src-testing/src/nodes/accessors/ReferenceNode.d.ts delete mode 100644 src-testing/src/nodes/accessors/ReflectVector.d.ts delete mode 100644 src-testing/src/nodes/accessors/RendererReferenceNode.d.ts delete mode 100644 src-testing/src/nodes/accessors/SceneNode.d.ts delete mode 100644 src-testing/src/nodes/accessors/SkinningNode.d.ts delete mode 100644 src-testing/src/nodes/accessors/StorageBufferNode.d.ts delete mode 100644 src-testing/src/nodes/accessors/StorageTextureNode.d.ts delete mode 100644 src-testing/src/nodes/accessors/Tangent.d.ts delete mode 100644 src-testing/src/nodes/accessors/Texture3DNode.d.ts delete mode 100644 src-testing/src/nodes/accessors/TextureBicubic.d.ts delete mode 100644 src-testing/src/nodes/accessors/TextureNode.ts delete mode 100644 src-testing/src/nodes/accessors/TextureSizeNode.d.ts delete mode 100644 src-testing/src/nodes/accessors/UV.d.ts delete mode 100644 src-testing/src/nodes/accessors/UniformArrayNode.d.ts delete mode 100644 src-testing/src/nodes/accessors/UserDataNode.d.ts delete mode 100644 src-testing/src/nodes/accessors/VelocityNode.d.ts delete mode 100644 src-testing/src/nodes/accessors/VertexColorNode.d.ts delete mode 100644 src-testing/src/nodes/code/CodeNode.ts delete mode 100644 src-testing/src/nodes/code/ExpressionNode.d.ts delete mode 100644 src-testing/src/nodes/code/FunctionCallNode.d.ts delete mode 100644 src-testing/src/nodes/code/FunctionNode.ts delete mode 100644 src-testing/src/nodes/code/ScriptableNode.d.ts delete mode 100644 src-testing/src/nodes/code/ScriptableValueNode.d.ts delete mode 100644 src-testing/src/nodes/core/AssignNode.d.ts delete mode 100644 src-testing/src/nodes/core/AttributeNode.d.ts delete mode 100644 src-testing/src/nodes/core/BypassNode.d.ts delete mode 100644 src-testing/src/nodes/core/CacheNode.d.ts delete mode 100644 src-testing/src/nodes/core/ConstNode.d.ts delete mode 100644 src-testing/src/nodes/core/ContextNode.ts delete mode 100644 src-testing/src/nodes/core/IndexNode.d.ts delete mode 100644 src-testing/src/nodes/core/InputNode.ts delete mode 100644 src-testing/src/nodes/core/LightingModel.d.ts delete mode 100644 src-testing/src/nodes/core/MRTNode.d.ts delete mode 100644 src-testing/src/nodes/core/Node.ts delete mode 100644 src-testing/src/nodes/core/NodeAttribute.ts delete mode 100644 src-testing/src/nodes/core/NodeBuilder.ts delete mode 100644 src-testing/src/nodes/core/NodeCache.ts delete mode 100644 src-testing/src/nodes/core/NodeCode.ts delete mode 100644 src-testing/src/nodes/core/NodeFrame.ts delete mode 100644 src-testing/src/nodes/core/NodeFunction.ts delete mode 100644 src-testing/src/nodes/core/NodeFunctionInput.d.ts delete mode 100644 src-testing/src/nodes/core/NodeParser.ts delete mode 100644 src-testing/src/nodes/core/NodeUniform.ts delete mode 100644 src-testing/src/nodes/core/NodeUtils.ts delete mode 100644 src-testing/src/nodes/core/NodeVar.ts delete mode 100644 src-testing/src/nodes/core/NodeVarying.ts delete mode 100644 src-testing/src/nodes/core/OutputStructNode.d.ts delete mode 100644 src-testing/src/nodes/core/ParameterNode.d.ts delete mode 100644 src-testing/src/nodes/core/PropertyNode.d.ts delete mode 100644 src-testing/src/nodes/core/StackNode.ts delete mode 100644 src-testing/src/nodes/core/StructTypeNode.ts delete mode 100644 src-testing/src/nodes/core/TempNode.d.ts delete mode 100644 src-testing/src/nodes/core/UniformGroup.d.ts delete mode 100644 src-testing/src/nodes/core/UniformGroupNode.ts delete mode 100644 src-testing/src/nodes/core/UniformNode.ts delete mode 100644 src-testing/src/nodes/core/VarNode.d.ts delete mode 100644 src-testing/src/nodes/core/VaryingNode.d.ts delete mode 100644 src-testing/src/nodes/core/constants.ts delete mode 100644 src-testing/src/nodes/display/BlendMode.d.ts delete mode 100644 src-testing/src/nodes/display/BumpMapNode.d.ts delete mode 100644 src-testing/src/nodes/display/ColorAdjustment.d.ts delete mode 100644 src-testing/src/nodes/display/ColorSpaceFunctions.d.ts delete mode 100644 src-testing/src/nodes/display/ColorSpaceNode.d.ts delete mode 100644 src-testing/src/nodes/display/FrontFacingNode.d.ts delete mode 100644 src-testing/src/nodes/display/NormalMapNode.d.ts delete mode 100644 src-testing/src/nodes/display/PassNode.d.ts delete mode 100644 src-testing/src/nodes/display/PosterizeNode.d.ts delete mode 100644 src-testing/src/nodes/display/RenderOutputNode.d.ts delete mode 100644 src-testing/src/nodes/display/ScreenNode.d.ts delete mode 100644 src-testing/src/nodes/display/ToneMappingFunctions.d.ts delete mode 100644 src-testing/src/nodes/display/ToneMappingNode.d.ts delete mode 100644 src-testing/src/nodes/display/ToonOutlinePassNode.d.ts delete mode 100644 src-testing/src/nodes/display/ViewportDepthNode.d.ts delete mode 100644 src-testing/src/nodes/display/ViewportDepthTextureNode.d.ts delete mode 100644 src-testing/src/nodes/display/ViewportSharedTextureNode.d.ts delete mode 100644 src-testing/src/nodes/display/ViewportTextureNode.d.ts delete mode 100644 src-testing/src/nodes/fog/FogExp2Node.d.ts delete mode 100644 src-testing/src/nodes/fog/FogNode.ts delete mode 100644 src-testing/src/nodes/fog/FogRangeNode.d.ts delete mode 100644 src-testing/src/nodes/functions/BSDF/BRDF_GGX.d.ts delete mode 100644 src-testing/src/nodes/functions/BSDF/BRDF_Lambert.d.ts delete mode 100644 src-testing/src/nodes/functions/BSDF/BRDF_Sheen.d.ts delete mode 100644 src-testing/src/nodes/functions/BSDF/DFGApprox.d.ts delete mode 100644 src-testing/src/nodes/functions/BSDF/D_GGX.d.ts delete mode 100644 src-testing/src/nodes/functions/BSDF/D_GGX_Anisotropic.d.ts delete mode 100644 src-testing/src/nodes/functions/BSDF/F_Schlick.d.ts delete mode 100644 src-testing/src/nodes/functions/BSDF/LTC.d.ts delete mode 100644 src-testing/src/nodes/functions/BSDF/Schlick_to_F0.d.ts delete mode 100644 src-testing/src/nodes/functions/BSDF/V_GGX_SmithCorrelated.d.ts delete mode 100644 src-testing/src/nodes/functions/BSDF/V_GGX_SmithCorrelated_Anisotropic.d.ts delete mode 100644 src-testing/src/nodes/functions/BasicLightingModel.d.ts delete mode 100644 src-testing/src/nodes/functions/PhongLightingModel.d.ts delete mode 100644 src-testing/src/nodes/functions/PhysicalLightingModel.d.ts delete mode 100644 src-testing/src/nodes/functions/ShadowMaskModel.d.ts delete mode 100644 src-testing/src/nodes/functions/ToonLightingModel.d.ts delete mode 100644 src-testing/src/nodes/functions/material/getGeometryRoughness.d.ts delete mode 100644 src-testing/src/nodes/functions/material/getRoughness.d.ts delete mode 100644 src-testing/src/nodes/functions/material/getShIrradianceAt.d.ts delete mode 100644 src-testing/src/nodes/geometry/RangeNode.d.ts delete mode 100644 src-testing/src/nodes/gpgpu/ComputeNode.ts delete mode 100644 src-testing/src/nodes/lighting/AONode.d.ts delete mode 100644 src-testing/src/nodes/lighting/AmbientLightNode.d.ts delete mode 100644 src-testing/src/nodes/lighting/AnalyticLightNode.d.ts delete mode 100644 src-testing/src/nodes/lighting/BasicEnvironmentNode.d.ts delete mode 100644 src-testing/src/nodes/lighting/BasicLightMapNode.d.ts delete mode 100644 src-testing/src/nodes/lighting/DirectionalLightNode.d.ts delete mode 100644 src-testing/src/nodes/lighting/EnvironmentNode.ts delete mode 100644 src-testing/src/nodes/lighting/HemisphereLightNode.d.ts delete mode 100644 src-testing/src/nodes/lighting/IESSpotLightNode.d.ts delete mode 100644 src-testing/src/nodes/lighting/IrradianceNode.d.ts delete mode 100644 src-testing/src/nodes/lighting/LightNode.d.ts delete mode 100644 src-testing/src/nodes/lighting/LightProbeNode.d.ts delete mode 100644 src-testing/src/nodes/lighting/LightUtils.d.ts delete mode 100644 src-testing/src/nodes/lighting/LightingContextNode.ts delete mode 100644 src-testing/src/nodes/lighting/LightingNode.d.ts delete mode 100644 src-testing/src/nodes/lighting/LightsNode.ts delete mode 100644 src-testing/src/nodes/lighting/PointLightNode.d.ts delete mode 100644 src-testing/src/nodes/lighting/RectAreaLightNode.d.ts delete mode 100644 src-testing/src/nodes/lighting/ShadowNode.d.ts delete mode 100644 src-testing/src/nodes/lighting/SpotLightNode.d.ts delete mode 100644 src-testing/src/nodes/materialx/MaterialXNodes.d.ts delete mode 100644 src-testing/src/nodes/materialx/lib/mx_hsv.d.ts delete mode 100644 src-testing/src/nodes/materialx/lib/mx_noise.d.ts delete mode 100644 src-testing/src/nodes/materialx/lib/mx_transform_color.d.ts delete mode 100644 src-testing/src/nodes/math/ConditionalNode.d.ts delete mode 100644 src-testing/src/nodes/math/Hash.d.ts delete mode 100644 src-testing/src/nodes/math/MathNode.d.ts delete mode 100644 src-testing/src/nodes/math/MathUtils.d.ts delete mode 100644 src-testing/src/nodes/math/OperatorNode.d.ts delete mode 100644 src-testing/src/nodes/math/TriNoise3D.d.ts delete mode 100644 src-testing/src/nodes/parsers/GLSLNodeFunction.d.ts delete mode 100644 src-testing/src/nodes/parsers/GLSLNodeParser.d.ts delete mode 100644 src-testing/src/nodes/pmrem/PMREMNode.d.ts delete mode 100644 src-testing/src/nodes/pmrem/PMREMUtils.d.ts delete mode 100644 src-testing/src/nodes/procedural/Checker.d.ts delete mode 100644 src-testing/src/nodes/tsl/TSLBase.d.ts delete mode 100644 src-testing/src/nodes/tsl/TSLCore.ts delete mode 100644 src-testing/src/nodes/utils/ArrayElementNode.d.ts delete mode 100644 src-testing/src/nodes/utils/ConvertNode.d.ts delete mode 100644 src-testing/src/nodes/utils/CubeMapNode.d.ts delete mode 100644 src-testing/src/nodes/utils/Discard.d.ts delete mode 100644 src-testing/src/nodes/utils/EquirectUVNode.d.ts delete mode 100644 src-testing/src/nodes/utils/FunctionOverloadingNode.d.ts delete mode 100644 src-testing/src/nodes/utils/JoinNode.d.ts delete mode 100644 src-testing/src/nodes/utils/LoopNode.d.ts delete mode 100644 src-testing/src/nodes/utils/MatcapUVNode.d.ts delete mode 100644 src-testing/src/nodes/utils/MaxMipLevelNode.d.ts delete mode 100644 src-testing/src/nodes/utils/Oscillators.d.ts delete mode 100644 src-testing/src/nodes/utils/Packing.d.ts delete mode 100644 src-testing/src/nodes/utils/PostProcessingUtils.d.ts delete mode 100644 src-testing/src/nodes/utils/RTTNode.d.ts delete mode 100644 src-testing/src/nodes/utils/ReflectorNode.d.ts delete mode 100644 src-testing/src/nodes/utils/RemapNode.d.ts delete mode 100644 src-testing/src/nodes/utils/RotateNode.d.ts delete mode 100644 src-testing/src/nodes/utils/SetNode.d.ts delete mode 100644 src-testing/src/nodes/utils/SplitNode.d.ts delete mode 100644 src-testing/src/nodes/utils/SpriteSheetUVNode.d.ts delete mode 100644 src-testing/src/nodes/utils/SpriteUtils.d.ts delete mode 100644 src-testing/src/nodes/utils/StorageArrayElementNode.d.ts delete mode 100644 src-testing/src/nodes/utils/Timer.d.ts delete mode 100644 src-testing/src/nodes/utils/TriplanarTexturesNode.d.ts delete mode 100644 src-testing/src/nodes/utils/UVUtils.d.ts delete mode 100644 src-testing/src/nodes/utils/ViewportUtils.d.ts delete mode 100644 src-testing/src/objects/BatchedMesh.d.ts delete mode 100644 src-testing/src/objects/Bone.d.ts delete mode 100644 src-testing/src/objects/Group.d.ts delete mode 100644 src-testing/src/objects/InstancedMesh.d.ts delete mode 100644 src-testing/src/objects/LOD.d.ts delete mode 100644 src-testing/src/objects/Line.d.ts delete mode 100644 src-testing/src/objects/LineLoop.d.ts delete mode 100644 src-testing/src/objects/LineSegments.d.ts delete mode 100644 src-testing/src/objects/Mesh.d.ts delete mode 100644 src-testing/src/objects/Points.d.ts delete mode 100644 src-testing/src/objects/Skeleton.d.ts delete mode 100644 src-testing/src/objects/SkinnedMesh.d.ts delete mode 100644 src-testing/src/objects/Sprite.d.ts delete mode 100644 src-testing/src/renderers/WebGL3DRenderTarget.d.ts delete mode 100644 src-testing/src/renderers/WebGLArrayRenderTarget.d.ts delete mode 100644 src-testing/src/renderers/WebGLCubeRenderTarget.d.ts delete mode 100644 src-testing/src/renderers/WebGLRenderTarget.d.ts delete mode 100644 src-testing/src/renderers/WebGLRenderer.d.ts delete mode 100644 src-testing/src/renderers/common/Animation.ts delete mode 100644 src-testing/src/renderers/common/Attributes.ts delete mode 100644 src-testing/src/renderers/common/Backend.ts delete mode 100644 src-testing/src/renderers/common/Background.ts delete mode 100644 src-testing/src/renderers/common/BindGroup.ts delete mode 100644 src-testing/src/renderers/common/Binding.ts delete mode 100644 src-testing/src/renderers/common/Bindings.ts delete mode 100644 src-testing/src/renderers/common/Buffer.ts delete mode 100644 src-testing/src/renderers/common/BufferUtils.ts delete mode 100644 src-testing/src/renderers/common/BundleGroup.ts delete mode 100644 src-testing/src/renderers/common/ChainMap.ts delete mode 100644 src-testing/src/renderers/common/ClippingContext.ts delete mode 100644 src-testing/src/renderers/common/Color4.ts delete mode 100644 src-testing/src/renderers/common/ComputePipeline.ts delete mode 100644 src-testing/src/renderers/common/Constants.ts delete mode 100644 src-testing/src/renderers/common/CubeRenderTarget.ts delete mode 100644 src-testing/src/renderers/common/DataMap.ts delete mode 100644 src-testing/src/renderers/common/Geometries.ts delete mode 100644 src-testing/src/renderers/common/IndirectStorageBufferAttribute.d.ts delete mode 100644 src-testing/src/renderers/common/Info.ts delete mode 100644 src-testing/src/renderers/common/Lighting.d.ts delete mode 100644 src-testing/src/renderers/common/Pipeline.ts delete mode 100644 src-testing/src/renderers/common/Pipelines.ts delete mode 100644 src-testing/src/renderers/common/PostProcessing.d.ts delete mode 100644 src-testing/src/renderers/common/PostProcessingUtils.d.ts delete mode 100644 src-testing/src/renderers/common/ProgrammableStage.ts delete mode 100644 src-testing/src/renderers/common/QuadMesh.d.ts delete mode 100644 src-testing/src/renderers/common/RenderBundle.ts delete mode 100644 src-testing/src/renderers/common/RenderBundles.ts delete mode 100644 src-testing/src/renderers/common/RenderContext.ts delete mode 100644 src-testing/src/renderers/common/RenderContexts.ts delete mode 100644 src-testing/src/renderers/common/RenderList.ts delete mode 100644 src-testing/src/renderers/common/RenderLists.ts delete mode 100644 src-testing/src/renderers/common/RenderObject.ts delete mode 100644 src-testing/src/renderers/common/RenderObjects.ts delete mode 100644 src-testing/src/renderers/common/RenderPipeline.ts delete mode 100644 src-testing/src/renderers/common/Renderer.ts delete mode 100644 src-testing/src/renderers/common/SampledTexture.ts delete mode 100644 src-testing/src/renderers/common/Sampler.ts delete mode 100644 src-testing/src/renderers/common/StorageBuffer.ts delete mode 100644 src-testing/src/renderers/common/StorageBufferAttribute.d.ts delete mode 100644 src-testing/src/renderers/common/StorageInstancedBufferAttribute.d.ts delete mode 100644 src-testing/src/renderers/common/StorageTexture.d.ts delete mode 100644 src-testing/src/renderers/common/Textures.ts delete mode 100644 src-testing/src/renderers/common/Uniform.ts delete mode 100644 src-testing/src/renderers/common/UniformBuffer.ts delete mode 100644 src-testing/src/renderers/common/UniformsGroup.ts delete mode 100644 src-testing/src/renderers/common/extras/PMREMGenerator.ts delete mode 100644 src-testing/src/renderers/common/nodes/NodeBuilderState.ts delete mode 100644 src-testing/src/renderers/common/nodes/NodeLibrary.ts delete mode 100644 src-testing/src/renderers/common/nodes/NodeSampledTexture.d.ts delete mode 100644 src-testing/src/renderers/common/nodes/NodeSampler.d.ts delete mode 100644 src-testing/src/renderers/common/nodes/NodeUniform.ts delete mode 100644 src-testing/src/renderers/common/nodes/NodeUniformsGroup.ts delete mode 100644 src-testing/src/renderers/common/nodes/Nodes.ts delete mode 100644 src-testing/src/renderers/common/nodes/StandardNodeLibrary.d.ts delete mode 100644 src-testing/src/renderers/shaders/ShaderChunk.d.ts delete mode 100644 src-testing/src/renderers/shaders/ShaderLib.d.ts delete mode 100644 src-testing/src/renderers/shaders/UniformsLib.d.ts delete mode 100644 src-testing/src/renderers/shaders/UniformsUtils.d.ts delete mode 100644 src-testing/src/renderers/webgl-fallback/WebGLBackend.ts delete mode 100644 src-testing/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.ts delete mode 100644 src-testing/src/renderers/webgl/WebGLAttributes.d.ts delete mode 100644 src-testing/src/renderers/webgl/WebGLBindingStates.d.ts delete mode 100644 src-testing/src/renderers/webgl/WebGLBufferRenderer.d.ts delete mode 100644 src-testing/src/renderers/webgl/WebGLCapabilities.d.ts delete mode 100644 src-testing/src/renderers/webgl/WebGLClipping.d.ts delete mode 100644 src-testing/src/renderers/webgl/WebGLCubeMaps.d.ts delete mode 100644 src-testing/src/renderers/webgl/WebGLCubeUVMaps.d.ts delete mode 100644 src-testing/src/renderers/webgl/WebGLExtensions.d.ts delete mode 100644 src-testing/src/renderers/webgl/WebGLGeometries.d.ts delete mode 100644 src-testing/src/renderers/webgl/WebGLIndexedBufferRenderer.d.ts delete mode 100644 src-testing/src/renderers/webgl/WebGLInfo.d.ts delete mode 100644 src-testing/src/renderers/webgl/WebGLLights.d.ts delete mode 100644 src-testing/src/renderers/webgl/WebGLObjects.d.ts delete mode 100644 src-testing/src/renderers/webgl/WebGLProgram.d.ts delete mode 100644 src-testing/src/renderers/webgl/WebGLPrograms.d.ts delete mode 100644 src-testing/src/renderers/webgl/WebGLProperties.d.ts delete mode 100644 src-testing/src/renderers/webgl/WebGLRenderLists.d.ts delete mode 100644 src-testing/src/renderers/webgl/WebGLShader.d.ts delete mode 100644 src-testing/src/renderers/webgl/WebGLShadowMap.d.ts delete mode 100644 src-testing/src/renderers/webgl/WebGLState.d.ts delete mode 100644 src-testing/src/renderers/webgl/WebGLTextures.d.ts delete mode 100644 src-testing/src/renderers/webgl/WebGLUniforms.d.ts delete mode 100644 src-testing/src/renderers/webgl/WebGLUniformsGroups.d.ts delete mode 100644 src-testing/src/renderers/webgl/WebGLUtils.d.ts delete mode 100644 src-testing/src/renderers/webgpu/WebGPUBackend.ts delete mode 100644 src-testing/src/renderers/webgpu/WebGPURenderer.Nodes.d.ts delete mode 100644 src-testing/src/renderers/webgpu/WebGPURenderer.ts delete mode 100644 src-testing/src/renderers/webgpu/nodes/BasicNodeLibrary.ts delete mode 100644 src-testing/src/renderers/webgpu/nodes/StandardNodeLibrary.ts delete mode 100644 src-testing/src/renderers/webgpu/nodes/WGSLNodeBuilder.ts delete mode 100644 src-testing/src/renderers/webgpu/nodes/WGSLNodeFunction.ts delete mode 100644 src-testing/src/renderers/webgpu/nodes/WGSLNodeParser.ts delete mode 100644 src-testing/src/renderers/webgpu/utils/WebGPUConstants.d.ts delete mode 100644 src-testing/src/renderers/webxr/WebXRController.d.ts delete mode 100644 src-testing/src/renderers/webxr/WebXRDepthSensing.d.ts delete mode 100644 src-testing/src/renderers/webxr/WebXRManager.d.ts delete mode 100644 src-testing/src/scenes/Fog.d.ts delete mode 100644 src-testing/src/scenes/FogExp2.d.ts delete mode 100644 src-testing/src/scenes/Scene.d.ts delete mode 100644 src-testing/src/textures/CanvasTexture.d.ts delete mode 100644 src-testing/src/textures/CompressedArrayTexture.d.ts delete mode 100644 src-testing/src/textures/CompressedCubeTexture.d.ts delete mode 100644 src-testing/src/textures/CompressedTexture.d.ts delete mode 100644 src-testing/src/textures/CubeTexture.d.ts delete mode 100644 src-testing/src/textures/Data3DTexture.d.ts delete mode 100644 src-testing/src/textures/DataArrayTexture.d.ts delete mode 100644 src-testing/src/textures/DataTexture.d.ts delete mode 100644 src-testing/src/textures/DepthTexture.d.ts delete mode 100644 src-testing/src/textures/FramebufferTexture.d.ts delete mode 100644 src-testing/src/textures/Source.d.ts delete mode 100644 src-testing/src/textures/Texture.d.ts delete mode 100644 src-testing/src/textures/VideoTexture.d.ts delete mode 100644 src-testing/src/textures/types.d.ts delete mode 100644 src-testing/src/utils.d.ts diff --git a/src-testing/changes.patch b/src-testing/changes.patch index 7020a9c2e..835affc17 100644 --- a/src-testing/changes.patch +++ b/src-testing/changes.patch @@ -6705,10 +6705,10 @@ index 520a3c91..524d188c 100644 } else { bindings.push(instanceGroup); diff --git a/src-testing/src/renderers/common/nodes/NodeLibrary.ts b/src-testing/src/renderers/common/nodes/NodeLibrary.ts -index b6738b95..6c1eaf57 100644 +index b6738b95..9b23a37b 100644 --- a/src-testing/src/renderers/common/nodes/NodeLibrary.ts +++ b/src-testing/src/renderers/common/nodes/NodeLibrary.ts -@@ -1,12 +1,29 @@ +@@ -1,12 +1,28 @@ +import { Material } from '../../../materials/Material.js'; +import NodeMaterial from '../../../materials/nodes/NodeMaterial.js'; +import { ToneMapping } from '../../../constants.js'; @@ -6725,7 +6725,6 @@ index b6738b95..6c1eaf57 100644 + ToneMapping, + (color: NodeRepresentation, exposure: NodeRepresentation) => ShaderNodeObject + >; -+ colorSpaceNodes: Map ShaderNodeObject>; + constructor() { this.lightNodes = new WeakMap(); @@ -6740,7 +6739,7 @@ index b6738b95..6c1eaf57 100644 let nodeMaterial = null; -@@ -23,31 +40,44 @@ class NodeLibrary { +@@ -23,31 +39,44 @@ class NodeLibrary { return nodeMaterial; } @@ -6793,7 +6792,7 @@ index b6738b95..6c1eaf57 100644 if (library.has(type)) { console.warn(`Redefinition of node ${type}`); return; -@@ -60,7 +90,11 @@ class NodeLibrary { +@@ -60,7 +89,11 @@ class NodeLibrary { library.set(type, nodeClass); } diff --git a/src-testing/src/Three.Legacy.d.ts b/src-testing/src/Three.Legacy.d.ts deleted file mode 100644 index 07f4743b9..000000000 --- a/src-testing/src/Three.Legacy.d.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { RenderTargetOptions } from "./core/RenderTarget.js"; -import { WebGLRenderTarget } from "./renderers/WebGLRenderTarget.js"; -import { Texture } from "./textures/Texture.js"; - -/** - * @deprecated THREE.WebGLMultipleRenderTargets has been deprecated and will be removed in r172. Use THREE.WebGLRenderTarget and set the "count" parameter to enable MRT. - */ -export class WebGLMultipleRenderTargets extends WebGLRenderTarget { - readonly isWebGLMultipleRenderTargets: true; - - /** - * @deprecated THREE.WebGLMultipleRenderTargets has been deprecated and will be removed in r172. Use THREE.WebGLRenderTarget and set the "count" parameter to enable MRT. - * @param width The width of the render target. - * @param height The height of the render target. - * @param count The number of render targets. - * @param options object that holds texture parameters for an auto-generated target texture and depthBuffer/stencilBuffer booleans. - * For an explanation of the texture parameters see {@link Texture}. - */ - constructor(width?: number, height?: number, count?: number, options?: RenderTargetOptions); -} diff --git a/src-testing/src/Three.WebGPU.Nodes.d.ts b/src-testing/src/Three.WebGPU.Nodes.d.ts deleted file mode 100644 index ac876f6fe..000000000 --- a/src-testing/src/Three.WebGPU.Nodes.d.ts +++ /dev/null @@ -1,205 +0,0 @@ -export * from "./animation/AnimationAction.js"; -export * from "./animation/AnimationClip.js"; -export * from "./animation/AnimationMixer.js"; -export * from "./animation/AnimationObjectGroup.js"; -export { AnimationUtils } from "./animation/AnimationUtils.js"; -export * from "./animation/KeyframeTrack.js"; -export * from "./animation/PropertyBinding.js"; -export * from "./animation/PropertyMixer.js"; -export * from "./animation/tracks/BooleanKeyframeTrack.js"; -export * from "./animation/tracks/ColorKeyframeTrack.js"; -export * from "./animation/tracks/NumberKeyframeTrack.js"; -export * from "./animation/tracks/QuaternionKeyframeTrack.js"; -export * from "./animation/tracks/StringKeyframeTrack.js"; -export * from "./animation/tracks/VectorKeyframeTrack.js"; -export * from "./audio/Audio.js"; -export * from "./audio/AudioAnalyser.js"; -export * from "./audio/AudioContext.js"; -export * from "./audio/AudioListener.js"; -export * from "./audio/PositionalAudio.js"; -export * from "./cameras/ArrayCamera.js"; -export * from "./cameras/Camera.js"; -export * from "./cameras/CubeCamera.js"; -export * from "./cameras/OrthographicCamera.js"; -export * from "./cameras/PerspectiveCamera.js"; -export * from "./cameras/StereoCamera.js"; -export * from "./constants.js"; -export * from "./core/BufferAttribute.js"; -export * from "./core/BufferGeometry.js"; -export * from "./core/Clock.js"; -export * from "./core/EventDispatcher.js"; -export * from "./core/GLBufferAttribute.js"; -export * from "./core/InstancedBufferAttribute.js"; -export * from "./core/InstancedBufferGeometry.js"; -export * from "./core/InstancedInterleavedBuffer.js"; -export * from "./core/InterleavedBuffer.js"; -export * from "./core/InterleavedBufferAttribute.js"; -export * from "./core/Layers.js"; -export * from "./core/Object3D.js"; -export * from "./core/Raycaster.js"; -export * from "./core/RenderTarget.js"; -export * from "./core/Uniform.js"; -export * from "./core/UniformsGroup.js"; -export * from "./extras/Controls.js"; -export * from "./extras/core/Curve.js"; -export * from "./extras/core/CurvePath.js"; -export * from "./extras/core/Path.js"; -export * from "./extras/core/Shape.js"; -export * from "./extras/core/ShapePath.js"; -export * from "./extras/curves/Curves.js"; -export { DataUtils } from "./extras/DataUtils.js"; -export * from "./extras/ImageUtils.js"; -// export * from "./extras/PMREMGenerator.js"; -export * from "./extras/ShapeUtils.js"; -export { TextureUtils } from "./extras/TextureUtils.js"; -export * from "./geometries/Geometries.js"; -export * from "./helpers/ArrowHelper.js"; -export * from "./helpers/AxesHelper.js"; -export * from "./helpers/Box3Helper.js"; -export * from "./helpers/BoxHelper.js"; -export * from "./helpers/CameraHelper.js"; -export * from "./helpers/DirectionalLightHelper.js"; -export * from "./helpers/GridHelper.js"; -export * from "./helpers/HemisphereLightHelper.js"; -export * from "./helpers/PlaneHelper.js"; -export * from "./helpers/PointLightHelper.js"; -export * from "./helpers/PolarGridHelper.js"; -export * from "./helpers/SkeletonHelper.js"; -export * from "./helpers/SpotLightHelper.js"; -export * from "./lights/AmbientLight.js"; -export * from "./lights/DirectionalLight.js"; -export type { DirectionalLightShadow } from "./lights/DirectionalLightShadow.js"; -export * from "./lights/HemisphereLight.js"; -export * from "./lights/Light.js"; -export * from "./lights/LightProbe.js"; -export type { LightShadow, LightShadowJSON } from "./lights/LightShadow.js"; -export * from "./lights/PointLight.js"; -export type { PointLightShadow } from "./lights/PointLightShadow.js"; -export * from "./lights/RectAreaLight.js"; -export * from "./lights/SpotLight.js"; -export type { SpotLightShadow } from "./lights/SpotLightShadow.js"; -export * from "./loaders/AnimationLoader.js"; -export * from "./loaders/AudioLoader.js"; -export * from "./loaders/BufferGeometryLoader.js"; -export * from "./loaders/Cache.js"; -export * from "./loaders/CompressedTextureLoader.js"; -export * from "./loaders/CubeTextureLoader.js"; -export * from "./loaders/DataTextureLoader.js"; -export * from "./loaders/FileLoader.js"; -export * from "./loaders/ImageBitmapLoader.js"; -export * from "./loaders/ImageLoader.js"; -export * from "./loaders/Loader.js"; -export * from "./loaders/LoaderUtils.js"; -export * from "./loaders/LoadingManager.js"; -export * from "./loaders/MaterialLoader.js"; -export * from "./loaders/ObjectLoader.js"; -export * from "./loaders/TextureLoader.js"; -export * from "./materials/Materials.js"; -export * from "./materials/nodes/NodeMaterials.js"; -export * from "./math/Box2.js"; -export * from "./math/Box3.js"; -export * from "./math/Color.js"; -export { ColorManagement, ColorSpaceDefinition } from "./math/ColorManagement.js"; -export * from "./math/Cylindrical.js"; -export * from "./math/Euler.js"; -export * from "./math/Frustum.js"; -export * from "./math/Interpolant.js"; -export * from "./math/interpolants/CubicInterpolant.js"; -export * from "./math/interpolants/DiscreteInterpolant.js"; -export * from "./math/interpolants/LinearInterpolant.js"; -export * from "./math/interpolants/QuaternionLinearInterpolant.js"; -export * from "./math/Line3.js"; -export { MathUtils } from "./math/MathUtils.js"; -export * from "./math/Matrix2.js"; -export * from "./math/Matrix3.js"; -export * from "./math/Matrix4.js"; -export * from "./math/Plane.js"; -export * from "./math/Quaternion.js"; -export * from "./math/Ray.js"; -export * from "./math/Sphere.js"; -export * from "./math/Spherical.js"; -export * from "./math/SphericalHarmonics3.js"; -export * from "./math/Triangle.js"; -export * from "./math/Vector2.js"; -export * from "./math/Vector3.js"; -export * from "./math/Vector4.js"; -export * from "./objects/BatchedMesh.js"; -export * from "./objects/Bone.js"; -export * from "./objects/Group.js"; -export * from "./objects/InstancedMesh.js"; -export * from "./objects/Line.js"; -export * from "./objects/LineLoop.js"; -export * from "./objects/LineSegments.js"; -export * from "./objects/LOD.js"; -export * from "./objects/Mesh.js"; -export * from "./objects/Points.js"; -export * from "./objects/Skeleton.js"; -export * from "./objects/SkinnedMesh.js"; -export * from "./objects/Sprite.js"; -// export * from "./renderers/shaders/ShaderChunk.js"; -// export * from "./renderers/shaders/ShaderLib.js"; -// export * from "./renderers/shaders/UniformsLib.js"; -// export { UniformsUtils } from './renderers/shaders/UniformsUtils.js'; -export type { WebGLProgramParameters, WebGLProgramParametersWithUniforms } from "./renderers/webgl/WebGLPrograms.js"; -export type { WebGLShadowMap } from "./renderers/webgl/WebGLShadowMap.js"; -// export * from "./renderers/webgl/WebGLUtils.js"; -export * from "./renderers/WebGL3DRenderTarget.js"; -export * from "./renderers/WebGLArrayRenderTarget.js"; -export * from "./renderers/WebGLCubeRenderTarget.js"; -// export * from "./renderers/WebGLRenderer.js"; -export * from "./renderers/WebGLRenderTarget.js"; -export type { - WebXRController, - WebXRSpaceEventMap, - XRControllerEventType, - XRGripSpace, - XRHandInputState, - XRHandJoints, - XRHandSpace, - XRJointSpace, - XRTargetRaySpace, -} from "./renderers/webxr/WebXRController.js"; -export type { WebXRDepthSensing } from "./renderers/webxr/WebXRDepthSensing.js"; -export type { - WebXRArrayCamera, - WebXRCamera, - WebXRManager, - WebXRManagerEventMap, -} from "./renderers/webxr/WebXRManager.js"; -export * from "./scenes/Fog.js"; -export * from "./scenes/FogExp2.js"; -export * from "./scenes/Scene.js"; -export * from "./textures/CanvasTexture.js"; -export * from "./textures/CompressedArrayTexture.js"; -export * from "./textures/CompressedCubeTexture.js"; -export * from "./textures/CompressedTexture.js"; -export * from "./textures/CubeTexture.js"; -export * from "./textures/Data3DTexture.js"; -export * from "./textures/DataArrayTexture.js"; -export * from "./textures/DataTexture.js"; -export * from "./textures/DepthTexture.js"; -export * from "./textures/FramebufferTexture.js"; -export * from "./textures/Source.js"; -export * from "./textures/Texture.js"; -export * from "./textures/VideoTexture.js"; -export * from "./Three.Legacy.js"; -export { createCanvasElement } from "./utils.js"; - -export { default as IESSpotLight } from "./lights/webgpu/IESSpotLight.js"; -export { default as NodeLoader } from "./loaders/nodes/NodeLoader.js"; -export { default as NodeMaterialLoader } from "./loaders/nodes/NodeMaterialLoader.js"; -export { default as NodeObjectLoader } from "./loaders/nodes/NodeObjectLoader.js"; -export * from "./nodes/Nodes.js"; -export * from "./nodes/TSL.js"; -export { default as PMREMGenerator } from "./renderers/common/extras/PMREMGenerator.js"; -export { default as PostProcessing } from "./renderers/common/PostProcessing.js"; -import * as PostProcessingUtils from "./renderers/common/PostProcessingUtils.js"; -export { PostProcessingUtils }; -export { default as IndirectStorageBufferAttribute } from "./renderers/common/IndirectStorageBufferAttribute.js"; -export { default as Lighting } from "./renderers/common/Lighting.js"; -export { default as QuadMesh } from "./renderers/common/QuadMesh.js"; -export type { default as Renderer } from "./renderers/common/Renderer.js"; -export { default as StorageBufferAttribute } from "./renderers/common/StorageBufferAttribute.js"; -export { default as StorageInstancedBufferAttribute } from "./renderers/common/StorageInstancedBufferAttribute.js"; -export { default as StorageTexture } from "./renderers/common/StorageTexture.js"; -export { default as WebGPURenderer } from "./renderers/webgpu/WebGPURenderer.Nodes.js"; diff --git a/src-testing/src/Three.WebGPU.d.ts b/src-testing/src/Three.WebGPU.d.ts deleted file mode 100644 index 254ef5332..000000000 --- a/src-testing/src/Three.WebGPU.d.ts +++ /dev/null @@ -1,206 +0,0 @@ -export * from "./animation/AnimationAction.js"; -export * from "./animation/AnimationClip.js"; -export * from "./animation/AnimationMixer.js"; -export * from "./animation/AnimationObjectGroup.js"; -export { AnimationUtils } from "./animation/AnimationUtils.js"; -export * from "./animation/KeyframeTrack.js"; -export * from "./animation/PropertyBinding.js"; -export * from "./animation/PropertyMixer.js"; -export * from "./animation/tracks/BooleanKeyframeTrack.js"; -export * from "./animation/tracks/ColorKeyframeTrack.js"; -export * from "./animation/tracks/NumberKeyframeTrack.js"; -export * from "./animation/tracks/QuaternionKeyframeTrack.js"; -export * from "./animation/tracks/StringKeyframeTrack.js"; -export * from "./animation/tracks/VectorKeyframeTrack.js"; -export * from "./audio/Audio.js"; -export * from "./audio/AudioAnalyser.js"; -export * from "./audio/AudioContext.js"; -export * from "./audio/AudioListener.js"; -export * from "./audio/PositionalAudio.js"; -export * from "./cameras/ArrayCamera.js"; -export * from "./cameras/Camera.js"; -export * from "./cameras/CubeCamera.js"; -export * from "./cameras/OrthographicCamera.js"; -export * from "./cameras/PerspectiveCamera.js"; -export * from "./cameras/StereoCamera.js"; -export * from "./constants.js"; -export * from "./core/BufferAttribute.js"; -export * from "./core/BufferGeometry.js"; -export * from "./core/Clock.js"; -export * from "./core/EventDispatcher.js"; -export * from "./core/GLBufferAttribute.js"; -export * from "./core/InstancedBufferAttribute.js"; -export * from "./core/InstancedBufferGeometry.js"; -export * from "./core/InstancedInterleavedBuffer.js"; -export * from "./core/InterleavedBuffer.js"; -export * from "./core/InterleavedBufferAttribute.js"; -export * from "./core/Layers.js"; -export * from "./core/Object3D.js"; -export * from "./core/Raycaster.js"; -export * from "./core/RenderTarget.js"; -export * from "./core/Uniform.js"; -export * from "./core/UniformsGroup.js"; -export * from "./extras/Controls.js"; -export * from "./extras/core/Curve.js"; -export * from "./extras/core/CurvePath.js"; -export * from "./extras/core/Path.js"; -export * from "./extras/core/Shape.js"; -export * from "./extras/core/ShapePath.js"; -export * from "./extras/curves/Curves.js"; -export { DataUtils } from "./extras/DataUtils.js"; -export * from "./extras/ImageUtils.js"; -// export * from "./extras/PMREMGenerator.js"; -export * from "./extras/ShapeUtils.js"; -export { TextureUtils } from "./extras/TextureUtils.js"; -export * from "./geometries/Geometries.js"; -export * from "./helpers/ArrowHelper.js"; -export * from "./helpers/AxesHelper.js"; -export * from "./helpers/Box3Helper.js"; -export * from "./helpers/BoxHelper.js"; -export * from "./helpers/CameraHelper.js"; -export * from "./helpers/DirectionalLightHelper.js"; -export * from "./helpers/GridHelper.js"; -export * from "./helpers/HemisphereLightHelper.js"; -export * from "./helpers/PlaneHelper.js"; -export * from "./helpers/PointLightHelper.js"; -export * from "./helpers/PolarGridHelper.js"; -export * from "./helpers/SkeletonHelper.js"; -export * from "./helpers/SpotLightHelper.js"; -export * from "./lights/AmbientLight.js"; -export * from "./lights/DirectionalLight.js"; -export type { DirectionalLightShadow } from "./lights/DirectionalLightShadow.js"; -export * from "./lights/HemisphereLight.js"; -export * from "./lights/Light.js"; -export * from "./lights/LightProbe.js"; -export type { LightShadow, LightShadowJSON } from "./lights/LightShadow.js"; -export * from "./lights/PointLight.js"; -export type { PointLightShadow } from "./lights/PointLightShadow.js"; -export * from "./lights/RectAreaLight.js"; -export * from "./lights/SpotLight.js"; -export type { SpotLightShadow } from "./lights/SpotLightShadow.js"; -export * from "./loaders/AnimationLoader.js"; -export * from "./loaders/AudioLoader.js"; -export * from "./loaders/BufferGeometryLoader.js"; -export * from "./loaders/Cache.js"; -export * from "./loaders/CompressedTextureLoader.js"; -export * from "./loaders/CubeTextureLoader.js"; -export * from "./loaders/DataTextureLoader.js"; -export * from "./loaders/FileLoader.js"; -export * from "./loaders/ImageBitmapLoader.js"; -export * from "./loaders/ImageLoader.js"; -export * from "./loaders/Loader.js"; -export * from "./loaders/LoaderUtils.js"; -export * from "./loaders/LoadingManager.js"; -export * from "./loaders/MaterialLoader.js"; -export * from "./loaders/ObjectLoader.js"; -export * from "./loaders/TextureLoader.js"; -export * from "./materials/Materials.js"; -export * from "./math/Box2.js"; -export * from "./math/Box3.js"; -export * from "./math/Color.js"; -export { ColorManagement, ColorSpaceDefinition } from "./math/ColorManagement.js"; -export * from "./math/Cylindrical.js"; -export * from "./math/Euler.js"; -export * from "./math/Frustum.js"; -export * from "./math/Interpolant.js"; -export * from "./math/interpolants/CubicInterpolant.js"; -export * from "./math/interpolants/DiscreteInterpolant.js"; -export * from "./math/interpolants/LinearInterpolant.js"; -export * from "./math/interpolants/QuaternionLinearInterpolant.js"; -export * from "./math/Line3.js"; -export { MathUtils } from "./math/MathUtils.js"; -export * from "./math/Matrix2.js"; -export * from "./math/Matrix3.js"; -export * from "./math/Matrix4.js"; -export * from "./math/Plane.js"; -export * from "./math/Quaternion.js"; -export * from "./math/Ray.js"; -export * from "./math/Sphere.js"; -export * from "./math/Spherical.js"; -export * from "./math/SphericalHarmonics3.js"; -export * from "./math/Triangle.js"; -export * from "./math/Vector2.js"; -export * from "./math/Vector3.js"; -export * from "./math/Vector4.js"; -export * from "./objects/BatchedMesh.js"; -export * from "./objects/Bone.js"; -export * from "./objects/Group.js"; -export * from "./objects/InstancedMesh.js"; -export * from "./objects/Line.js"; -export * from "./objects/LineLoop.js"; -export * from "./objects/LineSegments.js"; -export * from "./objects/LOD.js"; -export * from "./objects/Mesh.js"; -export * from "./objects/Points.js"; -export * from "./objects/Skeleton.js"; -export * from "./objects/SkinnedMesh.js"; -export * from "./objects/Sprite.js"; -// export * from "./renderers/shaders/ShaderChunk.js"; -// export * from "./renderers/shaders/ShaderLib.js"; -// export * from "./renderers/shaders/UniformsLib.js"; -// export { UniformsUtils } from './renderers/shaders/UniformsUtils.js'; -export type { WebGLProgramParameters, WebGLProgramParametersWithUniforms } from "./renderers/webgl/WebGLPrograms.js"; -export type { WebGLShadowMap } from "./renderers/webgl/WebGLShadowMap.js"; -// export * from "./renderers/webgl/WebGLUtils.js"; -export * from "./renderers/WebGL3DRenderTarget.js"; -export * from "./renderers/WebGLArrayRenderTarget.js"; -export * from "./renderers/WebGLCubeRenderTarget.js"; -// export * from "./renderers/WebGLRenderer.js"; -export * from "./renderers/WebGLRenderTarget.js"; -export type { - WebXRController, - WebXRSpaceEventMap, - XRControllerEventType, - XRGripSpace, - XRHandInputState, - XRHandJoints, - XRHandSpace, - XRJointSpace, - XRTargetRaySpace, -} from "./renderers/webxr/WebXRController.js"; -export type { WebXRDepthSensing } from "./renderers/webxr/WebXRDepthSensing.js"; -export type { - WebXRArrayCamera, - WebXRCamera, - WebXRManager, - WebXRManagerEventMap, -} from "./renderers/webxr/WebXRManager.js"; -export * from "./scenes/Fog.js"; -export * from "./scenes/FogExp2.js"; -export * from "./scenes/Scene.js"; -export * from "./textures/CanvasTexture.js"; -export * from "./textures/CompressedArrayTexture.js"; -export * from "./textures/CompressedCubeTexture.js"; -export * from "./textures/CompressedTexture.js"; -export * from "./textures/CubeTexture.js"; -export * from "./textures/Data3DTexture.js"; -export * from "./textures/DataArrayTexture.js"; -export * from "./textures/DataTexture.js"; -export * from "./textures/DepthTexture.js"; -export * from "./textures/FramebufferTexture.js"; -export * from "./textures/Source.js"; -export * from "./textures/Texture.js"; -export * from "./textures/VideoTexture.js"; -export * from "./Three.Legacy.js"; -export { createCanvasElement } from "./utils.js"; - -export { default as IESSpotLight } from "./lights/webgpu/IESSpotLight.js"; -export { default as NodeLoader } from "./loaders/nodes/NodeLoader.js"; -export { default as NodeMaterialLoader } from "./loaders/nodes/NodeMaterialLoader.js"; -export { default as NodeObjectLoader } from "./loaders/nodes/NodeObjectLoader.js"; -export * from "./materials/nodes/NodeMaterials.js"; -export * from "./nodes/Nodes.js"; -export * from "./nodes/TSL.js"; -export { default as BundleGroup } from "./renderers/common/BundleGroup.js"; -export { default as PMREMGenerator } from "./renderers/common/extras/PMREMGenerator.js"; -export { default as PostProcessing } from "./renderers/common/PostProcessing.js"; -import * as PostProcessingUtils from "./renderers/common/PostProcessingUtils.js"; -export { PostProcessingUtils }; -export { default as IndirectStorageBufferAttribute } from "./renderers/common/IndirectStorageBufferAttribute.js"; -export { default as Lighting } from "./renderers/common/Lighting.js"; -export { default as QuadMesh } from "./renderers/common/QuadMesh.js"; -export type { default as Renderer } from "./renderers/common/Renderer.js"; -export { default as StorageBufferAttribute } from "./renderers/common/StorageBufferAttribute.js"; -export { default as StorageInstancedBufferAttribute } from "./renderers/common/StorageInstancedBufferAttribute.js"; -export { default as StorageTexture } from "./renderers/common/StorageTexture.js"; -export { default as WebGPURenderer } from "./renderers/webgpu/WebGPURenderer.js"; diff --git a/src-testing/src/Three.d.ts b/src-testing/src/Three.d.ts deleted file mode 100644 index ade1c92b9..000000000 --- a/src-testing/src/Three.d.ts +++ /dev/null @@ -1,214 +0,0 @@ -export * from "./animation/AnimationAction.js"; -export * from "./animation/AnimationClip.js"; -export * from "./animation/AnimationMixer.js"; -export * from "./animation/AnimationObjectGroup.js"; -export { AnimationUtils } from "./animation/AnimationUtils.js"; -export * from "./animation/KeyframeTrack.js"; -export * from "./animation/PropertyBinding.js"; -export * from "./animation/PropertyMixer.js"; -export * from "./animation/tracks/BooleanKeyframeTrack.js"; -export * from "./animation/tracks/ColorKeyframeTrack.js"; -export * from "./animation/tracks/NumberKeyframeTrack.js"; -export * from "./animation/tracks/QuaternionKeyframeTrack.js"; -export * from "./animation/tracks/StringKeyframeTrack.js"; -export * from "./animation/tracks/VectorKeyframeTrack.js"; -export * from "./audio/Audio.js"; -export * from "./audio/AudioAnalyser.js"; -export * from "./audio/AudioContext.js"; -export * from "./audio/AudioListener.js"; -export * from "./audio/PositionalAudio.js"; -export * from "./cameras/ArrayCamera.js"; -export * from "./cameras/Camera.js"; -export * from "./cameras/CubeCamera.js"; -export * from "./cameras/OrthographicCamera.js"; -export * from "./cameras/PerspectiveCamera.js"; -export * from "./cameras/StereoCamera.js"; -export * from "./constants.js"; -export * from "./core/BufferAttribute.js"; -export * from "./core/BufferGeometry.js"; -export * from "./core/Clock.js"; -export * from "./core/EventDispatcher.js"; -export * from "./core/GLBufferAttribute.js"; -export * from "./core/InstancedBufferAttribute.js"; -export * from "./core/InstancedBufferGeometry.js"; -export * from "./core/InstancedInterleavedBuffer.js"; -export * from "./core/InterleavedBuffer.js"; -export * from "./core/InterleavedBufferAttribute.js"; -export * from "./core/Layers.js"; -export * from "./core/Object3D.js"; -export * from "./core/Raycaster.js"; -export * from "./core/RenderTarget.js"; -export * from "./core/Uniform.js"; -export * from "./core/UniformsGroup.js"; -export * from "./extras/Controls.js"; -export * from "./extras/core/Curve.js"; -export * from "./extras/core/CurvePath.js"; -export * from "./extras/core/Path.js"; -export * from "./extras/core/Shape.js"; -export * from "./extras/core/ShapePath.js"; -export * from "./extras/curves/Curves.js"; -export { DataUtils } from "./extras/DataUtils.js"; -export * from "./extras/ImageUtils.js"; -export * from "./extras/PMREMGenerator.js"; -export * from "./extras/ShapeUtils.js"; -export { TextureUtils } from "./extras/TextureUtils.js"; -export * from "./geometries/Geometries.js"; -export * from "./helpers/ArrowHelper.js"; -export * from "./helpers/AxesHelper.js"; -export * from "./helpers/Box3Helper.js"; -export * from "./helpers/BoxHelper.js"; -export * from "./helpers/CameraHelper.js"; -export * from "./helpers/DirectionalLightHelper.js"; -export * from "./helpers/GridHelper.js"; -export * from "./helpers/HemisphereLightHelper.js"; -export * from "./helpers/PlaneHelper.js"; -export * from "./helpers/PointLightHelper.js"; -export * from "./helpers/PolarGridHelper.js"; -export * from "./helpers/SkeletonHelper.js"; -export * from "./helpers/SpotLightHelper.js"; -export * from "./lights/AmbientLight.js"; -export * from "./lights/DirectionalLight.js"; -export type { DirectionalLightShadow } from "./lights/DirectionalLightShadow.js"; -export * from "./lights/HemisphereLight.js"; -export * from "./lights/Light.js"; -export * from "./lights/LightProbe.js"; -export type { LightShadow, LightShadowJSON } from "./lights/LightShadow.js"; -export * from "./lights/PointLight.js"; -export type { PointLightShadow } from "./lights/PointLightShadow.js"; -export * from "./lights/RectAreaLight.js"; -export * from "./lights/SpotLight.js"; -export type { SpotLightShadow } from "./lights/SpotLightShadow.js"; -export * from "./loaders/AnimationLoader.js"; -export * from "./loaders/AudioLoader.js"; -export * from "./loaders/BufferGeometryLoader.js"; -export * from "./loaders/Cache.js"; -export * from "./loaders/CompressedTextureLoader.js"; -export * from "./loaders/CubeTextureLoader.js"; -export * from "./loaders/DataTextureLoader.js"; -export * from "./loaders/FileLoader.js"; -export * from "./loaders/ImageBitmapLoader.js"; -export * from "./loaders/ImageLoader.js"; -export * from "./loaders/Loader.js"; -export * from "./loaders/LoaderUtils.js"; -export * from "./loaders/LoadingManager.js"; -export * from "./loaders/MaterialLoader.js"; -export * from "./loaders/ObjectLoader.js"; -export * from "./loaders/TextureLoader.js"; -export * from "./materials/Materials.js"; -export * from "./math/Box2.js"; -export * from "./math/Box3.js"; -export * from "./math/Color.js"; -export { ColorManagement, ColorSpaceDefinition } from "./math/ColorManagement.js"; -export * from "./math/Cylindrical.js"; -export * from "./math/Euler.js"; -export * from "./math/Frustum.js"; -export * from "./math/Interpolant.js"; -export * from "./math/interpolants/CubicInterpolant.js"; -export * from "./math/interpolants/DiscreteInterpolant.js"; -export * from "./math/interpolants/LinearInterpolant.js"; -export * from "./math/interpolants/QuaternionLinearInterpolant.js"; -export * from "./math/Line3.js"; -export { MathUtils } from "./math/MathUtils.js"; -export * from "./math/Matrix2.js"; -export * from "./math/Matrix3.js"; -export * from "./math/Matrix4.js"; -export * from "./math/Plane.js"; -export * from "./math/Quaternion.js"; -export * from "./math/Ray.js"; -export * from "./math/Sphere.js"; -export * from "./math/Spherical.js"; -export * from "./math/SphericalHarmonics3.js"; -export * from "./math/Triangle.js"; -export * from "./math/Vector2.js"; -export * from "./math/Vector3.js"; -export * from "./math/Vector4.js"; -export * from "./objects/BatchedMesh.js"; -export * from "./objects/Bone.js"; -export * from "./objects/Group.js"; -export * from "./objects/InstancedMesh.js"; -export * from "./objects/Line.js"; -export * from "./objects/LineLoop.js"; -export * from "./objects/LineSegments.js"; -export * from "./objects/LOD.js"; -export * from "./objects/Mesh.js"; -export * from "./objects/Points.js"; -export * from "./objects/Skeleton.js"; -export * from "./objects/SkinnedMesh.js"; -export * from "./objects/Sprite.js"; -export * from "./renderers/shaders/ShaderChunk.js"; -export * from "./renderers/shaders/ShaderLib.js"; -export * from "./renderers/shaders/UniformsLib.js"; -export { UniformsUtils } from "./renderers/shaders/UniformsUtils.js"; -export type { WebGLAttributes } from "./renderers/webgl/WebGLAttributes.js"; -export type { WebGLBindingStates } from "./renderers/webgl/WebGLBindingStates.js"; -export type { WebGLBufferRenderer } from "./renderers/webgl/WebGLBufferRenderer.js"; -export type { WebGLCapabilities, WebGLCapabilitiesParameters } from "./renderers/webgl/WebGLCapabilities.js"; -export type { WebGLClipping } from "./renderers/webgl/WebGLClipping.js"; -export type { WebGLCubeMaps } from "./renderers/webgl/WebGLCubeMaps.js"; -export type { WebGLCubeUVMaps } from "./renderers/webgl/WebGLCubeUVMaps.js"; -export type { WebGLExtensions } from "./renderers/webgl/WebGLExtensions.js"; -export type { WebGLGeometries } from "./renderers/webgl/WebGLGeometries.js"; -export type { WebGLIndexedBufferRenderer } from "./renderers/webgl/WebGLIndexedBufferRenderer.js"; -export type { WebGLInfo } from "./renderers/webgl/WebGLInfo.js"; -export type { WebGLLights, WebGLLightsState } from "./renderers/webgl/WebGLLights.js"; -export type { WebGLObjects } from "./renderers/webgl/WebGLObjects.js"; -export type { WebGLProgram } from "./renderers/webgl/WebGLProgram.js"; -export type { - WebGLProgramParameters, - WebGLProgramParametersWithUniforms, - WebGLPrograms, -} from "./renderers/webgl/WebGLPrograms.js"; -export type { WebGLProperties } from "./renderers/webgl/WebGLProperties.js"; -export type { RenderItem, WebGLRenderList, WebGLRenderLists } from "./renderers/webgl/WebGLRenderLists.js"; -export type { WebGLShader } from "./renderers/webgl/WebGLShader.js"; -export type { WebGLShadowMap } from "./renderers/webgl/WebGLShadowMap.js"; -export type { - WebGLColorBuffer, - WebGLDepthBuffer, - WebGLState, - WebGLStencilBuffer, -} from "./renderers/webgl/WebGLState.js"; -export type { WebGLTextures } from "./renderers/webgl/WebGLTextures.js"; -export type { WebGLUniforms } from "./renderers/webgl/WebGLUniforms.js"; -export * from "./renderers/webgl/WebGLUtils.js"; -export * from "./renderers/WebGL3DRenderTarget.js"; -export * from "./renderers/WebGLArrayRenderTarget.js"; -export * from "./renderers/WebGLCubeRenderTarget.js"; -export * from "./renderers/WebGLRenderer.js"; -export * from "./renderers/WebGLRenderTarget.js"; -export type { - WebXRController, - WebXRSpaceEventMap, - XRControllerEventType, - XRGripSpace, - XRHandInputState, - XRHandJoints, - XRHandSpace, - XRJointSpace, - XRTargetRaySpace, -} from "./renderers/webxr/WebXRController.js"; -export type { WebXRDepthSensing } from "./renderers/webxr/WebXRDepthSensing.js"; -export type { - WebXRArrayCamera, - WebXRCamera, - WebXRManager, - WebXRManagerEventMap, -} from "./renderers/webxr/WebXRManager.js"; -export * from "./scenes/Fog.js"; -export * from "./scenes/FogExp2.js"; -export * from "./scenes/Scene.js"; -export * from "./textures/CanvasTexture.js"; -export * from "./textures/CompressedArrayTexture.js"; -export * from "./textures/CompressedCubeTexture.js"; -export * from "./textures/CompressedTexture.js"; -export * from "./textures/CubeTexture.js"; -export * from "./textures/Data3DTexture.js"; -export * from "./textures/DataArrayTexture.js"; -export * from "./textures/DataTexture.js"; -export * from "./textures/DepthTexture.js"; -export * from "./textures/FramebufferTexture.js"; -export * from "./textures/Source.js"; -export * from "./textures/Texture.js"; -export * from "./textures/VideoTexture.js"; -export * from "./Three.Legacy.js"; -export { createCanvasElement } from "./utils.js"; diff --git a/src-testing/src/animation/AnimationAction.d.ts b/src-testing/src/animation/AnimationAction.d.ts deleted file mode 100644 index 3fa3852a2..000000000 --- a/src-testing/src/animation/AnimationAction.d.ts +++ /dev/null @@ -1,86 +0,0 @@ -import { AnimationActionLoopStyles, AnimationBlendMode } from "../constants.js"; -import { Object3D } from "../core/Object3D.js"; -import { AnimationClip } from "./AnimationClip.js"; -import { AnimationMixer } from "./AnimationMixer.js"; -// Animation //////////////////////////////////////////////////////////////////////////////////////// - -export class AnimationAction { - constructor(mixer: AnimationMixer, clip: AnimationClip, localRoot?: Object3D, blendMode?: AnimationBlendMode); - - blendMode: AnimationBlendMode; - - /** - * @default THREE.LoopRepeat - */ - loop: AnimationActionLoopStyles; - - /** - * @default 0 - */ - time: number; - - /** - * @default 1 - */ - timeScale: number; - - /** - * @default 1 - */ - weight: number; - - /** - * @default Infinity - */ - repetitions: number; - - /** - * @default false - */ - paused: boolean; - - /** - * @default true - */ - enabled: boolean; - - /** - * @default false - */ - clampWhenFinished: boolean; - - /** - * @default true - */ - zeroSlopeAtStart: boolean; - - /** - * @default true - */ - zeroSlopeAtEnd: boolean; - - play(): AnimationAction; - stop(): AnimationAction; - reset(): AnimationAction; - isRunning(): boolean; - isScheduled(): boolean; - startAt(time: number): AnimationAction; - setLoop(mode: AnimationActionLoopStyles, repetitions: number): AnimationAction; - setEffectiveWeight(weight: number): AnimationAction; - getEffectiveWeight(): number; - fadeIn(duration: number): AnimationAction; - fadeOut(duration: number): AnimationAction; - crossFadeFrom(fadeOutAction: AnimationAction, duration: number, warp: boolean): AnimationAction; - crossFadeTo(fadeInAction: AnimationAction, duration: number, warp: boolean): AnimationAction; - stopFading(): AnimationAction; - setEffectiveTimeScale(timeScale: number): AnimationAction; - getEffectiveTimeScale(): number; - setDuration(duration: number): AnimationAction; - syncWith(action: AnimationAction): AnimationAction; - halt(duration: number): AnimationAction; - warp(statTimeScale: number, endTimeScale: number, duration: number): AnimationAction; - stopWarping(): AnimationAction; - getMixer(): AnimationMixer; - getClip(): AnimationClip; - getRoot(): Object3D; -} diff --git a/src-testing/src/animation/AnimationClip.d.ts b/src-testing/src/animation/AnimationClip.d.ts deleted file mode 100644 index 4efc3df72..000000000 --- a/src-testing/src/animation/AnimationClip.d.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { AnimationBlendMode } from "../constants.js"; -import { Vector3 } from "../math/Vector3.js"; -import { Bone } from "../objects/Bone.js"; -import { KeyframeTrack, KeyframeTrackJSON } from "./KeyframeTrack.js"; - -export interface AnimationClipJSON { - name: string; - duration: number; - tracks: KeyframeTrackJSON[]; - uuid: string; - blendMode: AnimationBlendMode; -} - -export interface MorphTarget { - name: string; - vertices: Vector3[]; -} - -export class AnimationClip { - constructor(name?: string, duration?: number, tracks?: KeyframeTrack[], blendMode?: AnimationBlendMode); - - name: string; - tracks: KeyframeTrack[]; - - /** - * @default THREE.NormalAnimationBlendMode - */ - blendMode: AnimationBlendMode; - - /** - * @default -1 - */ - duration: number; - uuid: string; - results: any[]; - - resetDuration(): AnimationClip; - trim(): AnimationClip; - validate(): boolean; - optimize(): AnimationClip; - clone(): this; - toJSON(clip: AnimationClip): any; - - static CreateFromMorphTargetSequence( - name: string, - morphTargetSequence: MorphTarget[], - fps: number, - noLoop: boolean, - ): AnimationClip; - static findByName(clipArray: AnimationClip[], name: string): AnimationClip; - static CreateClipsFromMorphTargetSequences( - morphTargets: MorphTarget[], - fps: number, - noLoop: boolean, - ): AnimationClip[]; - static parse(json: AnimationClipJSON): AnimationClip; - static parseAnimation(animation: AnimationClipJSON, bones: Bone[]): AnimationClip; - static toJSON(clip: AnimationClip): AnimationClipJSON; -} diff --git a/src-testing/src/animation/AnimationMixer.d.ts b/src-testing/src/animation/AnimationMixer.d.ts deleted file mode 100644 index 95712d893..000000000 --- a/src-testing/src/animation/AnimationMixer.d.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { AnimationBlendMode } from "../constants.js"; -import { EventDispatcher } from "../core/EventDispatcher.js"; -import { Object3D } from "../core/Object3D.js"; -import { AnimationAction } from "./AnimationAction.js"; -import { AnimationClip } from "./AnimationClip.js"; -import { AnimationObjectGroup } from "./AnimationObjectGroup.js"; - -export interface AnimationMixerEventMap { - loop: { action: AnimationAction; loopDelta: number }; - finished: { action: AnimationAction; direction: number }; -} - -export class AnimationMixer extends EventDispatcher { - constructor(root: Object3D | AnimationObjectGroup); - - /** - * @default 0 - */ - time: number; - - /** - * @default 1.0 - */ - timeScale: number; - - clipAction( - clip: AnimationClip, - root?: Object3D | AnimationObjectGroup, - blendMode?: AnimationBlendMode, - ): AnimationAction; - existingAction(clip: AnimationClip, root?: Object3D | AnimationObjectGroup): AnimationAction | null; - stopAllAction(): AnimationMixer; - update(deltaTime: number): AnimationMixer; - setTime(timeInSeconds: number): AnimationMixer; - getRoot(): Object3D | AnimationObjectGroup; - uncacheClip(clip: AnimationClip): void; - uncacheRoot(root: Object3D | AnimationObjectGroup): void; - uncacheAction(clip: AnimationClip, root?: Object3D | AnimationObjectGroup): void; -} diff --git a/src-testing/src/animation/AnimationObjectGroup.d.ts b/src-testing/src/animation/AnimationObjectGroup.d.ts deleted file mode 100644 index 9d4f29ca9..000000000 --- a/src-testing/src/animation/AnimationObjectGroup.d.ts +++ /dev/null @@ -1,17 +0,0 @@ -export class AnimationObjectGroup { - constructor(...args: any[]); - - uuid: string; - stats: { - bindingsPerObject: number; - objects: { - total: number; - inUse: number; - }; - }; - readonly isAnimationObjectGroup: true; - - add(...args: any[]): void; - remove(...args: any[]): void; - uncache(...args: any[]): void; -} diff --git a/src-testing/src/animation/AnimationUtils.d.ts b/src-testing/src/animation/AnimationUtils.d.ts deleted file mode 100644 index 4a712ed30..000000000 --- a/src-testing/src/animation/AnimationUtils.d.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { AnimationClip } from "./AnimationClip.js"; - -declare function convertArray(array: any, type: any, forceClone: boolean): any; - -declare function isTypedArray(object: any): boolean; - -declare function getKeyframeOrder(times: number[]): number[]; - -declare function sortedArray(values: any[], stride: number, order: number[]): any[]; - -declare function flattenJSON(jsonKeys: string[], times: any[], values: any[], valuePropertyName: string): void; - -/** - * @param sourceClip - * @param name - * @param startFrame - * @param endFrame - * @param [fps=30] - */ -declare function subclip( - sourceClip: AnimationClip, - name: string, - startFrame: number, - endFrame: number, - fps?: number, -): AnimationClip; - -/** - * @param targetClip - * @param [referenceFrame=0] - * @param [referenceClip=targetClip] - * @param [fps=30] - */ -declare function makeClipAdditive( - targetClip: AnimationClip, - referenceFrame?: number, - referenceClip?: AnimationClip, - fps?: number, -): AnimationClip; - -declare const AnimationUtils: { - convertArray: typeof convertArray; - isTypedArray: typeof isTypedArray; - getKeyframeOrder: typeof getKeyframeOrder; - sortedArray: typeof sortedArray; - flattenJSON: typeof flattenJSON; - subclip: typeof subclip; - makeClipAdditive: typeof makeClipAdditive; -}; - -export { - AnimationUtils, - convertArray, - flattenJSON, - getKeyframeOrder, - isTypedArray, - makeClipAdditive, - sortedArray, - subclip, -}; diff --git a/src-testing/src/animation/KeyframeTrack.d.ts b/src-testing/src/animation/KeyframeTrack.d.ts deleted file mode 100644 index 2a48e2651..000000000 --- a/src-testing/src/animation/KeyframeTrack.d.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { InterpolationModes } from "../constants.js"; -import { Interpolant } from "../math/Interpolant.js"; -import { CubicInterpolant } from "../math/interpolants/CubicInterpolant.js"; -import { DiscreteInterpolant } from "../math/interpolants/DiscreteInterpolant.js"; -import { LinearInterpolant } from "../math/interpolants/LinearInterpolant.js"; - -export interface KeyframeTrackJSON { - name: string; - times: number[]; - values: number[]; - interpolation?: InterpolationModes; - type: string; -} - -export class KeyframeTrack { - /** - * @param name - * @param times - * @param values - * @param [interpolation=THREE.InterpolateLinear] - */ - constructor(name: string, times: ArrayLike, values: ArrayLike, interpolation?: InterpolationModes); - - name: string; - times: Float32Array; - values: Float32Array; - - ValueTypeName: string; - TimeBufferType: Float32Array; - ValueBufferType: Float32Array; - - /** - * @default THREE.InterpolateLinear - */ - DefaultInterpolation: InterpolationModes; - - InterpolantFactoryMethodDiscrete(result: any): DiscreteInterpolant; - InterpolantFactoryMethodLinear(result: any): LinearInterpolant; - InterpolantFactoryMethodSmooth(result: any): CubicInterpolant; - - setInterpolation(interpolation: InterpolationModes): KeyframeTrack; - getInterpolation(): InterpolationModes; - createInterpolant(): Interpolant; - - getValueSize(): number; - - shift(timeOffset: number): KeyframeTrack; - scale(timeScale: number): KeyframeTrack; - trim(startTime: number, endTime: number): KeyframeTrack; - validate(): boolean; - optimize(): KeyframeTrack; - clone(): this; - - static toJSON(track: KeyframeTrack): KeyframeTrackJSON; -} diff --git a/src-testing/src/animation/PropertyBinding.d.ts b/src-testing/src/animation/PropertyBinding.d.ts deleted file mode 100644 index fec777634..000000000 --- a/src-testing/src/animation/PropertyBinding.d.ts +++ /dev/null @@ -1,43 +0,0 @@ -export interface ParseTrackNameResults { - nodeName: string; - objectName: string; - objectIndex: string; - propertyName: string; - propertyIndex: string; -} - -declare class Composite { - constructor(targetGroup: any, path: any, parsedPath?: any); - - getValue(array: any, offset: number): any; - setValue(array: any, offset: number): void; - bind(): void; - unbind(): void; -} - -declare class PropertyBinding { - constructor(rootNode: any, path: string, parsedPath?: any); - - path: string; - parsedPath: any; - node: any; - rootNode: any; - - getValue(targetArray: any, offset: number): any; - setValue(sourceArray: any, offset: number): void; - bind(): void; - unbind(): void; - - BindingType: { [bindingType: string]: number }; - Versioning: { [versioning: string]: number }; - - GetterByBindingType: Array<() => void>; - SetterByBindingTypeAndVersioning: Array void>>; - - static create(root: any, path: any, parsedPath?: any): PropertyBinding | Composite; - static sanitizeNodeName(name: string): string; - static parseTrackName(trackName: string): ParseTrackNameResults; - static findNode(root: any, nodeName: string): any; -} - -export { PropertyBinding }; diff --git a/src-testing/src/animation/PropertyMixer.d.ts b/src-testing/src/animation/PropertyMixer.d.ts deleted file mode 100644 index f413291fa..000000000 --- a/src-testing/src/animation/PropertyMixer.d.ts +++ /dev/null @@ -1,17 +0,0 @@ -export class PropertyMixer { - constructor(binding: any, typeName: string, valueSize: number); - - binding: any; - valueSize: number; - buffer: any; - cumulativeWeight: number; - cumulativeWeightAdditive: number; - useCount: number; - referenceCount: number; - - accumulate(accuIndex: number, weight: number): void; - accumulateAdditive(weight: number): void; - apply(accuIndex: number): void; - saveOriginalState(): void; - restoreOriginalState(): void; -} diff --git a/src-testing/src/animation/tracks/BooleanKeyframeTrack.d.ts b/src-testing/src/animation/tracks/BooleanKeyframeTrack.d.ts deleted file mode 100644 index 45b65448a..000000000 --- a/src-testing/src/animation/tracks/BooleanKeyframeTrack.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { KeyframeTrack } from "../KeyframeTrack.js"; - -export class BooleanKeyframeTrack extends KeyframeTrack { - constructor(name: string, times: ArrayLike, values: ArrayLike); - - /** - * @default 'bool' - */ - ValueTypeName: string; -} diff --git a/src-testing/src/animation/tracks/ColorKeyframeTrack.d.ts b/src-testing/src/animation/tracks/ColorKeyframeTrack.d.ts deleted file mode 100644 index 60d0fe9f7..000000000 --- a/src-testing/src/animation/tracks/ColorKeyframeTrack.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { InterpolationModes } from "../../constants.js"; -import { KeyframeTrack } from "../KeyframeTrack.js"; - -export class ColorKeyframeTrack extends KeyframeTrack { - constructor(name: string, times: ArrayLike, values: ArrayLike, interpolation?: InterpolationModes); - - /** - * @default 'color' - */ - ValueTypeName: string; -} diff --git a/src-testing/src/animation/tracks/NumberKeyframeTrack.d.ts b/src-testing/src/animation/tracks/NumberKeyframeTrack.d.ts deleted file mode 100644 index e27ff0337..000000000 --- a/src-testing/src/animation/tracks/NumberKeyframeTrack.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { InterpolationModes } from "../../constants.js"; -import { KeyframeTrack } from "../KeyframeTrack.js"; - -export class NumberKeyframeTrack extends KeyframeTrack { - constructor(name: string, times: ArrayLike, values: ArrayLike, interpolation?: InterpolationModes); - - /** - * @default 'number' - */ - ValueTypeName: string; -} diff --git a/src-testing/src/animation/tracks/QuaternionKeyframeTrack.d.ts b/src-testing/src/animation/tracks/QuaternionKeyframeTrack.d.ts deleted file mode 100644 index 29942bad5..000000000 --- a/src-testing/src/animation/tracks/QuaternionKeyframeTrack.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { InterpolationModes } from "../../constants.js"; -import { KeyframeTrack } from "../KeyframeTrack.js"; - -export class QuaternionKeyframeTrack extends KeyframeTrack { - constructor(name: string, times: ArrayLike, values: ArrayLike, interpolation?: InterpolationModes); - - /** - * @default 'quaternion' - */ - ValueTypeName: string; -} diff --git a/src-testing/src/animation/tracks/StringKeyframeTrack.d.ts b/src-testing/src/animation/tracks/StringKeyframeTrack.d.ts deleted file mode 100644 index 9bbfd2027..000000000 --- a/src-testing/src/animation/tracks/StringKeyframeTrack.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { KeyframeTrack } from "../KeyframeTrack.js"; - -export class StringKeyframeTrack extends KeyframeTrack { - constructor(name: string, times: ArrayLike, values: ArrayLike); - - /** - * @default 'string' - */ - ValueTypeName: string; -} diff --git a/src-testing/src/animation/tracks/VectorKeyframeTrack.d.ts b/src-testing/src/animation/tracks/VectorKeyframeTrack.d.ts deleted file mode 100644 index 0909d4493..000000000 --- a/src-testing/src/animation/tracks/VectorKeyframeTrack.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { InterpolationModes } from "../../constants.js"; -import { KeyframeTrack } from "../KeyframeTrack.js"; - -export class VectorKeyframeTrack extends KeyframeTrack { - constructor(name: string, times: ArrayLike, values: ArrayLike, interpolation?: InterpolationModes); - - /** - * @default 'vector' - */ - ValueTypeName: string; -} diff --git a/src-testing/src/audio/Audio.d.ts b/src-testing/src/audio/Audio.d.ts deleted file mode 100644 index 63a944b5e..000000000 --- a/src-testing/src/audio/Audio.d.ts +++ /dev/null @@ -1,273 +0,0 @@ -import { Object3D } from "../core/Object3D.js"; -import { AudioContext } from "./AudioContext.js"; -import { AudioListener } from "./AudioListener.js"; - -// Extras / Audio ///////////////////////////////////////////////////////////////////// - -/** - * Create a non-positional ( global ) {@link Audio} object. - * This uses the {@link https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API | Web {@link Audio} API}. - * @example - * ```typescript - * // create an AudioListener and add it to the camera - * const listener = new THREE.AudioListener(); - * camera.add(listener); - * // create a global {@link Audio} source - * const sound = new THREE.Audio(listener); - * // load a sound and set it as the {@link Audio} object's buffer - * const audioLoader = new THREE.AudioLoader(); - * audioLoader.load('sounds/ambient.ogg', function (buffer) { - * sound.setBuffer(buffer); - * sound.setLoop(true); - * sound.setVolume(0.5); - * sound.play(); - * }); - * ``` - * @see Example: {@link https://threejs.org/examples/#webaudio_sandbox | webaudio / sandbox } - * @see Example: {@link https://threejs.org/examples/#webaudio_visualizer | webaudio / visualizer } - * @see {@link https://threejs.org/docs/index.html#api/en/audio/Audio | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/audio/Audio.js | Source} - */ -export class Audio extends Object3D { - /** - * Create a new instance of {@link Audio} - * @param listener (required) {@link AudioListener | AudioListener} instance. - */ - constructor(listener: AudioListener); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `Audio` - */ - readonly type: string | "Audio"; - - /** - * A reference to the listener object of this audio. - */ - listener: AudioListener; - - /** - * The {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioContext | AudioContext} of the {@link AudioListener | listener} given in the constructor. - */ - context: AudioContext; - - /** - * A {@link https://developer.mozilla.org/en-US/docs/Web/API/GainNode | GainNode} created using - * {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioContext/createGain | AudioContext.createGain}(). - */ - gain: GainNode; - - /** - * Whether to start playback automatically. - * @defaultValue `false` - */ - autoplay: boolean; - - buffer: AudioBuffer | null; - - /** - * Modify pitch, measured in cents. +/- 100 is a semitone. +/- 1200 is an octave. - * @defaultValue `0` - */ - detune: number; - - /** - * @default false - */ - loop: boolean; - - /** - * @default 0 - */ - loopStart: number; - - /** - * @default 0 - */ - loopEnd: number; - - /** - * An offset to the time within the {@link Audio} buffer that playback should begin. - * Same as the {@link Audio.offset | offset} parameter of {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/start | AudioBufferSourceNode.start()}. - * @defaultValue `0` - */ - offset: number; - - /** - * Overrides the duration of the audio. Same as the {@link Audio.duration | duration} parameter of - * {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/start | AudioBufferSourceNode.start()}. - * @defaultValue `undefined` _to play the whole buffer_. - */ - duration: number | undefined; - - /** - * Speed of playback. - * @defaultValue `1` - */ - playbackRate: number; - - /** - * Whether the {@link Audio} is currently playing. - * @defaultValue `false` - */ - isPlaying: boolean; - - /** - * Whether playback can be controlled using the {@link Audio.play | play}(), {@link Audio.pause | pause}() etc. methods. - * @defaultValue `true` - */ - hasPlaybackControl: boolean; - - /** - * Type of the {@link Audio} source. - * @defaultValue 'empty'. - */ - sourceType: string; - - /** - * An {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode | AudioBufferSourceNode} created using - * {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioContext/createBufferSource | AudioContext.createBufferSource()}. - */ - source: AudioScheduledSourceNode | null; - - /** - * Represents an array of {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioNode | AudioNodes}. - * Can be used to apply a variety of low-order filters to create more complex sound effects. - * In most cases, the array contains instances of {@link https://developer.mozilla.org/en-US/docs/Web/API/BiquadFilterNode | BiquadFilterNodes}. - * Filters are set via {@link THREE.Audio.setFilter | Audio.setFilter} or {@link THREE.Audio.setFilters | Audio.setFilters}. - * @defaultValue `[]` - */ - filters: AudioNode[]; - - /** - * Return the {@link Audio.gain | gainNode}. - */ - getOutput(): NodeType; - - /** - * Setup the {@link Audio.source | source} to the audioBuffer, and sets {@link Audio.sourceType | sourceType} to 'audioNode'. - * @remarks Also sets {@link Audio.hasPlaybackControl | hasPlaybackControl} to false. - */ - setNodeSource(audioNode: AudioScheduledSourceNode): this; - - /** - * Applies the given object of type {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement | HTMLMediaElement} as the source of this audio. - * @remarks Also sets {@link Audio.hasPlaybackControl | hasPlaybackControl} to false. - */ - setMediaElementSource(mediaElement: HTMLMediaElement): this; - - /** - * Applies the given object of type {@link https://developer.mozilla.org/en-US/docs/Web/API/MediaStream | MediaStream} as the source of this audio. - * @remarks Also sets {@link Audio.hasPlaybackControl | hasPlaybackControl} to false. - */ - setMediaStreamSource(mediaStream: MediaStream): this; - - /** - * Setup the {@link Audio.source | source} to the audioBuffer, and sets {@link Audio.sourceType | sourceType} to 'buffer'. - * @remarks If {@link Audio.autoplay | autoplay}, also starts playback. - */ - setBuffer(audioBuffer: AudioBuffer): this; - - /** - * If {@link Audio.hasPlaybackControl | hasPlaybackControl} is true, starts playback. - */ - play(delay?: number): this; - - /** - * If {@link Audio.hasPlaybackControl | hasPlaybackControl} is true, pauses playback. - */ - pause(): this; - - /** - * If {@link Audio.hasPlaybackControl | hasPlaybackControl} is enabled, stops playback. - * @param delay (optional) - The delay, in seconds, at which the audio should start playing. - */ - stop(delay?: number): this; - - /** - * Called automatically when playback finished. - */ - onEnded(): void; - - /** - * Connect to the {@link THREE.Audio.source | Audio.source} - * @remarks This is used internally on initialisation and when setting / removing filters. - */ - connect(): this; - /** - * Disconnect from the {@link THREE.Audio.source | Audio.source} - * @remarks This is used internally when setting / removing filters. - */ - disconnect(): this; - - /** - * Returns the detuning of oscillation in cents. - */ - getDetune(): number; - /** - * Defines the detuning of oscillation in cents. - * @param value Expects a `Float` - */ - setDetune(value: number): this; - - /** - * Returns the first element of the {@link Audio.filters | filters} array. - */ - getFilter(): AudioNode; - /** - * Applies a single filter node to the audio. - */ - setFilter(filter: AudioNode): this; - - /** - * Returns the {@link Audio.filters | filters} array. - */ - getFilters(): AudioNode[]; - /** - * Applies an array of filter nodes to the audio. - * @param value Arrays of filters. - */ - setFilters(value: AudioNode[]): this; - - /** - * Return the value of {@link Audio.playbackRate | playbackRate}. - */ - getPlaybackRate(): number; - /** - * If {@link Audio.hasPlaybackControl | hasPlaybackControl} is enabled, set the {@link Audio.playbackRate | playbackRate} to `value`. - * @param value Expects a `Float` - */ - setPlaybackRate(value: number): this; - - /** - * Return the value of {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/loop | source.loop} (whether playback should loop). - */ - getLoop(): boolean; - /** - * Set {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/loop | source.loop} to `value` (whether playback should loop). - * @param value - */ - setLoop(value: boolean): this; - - /** - * Set {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/loopStart | source.loopStart} to `value`. - * @param value Expects a `Float` - */ - setLoopStart(value: number): this; - /** - * Set {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/loopEnd | source.loopEnd} to `value`. - * @param value Expects a `Float` - */ - setLoopEnd(value: number): this; - - /** - * Return the current volume. - */ - getVolume(): number; - /** - * Set the volume. - * @param value Expects a `Float` - */ - setVolume(value: number): this; -} diff --git a/src-testing/src/audio/AudioAnalyser.d.ts b/src-testing/src/audio/AudioAnalyser.d.ts deleted file mode 100644 index 474583ec7..000000000 --- a/src-testing/src/audio/AudioAnalyser.d.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { Audio } from "./Audio.js"; - -/** - * Create a {@link AudioAnalyser} object, which uses an {@link https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode | AnalyserNode} to analyse audio data. - * This uses the {@link https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API | Web Audio API}. - * @example - * ```typescript - * // create an AudioListener and add it to the camera - * const listener = new THREE.AudioListener(); - * camera.add(listener); - * // create an Audio source - * const sound = new THREE.Audio(listener); - * // load a sound and set it as the Audio object's buffer - * const audioLoader = new THREE.AudioLoader(); - * audioLoader.load('sounds/ambient.ogg', function (buffer) { - * sound.setBuffer(buffer); - * sound.setLoop(true); - * sound.setVolume(0.5); - * sound.play(); - * }); - * // create an AudioAnalyser, passing in the sound and desired fftSize - * const analyser = new THREE.AudioAnalyser(sound, 32); - * // get the average frequency of the sound - * const data = analyser.getAverageFrequency(); - * ``` - * @see Example: {@link https://threejs.org/examples/#webaudio_sandbox | webaudio / sandbox } - * @see Example: {@link https://threejs.org/examples/#webaudio_visualizer | webaudio / visualizer } - * @see {@link https://threejs.org/docs/index.html#api/en/audio/AudioAnalyser | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/audio/AudioAnalyser.js | Source} - */ -export class AudioAnalyser { - /** - * Create a new {@link {@link AudioAnalyser} | AudioAnalyser}. - * @param audio - * @param fftSize See {@link https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode/fftSize | AnalyserNode.fftSize }. Expects a `unsigned integer`. Default `2048`. - */ - constructor(audio: Audio, fftSize?: number); - - /** - * An {@link https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode | AnalyserNode} used to analyze audio. - */ - analyser: AnalyserNode; - - /** - * A Uint8Array with size determined by {@link https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode/frequencyBinCount | analyser.frequencyBinCount} used to hold analysis data. - */ - data: Uint8Array; - - /** - * Uses the Web Audio's {@link https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode/getByteFrequencyData | getByteFrequencyData} method - */ - getFrequencyData(): Uint8Array; - - /** - * Get the average of the frequencies returned by the {@link AudioAnalyser.getFrequencyData | getFrequencyData} method. - */ - getAverageFrequency(): number; -} diff --git a/src-testing/src/audio/AudioContext.d.ts b/src-testing/src/audio/AudioContext.d.ts deleted file mode 100644 index 50a7f3d6e..000000000 --- a/src-testing/src/audio/AudioContext.d.ts +++ /dev/null @@ -1,19 +0,0 @@ -/** - * This contains methods for setting up an {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioContext | AudioContext}. - * Used internally by the {@link AudioListener | AudioListener} and {@link AudioLoader | AudioLoader} classes. - * This uses the {@link https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API | Web Audio API}. - * @see {@link https://threejs.org/docs/index.html#api/en/audio/AudioContext | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/audio/AudioContext.js | Source} - */ -export namespace AudioContext { - /** - * Return the value of the variable `context` in the outer scope, if defined, otherwise set it to a new {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioContext | AudioContext}. - */ - function getContext(): AudioContext; - - /** - * Set the variable `context` in the outer scope to `value`. - * @param value - */ - function setContext(context: AudioContext): void; -} diff --git a/src-testing/src/audio/AudioListener.d.ts b/src-testing/src/audio/AudioListener.d.ts deleted file mode 100644 index a49e4d5c7..000000000 --- a/src-testing/src/audio/AudioListener.d.ts +++ /dev/null @@ -1,96 +0,0 @@ -import { Object3D } from "../core/Object3D.js"; -import { AudioContext } from "./AudioContext.js"; - -/** - * The {@link AudioListener} represents a virtual {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioListener | listener} of the all positional and non-positional audio effects in the scene. - * A three.js application usually creates a single instance of {@link AudioListener} * @remarks - * It is a mandatory construtor parameter for audios entities like {@link Audio | Audio} and {@link PositionalAudio | PositionalAudio}. - * In most cases, the listener object is a child of the camera - * So the 3D transformation of the camera represents the 3D transformation of the listener. - * @example - * ```typescript - * // create an {@link AudioListener} and add it to the camera - * const listener = new THREE.AudioListener(); - * camera.add(listener); - * // create a global audio source - * const sound = new THREE.Audio(listener); - * // load a sound and set it as the Audio object's buffer - * const audioLoader = new THREE.AudioLoader(); - * audioLoader.load('sounds/ambient.ogg', function (buffer) { - * sound.setBuffer(buffer); - * sound.setLoop(true); - * sound.setVolume(0.5); - * sound.play(); - * }); - * ``` - * @see Example: {@link https://threejs.org/examples/#webaudio_sandbox | webaudio / sandbox } - * @see Example: {@link https://threejs.org/examples/#webaudio_timing | webaudio / timing } - * @see Example: {@link https://threejs.org/examples/#webaudio_visualizer | webaudio / visualizer } - * @see {@link https://threejs.org/docs/index.html#api/en/audio/AudioListener | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/audio/AudioListener.js | Source} - */ -export class AudioListener extends Object3D { - /** - * Create a new AudioListener. - */ - constructor(); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `AudioListener` - */ - readonly type: string | "AudioListener"; - - /** - * The {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioContext | AudioContext} of the {@link {@link AudioListener} | listener} given in the constructor. - */ - context: AudioContext; - - /** - * A {@link https://developer.mozilla.org/en-US/docs/Web/API/GainNode | GainNode} created using - * {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioContext/createGain | AudioContext.createGain()}. - */ - gain: GainNode; - - /** - * @defaultValue `null` - */ - filter: AudioNode; - - /** - * Time delta value for audio entities. Use in context of {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioParam/linearRampToValueAtTime | AudioParam.linearRampToValueAtTimeDefault()}. - * @defaultValue `0` - */ - timeDelta: number; - - /** - * Return the {@link AudioListener.gain | gainNode}. - */ - getInput(): GainNode; - /** - * Set the {@link AudioListener.filter | filter} property to `null`. - */ - removeFilter(): this; - - /** - * Returns the value of the {@link AudioListener.filter | filter} property. - */ - getFilter(): AudioNode; - /** - * Set the {@link AudioListener.filter | filter} property to `value`. - * @param value - */ - setFilter(value: AudioNode): this; - - /** - * Return the volume. - */ - getMasterVolume(): number; - - /** - * Set the volume. - * @param value - */ - setMasterVolume(value: number): this; -} diff --git a/src-testing/src/audio/PositionalAudio.d.ts b/src-testing/src/audio/PositionalAudio.d.ts deleted file mode 100644 index d72d10674..000000000 --- a/src-testing/src/audio/PositionalAudio.d.ts +++ /dev/null @@ -1,101 +0,0 @@ -import { Audio } from "./Audio.js"; -import { AudioListener } from "./AudioListener.js"; - -/** - * Create a positional audio object. - * This uses the {@link https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API | Web Audio API}. - * @example - * ```typescript - * // create an AudioListener and add it to the camera - * const listener = new THREE.AudioListener(); - * camera.add(listener); - * // create the {@link PositionalAudio} object (passing in the listener) - * const sound = new THREE.PositionalAudio(listener); - * // load a sound and set it as the {@link PositionalAudio} object's buffer - * const audioLoader = new THREE.AudioLoader(); - * audioLoader.load('sounds/song.ogg', function (buffer) { - * sound.setBuffer(buffer); - * sound.setRefDistance(20); - * sound.play(); - * }); - * // create an object for the sound to play from - * const sphere = new THREE.SphereGeometry(20, 32, 16); - * const material = new THREE.MeshPhongMaterial({ - * color: 0xff2200 - * }); - * const mesh = new THREE.Mesh(sphere, material); - * scene.add(mesh); - * // finally add the sound to the mesh - * mesh.add(sound); - * ``` - * @see Example: {@link https://threejs.org/examples/#webaudio_orientation | webaudio / orientation } - * @see Example: {@link https://threejs.org/examples/#webaudio_sandbox | webaudio / sandbox } - * @see Example: {@link https://threejs.org/examples/#webaudio_timing | webaudio / timing } - * @see {@link https://threejs.org/docs/index.html#api/en/audio/PositionalAudio | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/audio/PositionalAudio.js | Source} - */ -export class PositionalAudio extends Audio { - /** - * Create a new instance of {@link PositionalAudio} - * @param listener (required) {@link AudioListener | AudioListener} instance. - */ - constructor(listener: AudioListener); - - /** - * The PositionalAudio's {@link https://developer.mozilla.org/en-US/docs/Web/API/PannerNode | PannerNode}. - */ - panner: PannerNode; - - /** - * Returns the {@link PositionalAudio.panner | panner}. - */ - getOutput(): PannerNode; - - /** - * Returns the value of {@link https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/refDistance | panner.refDistance}. - */ - getRefDistance(): number; - /** - * Sets the value of {@link https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/refDistance | panner.refDistance}. - * @param value Expects a `Float` - */ - setRefDistance(value: number): this; - - /** - * Returns the value of {@link https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/rolloffFactor | panner.rolloffFactor}. - */ - getRolloffFactor(): number; - /** - * Sets the value of {@link https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/rolloffFactor | panner.rolloffFactor}. - * @param value Expects a `Float` - */ - setRolloffFactor(value: number): this; - - /** - * Returns the value of {@link https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/distanceModel | panner.distanceModel}. - */ - getDistanceModel(): string; - /** - * Sets the value of {@link https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/distanceModel | panner.distanceModel}. - * @param value - */ - setDistanceModel(value: string): this; - - /** - * Returns the value of {@link https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/maxDistance | panner.maxDistance}. - */ - getMaxDistance(): number; - /** - * Sets the value of {@link https://developer.mozilla.org/en-US/docs/Web/API/PannerNode/maxDistance | panner.maxDistance}. - * @param value Expects a `Float` - */ - setMaxDistance(value: number): this; - - /** - * This method can be used in order to transform an omnidirectional sound into a {@link https://developer.mozilla.org/en-US/docs/Web/API/PannerNode | directional sound}. - * @param coneInnerAngle Expects a `Float` - * @param coneOuterAngle Expects a `Float` - * @param coneOuterGain Expects a `Float` - */ - setDirectionalCone(coneInnerAngle: number, coneOuterAngle: number, coneOuterGain: number): this; -} diff --git a/src-testing/src/cameras/ArrayCamera.d.ts b/src-testing/src/cameras/ArrayCamera.d.ts deleted file mode 100644 index e9e9a221d..000000000 --- a/src-testing/src/cameras/ArrayCamera.d.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { PerspectiveCamera } from "./PerspectiveCamera.js"; - -/** - * {@link ArrayCamera} can be used in order to efficiently render a scene with a predefined set of cameras - * @remarks - * This is an important performance aspect for rendering VR scenes. - * An instance of {@link ArrayCamera} always has an array of sub cameras - * It's mandatory to define for each sub camera the `viewport` property which determines the part of the viewport that is rendered with this camera. - * @see Example: {@link https://threejs.org/examples/#webgl_camera_array | camera / array } - * @see {@link https://threejs.org/docs/index.html#api/en/cameras/ArrayCamera | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/cameras/ArrayCamera.js | Source} - */ -export class ArrayCamera extends PerspectiveCamera { - /** - * An array of cameras. - * @param array. Default `[]`. - */ - constructor(cameras?: PerspectiveCamera[]); - - /** - * Read-only flag to check if a given object is of type {@link ArrayCamera}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isArrayCamera: true; - - /** - * An array of cameras. - * @defaultValue `[]` - */ - cameras: PerspectiveCamera[]; -} diff --git a/src-testing/src/cameras/Camera.d.ts b/src-testing/src/cameras/Camera.d.ts deleted file mode 100644 index b49add52e..000000000 --- a/src-testing/src/cameras/Camera.d.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { CoordinateSystem } from "../constants.js"; -import { Layers } from "../core/Layers.js"; -import { Object3D } from "../core/Object3D.js"; -import { Matrix4 } from "../math/Matrix4.js"; -import { Vector3 } from "../math/Vector3.js"; -import { Vector4 } from "../math/Vector4.js"; - -/** - * Abstract base class for cameras - * @remarks - * This class should always be inherited when you build a new camera. - * @see {@link https://threejs.org/docs/index.html#api/en/cameras/Camera | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/cameras/Camera.js | Source} - */ -export class Camera extends Object3D { - /** - * @remarks - * Note that this class is not intended to be called directly; you probably want a - * {@link THREE.PerspectiveCamera | PerspectiveCamera} or - * {@link THREE.OrthographicCamera | OrthographicCamera} instead. - */ - constructor(); - - /** - * Read-only flag to check if a given object is of type {@link Camera}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isCamera: true; - - /** - * @override - * @defaultValue `Camera` - */ - override readonly type: string | "Camera"; - - /** - * @override - * The {@link THREE.Layers | layers} that the {@link Camera} is a member of. - * @remarks Objects must share at least one layer with the {@link Camera} to be n when the camera's viewpoint is rendered. - * @defaultValue `new THREE.Layers()` - */ - override layers: Layers; - - /** - * This is the inverse of matrixWorld. - * @remarks MatrixWorld contains the Matrix which has the world transform of the {@link Camera} . - * @defaultValue {@link THREE.Matrix4 | `new THREE.Matrix4()`} - */ - matrixWorldInverse: Matrix4; - - /** - * This is the matrix which contains the projection. - * @defaultValue {@link THREE.Matrix4 | `new THREE.Matrix4()`} - */ - projectionMatrix: Matrix4; - - /** - * This is the inverse of projectionMatrix. - * @defaultValue {@link THREE.Matrix4 | `new THREE.Matrix4()`} - */ - projectionMatrixInverse: Matrix4; - - coordinateSystem: CoordinateSystem; - - viewport?: Vector4; - - /** - * Returns a {@link THREE.Vector3 | Vector3} representing the world space direction in which the {@link Camera} is looking. - * @remarks Note: A {@link Camera} looks down its local, negative z-axis. - * @param target The result will be copied into this Vector3. - */ - getWorldDirection(target: Vector3): Vector3; -} diff --git a/src-testing/src/cameras/CubeCamera.d.ts b/src-testing/src/cameras/CubeCamera.d.ts deleted file mode 100644 index e6e82fb19..000000000 --- a/src-testing/src/cameras/CubeCamera.d.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { CoordinateSystem } from "../constants.js"; -import { Object3D } from "../core/Object3D.js"; -import { WebGLCubeRenderTarget } from "../renderers/WebGLCubeRenderTarget.js"; -import { WebGLRenderer } from "../renderers/WebGLRenderer.js"; - -/** - * Creates **6** {@link THREE.PerspectiveCamera | cameras} that render to a {@link THREE.WebGLCubeRenderTarget | WebGLCubeRenderTarget}. - * @remarks The cameras are added to the {@link children} array. - * @example - * ```typescript - * // Create cube render target - * const cubeRenderTarget = new THREE.WebGLCubeRenderTarget( 128, { generateMipmaps: true, minFilter: THREE.LinearMipmapLinearFilter } ); - * - * // Create cube camera - * const cubeCamera = new THREE.CubeCamera( 1, 100000, cubeRenderTarget ); - * scene.add( cubeCamera ); - * - * // Create car - * const chromeMaterial = new THREE.MeshLambertMaterial( { color: 0xffffff, envMap: cubeRenderTarget.texture } ); - * const car = new THREE.Mesh( carGeometry, chromeMaterial ); - * scene.add( car ); - * - * // Update the render target cube - * car.visible = false; - * cubeCamera.position.copy( car.position ); - * cubeCamera.update( renderer, scene ); - * - * // Render the scene - * car.visible = true; - * renderer.render( scene, camera ); - * ``` - * @see Example: {@link https://threejs.org/examples/#webgl_materials_cubemap_dynamic | materials / cubemap / dynamic } - * @see {@link https://threejs.org/docs/index.html#api/en/cameras/CubeCamera | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/cameras/CubeCamera.js | Source} - */ -export class CubeCamera extends Object3D { - /** - * Constructs a {@link CubeCamera} that contains 6 {@link PerspectiveCamera | PerspectiveCameras} that render to a {@link THREE.WebGLCubeRenderTarget | WebGLCubeRenderTarget}. - * @param near The near clipping distance. - * @param far The far clipping distance. - * @param renderTarget The destination cube render target. - */ - constructor(near: number, far: number, renderTarget: WebGLCubeRenderTarget); - - /** - * @override - * @defaultValue `CubeCamera` - */ - override readonly type: string | "CubeCamera"; - - /** - * The destination cube render target. - */ - renderTarget: WebGLCubeRenderTarget; - - coordinateSystem: CoordinateSystem; - - activeMipmapLevel: number; - - updateCoordinateSystem(): void; - - /** - * Call this to update the {@link CubeCamera.renderTarget | renderTarget}. - * @param renderer The current WebGL renderer - * @param scene The current scene - */ - update(renderer: WebGLRenderer, scene: Object3D): void; -} diff --git a/src-testing/src/cameras/OrthographicCamera.d.ts b/src-testing/src/cameras/OrthographicCamera.d.ts deleted file mode 100644 index 745d11416..000000000 --- a/src-testing/src/cameras/OrthographicCamera.d.ts +++ /dev/null @@ -1,174 +0,0 @@ -import { JSONMeta, Object3DJSON, Object3DJSONObject } from "../core/Object3D.js"; -import { Camera } from "./Camera.js"; - -export interface OrthographicCameraJSONObject extends Object3DJSONObject { - zoom: number; - left: number; - right: number; - top: number; - bottom: number; - near: number; - far: number; - - view?: { - enabled: boolean; - fullWidth: number; - fullHeight: number; - offsetX: number; - offsetY: number; - width: number; - height: number; - }; -} - -export interface OrthographicCameraJSON extends Object3DJSON { - object: OrthographicCameraJSONObject; -} - -/** - * Camera that uses {@link https://en.wikipedia.org/wiki/Orthographic_projection | orthographic projection}. - * In this projection mode, an object's size in the rendered image stays constant regardless of its distance from the camera. - * This can be useful for rendering 2D scenes and UI elements, amongst other things. - * @example - * ```typescript - * const camera = new THREE.OrthographicCamera(width / -2, width / 2, height / 2, height / -2, 1, 1000); - * scene.add(camera); - * ``` - * @see Example: {@link https://threejs.org/examples/#webgl_camera | camera } - * @see Example: {@link https://threejs.org/examples/#webgl_interactive_cubes_ortho | interactive / cubes / ortho } - * @see Example: {@link https://threejs.org/examples/#webgl_materials_cubemap_dynamic | materials / cubemap / dynamic } - * @see Example: {@link https://threejs.org/examples/#webgl_postprocessing_advanced | postprocessing / advanced } - * @see Example: {@link https://threejs.org/examples/#webgl_postprocessing_dof2 | postprocessing / dof2 } - * @see Example: {@link https://threejs.org/examples/#webgl_postprocessing_godrays | postprocessing / godrays } - * @see Example: {@link https://threejs.org/examples/#webgl_rtt | rtt } - * @see Example: {@link https://threejs.org/examples/#webgl_shaders_tonemapping | shaders / tonemapping } - * @see Example: {@link https://threejs.org/examples/#webgl_shadowmap | shadowmap } - * @see {@link https://threejs.org/docs/index.html#api/en/cameras/OrthographicCamera | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/cameras/OrthographicCamera.js | Source} - */ -export class OrthographicCamera extends Camera { - /** - * Creates a new {@link OrthographicCamera}. - * @remarks Together these define the camera's {@link https://en.wikipedia.org/wiki/Viewing_frustum | viewing frustum}. - * @param left Camera frustum left plane. Default `-1`. - * @param right Camera frustum right plane. Default `1`. - * @param top Camera frustum top plane. Default `1`. - * @param bottom Camera frustum bottom plane. Default `-1`. - * @param near Camera frustum near plane. Default `0.1`. - * @param far Camera frustum far plane. Default `2000`. - */ - constructor(left?: number, right?: number, top?: number, bottom?: number, near?: number, far?: number); - - /** - * Read-only flag to check if a given object is of type {@link OrthographicCamera}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isOrthographicCamera: true; - - /** - * @override - * @defaultValue `OrthographicCamera` - */ - override readonly type: string | "OrthographicCamera"; - - /** - * Gets or sets the zoom factor of the camera. - * @defaultValue `1` - */ - zoom: number; - - /** - * Set by {@link setViewOffset | .setViewOffset()}. - * @defaultValue `null` - */ - view: null | { - enabled: boolean; - fullWidth: number; - fullHeight: number; - offsetX: number; - offsetY: number; - width: number; - height: number; - }; - - /** - * Camera frustum left plane. - * @remarks Expects a `Float` - * @defaultValue `-1` - */ - left: number; - - /** - * Camera frustum right plane. - * @remarks Expects a `Float` - * @defaultValue `1` - */ - right: number; - - /** - * Camera frustum top plane. - * @remarks Expects a `Float` - * @defaultValue `1` - */ - top: number; - - /** - * Camera frustum bottom plane. - * @remarks Expects a `Float`. - * @defaultValue `-1` - */ - bottom: number; - - /** - * Camera frustum near plane.`. - * @remarks The valid range is between `0` and the current value of the {@link far | .far} plane. - * @remarks Note that, unlike for the {@link THREE.PerspectiveCamera | PerspectiveCamera}, `0` is a valid value for an {@link THREE.OrthographicCamera | OrthographicCamera's} near plane. - * @remarks Expects a `Float` - * @defaultValue `0.1` - */ - near: number; - - /** - * Camera frustum far plane. - * @remarks Must be greater than the current value of {@link near | .near} plane. - * @remarks Expects a `Float` - * @defaultValue `2000` - */ - far: number; - - /** - * Updates the camera projection matrix - * @remarks Must be called after any change of parameters. - */ - updateProjectionMatrix(): void; - - /** - * Sets an offset in a larger {@link https://en.wikipedia.org/wiki/Viewing_frustum | viewing frustum} - * @remarks - * This is useful for multi-window or multi-monitor/multi-machine setups - * For an example on how to use it see {@link PerspectiveCamera.setViewOffset | PerspectiveCamera}. - * @see {@link THREE.PerspectiveCamera.setViewOffset | PerspectiveCamera}. - * @param fullWidth Full width of multiview setup Expects a `Float`. - * @param fullHeight Full height of multiview setup Expects a `Float`. - * @param x Horizontal offset of subcamera Expects a `Float`. - * @param y Vertical offset of subcamera Expects a `Float`. - * @param width Width of subcamera Expects a `Float`. - * @param height Height of subcamera Expects a `Float`. - */ - setViewOffset( - fullWidth: number, - fullHeight: number, - offsetX: number, - offsetY: number, - width: number, - height: number, - ): void; - - /** - * Removes any offset set by the {@link setViewOffset | .setViewOffset} method. - */ - clearViewOffset(): void; - - toJSON(meta?: JSONMeta): OrthographicCameraJSON; -} diff --git a/src-testing/src/cameras/PerspectiveCamera.d.ts b/src-testing/src/cameras/PerspectiveCamera.d.ts deleted file mode 100644 index 60567105f..000000000 --- a/src-testing/src/cameras/PerspectiveCamera.d.ts +++ /dev/null @@ -1,254 +0,0 @@ -import { JSONMeta, Object3DJSON, Object3DJSONObject } from "../core/Object3D.js"; -import { Vector2 } from "../math/Vector2.js"; -import { Camera } from "./Camera.js"; - -export interface PerspectiveCameraJSONObject extends Object3DJSONObject { - fov: number; - zoom: number; - - near: number; - far: number; - focus: number; - - aspect: number; - - view?: { - enabled: boolean; - fullWidth: number; - fullHeight: number; - offsetX: number; - offsetY: number; - width: number; - height: number; - }; - - filmGauge: number; - filmOffset: number; -} - -export interface PerspectiveCameraJSON extends Object3DJSON { - object: PerspectiveCameraJSONObject; -} - -/** - * Camera that uses {@link https://en.wikipedia.org/wiki/Perspective_(graphical) | perspective projection}. - * This projection mode is designed to mimic the way the human eye sees - * @remarks - * It is the most common projection mode used for rendering a 3D scene. - * @example - * ```typescript - * const camera = new THREE.PerspectiveCamera(45, width / height, 1, 1000); - * scene.add(camera); - * ``` - * @see Example: {@link https://threejs.org/examples/#webgl_animation_skinning_blending | animation / skinning / blending } - * @see Example: {@link https://threejs.org/examples/#webgl_animation_skinning_morph | animation / skinning / morph } - * @see Example: {@link https://threejs.org/examples/#webgl_effects_stereo | effects / stereo } - * @see Example: {@link https://threejs.org/examples/#webgl_interactive_cubes | interactive / cubes } - * @see Example: {@link https://threejs.org/examples/#webgl_loader_collada_skinning | loader / collada / skinning } - * @see {@link https://threejs.org/docs/index.html#api/en/cameras/PerspectiveCamera | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/cameras/PerspectiveCamera.js | Source} - */ -export class PerspectiveCamera extends Camera { - /** - * Creates a new {@link PerspectiveCamera}. - * @remarks Together these define the camera's {@link https://en.wikipedia.org/wiki/Viewing_frustum | viewing frustum}. - * @param fov Camera frustum vertical field of view. Default `50`. - * @param aspect Camera frustum aspect ratio. Default `1`. - * @param near Camera frustum near plane. Default `0.1`. - * @param far Camera frustum far plane. Default `2000`. - */ - constructor(fov?: number, aspect?: number, near?: number, far?: number); - - /** - * Read-only flag to check if a given object is of type {@link Camera}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isPerspectiveCamera: true; - - /** - * @override - * @defaultValue `PerspectiveCamera` - */ - override readonly type: string | "PerspectiveCamera"; - - /** - * Gets or sets the zoom factor of the camera. - * @defaultValue `1` - */ - zoom: number; - - /** - * Camera frustum vertical field of view, from bottom to top of view, in degrees. - * @remarks Expects a `Float` - * @defaultValue `50` - */ - fov: number; - - /** - * Camera frustum aspect ratio, usually the canvas width / canvas height. - * @remarks Expects a `Float` - * @defaultValue `1`, _(square canvas)_. - */ - aspect: number; - - /** - * Camera frustum near plane. - * @remarks The valid range is greater than `0` and less than the current value of the {@link far | .far} plane. - * @remarks Note that, unlike for the {@link THREE.OrthographicCamera | OrthographicCamera}, `0` is **not** a valid value for a {@link PerspectiveCamera |PerspectiveCamera's}. near plane. - * @defaultValue `0.1` - * @remarks Expects a `Float` - */ - near: number; - - /** - * Camera frustum far plane. - * @remarks Must be greater than the current value of {@link near | .near} plane. - * @remarks Expects a `Float` - * @defaultValue `2000` - */ - far: number; - - /** - * Object distance used for stereoscopy and depth-of-field effects. - * @remarks This parameter does not influence the projection matrix unless a {@link THREE.StereoCamera | StereoCamera} is being used. - * @remarks Expects a `Float` - * @defaultValue `10` - */ - focus: number; - - /** - * Frustum window specification or null. - * This is set using the {@link setViewOffset | .setViewOffset} method and cleared using {@link clearViewOffset | .clearViewOffset}. - * @defaultValue `null` - */ - view: null | { - enabled: boolean; - fullWidth: number; - fullHeight: number; - offsetX: number; - offsetY: number; - width: number; - height: number; - }; - - /** - * Film size used for the larger axis. - * This parameter does not influence the projection matrix unless {@link filmOffset | .filmOffset} is set to a nonzero value. - * @remarks Expects a `Float` - * @defaultValue `35`, _millimeters_. - */ - filmGauge: number; - - /** - * Horizontal off-center offset in the same unit as {@link filmGauge | .filmGauge}. - * @remarks Expects a `Float` - * @defaultValue `0` - */ - filmOffset: number; - - /** - * Returns the focal length of the current {@link .fov | fov} in respect to {@link filmGauge | .filmGauge}. - */ - getFocalLength(): number; - - /** - * Sets the FOV by focal length in respect to the current {@link filmGauge | .filmGauge}. - * @remarks By default, the focal length is specified for a `35mm` (full frame) camera. - * @param focalLength Expects a `Float` - */ - setFocalLength(focalLength: number): void; - - /** - * Returns the current vertical field of view angle in degrees considering {@link zoom | .zoom}. - */ - getEffectiveFOV(): number; - - /** - * Returns the width of the image on the film - * @remarks - * If {@link aspect | .aspect}. is greater than or equal to one (landscape format), the result equals {@link filmGauge | .filmGauge}. - */ - getFilmWidth(): number; - - /** - * Returns the height of the image on the film - * @remarks - * If {@link aspect | .aspect}. is less than or equal to one (portrait format), the result equals {@link filmGauge | .filmGauge}. - */ - getFilmHeight(): number; - - /** - * Computes the 2D bounds of the camera's viewable rectangle at a given distance along the viewing direction. - * Sets minTarget and maxTarget to the coordinates of the lower-left and upper-right corners of the view rectangle. - */ - getViewBounds(distance: number, minTarget: Vector2, maxTarget: Vector2): void; - - /** - * Computes the width and height of the camera's viewable rectangle at a given distance along the viewing direction. - * Copies the result into the target Vector2, where x is width and y is height. - */ - getViewSize(distance: number, target: Vector2): Vector2; - - /** - * Sets an offset in a larger frustum. - * @remarks - * This is useful for multi-window or multi-monitor/multi-machine setups. - * - * For example, if you have 3x2 monitors and each monitor is _1920x1080_ and - * the monitors are in grid like this - * ``` - * ┌───┬───┬───┐ - * │ A │ B │ C │ - * ├───┼───┼───┤ - * │ D │ E │ F │ - * └───┴───┴───┘ - * ``` - * then for each monitor you would call it like this - * ```typescript - * const w = 1920; - * const h = 1080; - * const fullWidth = w * 3; - * const fullHeight = h * 2; - * - * // Monitor - A - * camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 0, w, h ); - * // Monitor - B - * camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 0, w, h ); - * // Monitor - C - * camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 0, w, h ); - * // Monitor - D - * camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 1, w, h ); - * // Monitor - E - * camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 1, w, h ); - * // Monitor - F - * camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 1, w, h ); - * ``` - * Note there is no reason monitors have to be the same size or in a grid. - * @param fullWidth Full width of multiview setup Expects a `Float`. - * @param fullHeight Full height of multiview setup Expects a `Float`. - * @param x Horizontal offset of subcamera Expects a `Float`. - * @param y Vertical offset of subcamera Expects a `Float`. - * @param width Width of subcamera Expects a `Float`. - * @param height Height of subcamera Expects a `Float`. - */ - setViewOffset(fullWidth: number, fullHeight: number, x: number, y: number, width: number, height: number): void; - - /** - * Removes any offset set by the {@link setViewOffset | .setViewOffset} method. - */ - clearViewOffset(): void; - - /** - * Updates the camera projection matrix - * @remarks Must be called after any change of parameters. - */ - updateProjectionMatrix(): void; - - /** - * @deprecated Use {@link PerspectiveCamera.setFocalLength | .setFocalLength()} and {@link PerspectiveCamera.filmGauge | .filmGauge} instead. - */ - setLens(focalLength: number, frameHeight?: number): void; - - toJSON(meta?: JSONMeta): PerspectiveCameraJSON; -} diff --git a/src-testing/src/cameras/StereoCamera.d.ts b/src-testing/src/cameras/StereoCamera.d.ts deleted file mode 100644 index 3f359e3e0..000000000 --- a/src-testing/src/cameras/StereoCamera.d.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { Camera } from "./Camera.js"; -import { PerspectiveCamera } from "./PerspectiveCamera.js"; - -/** - * Dual {@link PerspectiveCamera | PerspectiveCamera}s used for effects such as - * {@link https://en.wikipedia.org/wiki/Anaglyph_3D | 3D Anaglyph} or - * {@link https://en.wikipedia.org/wiki/parallax_barrier | Parallax Barrier}. - * @see Example: {@link https://threejs.org/examples/#webgl_effects_anaglyph | effects / anaglyph } - * @see Example: {@link https://threejs.org/examples/#webgl_effects_parallaxbarrier | effects / parallaxbarrier } - * @see Example: {@link https://threejs.org/examples/#webgl_effects_stereo | effects / stereo } - * @see {@link https://threejs.org/docs/index.html#api/en/cameras/StereoCamera | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/cameras/StereoCamera.js | Source} - */ -export class StereoCamera extends Camera { - constructor(); - - type: "StereoCamera"; - - /** - * @remarks Expects a `Float` - * @defaultValue `1` - */ - aspect: number; - - /** - * @remarks Expects a `Float` - * @defaultValue `0.064` - */ - eyeSep: number; - - /** - * The Left camera. - * A {@link PerspectiveCamera } added to {@link THREE.PerspectiveCamera.layers | layer 1} - * @remarks Objects to be rendered by the **left** camera must also be added to this layer. - */ - cameraL: PerspectiveCamera; - - /** - * The Right camera. - * A {@link PerspectiveCamera } added to {@link THREE.PerspectiveCamera.layers | layer 2} - * @remarks Objects to be rendered by the **right** camera must also be added to this layer. - */ - cameraR: PerspectiveCamera; - - /** - * Update the stereo cameras based on the camera passed in. - * @param camera - */ - update(camera: PerspectiveCamera): void; -} diff --git a/src-testing/src/constants.d.ts b/src-testing/src/constants.d.ts deleted file mode 100644 index f5d26b42a..000000000 --- a/src-testing/src/constants.d.ts +++ /dev/null @@ -1,918 +0,0 @@ -export const REVISION: string; - -// https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent.button -export enum MOUSE { - LEFT = 0, - MIDDLE = 1, - RIGHT = 2, - ROTATE = 0, - DOLLY = 1, - PAN = 2, -} - -export enum TOUCH { - ROTATE = 0, - PAN = 1, - DOLLY_PAN = 2, - DOLLY_ROTATE = 3, -} - -// GL STATE CONSTANTS -export const CullFaceNone: 0; -export const CullFaceBack: 1; -export const CullFaceFront: 2; -export const CullFaceFrontBack: 3; -export type CullFace = typeof CullFaceNone | typeof CullFaceBack | typeof CullFaceFront | typeof CullFaceFrontBack; - -// Shadowing Type -export const BasicShadowMap: 0; -export const PCFShadowMap: 1; -export const PCFSoftShadowMap: 2; -export const VSMShadowMap: 3; -export type ShadowMapType = typeof BasicShadowMap | typeof PCFShadowMap | typeof PCFSoftShadowMap | typeof VSMShadowMap; - -// MATERIAL CONSTANTS - -// side -export const FrontSide: 0; -export const BackSide: 1; -export const DoubleSide: 2; -/** - * Defines which side of faces will be rendered - front, back or both. - * Default is {@link FrontSide}. - */ -export type Side = typeof FrontSide | typeof BackSide | typeof DoubleSide; - -// blending modes -export const NoBlending: 0; -export const NormalBlending: 1; -export const AdditiveBlending: 2; -export const SubtractiveBlending: 3; -export const MultiplyBlending: 4; -export const CustomBlending: 5; -export type Blending = - | typeof NoBlending - | typeof NormalBlending - | typeof AdditiveBlending - | typeof SubtractiveBlending - | typeof MultiplyBlending - | typeof CustomBlending; - -// custom blending equations -// (numbers start from 100 not to clash with other -// mappings to OpenGL constants defined in Texture.js) -export const AddEquation: 100; -export const SubtractEquation: 101; -export const ReverseSubtractEquation: 102; -export const MinEquation: 103; -export const MaxEquation: 104; -export type BlendingEquation = - | typeof AddEquation - | typeof SubtractEquation - | typeof ReverseSubtractEquation - | typeof MinEquation - | typeof MaxEquation; - -// custom blending factors -export const ZeroFactor: 200; -export const OneFactor: 201; -export const SrcColorFactor: 202; -export const OneMinusSrcColorFactor: 203; -export const SrcAlphaFactor: 204; -export const OneMinusSrcAlphaFactor: 205; -export const DstAlphaFactor: 206; -export const OneMinusDstAlphaFactor: 207; -export const DstColorFactor: 208; -export const OneMinusDstColorFactor: 209; -export const SrcAlphaSaturateFactor: 210; -export const ConstantColorFactor: 211; -export const OneMinusConstantColorFactor: 212; -export const ConstantAlphaFactor: 213; -export const OneMinusConstantAlphaFactor: 214; -export type BlendingDstFactor = - | typeof ZeroFactor - | typeof OneFactor - | typeof SrcColorFactor - | typeof OneMinusSrcColorFactor - | typeof SrcAlphaFactor - | typeof OneMinusSrcAlphaFactor - | typeof DstAlphaFactor - | typeof OneMinusDstAlphaFactor - | typeof DstColorFactor - | typeof OneMinusDstColorFactor - | typeof ConstantColorFactor - | typeof OneMinusConstantColorFactor - | typeof ConstantAlphaFactor - | typeof OneMinusConstantAlphaFactor; -export type BlendingSrcFactor = BlendingDstFactor | typeof SrcAlphaSaturateFactor; - -// depth modes -export const NeverDepth: 0; -export const AlwaysDepth: 1; -export const LessDepth: 2; -export const LessEqualDepth: 3; -export const EqualDepth: 4; -export const GreaterEqualDepth: 5; -export const GreaterDepth: 6; -export const NotEqualDepth: 7; -export type DepthModes = - | typeof NeverDepth - | typeof AlwaysDepth - | typeof LessDepth - | typeof LessEqualDepth - | typeof EqualDepth - | typeof GreaterEqualDepth - | typeof GreaterDepth - | typeof NotEqualDepth; - -// TEXTURE CONSTANTS -// Operations -export const MultiplyOperation: 0; -export const MixOperation: 1; -export const AddOperation: 2; -export type Combine = typeof MultiplyOperation | typeof MixOperation | typeof AddOperation; - -// Tone Mapping modes -export const NoToneMapping: 0; -export const LinearToneMapping: 1; -export const ReinhardToneMapping: 2; -export const CineonToneMapping: 3; -export const ACESFilmicToneMapping: 4; -export const CustomToneMapping: 5; -export const AgXToneMapping: 6; -export const NeutralToneMapping: 7; -export type ToneMapping = - | typeof NoToneMapping - | typeof LinearToneMapping - | typeof ReinhardToneMapping - | typeof CineonToneMapping - | typeof ACESFilmicToneMapping - | typeof CustomToneMapping - | typeof AgXToneMapping - | typeof NeutralToneMapping; - -// Bind modes -export const AttachedBindMode: "attached"; -export const DetachedBindMode: "detached"; -export type BindMode = typeof AttachedBindMode | typeof DetachedBindMode; - -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// -// Mapping modes - -/** - * Maps the texture using the mesh's UV coordinates. - * @remarks This is the _default_ value and behaver for Texture Mapping. - */ -export const UVMapping: 300; - -/** - * @remarks This is the _default_ value and behaver for Cube Texture Mapping. - */ -export const CubeReflectionMapping: 301; -export const CubeRefractionMapping: 302; -export const CubeUVReflectionMapping: 306; - -export const EquirectangularReflectionMapping: 303; -export const EquirectangularRefractionMapping: 304; - -/** - * Texture Mapping Modes for non-cube Textures - * @remarks {@link UVMapping} is the _default_ value and behaver for Texture Mapping. - * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} - */ -export type Mapping = - | typeof UVMapping - | typeof EquirectangularReflectionMapping - | typeof EquirectangularRefractionMapping; - -/** - * Texture Mapping Modes for cube Textures - * @remarks {@link CubeReflectionMapping} is the _default_ value and behaver for Cube Texture Mapping. - * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} - */ -export type CubeTextureMapping = - | typeof CubeReflectionMapping - | typeof CubeRefractionMapping - | typeof CubeUVReflectionMapping; - -/** - * Texture Mapping Modes for any type of Textures - * @see {@link Mapping} and {@link CubeTextureMapping} - * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} - */ -export type AnyMapping = Mapping | CubeTextureMapping; - -/////////////////////////////////////////////////////////////////////////////// -// Wrapping modes - -/** With {@link RepeatWrapping} the texture will simply repeat to infinity. */ -export const RepeatWrapping: 1000; -/** - * With {@link ClampToEdgeWrapping} the last pixel of the texture stretches to the edge of the mesh. - * @remarks This is the _default_ value and behaver for Wrapping Mapping. - */ -export const ClampToEdgeWrapping: 1001; -/** With {@link MirroredRepeatWrapping} the texture will repeats to infinity, mirroring on each repeat. */ -export const MirroredRepeatWrapping: 1002; - -/** - * Texture Wrapping Modes - * @remarks {@link ClampToEdgeWrapping} is the _default_ value and behaver for Wrapping Mapping. - * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} - */ -export type Wrapping = typeof RepeatWrapping | typeof ClampToEdgeWrapping | typeof MirroredRepeatWrapping; - -/////////////////////////////////////////////////////////////////////////////// -// Filters - -/** {@link NearestFilter} returns the value of the texture element that is nearest (in Manhattan distance) to the specified texture coordinates. */ -export const NearestFilter: 1003; - -/** - * {@link NearestMipmapNearestFilter} chooses the mipmap that most closely matches the size of the pixel being textured - * and uses the {@link NearestFilter} criterion (the texel nearest to the center of the pixel) to produce a texture value. - */ -export const NearestMipmapNearestFilter: 1004; -/** - * {@link NearestMipmapNearestFilter} chooses the mipmap that most closely matches the size of the pixel being textured - * and uses the {@link NearestFilter} criterion (the texel nearest to the center of the pixel) to produce a texture value. - */ -export const NearestMipMapNearestFilter: 1004; - -/** - * {@link NearestMipmapLinearFilter} chooses the two mipmaps that most closely match the size of the pixel being textured - * and uses the {@link NearestFilter} criterion to produce a texture value from each mipmap. - * The final texture value is a weighted average of those two values. - */ -export const NearestMipmapLinearFilter: 1005; -/** - * {@link NearestMipMapLinearFilter} chooses the two mipmaps that most closely match the size of the pixel being textured - * and uses the {@link NearestFilter} criterion to produce a texture value from each mipmap. - * The final texture value is a weighted average of those two values. - */ -export const NearestMipMapLinearFilter: 1005; - -/** - * {@link LinearFilter} returns the weighted average of the four texture elements that are closest to the specified texture coordinates, - * and can include items wrapped or repeated from other parts of a texture, - * depending on the values of {@link THREE.Texture.wrapS | wrapS} and {@link THREE.Texture.wrapT | wrapT}, and on the exact mapping. - */ -export const LinearFilter: 1006; - -/** - * {@link LinearMipmapNearestFilter} chooses the mipmap that most closely matches the size of the pixel being textured and - * uses the {@link LinearFilter} criterion (a weighted average of the four texels that are closest to the center of the pixel) to produce a texture value. - */ -export const LinearMipmapNearestFilter: 1007; -/** - * {@link LinearMipMapNearestFilter} chooses the mipmap that most closely matches the size of the pixel being textured and - * uses the {@link LinearFilter} criterion (a weighted average of the four texels that are closest to the center of the pixel) to produce a texture value. - */ -export const LinearMipMapNearestFilter: 1007; - -/** - * {@link LinearMipmapLinearFilter} is the default and chooses the two mipmaps that most closely match the size of the pixel being textured and - * uses the {@link LinearFilter} criterion to produce a texture value from each mipmap. - * The final texture value is a weighted average of those two values. - */ -export const LinearMipmapLinearFilter: 1008; - -/** - * {@link LinearMipMapLinearFilter} is the default and chooses the two mipmaps that most closely match the size of the pixel being textured and - * uses the {@link LinearFilter} criterion to produce a texture value from each mipmap. - * The final texture value is a weighted average of those two values. - */ -export const LinearMipMapLinearFilter: 1008; - -/** - * Texture Magnification Filter Modes. - * For use with a texture's {@link THREE.Texture.magFilter | magFilter} property, - * these define the texture magnification function to be used when the pixel being textured maps to an area less than or equal to one texture element (texel). - * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} - * @see {@link https://sbcode.net/threejs/mipmaps/ | Texture Mipmaps (non-official)} - */ -export type MagnificationTextureFilter = typeof NearestFilter | typeof LinearFilter; - -/** - * Texture Minification Filter Modes. - * For use with a texture's {@link THREE.Texture.minFilter | minFilter} property, - * these define the texture minifying function that is used whenever the pixel being textured maps to an area greater than one texture element (texel). - * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} - * @see {@link https://sbcode.net/threejs/mipmaps/ | Texture Mipmaps (non-official)} - */ -export type MinificationTextureFilter = - | typeof NearestFilter - | typeof NearestMipmapNearestFilter - | typeof NearestMipMapNearestFilter - | typeof NearestMipmapLinearFilter - | typeof NearestMipMapLinearFilter - | typeof LinearFilter - | typeof LinearMipmapNearestFilter - | typeof LinearMipMapNearestFilter - | typeof LinearMipmapLinearFilter - | typeof LinearMipMapLinearFilter; - -/** - * Texture all Magnification and Minification Filter Modes. - * @see {@link MagnificationTextureFilter} and {@link MinificationTextureFilter} - * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} - * @see {@link https://sbcode.net/threejs/mipmaps/ | Texture Mipmaps (non-official)} - */ -export type TextureFilter = MagnificationTextureFilter | MinificationTextureFilter; - -/////////////////////////////////////////////////////////////////////////////// -// Data types - -export const UnsignedByteType: 1009; -export const ByteType: 1010; -export const ShortType: 1011; -export const UnsignedShortType: 1012; -export const IntType: 1013; -export const UnsignedIntType: 1014; -export const FloatType: 1015; -export const HalfFloatType: 1016; -export const UnsignedShort4444Type: 1017; -export const UnsignedShort5551Type: 1018; -export const UnsignedInt248Type: 1020; -export const UnsignedInt5999Type: 35902; - -export type AttributeGPUType = typeof FloatType | typeof IntType; - -/** - * Texture Types. - * @remarks Must correspond to the correct {@link PixelFormat | format}. - * @see {@link THREE.Texture.type} - * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} - */ -export type TextureDataType = - | typeof UnsignedByteType - | typeof ByteType - | typeof ShortType - | typeof UnsignedShortType - | typeof IntType - | typeof UnsignedIntType - | typeof FloatType - | typeof HalfFloatType - | typeof UnsignedShort4444Type - | typeof UnsignedShort5551Type - | typeof UnsignedInt248Type - | typeof UnsignedInt5999Type; - -/////////////////////////////////////////////////////////////////////////////// -// Pixel formats - -/** {@link AlphaFormat} discards the red, green and blue components and reads just the alpha component. */ -export const AlphaFormat: 1021; - -export const RGBFormat: 1022; - -/** {@link RGBAFormat} is the default and reads the red, green, blue and alpha components. */ -export const RGBAFormat: 1023; - -/** - * {@link LuminanceFormat} reads each element as a single luminance component. - * This is then converted to a floating point, clamped to the range `[0,1]`, and then assembled into an RGBA element by - * placing the luminance value in the red, green and blue channels, and attaching `1.0` to the alpha channel. - */ -export const LuminanceFormat: 1024; - -/** - * {@link LuminanceAlphaFormat} reads each element as a luminance/alpha double. - * The same process occurs as for the {@link LuminanceFormat}, except that the alpha channel may have values other than `1.0`. - */ -export const LuminanceAlphaFormat: 1025; - -/** - * {@link DepthFormat} reads each element as a single depth value, converts it to floating point, and clamps to the range `[0,1]`. - * @remarks This is the default for {@link THREE.DepthTexture}. - */ -export const DepthFormat: 1026; - -/** - * {@link DepthStencilFormat} reads each element is a pair of depth and stencil values. - * The depth component of the pair is interpreted as in {@link DepthFormat}. - * The stencil component is interpreted based on the depth + stencil internal format. - */ -export const DepthStencilFormat: 1027; - -/** - * {@link RedFormat} discards the green and blue components and reads just the red component. - */ -export const RedFormat: 1028; - -/** - * {@link RedIntegerFormat} discards the green and blue components and reads just the red component. - * The texels are read as integers instead of floating point. - */ -export const RedIntegerFormat: 1029; - -/** - * {@link RGFormat} discards the alpha, and blue components and reads the red, and green components. - */ -export const RGFormat: 1030; - -/** - * {@link RGIntegerFormat} discards the alpha, and blue components and reads the red, and green components. - * The texels are read as integers instead of floating point. - */ -export const RGIntegerFormat: 1031; - -/** - * {@link RGBIntegerFormat} discrads the alpha components and reads the red, green, and blue components. - */ -export const RGBIntegerFormat: 1032; - -/** - * {@link RGBAIntegerFormat} reads the red, green, blue and alpha component - * @remarks This is the default for {@link THREE.Texture}. - */ -export const RGBAIntegerFormat: 1033; - -/** - * All Texture Pixel Formats Modes. - * @remarks Note that the texture must have the correct {@link THREE.Texture.type} set, as described in {@link TextureDataType}. - * @see {@link WebGLRenderingContext.texImage2D} for details. - * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} - */ -export type PixelFormat = - | typeof AlphaFormat - | typeof RGBFormat - | typeof RGBAFormat - | typeof LuminanceFormat - | typeof LuminanceAlphaFormat - | typeof DepthFormat - | typeof DepthStencilFormat - | typeof RedFormat - | typeof RedIntegerFormat - | typeof RGFormat - | typeof RGIntegerFormat - | typeof RGBIntegerFormat - | typeof RGBAIntegerFormat; - -/** - * All Texture Pixel Formats Modes for {@link THREE.DepthTexture}. - * @see {@link WebGLRenderingContext.texImage2D} for details. - * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} - */ -export type DepthTexturePixelFormat = typeof DepthFormat | typeof DepthStencilFormat; - -/////////////////////////////////////////////////////////////////////////////// -// Compressed texture formats -// DDS / ST3C Compressed texture formats - -/** - * A DXT1-compressed image in an RGB image format. - * @remarks Require support for the _WEBGL_compressed_texture_s3tc_ WebGL extension. - */ -export const RGB_S3TC_DXT1_Format: 33776; -/** - * A DXT1-compressed image in an RGB image format with a simple on/off alpha value. - * @remarks Require support for the _WEBGL_compressed_texture_s3tc_ WebGL extension. - */ -export const RGBA_S3TC_DXT1_Format: 33777; -/** - * A DXT3-compressed image in an RGBA image format. Compared to a 32-bit RGBA texture, it offers 4:1 compression. - * @remarks Require support for the _WEBGL_compressed_texture_s3tc_ WebGL extension. - */ -export const RGBA_S3TC_DXT3_Format: 33778; -/** - * A DXT5-compressed image in an RGBA image format. It also provides a 4:1 compression, but differs to the DXT3 compression in how the alpha compression is done. - * @remarks Require support for the _WEBGL_compressed_texture_s3tc_ WebGL extension. - */ -export const RGBA_S3TC_DXT5_Format: 33779; - -// PVRTC compressed './texture formats - -/** - * RGB compression in 4-bit mode. One block for each 4×4 pixels. - * @remarks Require support for the _WEBGL_compressed_texture_pvrtc_ WebGL extension. - */ -export const RGB_PVRTC_4BPPV1_Format: 35840; -/** - * RGB compression in 2-bit mode. One block for each 8×4 pixels. - * @remarks Require support for the _WEBGL_compressed_texture_pvrtc_ WebGL extension. - */ -export const RGB_PVRTC_2BPPV1_Format: 35841; -/** - * RGBA compression in 4-bit mode. One block for each 4×4 pixels. - * @remarks Require support for the _WEBGL_compressed_texture_pvrtc_ WebGL extension. - */ -export const RGBA_PVRTC_4BPPV1_Format: 35842; -/** - * RGBA compression in 2-bit mode. One block for each 8×4 pixels. - * @remarks Require support for the _WEBGL_compressed_texture_pvrtc_ WebGL extension. - */ -export const RGBA_PVRTC_2BPPV1_Format: 35843; - -// ETC compressed texture formats - -/** - * @remarks Require support for the _WEBGL_compressed_texture_etc1_ (ETC1) or _WEBGL_compressed_texture_etc_ (ETC2) WebGL extension. - */ -export const RGB_ETC1_Format: 36196; -/** - * @remarks Require support for the _WEBGL_compressed_texture_etc1_ (ETC1) or _WEBGL_compressed_texture_etc_ (ETC2) WebGL extension. - */ -export const RGB_ETC2_Format: 37492; -/** - * @remarks Require support for the _WEBGL_compressed_texture_etc1_ (ETC1) or _WEBGL_compressed_texture_etc_ (ETC2) WebGL extension. - */ -export const RGBA_ETC2_EAC_Format: 37496; - -// ASTC compressed texture formats - -/** - * @remarks Require support for the _WEBGL_compressed_texture_astc_ WebGL extension. - */ -export const RGBA_ASTC_4x4_Format: 37808; -/** - * @remarks Require support for the _WEBGL_compressed_texture_astc_ WebGL extension. - */ -export const RGBA_ASTC_5x4_Format: 37809; -/** - * @remarks Require support for the _WEBGL_compressed_texture_astc_ WebGL extension. - */ -export const RGBA_ASTC_5x5_Format: 37810; -/** - * @remarks Require support for the _WEBGL_compressed_texture_astc_ WebGL extension. - */ -export const RGBA_ASTC_6x5_Format: 37811; -/** - * @remarks Require support for the _WEBGL_compressed_texture_astc_ WebGL extension. - */ -export const RGBA_ASTC_6x6_Format: 37812; -/** - * @remarks Require support for the _WEBGL_compressed_texture_astc_ WebGL extension. - */ -export const RGBA_ASTC_8x5_Format: 37813; -/** - * @remarks Require support for the _WEBGL_compressed_texture_astc_ WebGL extension. - */ -export const RGBA_ASTC_8x6_Format: 37814; -/** - * @remarks Require support for the _WEBGL_compressed_texture_astc_ WebGL extension. - */ -export const RGBA_ASTC_8x8_Format: 37815; -/** - * @remarks Require support for the _WEBGL_compressed_texture_astc_ WebGL extension. - */ -export const RGBA_ASTC_10x5_Format: 37816; -/** - * @remarks Require support for the _WEBGL_compressed_texture_astc_ WebGL extension. - */ -export const RGBA_ASTC_10x6_Format: 37817; -/** - * @remarks Require support for the _WEBGL_compressed_texture_astc_ WebGL extension. - */ -export const RGBA_ASTC_10x8_Format: 37818; -/** - * @remarks Require support for the _WEBGL_compressed_texture_astc_ WebGL extension. - */ -export const RGBA_ASTC_10x10_Format: 37819; -/** - * @remarks Require support for the _WEBGL_compressed_texture_astc_ WebGL extension. - */ -export const RGBA_ASTC_12x10_Format: 37820; -/** - * @remarks Require support for the _WEBGL_compressed_texture_astc_ WebGL extension. - */ -export const RGBA_ASTC_12x12_Format: 37821; - -// BPTC compressed texture formats - -/** - * @remarks Require support for the _EXT_texture_compression_bptc_ WebGL extension. - */ -export const RGBA_BPTC_Format: 36492; -export const RGB_BPTC_SIGNED_Format = 36494; -export const RGB_BPTC_UNSIGNED_Format = 36495; - -// RGTC compressed texture formats -export const RED_RGTC1_Format: 36283; -export const SIGNED_RED_RGTC1_Format: 36284; -export const RED_GREEN_RGTC2_Format: 36285; -export const SIGNED_RED_GREEN_RGTC2_Format: 36286; - -/** - * For use with a {@link THREE.CompressedTexture}'s {@link THREE.CompressedTexture.format | .format} property. - * @remarks Compressed Require support for correct WebGL extension. - */ -export type CompressedPixelFormat = - | typeof RGB_S3TC_DXT1_Format - | typeof RGBA_S3TC_DXT1_Format - | typeof RGBA_S3TC_DXT3_Format - | typeof RGBA_S3TC_DXT5_Format - | typeof RGB_PVRTC_4BPPV1_Format - | typeof RGB_PVRTC_2BPPV1_Format - | typeof RGBA_PVRTC_4BPPV1_Format - | typeof RGBA_PVRTC_2BPPV1_Format - | typeof RGB_ETC1_Format - | typeof RGB_ETC2_Format - | typeof RGBA_ETC2_EAC_Format - | typeof RGBA_ASTC_4x4_Format - | typeof RGBA_ASTC_5x4_Format - | typeof RGBA_ASTC_5x5_Format - | typeof RGBA_ASTC_6x5_Format - | typeof RGBA_ASTC_6x6_Format - | typeof RGBA_ASTC_8x5_Format - | typeof RGBA_ASTC_8x6_Format - | typeof RGBA_ASTC_8x8_Format - | typeof RGBA_ASTC_10x5_Format - | typeof RGBA_ASTC_10x6_Format - | typeof RGBA_ASTC_10x8_Format - | typeof RGBA_ASTC_10x10_Format - | typeof RGBA_ASTC_12x10_Format - | typeof RGBA_ASTC_12x12_Format - | typeof RGBA_BPTC_Format - | typeof RGB_BPTC_SIGNED_Format - | typeof RGB_BPTC_UNSIGNED_Format - | typeof RED_RGTC1_Format - | typeof SIGNED_RED_RGTC1_Format - | typeof RED_GREEN_RGTC2_Format - | typeof SIGNED_RED_GREEN_RGTC2_Format; - -/////////////////////////////////////////////////////////////////////////////// - -/** - * All Possible Texture Pixel Formats Modes. For any Type or SubType of Textures. - * @remarks Note that the texture must have the correct {@link THREE.Texture.type} set, as described in {@link TextureDataType}. - * @see {@link WebGLRenderingContext.texImage2D} for details. - * @see {@link PixelFormat} and {@link DepthTexturePixelFormat} and {@link CompressedPixelFormat} - * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} - */ -export type AnyPixelFormat = PixelFormat | DepthTexturePixelFormat | CompressedPixelFormat; - -/////////////////////////////////////////////////////////////////////////////// -// Loop styles for AnimationAction -export const LoopOnce: 2200; -export const LoopRepeat: 2201; -export const LoopPingPong: 2202; -export type AnimationActionLoopStyles = typeof LoopOnce | typeof LoopRepeat | typeof LoopPingPong; - -// Interpolation -export const InterpolateDiscrete: 2300; -export const InterpolateLinear: 2301; -export const InterpolateSmooth: 2302; -export type InterpolationModes = typeof InterpolateDiscrete | typeof InterpolateLinear | typeof InterpolateSmooth; - -// Interpolant ending modes -export const ZeroCurvatureEnding: 2400; -export const ZeroSlopeEnding: 2401; -export const WrapAroundEnding: 2402; -export type InterpolationEndingModes = typeof ZeroCurvatureEnding | typeof ZeroSlopeEnding | typeof WrapAroundEnding; - -// Animation blending modes -export const NormalAnimationBlendMode: 2500; -export const AdditiveAnimationBlendMode: 2501; -export type AnimationBlendMode = typeof NormalAnimationBlendMode | typeof AdditiveAnimationBlendMode; - -// Triangle Draw modes -export const TrianglesDrawMode: 0; -export const TriangleStripDrawMode: 1; -export const TriangleFanDrawMode: 2; -export type TrianglesDrawModes = typeof TrianglesDrawMode | typeof TriangleStripDrawMode | typeof TriangleFanDrawMode; - -/////////////////////////////////////////////////////////////////////////////// -// Depth packing strategies - -export const BasicDepthPacking: 3200; -export const RGBADepthPacking: 3201; -export const RGBDepthPacking: 3202; -export const RGDepthPacking: 3203; -export type DepthPackingStrategies = - | typeof BasicDepthPacking - | typeof RGBADepthPacking - | typeof RGBDepthPacking - | typeof RGDepthPacking; - -/////////////////////////////////////////////////////////////////////////////// -// Normal Map types - -export const TangentSpaceNormalMap: 0; -export const ObjectSpaceNormalMap: 1; -export type NormalMapTypes = typeof TangentSpaceNormalMap | typeof ObjectSpaceNormalMap; - -export const NoColorSpace: ""; -export const SRGBColorSpace: "srgb"; -export const LinearSRGBColorSpace: "srgb-linear"; -export type ColorSpace = - | typeof NoColorSpace - | typeof SRGBColorSpace - | typeof LinearSRGBColorSpace; - -export const LinearTransfer: "linear"; -export const SRGBTransfer: "srgb"; -export type ColorSpaceTransfer = typeof LinearTransfer | typeof SRGBTransfer; - -// Stencil Op types -export const ZeroStencilOp: 0; -export const KeepStencilOp: 7680; -export const ReplaceStencilOp: 7681; -export const IncrementStencilOp: 7682; -export const DecrementStencilOp: 7283; -export const IncrementWrapStencilOp: 34055; -export const DecrementWrapStencilOp: 34056; -export const InvertStencilOp: 5386; -export type StencilOp = - | typeof ZeroStencilOp - | typeof KeepStencilOp - | typeof ReplaceStencilOp - | typeof IncrementStencilOp - | typeof DecrementStencilOp - | typeof IncrementWrapStencilOp - | typeof DecrementWrapStencilOp - | typeof InvertStencilOp; - -// Stencil Func types -export const NeverStencilFunc: 512; -export const LessStencilFunc: 513; -export const EqualStencilFunc: 514; -export const LessEqualStencilFunc: 515; -export const GreaterStencilFunc: 516; -export const NotEqualStencilFunc: 517; -export const GreaterEqualStencilFunc: 518; -export const AlwaysStencilFunc: 519; -export type StencilFunc = - | typeof NeverStencilFunc - | typeof LessStencilFunc - | typeof EqualStencilFunc - | typeof LessEqualStencilFunc - | typeof GreaterStencilFunc - | typeof NotEqualStencilFunc - | typeof GreaterEqualStencilFunc - | typeof AlwaysStencilFunc; - -export const NeverCompare: 512; -export const LessCompare: 513; -export const EqualCompare: 514; -export const LessEqualCompare: 515; -export const GreaterCompare: 516; -export const NotEqualCompare: 517; -export const GreaterEqualCompare: 518; -export const AlwaysCompare: 519; -export type TextureComparisonFunction = - | typeof NeverCompare - | typeof LessCompare - | typeof EqualCompare - | typeof LessEqualCompare - | typeof GreaterCompare - | typeof NotEqualCompare - | typeof GreaterEqualCompare - | typeof AlwaysCompare; - -// usage types -export const StaticDrawUsage: 35044; -export const DynamicDrawUsage: 35048; -export const StreamDrawUsage: 35040; -export const StaticReadUsage: 35045; -export const DynamicReadUsage: 35049; -export const StreamReadUsage: 35041; -export const StaticCopyUsage: 35046; -export const DynamicCopyUsage: 35050; -export const StreamCopyUsage: 35042; -export type Usage = - | typeof StaticDrawUsage - | typeof DynamicDrawUsage - | typeof StreamDrawUsage - | typeof StaticReadUsage - | typeof DynamicReadUsage - | typeof StreamReadUsage - | typeof StaticCopyUsage - | typeof DynamicCopyUsage - | typeof StreamCopyUsage; - -export const GLSL1: "100"; -export const GLSL3: "300 es"; -export type GLSLVersion = typeof GLSL1 | typeof GLSL3; - -export const WebGLCoordinateSystem: 2000; -export const WebGPUCoordinateSystem: 2001; -export type CoordinateSystem = typeof WebGLCoordinateSystem | typeof WebGPUCoordinateSystem; - -/////////////////////////////////////////////////////////////////////////////// -// Texture - Internal Pixel Formats - -/** - * For use with a texture's {@link THREE.Texture.internalFormat} property, these define how elements of a {@link THREE.Texture}, or texels, are stored on the GPU. - * - `R8` stores the red component on 8 bits. - * - `R8_SNORM` stores the red component on 8 bits. The component is stored as normalized. - * - `R8I` stores the red component on 8 bits. The component is stored as an integer. - * - `R8UI` stores the red component on 8 bits. The component is stored as an unsigned integer. - * - `R16I` stores the red component on 16 bits. The component is stored as an integer. - * - `R16UI` stores the red component on 16 bits. The component is stored as an unsigned integer. - * - `R16F` stores the red component on 16 bits. The component is stored as floating point. - * - `R32I` stores the red component on 32 bits. The component is stored as an integer. - * - `R32UI` stores the red component on 32 bits. The component is stored as an unsigned integer. - * - `R32F` stores the red component on 32 bits. The component is stored as floating point. - * - `RG8` stores the red and green components on 8 bits each. - * - `RG8_SNORM` stores the red and green components on 8 bits each. Every component is stored as normalized. - * - `RG8I` stores the red and green components on 8 bits each. Every component is stored as an integer. - * - `RG8UI` stores the red and green components on 8 bits each. Every component is stored as an unsigned integer. - * - `RG16I` stores the red and green components on 16 bits each. Every component is stored as an integer. - * - `RG16UI` stores the red and green components on 16 bits each. Every component is stored as an unsigned integer. - * - `RG16F` stores the red and green components on 16 bits each. Every component is stored as floating point. - * - `RG32I` stores the red and green components on 32 bits each. Every component is stored as an integer. - * - `RG32UI` stores the red and green components on 32 bits. Every component is stored as an unsigned integer. - * - `RG32F` stores the red and green components on 32 bits. Every component is stored as floating point. - * - `RGB8` stores the red, green, and blue components on 8 bits each. RGB8_SNORM` stores the red, green, and blue components on 8 bits each. Every component is stored as normalized. - * - `RGB8I` stores the red, green, and blue components on 8 bits each. Every component is stored as an integer. - * - `RGB8UI` stores the red, green, and blue components on 8 bits each. Every component is stored as an unsigned integer. - * - `RGB16I` stores the red, green, and blue components on 16 bits each. Every component is stored as an integer. - * - `RGB16UI` stores the red, green, and blue components on 16 bits each. Every component is stored as an unsigned integer. - * - `RGB16F` stores the red, green, and blue components on 16 bits each. Every component is stored as floating point - * - `RGB32I` stores the red, green, and blue components on 32 bits each. Every component is stored as an integer. - * - `RGB32UI` stores the red, green, and blue components on 32 bits each. Every component is stored as an unsigned integer. - * - `RGB32F` stores the red, green, and blue components on 32 bits each. Every component is stored as floating point - * - `R11F_G11F_B10F` stores the red, green, and blue components respectively on 11 bits, 11 bits, and 10bits. Every component is stored as floating point. - * - `RGB565` stores the red, green, and blue components respectively on 5 bits, 6 bits, and 5 bits. - * - `RGB9_E5` stores the red, green, and blue components on 9 bits each. - * - `RGBA8` stores the red, green, blue, and alpha components on 8 bits each. - * - `RGBA8_SNORM` stores the red, green, blue, and alpha components on 8 bits. Every component is stored as normalized. - * - `RGBA8I` stores the red, green, blue, and alpha components on 8 bits each. Every component is stored as an integer. - * - `RGBA8UI` stores the red, green, blue, and alpha components on 8 bits. Every component is stored as an unsigned integer. - * - `RGBA16I` stores the red, green, blue, and alpha components on 16 bits. Every component is stored as an integer. - * - `RGBA16UI` stores the red, green, blue, and alpha components on 16 bits. Every component is stored as an unsigned integer. - * - `RGBA16F` stores the red, green, blue, and alpha components on 16 bits. Every component is stored as floating point. - * - `RGBA32I` stores the red, green, blue, and alpha components on 32 bits. Every component is stored as an integer. - * - `RGBA32UI` stores the red, green, blue, and alpha components on 32 bits. Every component is stored as an unsigned integer. - * - `RGBA32F` stores the red, green, blue, and alpha components on 32 bits. Every component is stored as floating point. - * - `RGB5_A1` stores the red, green, blue, and alpha components respectively on 5 bits, 5 bits, 5 bits, and 1 bit. - * - `RGB10_A2` stores the red, green, blue, and alpha components respectively on 10 bits, 10 bits, 10 bits and 2 bits. - * - `RGB10_A2UI` stores the red, green, blue, and alpha components respectively on 10 bits, 10 bits, 10 bits and 2 bits. Every component is stored as an unsigned integer. - * - `SRGB8` stores the red, green, and blue components on 8 bits each. - * - `SRGB8_ALPHA8` stores the red, green, blue, and alpha components on 8 bits each. - * - `DEPTH_COMPONENT16` stores the depth component on 16bits. - * - `DEPTH_COMPONENT24` stores the depth component on 24bits. - * - `DEPTH_COMPONENT32F` stores the depth component on 32bits. The component is stored as floating point. - * - `DEPTH24_STENCIL8` stores the depth, and stencil components respectively on 24 bits and 8 bits. The stencil component is stored as an unsigned integer. - * - `DEPTH32F_STENCIL8` stores the depth, and stencil components respectively on 32 bits and 8 bits. The depth component is stored as floating point, and the stencil component as an unsigned integer. - * @remark Note that the texture must have the correct {@link THREE.Texture.type} set, as well as the correct {@link THREE.Texture.format}. - * @see {@link WebGLRenderingContext.texImage2D} and {@link WebGLRenderingContext.texImage3D} for more details regarding the possible combination - * of {@link THREE.Texture.format}, {@link THREE.Texture.internalFormat}, and {@link THREE.Texture.type}. - * @see {@link https://registry.khronos.org/webgl/specs/latest/2.0/ | WebGL2 Specification} and - * {@link https://registry.khronos.org/OpenGL/specs/es/3.0/es_spec_3.0.pdf | OpenGL ES 3.0 Specification} For more in-depth information regarding internal formats. - */ -export type PixelFormatGPU = - | "ALPHA" - | "RGB" - | "RGBA" - | "LUMINANCE" - | "LUMINANCE_ALPHA" - | "RED_INTEGER" - | "R8" - | "R8_SNORM" - | "R8I" - | "R8UI" - | "R16I" - | "R16UI" - | "R16F" - | "R32I" - | "R32UI" - | "R32F" - | "RG8" - | "RG8_SNORM" - | "RG8I" - | "RG8UI" - | "RG16I" - | "RG16UI" - | "RG16F" - | "RG32I" - | "RG32UI" - | "RG32F" - | "RGB565" - | "RGB8" - | "RGB8_SNORM" - | "RGB8I" - | "RGB8UI" - | "RGB16I" - | "RGB16UI" - | "RGB16F" - | "RGB32I" - | "RGB32UI" - | "RGB32F" - | "RGB9_E5" - | "SRGB8" - | "R11F_G11F_B10F" - | "RGBA4" - | "RGBA8" - | "RGBA8_SNORM" - | "RGBA8I" - | "RGBA8UI" - | "RGBA16I" - | "RGBA16UI" - | "RGBA16F" - | "RGBA32I" - | "RGBA32UI" - | "RGBA32F" - | "RGB5_A1" - | "RGB10_A2" - | "RGB10_A2UI" - | "SRGB8_ALPHA8" - | "SRGB8" - | "DEPTH_COMPONENT16" - | "DEPTH_COMPONENT24" - | "DEPTH_COMPONENT32F" - | "DEPTH24_STENCIL8" - | "DEPTH32F_STENCIL8"; diff --git a/src-testing/src/core/BufferAttribute.d.ts b/src-testing/src/core/BufferAttribute.d.ts deleted file mode 100644 index 01e8e882d..000000000 --- a/src-testing/src/core/BufferAttribute.d.ts +++ /dev/null @@ -1,622 +0,0 @@ -import { AttributeGPUType, Usage } from "../constants.js"; -import { Matrix3 } from "../math/Matrix3.js"; -import { Matrix4 } from "../math/Matrix4.js"; - -export type TypedArray = - | Int8Array - | Uint8Array - | Uint8ClampedArray - | Int16Array - | Uint16Array - | Int32Array - | Uint32Array - | Float32Array - | Float64Array; - -export interface BufferAttributeJSON { - itemSize: number; - type: string; - array: number[]; - normalized: boolean; - - name?: string; - usage?: Usage; -} - -/** - * This class stores data for an attribute (such as vertex positions, face indices, normals, colors, UVs, and any custom attributes ) - * associated with a {@link THREE.BufferGeometry | BufferGeometry}, which allows for more efficient passing of data to the GPU - * @remarks - * When working with _vector-like_ data, the _`.fromBufferAttribute( attribute, index )`_ helper methods on - * {@link THREE.Vector2.fromBufferAttribute | Vector2}, - * {@link THREE.Vector3.fromBufferAttribute | Vector3}, - * {@link THREE.Vector4.fromBufferAttribute | Vector4}, and - * {@link THREE.Color.fromBufferAttribute | Color} classes may be helpful. - * @see {@link THREE.BufferGeometry | BufferGeometry} for details and a usage examples. - * @see Example: {@link https://threejs.org/examples/#webgl_buffergeometry | WebGL / BufferGeometry - Clean up Memory} - * @see {@link https://threejs.org/docs/index.html#api/en/core/BufferAttribute | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/BufferAttribute.js | Source} - */ -export class BufferAttribute { - /** - * This creates a new {@link THREE.GLBufferAttribute | GLBufferAttribute} object. - * @param array Must be a `TypedArray`. Used to instantiate the buffer. - * This array should have `itemSize * numVertices` elements, where numVertices is the number of vertices in the associated {@link THREE.BufferGeometry | BufferGeometry}. - * @param itemSize the number of values of the {@link array} that should be associated with a particular vertex. - * For instance, if this attribute is storing a 3-component vector (such as a _position_, _normal_, or _color_), - * then itemSize should be `3`. - * @param normalized Applies to integer data only. - * Indicates how the underlying data in the buffer maps to the values in the GLSL code. - * For instance, if {@link array} is an instance of `UInt16Array`, and {@link normalized} is true, - * the values `0` - `+65535` in the array data will be mapped to `0.0f` - `+1.0f` in the GLSL attribute. - * An `Int16Array` (signed) would map from `-32768` - `+32767` to `-1.0f` - `+1.0f`. - * If normalized is false, the values will be converted to floats unmodified, - * i.e. `32767` becomes `32767.0f`. - * Default `false`. - * @throws `TypeError` When the {@link array} is not a `TypedArray`; - */ - constructor(array: TypedArray, itemSize: number, normalized?: boolean); - - /** - * Optional name for this attribute instance. - * @defaultValue '' - */ - name: string; - - /** - * The {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray | TypedArray} holding data stored in the buffer. - * @returns `TypedArray` - */ - array: TypedArray; - - /** - * The length of vectors that are being stored in the {@link BufferAttribute.array | array}. - * @remarks Expects a `Integer` - */ - itemSize: number; - - /** - * Defines the intended usage pattern of the data store for optimization purposes. - * Corresponds to the {@link BufferAttribute.usage | usage} parameter of - * {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/bufferData | WebGLRenderingContext.bufferData}. - * @remarks - * After the initial use of a buffer, its usage cannot be changed. Instead, instantiate a new one and set the desired usage before the next render. - * @see {@link https://threejs.org/docs/index.html#api/en/constants/BufferAttributeUsage | Buffer Attribute Usage Constants} for all possible values. - * @see {@link BufferAttribute.setUsage | setUsage} - * @defaultValue {@link THREE.StaticDrawUsage | THREE.StaticDrawUsage}. - */ - usage: Usage; - - /** - * Configures the bound GPU type for use in shaders. Either {@link FloatType} or {@link IntType}, default is {@link FloatType}. - * - * Note: this only has an effect for integer arrays and is not configurable for float arrays. For lower precision - * float types, see https://threejs.org/docs/#api/en/core/bufferAttributeTypes/BufferAttributeTypes. - */ - gpuType: AttributeGPUType; - - /** - * This can be used to only update some components of stored vectors (for example, just the component related to - * color). Use the {@link .addUpdateRange} function to add ranges to this array. - */ - updateRanges: Array<{ - /** - * Position at which to start update. - */ - start: number; - /** - * The number of components to update. - */ - count: number; - }>; - - /** - * A version number, incremented every time the {@link BufferAttribute.needsUpdate | needsUpdate} property is set to true. - * @remarks Expects a `Integer` - * @defaultValue `0` - */ - version: number; - - /** - * Indicates how the underlying data in the buffer maps to the values in the GLSL shader code. - * @see `constructor` above for details. - * @defaultValue `false` - */ - normalized: boolean; - - /** - * Represents the number of items this buffer attribute stores. It is internally computed by dividing the - * {@link BufferAttribute.array | array}'s length by the {@link BufferAttribute.itemSize | itemSize}. Read-only - * property. - */ - readonly count: number; - - /** - * Flag to indicate that this attribute has changed and should be re-sent to the GPU. - * Set this to true when you modify the value of the array. - * @remarks Setting this to true also increments the {@link BufferAttribute.version | version}. - * @remarks _set-only property_. - */ - set needsUpdate(value: boolean); - - /** - * Read-only flag to check if a given object is of type {@link BufferAttribute}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isBufferAttribute: true; - - /** - * A callback function that is executed after the Renderer has transferred the attribute array data to the GPU. - */ - onUploadCallback: () => void; - - /** - * Sets the value of the {@link onUploadCallback} property. - * @see Example: {@link https://threejs.org/examples/#webgl_buffergeometry | WebGL / BufferGeometry} this is used to free memory after the buffer has been transferred to the GPU. - * @see {@link onUploadCallback} - * @param callback function that is executed after the Renderer has transferred the attribute array data to the GPU. - */ - onUpload(callback: () => void): this; - - /** - * Set {@link BufferAttribute.usage | usage} - * @remarks - * After the initial use of a buffer, its usage cannot be changed. Instead, instantiate a new one and set the desired usage before the next render. - * @see {@link https://threejs.org/docs/index.html#api/en/constants/BufferAttributeUsage | Buffer Attribute Usage Constants} for all possible values. - * @see {@link BufferAttribute.usage | usage} - * @param value Corresponds to the {@link BufferAttribute.usage | usage} parameter of - * {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/bufferData | WebGLRenderingContext.bufferData}. - */ - setUsage(usage: Usage): this; - - /** - * Adds a range of data in the data array to be updated on the GPU. Adds an object describing the range to the - * {@link .updateRanges} array. - */ - addUpdateRange(start: number, count: number): void; - - /** - * Clears the {@link .updateRanges} array. - */ - clearUpdateRanges(): void; - - /** - * @returns a copy of this {@link BufferAttribute}. - */ - clone(): BufferAttribute; - - /** - * Copies another {@link BufferAttribute} to this {@link BufferAttribute}. - * @param bufferAttribute - */ - copy(source: BufferAttribute): this; - - /** - * Copy a vector from bufferAttribute[index2] to {@link BufferAttribute.array | array}[index1]. - * @param index1 - * @param bufferAttribute - * @param index2 - */ - copyAt(index1: number, attribute: BufferAttribute, index2: number): this; - - /** - * Copy the array given here (which can be a normal array or `TypedArray`) into {@link BufferAttribute.array | array}. - * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set | TypedArray.set} for notes on requirements if copying a `TypedArray`. - */ - copyArray(array: ArrayLike): this; - - /** - * Applies matrix {@link Matrix3 | m} to every Vector3 element of this {@link BufferAttribute}. - * @param m - */ - applyMatrix3(m: Matrix3): this; - - /** - * Applies matrix {@link Matrix4 | m} to every Vector3 element of this {@link BufferAttribute}. - * @param m - */ - applyMatrix4(m: Matrix4): this; - - /** - * Applies normal matrix {@link Matrix3 | m} to every Vector3 element of this {@link BufferAttribute}. - * @param m - */ - applyNormalMatrix(m: Matrix3): this; - - /** - * Applies matrix {@link Matrix4 | m} to every Vector3 element of this {@link BufferAttribute}, interpreting the elements as a direction vectors. - * @param m - */ - transformDirection(m: Matrix4): this; - - /** - * Calls {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set | TypedArray.set}( {@link value}, {@link offset} ) - * on the {@link BufferAttribute.array | array}. - * @param value {@link Array | Array} or `TypedArray` from which to copy values. - * @param offset index of the {@link BufferAttribute.array | array} at which to start copying. Expects a `Integer`. Default `0`. - * @throws `RangeError` When {@link offset} is negative or is too large. - */ - set(value: ArrayLike | ArrayBufferView, offset?: number): this; - - /** - * Returns the given component of the vector at the given index. - */ - getComponent(index: number, component: number): number; - - /** - * Sets the given component of the vector at the given index. - */ - setComponent(index: number, component: number, value: number): void; - - /** - * Returns the x component of the vector at the given index. - * @param index Expects a `Integer` - */ - getX(index: number): number; - - /** - * Sets the x component of the vector at the given index. - * @param index Expects a `Integer` - * @param x - */ - setX(index: number, x: number): this; - - /** - * Returns the y component of the vector at the given index. - * @param index Expects a `Integer` - */ - getY(index: number): number; - - /** - * Sets the y component of the vector at the given index. - * @param index Expects a `Integer` - * @param y - */ - setY(index: number, y: number): this; - - /** - * Returns the z component of the vector at the given index. - * @param index Expects a `Integer` - */ - getZ(index: number): number; - - /** - * Sets the z component of the vector at the given index. - * @param index Expects a `Integer` - * @param z - */ - setZ(index: number, z: number): this; - - /** - * Returns the w component of the vector at the given index. - * @param index Expects a `Integer` - */ - getW(index: number): number; - - /** - * Sets the w component of the vector at the given index. - * @param index Expects a `Integer` - * @param w - */ - setW(index: number, z: number): this; - - /** - * Sets the x and y components of the vector at the given index. - * @param index Expects a `Integer` - * @param x - * @param y - */ - setXY(index: number, x: number, y: number): this; - - /** - * Sets the x, y and z components of the vector at the given index. - * @param index Expects a `Integer` - * @param x - * @param y - * @param z - */ - setXYZ(index: number, x: number, y: number, z: number): this; - - /** - * Sets the x, y, z and w components of the vector at the given index. - * @param index Expects a `Integer` - * @param x - * @param y - * @param z - * @param w - */ - setXYZW(index: number, x: number, y: number, z: number, w: number): this; - - /** - * Convert this object to three.js to the `data.attributes` part of {@link https://github.com/mrdoob/three.js/wiki/JSON-Geometry-format-4 | JSON Geometry format v4}, - */ - toJSON(): BufferAttributeJSON; -} - -/** - * A {@link THREE.BufferAttribute | BufferAttribute} for {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Int8Array: Int8Array} - * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray#typedarray_objects | TypedArray} - * @see {@link THREE.BufferAttribute | BufferAttribute} for details and for inherited methods and properties. - * @see {@link https://threejs.org/docs/index.html#api/en/core/bufferAttributeTypes/BufferAttributeTypes | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/BufferAttribute.js | Source} - */ -export class Int8BufferAttribute extends BufferAttribute { - /** - * This creates a new {@link THREE.Int8BufferAttribute | Int8BufferAttribute} object. - * @param array This can be a typed or untyped (normal) array or an integer length. An array value will be converted to `Int8Array`. - * If a length is given a new `TypedArray` will created, initialized with all elements set to zero. - * @param itemSize the number of values of the {@link array} that should be associated with a particular vertex. - * For instance, if this attribute is storing a 3-component vector (such as a _position_, _normal_, or _color_), - * then itemSize should be `3`. - * @param normalized Applies to integer data only. - * Indicates how the underlying data in the buffer maps to the values in the GLSL code. - * For instance, if {@link array} is an instance of `UInt16Array`, and {@link normalized} is true, - * the values `0` - `+65535` in the array data will be mapped to `0.0f` - `+1.0f` in the GLSL attribute. - * An `Int16Array` (signed) would map from `-32768` - `+32767` to `-1.0f` - `+1.0f`. - * If normalized is false, the values will be converted to floats unmodified, - * i.e. `32767` becomes `32767.0f`. - * Default `false`. - */ - constructor( - array: Iterable | ArrayLike | ArrayBuffer | number, - itemSize: number, - normalized?: boolean, - ); -} - -/** - * A {@link THREE.BufferAttribute | BufferAttribute} for {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array: Uint8Array} - * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray#typedarray_objects | TypedArray} - * @see {@link THREE.BufferAttribute | BufferAttribute} for details and for inherited methods and properties. - * @see {@link https://threejs.org/docs/index.html#api/en/core/bufferAttributeTypes/BufferAttributeTypes | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/BufferAttribute.js | Source} - */ -export class Uint8BufferAttribute extends BufferAttribute { - /** - * This creates a new {@link THREE.Uint8BufferAttribute | Uint8BufferAttribute} object. - * @param array This can be a typed or untyped (normal) array or an integer length. An array value will be converted to `Uint8Array`. - * If a length is given a new `TypedArray` will created, initialized with all elements set to zero. - * @param itemSize the number of values of the {@link array} that should be associated with a particular vertex. - * For instance, if this attribute is storing a 3-component vector (such as a _position_, _normal_, or _color_), - * then itemSize should be `3`. - * @param normalized Applies to integer data only. - * Indicates how the underlying data in the buffer maps to the values in the GLSL code. - * For instance, if {@link array} is an instance of `UInt16Array`, and {@link normalized} is true, - * the values `0` - `+65535` in the array data will be mapped to `0.0f` - `+1.0f` in the GLSL attribute. - * An `Int16Array` (signed) would map from `-32768` - `+32767` to `-1.0f` - `+1.0f`. - * If normalized is false, the values will be converted to floats unmodified, - * i.e. `32767` becomes `32767.0f`. - * Default `false`. - * @see {@link THREE.BufferAttribute | BufferAttribute} - */ - constructor( - array: Iterable | ArrayLike | ArrayBuffer | number, - itemSize: number, - normalized?: boolean, - ); -} - -/** - * A {@link THREE.BufferAttribute | BufferAttribute} for {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8ClampedArray: Uint8ClampedArray} - * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray#typedarray_objects | TypedArray} - * @see {@link THREE.BufferAttribute | BufferAttribute} for details and for inherited methods and properties. - * @see {@link https://threejs.org/docs/index.html#api/en/core/bufferAttributeTypes/BufferAttributeTypes | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/BufferAttribute.js | Source} - */ -export class Uint8ClampedBufferAttribute extends BufferAttribute { - /** - * This creates a new {@link THREE.Uint8ClampedBufferAttribute | Uint8ClampedBufferAttribute} object. - * @param array This can be a typed or untyped (normal) array or an integer length. An array value will be converted to `Uint8ClampedArray`. - * If a length is given a new `TypedArray` will created, initialized with all elements set to zero. - * @param itemSize the number of values of the {@link array} that should be associated with a particular vertex. - * For instance, if this attribute is storing a 3-component vector (such as a _position_, _normal_, or _color_), - * then itemSize should be `3`. - * @param normalized Applies to integer data only. - * Indicates how the underlying data in the buffer maps to the values in the GLSL code. - * For instance, if {@link array} is an instance of `UInt16Array`, and {@link normalized} is true, - * the values `0` - `+65535` in the array data will be mapped to `0.0f` - `+1.0f` in the GLSL attribute. - * An `Int16Array` (signed) would map from `-32768` - `+32767` to `-1.0f` - `+1.0f`. - * If normalized is false, the values will be converted to floats unmodified, - * i.e. `32767` becomes `32767.0f`. - * Default `false`. - * @see {@link THREE.BufferAttribute | BufferAttribute} - */ - constructor( - array: Iterable | ArrayLike | ArrayBuffer | number, - itemSize: number, - normalized?: boolean, - ); -} - -/** - * A {@link THREE.BufferAttribute | BufferAttribute} for {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Int16Array: Int16Array} - * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray#typedarray_objects | TypedArray} - * @see {@link THREE.BufferAttribute | BufferAttribute} for details and for inherited methods and properties. - * @see {@link https://threejs.org/docs/index.html#api/en/core/bufferAttributeTypes/BufferAttributeTypes | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/BufferAttribute.js | Source} - */ -export class Int16BufferAttribute extends BufferAttribute { - /** - * This creates a new {@link THREE.Int16BufferAttribute | Int16BufferAttribute} object. - * @param array This can be a typed or untyped (normal) array or an integer length. An array value will be converted to `Int16Array`. - * If a length is given a new `TypedArray` will created, initialized with all elements set to zero. - * @param itemSize the number of values of the {@link array} that should be associated with a particular vertex. - * For instance, if this attribute is storing a 3-component vector (such as a _position_, _normal_, or _color_), - * then itemSize should be `3`. - * @param normalized Applies to integer data only. - * Indicates how the underlying data in the buffer maps to the values in the GLSL code. - * For instance, if {@link array} is an instance of `UInt16Array`, and {@link normalized} is true, - * the values `0` - `+65535` in the array data will be mapped to `0.0f` - `+1.0f` in the GLSL attribute. - * An `Int16Array` (signed) would map from `-32768` - `+32767` to `-1.0f` - `+1.0f`. - * If normalized is false, the values will be converted to floats unmodified, - * i.e. `32767` becomes `32767.0f`. - * Default `false`. - * @see {@link THREE.BufferAttribute | BufferAttribute} - */ - constructor( - array: Iterable | ArrayLike | ArrayBuffer | number, - itemSize: number, - normalized?: boolean, - ); -} - -/** - * A {@link THREE.BufferAttribute | BufferAttribute} for {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint16Array: Uint16Array} - * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray#typedarray_objects | TypedArray} - * @see {@link THREE.BufferAttribute | BufferAttribute} for details and for inherited methods and properties. - * @see {@link https://threejs.org/docs/index.html#api/en/core/bufferAttributeTypes/BufferAttributeTypes | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/BufferAttribute.js | Source} - */ -export class Uint16BufferAttribute extends BufferAttribute { - /** - * This creates a new {@link THREE.Uint16BufferAttribute | Uint16BufferAttribute} object. - * @param array This can be a typed or untyped (normal) array or an integer length. An array value will be converted to `Uint16Array`. - * If a length is given a new `TypedArray` will created, initialized with all elements set to zero. - * @param itemSize the number of values of the {@link array} that should be associated with a particular vertex. - * For instance, if this attribute is storing a 3-component vector (such as a _position_, _normal_, or _color_), - * then itemSize should be `3`. - * @param normalized Applies to integer data only. - * Indicates how the underlying data in the buffer maps to the values in the GLSL code. - * For instance, if {@link array} is an instance of `UInt16Array`, and {@link normalized} is true, - * the values `0` - `+65535` in the array data will be mapped to `0.0f` - `+1.0f` in the GLSL attribute. - * An `Int16Array` (signed) would map from `-32768` - `+32767` to `-1.0f` - `+1.0f`. - * If normalized is false, the values will be converted to floats unmodified, - * i.e. `32767` becomes `32767.0f`. - * Default `false`. - * @see {@link THREE.BufferAttribute | BufferAttribute} - */ - constructor( - array: Iterable | ArrayLike | ArrayBuffer | number, - itemSize: number, - normalized?: boolean, - ); -} - -/** - * A {@link THREE.BufferAttribute | BufferAttribute} for {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Int32Array: Int32Array} - * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray#typedarray_objects | TypedArray} - * @see {@link THREE.BufferAttribute | BufferAttribute} for details and for inherited methods and properties. - * @see {@link https://threejs.org/docs/index.html#api/en/core/bufferAttributeTypes/BufferAttributeTypes | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/BufferAttribute.js | Source} - */ -export class Int32BufferAttribute extends BufferAttribute { - /** - * This creates a new {@link THREE.Int32BufferAttribute | Int32BufferAttribute} object. - * @param array This can be a typed or untyped (normal) array or an integer length. An array value will be converted to `Int32Array`. - * If a length is given a new `TypedArray` will created, initialized with all elements set to zero. - * @param itemSize the number of values of the {@link array} that should be associated with a particular vertex. - * For instance, if this attribute is storing a 3-component vector (such as a _position_, _normal_, or _color_), - * then itemSize should be `3`. - * @param normalized Applies to integer data only. - * Indicates how the underlying data in the buffer maps to the values in the GLSL code. - * For instance, if {@link array} is an instance of `UInt16Array`, and {@link normalized} is true, - * the values `0` - `+65535` in the array data will be mapped to `0.0f` - `+1.0f` in the GLSL attribute. - * An `Int16Array` (signed) would map from `-32768` - `+32767` to `-1.0f` - `+1.0f`. - * If normalized is false, the values will be converted to floats unmodified, - * i.e. `32767` becomes `32767.0f`. - * Default `false`. - * @see {@link THREE.BufferAttribute | BufferAttribute} - */ - constructor( - array: Iterable | ArrayLike | ArrayBuffer | number, - itemSize: number, - normalized?: boolean, - ); -} - -/** - * A {@link THREE.BufferAttribute | BufferAttribute} for {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint32Array: Uint32Array} - * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray#typedarray_objects | TypedArray} - * @see {@link THREE.BufferAttribute | BufferAttribute} for details and for inherited methods and properties. - * @see {@link https://threejs.org/docs/index.html#api/en/core/bufferAttributeTypes/BufferAttributeTypes | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/BufferAttribute.js | Source} - */ -export class Uint32BufferAttribute extends BufferAttribute { - /** - * This creates a new {@link THREE.Uint32BufferAttribute | Uint32BufferAttribute} object. - * @param array This can be a typed or untyped (normal) array or an integer length. An array value will be converted to `Uint32Array`. - * If a length is given a new `TypedArray` will created, initialized with all elements set to zero. - * @param itemSize the number of values of the {@link array} that should be associated with a particular vertex. - * For instance, if this attribute is storing a 3-component vector (such as a _position_, _normal_, or _color_), - * then itemSize should be `3`. - * @param normalized Applies to integer data only. - * Indicates how the underlying data in the buffer maps to the values in the GLSL code. - * For instance, if {@link array} is an instance of `UInt16Array`, and {@link normalized} is true, - * the values `0` - `+65535` in the array data will be mapped to `0.0f` - `+1.0f` in the GLSL attribute. - * An `Int16Array` (signed) would map from `-32768` - `+32767` to `-1.0f` - `+1.0f`. - * If normalized is false, the values will be converted to floats unmodified, - * i.e. `32767` becomes `32767.0f`. - * Default `false`. - * @see {@link THREE.BufferAttribute | BufferAttribute} - */ - constructor( - array: Iterable | ArrayLike | ArrayBuffer | number, - itemSize: number, - normalized?: boolean, - ); -} - -/** - * A {@link THREE.BufferAttribute | BufferAttribute} for {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint16Array: Uint16Array} - * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray#typedarray_objects | TypedArray} - * @see {@link THREE.BufferAttribute | BufferAttribute} for details and for inherited methods and properties. - * @see {@link https://threejs.org/docs/index.html#api/en/core/bufferAttributeTypes/BufferAttributeTypes | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/BufferAttribute.js | Source} - */ -export class Float16BufferAttribute extends BufferAttribute { - /** - * This creates a new {@link THREE.Float16BufferAttribute | Float16BufferAttribute} object. - * @param array This can be a typed or untyped (normal) array or an integer length. An array value will be converted to `Uint16Array`. - * If a length is given a new `TypedArray` will created, initialized with all elements set to zero. - * @param itemSize the number of values of the {@link array} that should be associated with a particular vertex. - * For instance, if this attribute is storing a 3-component vector (such as a _position_, _normal_, or _color_), - * then itemSize should be `3`. - * @param normalized Applies to integer data only. - * Indicates how the underlying data in the buffer maps to the values in the GLSL code. - * For instance, if {@link array} is an instance of `UInt16Array`, and {@link normalized} is true, - * the values `0` - `+65535` in the array data will be mapped to `0.0f` - `+1.0f` in the GLSL attribute. - * An `Int16Array` (signed) would map from `-32768` - `+32767` to `-1.0f` - `+1.0f`. - * If normalized is false, the values will be converted to floats unmodified, - * i.e. `32767` becomes `32767.0f`. - * Default `false`. - * @see {@link THREE.BufferAttribute | BufferAttribute} - */ - constructor( - array: Iterable | ArrayLike | ArrayBuffer | number, - itemSize: number, - normalized?: boolean, - ); -} - -/** - * A {@link THREE.BufferAttribute | BufferAttribute} for {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float32Array: Float32Array} - * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray#typedarray_objects | TypedArray} - * @see {@link THREE.BufferAttribute | BufferAttribute} for details and for inherited methods and properties. - * @see {@link https://threejs.org/docs/index.html#api/en/core/bufferAttributeTypes/BufferAttributeTypes | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/BufferAttribute.js | Source} - */ -export class Float32BufferAttribute extends BufferAttribute { - /** - * This creates a new {@link THREE.Float32BufferAttribute | Float32BufferAttribute} object. - * @param array This can be a typed or untyped (normal) array or an integer length. An array value will be converted to `Float32Array`. - * If a length is given a new `TypedArray` will created, initialized with all elements set to zero. - * @param itemSize the number of values of the {@link array} that should be associated with a particular vertex. - * For instance, if this attribute is storing a 3-component vector (such as a _position_, _normal_, or _color_), - * then itemSize should be `3`. - * @param normalized Applies to integer data only. - * Indicates how the underlying data in the buffer maps to the values in the GLSL code. - * For instance, if {@link array} is an instance of `UInt16Array`, and {@link normalized} is true, - * the values `0` - `+65535` in the array data will be mapped to `0.0f` - `+1.0f` in the GLSL attribute. - * An `Int16Array` (signed) would map from `-32768` - `+32767` to `-1.0f` - `+1.0f`. - * If normalized is false, the values will be converted to floats unmodified, - * i.e. `32767` becomes `32767.0f`. - * Default `false`. - * @see {@link THREE.BufferAttribute | BufferAttribute} - */ - constructor( - array: Iterable | ArrayLike | ArrayBuffer | number, - itemSize: number, - normalized?: boolean, - ); -} diff --git a/src-testing/src/core/BufferGeometry.d.ts b/src-testing/src/core/BufferGeometry.d.ts deleted file mode 100644 index 516d5f765..000000000 --- a/src-testing/src/core/BufferGeometry.d.ts +++ /dev/null @@ -1,433 +0,0 @@ -import { Box3 } from "../math/Box3.js"; -import { Matrix4 } from "../math/Matrix4.js"; -import { Quaternion } from "../math/Quaternion.js"; -import { Sphere } from "../math/Sphere.js"; -import { Vector2 } from "../math/Vector2.js"; -import { Vector3, Vector3Tuple } from "../math/Vector3.js"; -import IndirectStorageBufferAttribute from "../renderers/common/IndirectStorageBufferAttribute.js"; -import { BufferAttribute, BufferAttributeJSON } from "./BufferAttribute.js"; -import { EventDispatcher } from "./EventDispatcher.js"; -import { GLBufferAttribute } from "./GLBufferAttribute.js"; -import { InterleavedBufferAttribute } from "./InterleavedBufferAttribute.js"; - -export type NormalBufferAttributes = Record; -export type NormalOrGLBufferAttributes = Record< - string, - BufferAttribute | InterleavedBufferAttribute | GLBufferAttribute ->; - -export interface BufferGeometryJSON { - metadata?: { version: number; type: string; generator: string }; - - uuid: string; - type: string; - - name?: string; - userData?: Record; - - data?: { - attributes: Record; - - index?: { type: string; array: number[] }; - - morphAttributes?: Record; - morphTargetsRelative?: boolean; - - groups?: GeometryGroup[]; - - boundingSphere?: { center: Vector3Tuple; radius: number }; - }; -} - -export interface GeometryGroup { - /** - * Specifies the first element in this draw call – the first vertex for non-indexed geometry, otherwise the first triangle index. - * @remarks Expects a `Integer` - */ - start: number; - /** - * Specifies how many vertices (or indices) are included. - * @remarks Expects a `Integer` - */ - count: number; - /** - * Specifies the material array index to use. - * @remarks Expects a `Integer` - */ - materialIndex?: number | undefined; -} - -/** - * A representation of mesh, line, or point geometry - * Includes vertex positions, face indices, normals, colors, UVs, and custom attributes within buffers, reducing the cost of passing all this data to the GPU. - * @remarks - * To read and edit data in BufferGeometry attributes, see {@link THREE.BufferAttribute | BufferAttribute} documentation. - * @example - * ```typescript - * const geometry = new THREE.BufferGeometry(); - * - * // create a simple square shape. We duplicate the top left and bottom right - * // vertices because each vertex needs to appear once per triangle. - * const vertices = new Float32Array( [ - * -1.0, -1.0, 1.0, // v0 - * 1.0, -1.0, 1.0, // v1 - * 1.0, 1.0, 1.0, // v2 - * - * 1.0, 1.0, 1.0, // v3 - * -1.0, 1.0, 1.0, // v4 - * -1.0, -1.0, 1.0 // v5 - * ] ); - * - * // itemSize = 3 because there are 3 values (components) per vertex - * geometry.setAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) ); - * const material = new THREE.MeshBasicMaterial( { color: 0xff0000 } ); - * const mesh = new THREE.Mesh( geometry, material ); - * ``` - * @example - * ```typescript - * const geometry = new THREE.BufferGeometry(); - * - * const vertices = new Float32Array( [ - * -1.0, -1.0, 1.0, // v0 - * 1.0, -1.0, 1.0, // v1 - * 1.0, 1.0, 1.0, // v2 - * -1.0, 1.0, 1.0, // v3 - * ] ); - * geometry.setAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) ); - * - * const indices = [ - * 0, 1, 2, - * 2, 3, 0, - * ]; - * - * geometry.setIndex( indices ); - * geometry.setAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) ); - * - * const material = new THREE.MeshBasicMaterial( { color: 0xff0000 } ); - * const mesh = new THREE.Mesh( geometry, material ); - * ``` - * @see Example: {@link https://threejs.org/examples/#webgl_buffergeometry | Mesh with non-indexed faces} - * @see Example: {@link https://threejs.org/examples/#webgl_buffergeometry_indexed | Mesh with indexed faces} - * @see Example: {@link https://threejs.org/examples/#webgl_buffergeometry_lines | Lines} - * @see Example: {@link https://threejs.org/examples/#webgl_buffergeometry_lines_indexed | Indexed Lines} - * @see Example: {@link https://threejs.org/examples/#webgl_buffergeometry_custom_attributes_particles | Particles} - * @see Example: {@link https://threejs.org/examples/#webgl_buffergeometry_rawshader | Raw Shaders} - * @see {@link https://threejs.org/docs/index.html#api/en/core/BufferGeometry | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/BufferGeometry.js | Source} - */ -export class BufferGeometry< - Attributes extends NormalOrGLBufferAttributes = NormalBufferAttributes, -> extends EventDispatcher<{ dispose: {} }> { - /** - * This creates a new {@link THREE.BufferGeometry | BufferGeometry} object. - */ - constructor(); - - /** - * Unique number for this {@link THREE.BufferGeometry | BufferGeometry} instance. - * @remarks Expects a `Integer` - */ - id: number; - - /** - * {@link http://en.wikipedia.org/wiki/Universally_unique_identifier | UUID} of this object instance. - * @remarks This gets automatically assigned and shouldn't be edited. - */ - uuid: string; - - /** - * Optional name for this {@link THREE.BufferGeometry | BufferGeometry} instance. - * @defaultValue `''` - */ - name: string; - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `BufferGeometry` - */ - readonly type: string | "BufferGeometry"; - - /** - * Allows for vertices to be re-used across multiple triangles; this is called using "indexed triangles". - * Each triangle is associated with the indices of three vertices. This attribute therefore stores the index of each vertex for each triangular face. - * If this attribute is not set, the {@link THREE.WebGLRenderer | renderer} assumes that each three contiguous positions represent a single triangle. - * @defaultValue `null` - */ - index: BufferAttribute | null; - - indirect: IndirectStorageBufferAttribute | null; - - /** - * This hashmap has as id the name of the attribute to be set and as value the {@link THREE.BufferAttribute | buffer} to set it to. Rather than accessing this property directly, - * use {@link setAttribute | .setAttribute} and {@link getAttribute | .getAttribute} to access attributes of this geometry. - * @defaultValue `{}` - */ - attributes: Attributes; - - /** - * Hashmap of {@link THREE.BufferAttribute | BufferAttributes} holding details of the geometry's morph targets. - * @remarks - * Once the geometry has been rendered, the morph attribute data cannot be changed. - * You will have to call {@link dispose | .dispose}(), and create a new instance of {@link THREE.BufferGeometry | BufferGeometry}. - * @defaultValue `{}` - */ - morphAttributes: { - [name: string]: Array; // TODO Replace for 'Record<>' - }; - - /** - * Used to control the morph target behavior; when set to true, the morph target data is treated as relative offsets, rather than as absolute positions/normals. - * @defaultValue `false` - */ - morphTargetsRelative: boolean; - - /** - * Split the geometry into groups, each of which will be rendered in a separate WebGL draw call. This allows an array of materials to be used with the geometry. - * @remarks Every vertex and index must belong to exactly one group — groups must not share vertices or indices, and must not leave vertices or indices unused. - * @remarks Use {@link addGroup | .addGroup} to add groups, rather than modifying this array directly. - * @defaultValue `[]` - */ - groups: GeometryGroup[]; - - /** - * Bounding box for the {@link THREE.BufferGeometry | BufferGeometry}, which can be calculated with {@link computeBoundingBox | .computeBoundingBox()}. - * @remarks Bounding boxes aren't computed by default. They need to be explicitly computed, otherwise they are `null`. - * @defaultValue `null` - */ - boundingBox: Box3 | null; - - /** - * Bounding sphere for the {@link THREE.BufferGeometry | BufferGeometry}, which can be calculated with {@link computeBoundingSphere | .computeBoundingSphere()}. - * @remarks bounding spheres aren't computed by default. They need to be explicitly computed, otherwise they are `null`. - * @defaultValue `null` - */ - boundingSphere: Sphere | null; - - /** - * Determines the part of the geometry to render. This should not be set directly, instead use {@link setDrawRange | .setDrawRange(...)}. - * @remarks For non-indexed {@link THREE.BufferGeometry | BufferGeometry}, count is the number of vertices to render. - * @remarks For indexed {@link THREE.BufferGeometry | BufferGeometry}, count is the number of indices to render. - * @defaultValue `{ start: 0, count: Infinity }` - */ - drawRange: { start: number; count: number }; - - /** - * An object that can be used to store custom data about the BufferGeometry. It should not hold references to functions as these will not be cloned. - * @defaultValue `{}` - */ - userData: Record; - - /** - * Read-only flag to check if a given object is of type {@link BufferGeometry}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isBufferGeometry: true; - - /** - * Return the {@link index | .index} buffer. - */ - getIndex(): BufferAttribute | null; - - /** - * Set the {@link THREE.BufferGeometry.index | .index} buffer. - * @param index - */ - setIndex(index: BufferAttribute | number[] | null): this; - - setIndirect(indirect: IndirectStorageBufferAttribute | null): this; - - getIndirect(): IndirectStorageBufferAttribute | null; - - /** - * Sets an {@link attributes | attribute} to this geometry with the specified name. - * @remarks - * Use this rather than the attributes property, because an internal hashmap of {@link attributes | .attributes} is maintained to speed up iterating over attributes. - * @param name - * @param attribute - */ - setAttribute(name: K, attribute: Attributes[K]): this; - - /** - * Returns the {@link attributes | attribute} with the specified name. - * @param name - */ - getAttribute(name: K): Attributes[K]; - - /** - * Deletes the {@link attributes | attribute} with the specified name. - * @param name - */ - deleteAttribute(name: keyof Attributes): this; - - /** - * Returns true if the {@link attributes | attribute} with the specified name exists. - * @param name - */ - hasAttribute(name: keyof Attributes): boolean; - - /** - * Adds a group to this geometry - * @see the {@link BufferGeometry.groups | groups} property for details. - * @param start - * @param count - * @param materialIndex - */ - addGroup(start: number, count: number, materialIndex?: number): void; - - /** - * Clears all groups. - */ - clearGroups(): void; - - /** - * Set the {@link drawRange | .drawRange} property - * @remarks For non-indexed BufferGeometry, count is the number of vertices to render - * @remarks For indexed BufferGeometry, count is the number of indices to render. - * @param start - * @param count is the number of vertices or indices to render. Expects a `Integer` - */ - setDrawRange(start: number, count: number): void; - - /** - * Applies the matrix transform to the geometry. - * @param matrix - */ - applyMatrix4(matrix: Matrix4): this; - - /** - * Applies the rotation represented by the quaternion to the geometry. - * @param quaternion - */ - applyQuaternion(quaternion: Quaternion): this; - - /** - * Rotate the geometry about the X axis. This is typically done as a one time operation, and not during a loop. - * @remarks Use {@link THREE.Object3D.rotation | Object3D.rotation} for typical real-time mesh rotation. - * @param angle radians. Expects a `Float` - */ - rotateX(angle: number): this; - - /** - * Rotate the geometry about the Y axis. - * @remarks This is typically done as a one time operation, and not during a loop. - * @remarks Use {@link THREE.Object3D.rotation | Object3D.rotation} for typical real-time mesh rotation. - * @param angle radians. Expects a `Float` - */ - rotateY(angle: number): this; - - /** - * Rotate the geometry about the Z axis. - * @remarks This is typically done as a one time operation, and not during a loop. - * @remarks Use {@link THREE.Object3D.rotation | Object3D.rotation} for typical real-time mesh rotation. - * @param angle radians. Expects a `Float` - */ - rotateZ(angle: number): this; - - /** - * Translate the geometry. - * @remarks This is typically done as a one time operation, and not during a loop. - * @remarks Use {@link THREE.Object3D.position | Object3D.position} for typical real-time mesh rotation. - * @param x Expects a `Float` - * @param y Expects a `Float` - * @param z Expects a `Float` - */ - translate(x: number, y: number, z: number): this; - - /** - * Scale the geometry data. - * @remarks This is typically done as a one time operation, and not during a loop. - * @remarks Use {@link THREE.Object3D.scale | Object3D.scale} for typical real-time mesh scaling. - * @param x Expects a `Float` - * @param y Expects a `Float` - * @param z Expects a `Float` - */ - scale(x: number, y: number, z: number): this; - - /** - * Rotates the geometry to face a point in space. - * @remarks This is typically done as a one time operation, and not during a loop. - * @remarks Use {@link THREE.Object3D.lookAt | Object3D.lookAt} for typical real-time mesh usage. - * @param vector A world vector to look at. - */ - lookAt(vector: Vector3): this; - - /** - * Center the geometry based on the bounding box. - */ - center(): this; - - /** - * Defines a geometry by creating a `position` attribute based on the given array of points. The array can hold - * instances of {@link Vector2} or {@link Vector3}. When using two-dimensional data, the `z` coordinate for all - * vertices is set to `0`. - * - * If the method is used with an existing `position` attribute, the vertex data are overwritten with the data from - * the array. The length of the array must match the vertex count. - */ - setFromPoints(points: Vector3[] | Vector2[]): this; - - /** - * Computes the bounding box of the geometry, and updates the {@link .boundingBox} attribute. The bounding box is - * not computed by the engine; it must be computed by your app. You may need to recompute the bounding box if the - * geometry vertices are modified. - */ - computeBoundingBox(): void; - - /** - * Computes the bounding sphere of the geometry, and updates the {@link .boundingSphere} attribute. The engine - * automatically computes the bounding sphere when it is needed, e.g., for ray casting or view frustum culling. You - * may need to recompute the bounding sphere if the geometry vertices are modified. - */ - computeBoundingSphere(): void; - - /** - * Calculates and adds a tangent attribute to this geometry. - * The computation is only supported for indexed geometries and if position, normal, and uv attributes are defined - * @remarks - * When using a tangent space normal map, prefer the MikkTSpace algorithm provided by - * {@link BufferGeometryUtils.computeMikkTSpaceTangents} instead. - */ - computeTangents(): void; - - /** - * Computes vertex normals for the given vertex data. For indexed geometries, the method sets each vertex normal to - * be the average of the face normals of the faces that share that vertex. For non-indexed geometries, vertices are - * not shared, and the method sets each vertex normal to be the same as the face normal. - */ - computeVertexNormals(): void; - - /** - * Every normal vector in a geometry will have a magnitude of 1 - * @remarks This will correct lighting on the geometry surfaces. - */ - normalizeNormals(): void; - - /** - * Return a non-index version of an indexed BufferGeometry. - */ - toNonIndexed(): BufferGeometry; - - /** - * Convert the buffer geometry to three.js {@link https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 | JSON Object/Scene format}. - */ - toJSON(): BufferGeometryJSON; - - /** - * Creates a clone of this BufferGeometry - */ - clone(): this; - - /** - * Copies another BufferGeometry to this BufferGeometry. - * @param source - */ - copy(source: BufferGeometry): this; - - /** - * Frees the GPU-related resources allocated by this instance. - * @remarks Call this method whenever this instance is no longer used in your app. - */ - dispose(): void; -} diff --git a/src-testing/src/core/Clock.d.ts b/src-testing/src/core/Clock.d.ts deleted file mode 100644 index 05307083c..000000000 --- a/src-testing/src/core/Clock.d.ts +++ /dev/null @@ -1,72 +0,0 @@ -/** - * Object for keeping track of time - * @remarks - * This uses {@link https://developer.mozilla.org/en-US/docs/Web/API/Performance/now | performance.now} if it is available, - * otherwise it reverts to the less accurate {@link https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Date/now | Date.now}. - * @see {@link https://threejs.org/docs/index.html#api/en/core/Clock | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/Clock.js | Source} - */ -export class Clock { - /** - * Create a new instance of {@link THREE.Clock | Clock} - * @param autoStart - Whether to automatically start the clock when {@link getDelta | .getDelta()} is called for the first time. Default `true` - */ - constructor(autoStart?: boolean); - - /** - * If set, starts the clock automatically when {@link getDelta | .getDelta()} is called for the first time. - * @defaultValue `true` - */ - autoStart: boolean; - - /** - * Holds the time at which the clock's {@link start | .start()} method was last called. - * @defaultValue `0` - */ - startTime: number; - - /** - * Holds the time at which the clock's {@link start | .start()}, {@link getElapsedTime | .getElapsedTime()} or {@link getDelta | .getDelta()} methods were last called. - * @defaultValue `0` - */ - oldTime: number; - - /** - * Keeps track of the total time that the clock has been running. - * @defaultValue `0` - */ - elapsedTime: number; - - /** - * Whether the clock is running or not. - * @defaultValue `false` - */ - running: boolean; - - /** - * Starts clock. - * @remarks - * Also sets the {@link startTime | .startTime} and {@link oldTime | .oldTime} to the current time, - * sets {@link elapsedTime | .elapsedTime} to `0` and {@link running | .running} to `true`. - */ - start(): void; - - /** - * Stops clock and sets {@link oldTime | oldTime} to the current time. - */ - stop(): void; - - /** - * Get the seconds passed since the clock started and sets {@link oldTime | .oldTime} to the current time. - * @remarks - * If {@link autoStart | .autoStart} is `true` and the clock is not running, also starts the clock. - */ - getElapsedTime(): number; - - /** - * Get the seconds passed since the time {@link oldTime | .oldTime} was set and sets {@link oldTime | .oldTime} to the current time. - * @remarks - * If {@link autoStart | .autoStart} is `true` and the clock is not running, also starts the clock. - */ - getDelta(): number; -} diff --git a/src-testing/src/core/EventDispatcher.d.ts b/src-testing/src/core/EventDispatcher.d.ts deleted file mode 100644 index 403dd1c2e..000000000 --- a/src-testing/src/core/EventDispatcher.d.ts +++ /dev/null @@ -1,82 +0,0 @@ -/** - * The minimal basic Event that can be dispatched by a {@link EventDispatcher<>}. - */ -export interface BaseEvent { - readonly type: TEventType; -} - -/** - * The minimal expected contract of a fired Event that was dispatched by a {@link EventDispatcher<>}. - */ -export interface Event { - readonly type: TEventType; - readonly target: TTarget; -} - -export type EventListener = ( - event: TEventData & Event, -) => void; - -/** - * JavaScript events for custom objects - * @example - * ```typescript - * // Adding events to a custom object - * class Car extends EventDispatcher { - * start() { - * this.dispatchEvent( { type: 'start', message: 'vroom vroom!' } ); - * } - * }; - * // Using events with the custom object - * const car = new Car(); - * car.addEventListener( 'start', ( event ) => { - * alert( event.message ); - * } ); - * car.start(); - * ``` - * @see {@link https://github.com/mrdoob/eventdispatcher.js | mrdoob EventDispatcher on GitHub} - * @see {@link https://threejs.org/docs/index.html#api/en/core/EventDispatcher | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/EventDispatcher.js | Source} - */ -export class EventDispatcher { - /** - * Creates {@link THREE.EventDispatcher | EventDispatcher} object. - */ - constructor(); - - /** - * Adds a listener to an event type. - * @param type The type of event to listen to. - * @param listener The function that gets called when the event is fired. - */ - addEventListener>( - type: T, - listener: EventListener, - ): void; - - /** - * Checks if listener is added to an event type. - * @param type The type of event to listen to. - * @param listener The function that gets called when the event is fired. - */ - hasEventListener>( - type: T, - listener: EventListener, - ): boolean; - - /** - * Removes a listener from an event type. - * @param type The type of the listener that gets removed. - * @param listener The listener function that gets removed. - */ - removeEventListener>( - type: T, - listener: EventListener, - ): void; - - /** - * Fire an event type. - * @param event The event that gets fired. - */ - dispatchEvent>(event: BaseEvent & TEventMap[T]): void; -} diff --git a/src-testing/src/core/GLBufferAttribute.d.ts b/src-testing/src/core/GLBufferAttribute.d.ts deleted file mode 100644 index c549518dd..000000000 --- a/src-testing/src/core/GLBufferAttribute.d.ts +++ /dev/null @@ -1,121 +0,0 @@ -/** - * This buffer attribute class does not construct a VBO. - * Instead, it uses whatever VBO is passed in constructor and can later be altered via the {@link buffer | .buffer} property. - * @remarks - * It is required to pass additional params alongside the VBO - * Those are: the GL context, the GL data type, the number of components per vertex, the number of bytes per component, and the number of vertices. - * @remarks - * The most common use case for this class is when some kind of GPGPU calculation interferes or even produces the VBOs in question. - * @see Example: {@link https://threejs.org/examples/#webgl_buffergeometry_glbufferattribute | WebGL / buffergeometry / glbufferattribute} - * @see {@link https://threejs.org/docs/index.html#api/en/core/GLBufferAttribute | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/GLBufferAttribute.js | Source} - */ -export class GLBufferAttribute { - /** - * This creates a new GLBufferAttribute object. - * @param buffer Must be a {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGLBuffer | WebGLBuffer}. See {@link GLBufferAttribute.buffer | .buffer} - * @param type One of {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Constants#Data_types | WebGL Data Types}. See {@link GLBufferAttribute.type | .type} - * @param itemSize How many values make up each item (vertex). See {@link GLBufferAttribute.itemSize | .itemSize} - * @param elementSize `1`, `2` or `4`. The corresponding size (in bytes) for the given {@link type} param. See {@link GLBufferAttribute.elementSize | .elementSize} - * @param count The expected number of vertices in VBO. See {@link GLBufferAttribute.count | .count} - */ - constructor(buffer: WebGLBuffer, type: GLenum, itemSize: number, elementSize: 1 | 2 | 4, count: number); - - /** - * Read-only flag to check if a given object is of type {@link GLBufferAttribute}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isGLBufferAttribute: true; - - /** - * Optional name for this attribute instance. - * @defaultValue `""` - */ - name: string; - - /** - * The current {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGLBuffer | WebGLBuffer} instance. - */ - buffer: WebGLBuffer; - - /** - * A {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Constants#Data_types | WebGL Data Type} describing the underlying VBO contents. - * - * #### WebGL Data Type (`GLenum`) - * - gl.BYTE: 0x1400 - * - gl.UNSIGNED_BYTE: 0x1401 - * - gl.SHORT: 0x1402 - * - gl.UNSIGNED_SHORT: 0x1403 - * - gl.INT: 0x1404 - * - gl.UNSIGNED_INT: 0x1405 - * - gl.FLOAT: 0x1406 - * @remarks Set this property together with {@link elementSize | .elementSize}. The recommended way is using the {@link setType | .setType()} method. - * @remarks Expects a `DataType` `GLenum` _possible values:_ `0x1400` `0x1401` `0x1402` `0x1403` `0x1404` `0x1405` `0x1406` - */ - type: GLenum; - - /** - * How many values make up each item (vertex). - * @remarks The number of values of the array that should be associated with a particular vertex. - * For instance, if this attribute is storing a 3-component vector (such as a position, normal, or color), then itemSize should be 3. - * @remarks Expects a `Integer` - */ - itemSize: number; - - /** - * Stores the corresponding size in bytes for the current {@link type | .type} property value. - * - * The corresponding size (_in bytes_) for the given "type" param. - * #### WebGL Data Type (`GLenum`) - * - gl.BYTE: 1 - * - gl.UNSIGNED_BYTE: 1 - * - gl.SHORT: 2 - * - gl.UNSIGNED_SHORT: 2 - * - gl.INT: 4 - * - gl.UNSIGNED_INT: 4 - * - gl.FLOAT: 4 - * @remarks Set this property together with {@link type | .type}. The recommended way is using the {@link setType | .setType} method. - * @see `constructor`` for a list of known type sizes. - * @remarks Expects a `1`, `2` or `4` - */ - elementSize: 1 | 2 | 4; - - /** - * The expected number of vertices in VBO. - * @remarks Expects a `Integer` - */ - count: number; - - /** - * A version number, incremented every time the needsUpdate property is set to true. - * @remarks Expects a `Integer` - */ - version: number; - - /** - * Setting this to true increments {@link version | .version}. - * @remarks _set-only property_. - */ - set needsUpdate(value: boolean); - - /** - * Sets the {@link buffer | .buffer} property. - */ - setBuffer(buffer: WebGLBuffer): this; - - /** - * Sets the both {@link GLBufferAttribute.type | type} and {@link GLBufferAttribute.elementSize | elementSize} properties. - */ - setType(type: GLenum, elementSize: 1 | 2 | 4): this; - - /** - * Sets the {@link GLBufferAttribute.itemSize | itemSize} property. - */ - setItemSize(itemSize: number): this; - - /** - * Sets the {@link GLBufferAttribute.count | count} property. - */ - setCount(count: number): this; -} diff --git a/src-testing/src/core/InstancedBufferAttribute.d.ts b/src-testing/src/core/InstancedBufferAttribute.d.ts deleted file mode 100644 index fde083b81..000000000 --- a/src-testing/src/core/InstancedBufferAttribute.d.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { BufferAttribute, TypedArray } from "./BufferAttribute.js"; - -/** - * An instanced version of {@link THREE.BufferAttribute | BufferAttribute}. - * @see {@link https://threejs.org/docs/index.html#api/en/core/InstancedBufferAttribute | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/InstancedBufferAttribute.js | Source} - */ -export class InstancedBufferAttribute extends BufferAttribute { - /** - * Create a new instance of {@link THREE.InstancedBufferAttribute | InstancedBufferAttribute} - * @param array - * @param itemSize - * @param normalized - * @param meshPerAttribute - */ - constructor(array: TypedArray, itemSize: number, normalized?: boolean, meshPerAttribute?: number); - - /** - * Defines how often a value of this buffer attribute should be repeated. - * A value of one means that each value of the instanced attribute is used for a single instance. - * A value of two means that each value is used for two consecutive instances (and so on). - * @defaultValue `1` - */ - meshPerAttribute: number; - - /** - * Read-only flag to check if a given object is of type {@link InstancedBufferAttribute}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isInstancedBufferAttribute: true; -} diff --git a/src-testing/src/core/InstancedBufferGeometry.d.ts b/src-testing/src/core/InstancedBufferGeometry.d.ts deleted file mode 100644 index 421294c49..000000000 --- a/src-testing/src/core/InstancedBufferGeometry.d.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { BufferGeometry } from "./BufferGeometry.js"; - -/** - * An instanced version of {@link THREE.BufferGeometry | BufferGeometry}. - * @see {@link https://threejs.org/docs/index.html#api/en/core/InstancedBufferGeometry | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/InstancedBufferGeometry.js | Source} - */ -export class InstancedBufferGeometry extends BufferGeometry { - /** - * Create a new instance of {@link InstancedBufferGeometry} - */ - constructor(); - - /** - * @defaultValue `InstancedBufferGeometry` - */ - type: string; - - /** - * Read-only flag to check if a given object is of type {@link InstancedBufferGeometry}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isInstancedBufferGeometry: true; - - /** - * @defaultValue `Infinity` - */ - instanceCount: number; - - /** - * Copies the given {@link InstancedBufferGeometry} to this instance. - * @param source - * @override - */ - copy(source: InstancedBufferGeometry): this; -} diff --git a/src-testing/src/core/InstancedInterleavedBuffer.d.ts b/src-testing/src/core/InstancedInterleavedBuffer.d.ts deleted file mode 100644 index 3c78beae4..000000000 --- a/src-testing/src/core/InstancedInterleavedBuffer.d.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { TypedArray } from "./BufferAttribute.js"; -import { InterleavedBuffer } from "./InterleavedBuffer.js"; - -/** - * An instanced version of {@link THREE.InterleavedBuffer | InterleavedBuffer}. - * @see {@link https://threejs.org/docs/index.html#api/en/core/InstancedInterleavedBuffer | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/InstancedInterleavedBuffer.js | Source} - */ -export class InstancedInterleavedBuffer extends InterleavedBuffer { - /** - * Create a new instance of {@link InstancedInterleavedBuffer} - * @param array - * @param itemSize - * @param meshPerAttribute - */ - constructor(array: TypedArray, stride: number, meshPerAttribute?: number); - - /** - * @defaultValue `1` - */ - meshPerAttribute: number; -} diff --git a/src-testing/src/core/InterleavedBuffer.d.ts b/src-testing/src/core/InterleavedBuffer.d.ts deleted file mode 100644 index 89819f6c2..000000000 --- a/src-testing/src/core/InterleavedBuffer.d.ts +++ /dev/null @@ -1,150 +0,0 @@ -import { Usage } from "../constants.js"; -import { TypedArray } from "./BufferAttribute.js"; -import { InterleavedBufferAttribute } from "./InterleavedBufferAttribute.js"; - -/** - * **"Interleaved"** means that multiple attributes, possibly of different types, (e.g., _position, normal, uv, color_) are packed into a single array buffer. - * An introduction into interleaved arrays can be found here: {@link https://blog.tojicode.com/2011/05/interleaved-array-basics.html | Interleaved array basics} - * @see Example: {@link https://threejs.org/examples/#webgl_buffergeometry_points_interleaved | webgl / buffergeometry / points / interleaved} - * @see {@link https://threejs.org/docs/index.html#api/en/core/InterleavedBuffer | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/InterleavedBuffer.js | Source} - */ -export class InterleavedBuffer { - readonly isInterleavedBuffer: true; - - /** - * Create a new instance of {@link InterleavedBuffer} - * @param array A {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray | TypedArray} with a shared buffer. Stores the geometry data. - * @param stride The number of typed-array elements per vertex. Expects a `Integer` - */ - constructor(array: TypedArray, stride: number); - - /** - * A {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray | TypedArray} with a shared buffer. Stores the geometry data. - */ - array: TypedArray; - - /** - * The number of {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray | TypedArray} elements per vertex. - * @remarks Expects a `Integer` - */ - stride: number; - - /** - * Defines the intended usage pattern of the data store for optimization purposes. - * Corresponds to the {@link BufferAttribute.usage | usage} parameter of - * {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/bufferData | WebGLRenderingContext.bufferData}. - * @remarks - * After the initial use of a buffer, its usage cannot be changed. Instead, instantiate a new one and set the desired usage before the next render. - * @see {@link https://threejs.org/docs/index.html#api/en/constants/BufferAttributeUsage | Buffer Attribute Usage Constants} for all possible values. - * @see {@link BufferAttribute.setUsage | setUsage} - * @defaultValue {@link THREE.StaticDrawUsage | THREE.StaticDrawUsage}. - */ - usage: Usage; - - /** - * This can be used to only update some components of stored data. Use the {@link .addUpdateRange} function to add - * ranges to this array. - */ - updateRanges: Array<{ - /** - * Position at which to start update. - */ - start: number; - /** - * The number of components to update. - */ - count: number; - }>; - - /** - * A version number, incremented every time the {@link BufferAttribute.needsUpdate | needsUpdate} property is set to true. - * @remarks Expects a `Integer` - * @defaultValue `0` - */ - version: number; - - /** - * Gives the total number of elements in the array. - * @remarks Expects a `Integer` - * @defaultValue 0 - */ - count: number; - - /** - * Flag to indicate that this attribute has changed and should be re-sent to the GPU. - * Set this to true when you modify the value of the array. - * @remarks Setting this to true also increments the {@link BufferAttribute.version | version}. - * @remarks _set-only property_. - */ - set needsUpdate(value: boolean); - - /** - * {@link http://en.wikipedia.org/wiki/Universally_unique_identifier | UUID} of this object instance. - * @remarks This gets automatically assigned and shouldn't be edited. - */ - uuid: string; - - /** - * Calls {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set | TypedArray.set}( {@link value}, {@link offset} ) - * on the {@link BufferAttribute.array | array}. - * @param value The source `TypedArray`. - * @param offset index of the {@link BufferAttribute.array | array} at which to start copying. Expects a `Integer`. Default `0`. - * @throws `RangeError` When {@link offset} is negative or is too large. - */ - set(value: ArrayLike, offset: number): this; - - /** - * Set {@link BufferAttribute.usage | usage} - * @remarks - * After the initial use of a buffer, its usage cannot be changed. Instead, instantiate a new one and set the desired usage before the next render. - * @see {@link https://threejs.org/docs/index.html#api/en/constants/BufferAttributeUsage | Buffer Attribute Usage Constants} for all possible values. - * @see {@link BufferAttribute.usage | usage} - * @param value Corresponds to the {@link BufferAttribute.usage | usage} parameter of - * {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/bufferData | WebGLRenderingContext.bufferData}. - */ - setUsage(value: Usage): this; - - /** - * Adds a range of data in the data array to be updated on the GPU. Adds an object describing the range to the - * {@link .updateRanges} array. - */ - addUpdateRange(start: number, count: number): void; - - /** - * Clears the {@link .updateRanges} array. - */ - clearUpdateRanges(): void; - - /** - * Copies another {@link InterleavedBuffer} to this {@link InterleavedBuffer} instance. - * @param source - */ - copy(source: InterleavedBuffer): this; - - /** - * Copies data from {@link attribute}[{@link index2}] to {@link InterleavedBuffer.array | array}[{@link index1}]. - * @param index1 Expects a `Integer` - * @param attribute - * @param index2 Expects a `Integer` - */ - copyAt(index1: number, attribute: InterleavedBufferAttribute, index2: number): this; - - /** - * Creates a clone of this {@link InterleavedBuffer}. - * @param data This object holds shared array buffers required for properly cloning geometries with interleaved attributes. - */ - clone(data: {}): InterleavedBuffer; - - /** - * Serializes this {@link InterleavedBuffer}. - * Converting to {@link https://github.com/mrdoob/three.js/wiki/JSON-Geometry-format-4 | JSON Geometry format v4}, - * @param data This object holds shared array buffers required for properly serializing geometries with interleaved attributes. - */ - toJSON(data: {}): { - uuid: string; - buffer: string; - type: string; - stride: number; - }; -} diff --git a/src-testing/src/core/InterleavedBufferAttribute.d.ts b/src-testing/src/core/InterleavedBufferAttribute.d.ts deleted file mode 100644 index 955049938..000000000 --- a/src-testing/src/core/InterleavedBufferAttribute.d.ts +++ /dev/null @@ -1,201 +0,0 @@ -import { Matrix3 } from "../math/Matrix3.js"; -import { Matrix4 } from "../math/Matrix4.js"; -import { BufferAttribute, TypedArray } from "./BufferAttribute.js"; -import { InterleavedBuffer } from "./InterleavedBuffer.js"; - -/** - * @see {@link https://threejs.org/docs/index.html#api/en/core/InterleavedBufferAttribute | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/InterleavedBufferAttribute.js | Source} - */ -export class InterleavedBufferAttribute { - /** - * Create a new instance of {@link THREE.InterleavedBufferAttribute | InterleavedBufferAttribute}. - * @param interleavedBuffer - * @param itemSize - * @param offset - * @param normalized Default `false`. - */ - constructor(interleavedBuffer: InterleavedBuffer, itemSize: number, offset: number, normalized?: boolean); - - /** - * Optional name for this attribute instance. - * @defaultValue `''` - */ - name: string; - - /** - * The {@link InterleavedBuffer | InterleavedBuffer} instance passed in the constructor. - */ - data: InterleavedBuffer; - - /** - * How many values make up each item. - * @remarks Expects a `Integer` - */ - itemSize: number; - - /** - * The offset in the underlying array buffer where an item starts. - * @remarks Expects a `Integer` - */ - offset: number; - - /** - * @defaultValue `false` - */ - normalized: boolean; - - /** - * The value of {@link data | .data}.{@link InterleavedBuffer.count | count}. - * If the buffer is storing a 3-component item (such as a _position, normal, or color_), then this will count the number of such items stored. - * @remarks _get-only property_. - * @remarks Expects a `Integer` - */ - get count(): number; - - /** - * The value of {@link InterleavedBufferAttribute.data | data}.{@link InterleavedBuffer.array | array}. - * @remarks _get-only property_. - */ - get array(): TypedArray; - - /** - * Flag to indicate that the {@link data | .data} ({@link InterleavedBuffer}) attribute has changed and should be re-sent to the GPU. - * @remarks Setting this to have the same result of setting true also increments the {@link InterleavedBuffer.needsUpdate | InterleavedBuffer.needsUpdate} of {@link data | .data}. - * @remarks Setting this to true also increments the {@link InterleavedBuffer.version | InterleavedBuffer.version}. - * @remarks _set-only property_. - */ - set needsUpdate(value: boolean); - - /** - * Read-only flag to check if a given object is of type {@link InterleavedBufferAttribute}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isInterleavedBufferAttribute: true; - - /** - * Applies matrix {@link Matrix4 | m} to every Vector3 element of this InterleavedBufferAttribute. - * @param m - */ - applyMatrix4(m: Matrix4): this; - - /** - * Applies normal matrix {@link Matrix3 | m} to every Vector3 element of this InterleavedBufferAttribute. - * @param m - */ - applyNormalMatrix(m: Matrix3): this; - - /** - * Applies matrix {@link Matrix4 | m} to every Vector3 element of this InterleavedBufferAttribute, interpreting the elements as a direction vectors. - * @param m - */ - transformDirection(m: Matrix4): this; - - /** - * Returns the given component of the vector at the given index. - */ - getComponent(index: number, component: number): number; - - /** - * Sets the given component of the vector at the given index. - */ - setComponent(index: number, component: number, value: number): this; - - /** - * Returns the x component of the item at the given index. - * @param index Expects a `Integer` - */ - getX(index: number): number; - - /** - * Sets the x component of the item at the given index. - * @param index Expects a `Integer` - * @param x Expects a `Float` - */ - setX(index: number, x: number): this; - - /** - * Returns the y component of the item at the given index. - * @param index Expects a `Integer` - */ - getY(index: number): number; - - /** - * Sets the y component of the item at the given index. - * @param index Expects a `Integer` - * @param y Expects a `Float` - */ - setY(index: number, y: number): this; - - /** - * Returns the z component of the item at the given index. - * @param index Expects a `Integer` - */ - getZ(index: number): number; - - /** - * Sets the z component of the item at the given index. - * @param index Expects a `Integer` - * @param z Expects a `Float` - */ - setZ(index: number, z: number): this; - - /** - * Returns the w component of the item at the given index. - * @param index Expects a `Integer` - */ - getW(index: number): number; - - /** - * Sets the w component of the item at the given index. - * @param index Expects a `Integer` - * @param w Expects a `Float` - */ - setW(index: number, z: number): this; - - /** - * Sets the x and y components of the item at the given index. - * @param index Expects a `Integer` - * @param x Expects a `Float` - * @param y Expects a `Float` - */ - setXY(index: number, x: number, y: number): this; - /** - * Sets the x, y and z components of the item at the given index. - * @param index Expects a `Integer` - * @param x Expects a `Float` - * @param y Expects a `Float` - * @param z Expects a `Float` - */ - setXYZ(index: number, x: number, y: number, z: number): this; - - /** - * Sets the x, y, z and w components of the item at the given index. - * @param index Expects a `Integer` - * @param x Expects a `Float` - * @param y Expects a `Float` - * @param z Expects a `Float` - * @param w Expects a `Float` - */ - setXYZW(index: number, x: number, y: number, z: number, w: number): this; - - /** - * Creates a clone of this {@link InterleavedBufferAttribute}. - * @param data This object holds shared array buffers required for properly cloning geometries with interleaved attributes. - */ - clone(data?: {}): BufferAttribute; - - /** - * Serializes this {@link InterleavedBufferAttribute}. - * Converting to {@link https://github.com/mrdoob/three.js/wiki/JSON-Geometry-format-4 | JSON Geometry format v4}, - * @param data This object holds shared array buffers required for properly serializing geometries with interleaved attributes. - */ - toJSON(data?: {}): { - isInterleavedBufferAttribute: true; - itemSize: number; - data: string; - offset: number; - normalized: boolean; - }; -} diff --git a/src-testing/src/core/Layers.d.ts b/src-testing/src/core/Layers.d.ts deleted file mode 100644 index ad95f892d..000000000 --- a/src-testing/src/core/Layers.d.ts +++ /dev/null @@ -1,72 +0,0 @@ -/** - * A {@link THREE.Layers | Layers} object assigns an {@link THREE.Object3D | Object3D} to 1 or more of 32 layers numbered `0` to `31` - internally the - * layers are stored as a {@link https://en.wikipedia.org/wiki/Mask_(computing) | bit mask}, and - * by default all Object3Ds are a member of layer `0`. - * @remarks - * This can be used to control visibility - an object must share a layer with a {@link Camera | camera} to be visible when that camera's view is rendered. - * @remarks - * All classes that inherit from {@link THREE.Object3D | Object3D} have an {@link THREE.Object3D.layers | Object3D.layers} property which is an instance of this class. - * @see Example: {@link https://threejs.org/examples/#webgl_layers | WebGL / layers} - * @see Example: {@link https://threejs.org/examples/#webxr_vr_layers | Webxr / vr / layers} - * @see {@link https://threejs.org/docs/index.html#api/en/core/Layers | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/Layers.js | Source} - */ -export class Layers { - /** - * Create a new Layers object, with membership initially set to layer 0. - */ - constructor(); - - /** - * A bit mask storing which of the 32 layers this layers object is currently a member of. - * @defaultValue `1 | 0` - * @remarks Expects a `Integer` - */ - mask: number; - - /** - * Set membership to `layer`, and remove membership all other layers. - * @param layer An integer from 0 to 31. - */ - set(layer: number): void; - - /** - * Add membership of this `layer`. - * @param layer An integer from 0 to 31. - */ - enable(layer: number): void; - - /** - * Add membership to all layers. - */ - enableAll(): void; - - /** - * Toggle membership of `layer`. - * @param layer An integer from 0 to 31. - */ - toggle(layer: number): void; - - /** - * Remove membership of this `layer`. - * @param layer An integer from 0 to 31. - */ - disable(layer: number): void; - - /** - * Remove membership from all layers. - */ - disableAll(): void; - - /** - * Returns true if this and the passed `layers` object have at least one layer in common. - * @param layers A Layers object - */ - test(layers: Layers): boolean; - - /** - * Returns true if the given layer is enabled. - * @param layer An integer from 0 to 31. - */ - isEnabled(layer: number): boolean; -} diff --git a/src-testing/src/core/Object3D.d.ts b/src-testing/src/core/Object3D.d.ts deleted file mode 100644 index 20bba57ce..000000000 --- a/src-testing/src/core/Object3D.d.ts +++ /dev/null @@ -1,674 +0,0 @@ -import { AnimationClip, AnimationClipJSON } from "../animation/AnimationClip.js"; -import { Camera } from "../cameras/Camera.js"; -import { ShapeJSON } from "../extras/core/Shape.js"; -import { Material, MaterialJSON } from "../materials/Material.js"; -import { Euler } from "../math/Euler.js"; -import { Matrix3 } from "../math/Matrix3.js"; -import { Matrix4, Matrix4Tuple } from "../math/Matrix4.js"; -import { Quaternion } from "../math/Quaternion.js"; -import { Vector3, Vector3Tuple } from "../math/Vector3.js"; -import { Group } from "../objects/Group.js"; -import { SkeletonJSON } from "../objects/Skeleton.js"; -import { WebGLRenderer } from "../renderers/WebGLRenderer.js"; -import { Scene } from "../scenes/Scene.js"; -import { SourceJSON } from "../textures/Source.js"; -import { TextureJSON } from "../textures/Texture.js"; -import { BufferGeometry, BufferGeometryJSON } from "./BufferGeometry.js"; -import { EventDispatcher } from "./EventDispatcher.js"; -import { Layers } from "./Layers.js"; -import { Intersection, Raycaster } from "./Raycaster.js"; - -export interface Object3DJSONObject { - uuid: string; - type: string; - - name?: string; - castShadow?: boolean; - receiveShadow?: boolean; - visible?: boolean; - frustumCulled?: boolean; - renderOrder?: number; - userData?: Record; - - layers: number; - matrix: Matrix4Tuple; - up: Vector3Tuple; - - matrixAutoUpdate?: boolean; - - material?: string | string[]; - - children?: string[]; - - animations?: string[]; -} - -export interface Object3DJSON { - metadata?: { version: number; type: string; generator: string }; - object: Object3DJSONObject; -} - -export interface JSONMeta { - geometries: Record; - materials: Record; - textures: Record; - images: Record; - shapes: Record; - skeletons: Record; - animations: Record; - nodes: Record; -} - -export interface Object3DEventMap { - /** - * Fires when the object has been added to its parent object. - */ - added: {}; - - /** - * Fires when the object has been removed from its parent object. - */ - removed: {}; - - /** - * Fires when a new child object has been added. - */ - childadded: { child: Object3D }; - - /** - * Fires when a new child object has been removed. - */ - childremoved: { child: Object3D }; -} - -/** - * This is the base class for most objects in three.js and provides a set of properties and methods for manipulating objects in 3D space. - * @remarks Note that this can be used for grouping objects via the {@link THREE.Object3D.add | .add()} method which adds the object as a child, - * however it is better to use {@link THREE.Group | Group} for this. - * @see {@link https://threejs.org/docs/index.html#api/en/core/Object3D | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/Object3D.js | Source} - */ -export class Object3D extends EventDispatcher { - /** - * This creates a new {@link Object3D} object. - */ - constructor(); - - /** - * Flag to check if a given object is of type {@link Object3D}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isObject3D: true; - - /** - * Unique number for this {@link Object3D} instance. - * @remarks Note that ids are assigned in chronological order: 1, 2, 3, ..., incrementing by one for each new object. - * Expects a `Integer` - */ - readonly id: number; - - /** - * {@link http://en.wikipedia.org/wiki/Universally_unique_identifier | UUID} of this object instance. - * @remarks This gets automatically assigned and shouldn't be edited. - */ - uuid: string; - - /** - * Optional name of the object - * @remarks _(doesn't need to be unique)_. - * @defaultValue `""` - */ - name: string; - - /** - * A Read-only _string_ to check `this` object type. - * @remarks This can be used to find a specific type of Object3D in a scene. - * Sub-classes will update this value. - * @defaultValue `Object3D` - */ - readonly type: string; - - /** - * Object's parent in the {@link https://en.wikipedia.org/wiki/Scene_graph | scene graph}. - * @remarks An object can have at most one parent. - * @defaultValue `null` - */ - parent: Object3D | null; - - /** - * Array with object's children. - * @see {@link THREE.Object3DGroup | Group} for info on manually grouping objects. - * @defaultValue `[]` - */ - - children: Object3D[]; - - /** - * This is used by the {@link lookAt | lookAt} method, for example, to determine the orientation of the result. - * @defaultValue {@link DEFAULT_UP | Object3D.DEFAULT_UP} - that is `(0, 1, 0)`. - */ - up: Vector3; - - /** - * Object's local position. - * @defaultValue `new THREE.Vector3()` - that is `(0, 0, 0)`. - */ - readonly position: Vector3; - - /** - * Object's local rotation ({@link https://en.wikipedia.org/wiki/Euler_angles | Euler angles}), in radians. - * @defaultValue `new THREE.Euler()` - that is `(0, 0, 0, Euler.DEFAULT_ORDER)`. - */ - readonly rotation: Euler; - - /** - * Object's local rotation as a {@link THREE.Quaternion | Quaternion}. - * @defaultValue `new THREE.Quaternion()` - that is `(0, 0, 0, 1)`. - */ - readonly quaternion: Quaternion; - - /** - * The object's local scale. - * @defaultValue `new THREE.Vector3( 1, 1, 1 )` - */ - readonly scale: Vector3; - - /** - * @defaultValue `new THREE.Matrix4()` - */ - readonly modelViewMatrix: Matrix4; - - /** - * @defaultValue `new THREE.Matrix3()` - */ - readonly normalMatrix: Matrix3; - - /** - * The local transform matrix. - * @defaultValue `new THREE.Matrix4()` - */ - matrix: Matrix4; - - /** - * The global transform of the object. - * @remarks If the {@link Object3D} has no parent, then it's identical to the local transform {@link THREE.Object3D.matrix | .matrix}. - * @defaultValue `new THREE.Matrix4()` - */ - matrixWorld: Matrix4; - - /** - * When this is set, it calculates the matrix of position, (rotation or quaternion) and - * scale every frame and also recalculates the matrixWorld property. - * @defaultValue {@link DEFAULT_MATRIX_AUTO_UPDATE} - that is `(true)`. - */ - matrixAutoUpdate: boolean; - - /** - * If set, then the renderer checks every frame if the object and its children need matrix updates. - * When it isn't, then you have to maintain all matrices in the object and its children yourself. - * @defaultValue {@link DEFAULT_MATRIX_WORLD_AUTO_UPDATE} - that is `(true)`. - */ - matrixWorldAutoUpdate: boolean; - - /** - * When this is set, it calculates the matrixWorld in that frame and resets this property to false. - * @defaultValue `false` - */ - matrixWorldNeedsUpdate: boolean; - - /** - * The layer membership of the object. - * @remarks The object is only visible if it has at least one layer in common with the {@link THREE.Object3DCamera | Camera} in use. - * This property can also be used to filter out unwanted objects in ray-intersection tests when using {@link THREE.Raycaster | Raycaster}. - * @defaultValue `new THREE.Layers()` - */ - layers: Layers; - - /** - * Object gets rendered if `true`. - * @defaultValue `true` - */ - visible: boolean; - - /** - * Whether the object gets rendered into shadow map. - * @defaultValue `false` - */ - castShadow: boolean; - - /** - * Whether the material receives shadows. - * @defaultValue `false` - */ - receiveShadow: boolean; - - /** - * When this is set, it checks every frame if the object is in the frustum of the camera before rendering the object. - * If set to `false` the object gets rendered every frame even if it is not in the frustum of the camera. - * @defaultValue `true` - */ - frustumCulled: boolean; - - /** - * This value allows the default rendering order of {@link https://en.wikipedia.org/wiki/Scene_graph | scene graph} - * objects to be overridden although opaque and transparent objects remain sorted independently. - * @remarks When this property is set for an instance of {@link Group | Group}, all descendants objects will be sorted and rendered together. - * Sorting is from lowest to highest renderOrder. - * @defaultValue `0` - */ - renderOrder: number; - - /** - * Array with object's animation clips. - * @defaultValue `[]` - */ - animations: AnimationClip[]; - - /** - * An object that can be used to store custom data about the {@link Object3D}. - * @remarks It should not hold references to _functions_ as these **will not** be cloned. - * @default `{}` - */ - userData: Record; - - /** - * Custom depth material to be used when rendering to the depth map. - * @remarks Can only be used in context of meshes. - * When shadow-casting with a {@link THREE.DirectionalLight | DirectionalLight} or {@link THREE.SpotLight | SpotLight}, - * if you are modifying vertex positions in the vertex shader you must specify a customDepthMaterial for proper shadows. - * @defaultValue `undefined` - */ - customDepthMaterial?: Material | undefined; - - /** - * Same as {@link customDepthMaterial}, but used with {@link THREE.Object3DPointLight | PointLight}. - * @defaultValue `undefined` - */ - customDistanceMaterial?: Material | undefined; - - /** - * An optional callback that is executed immediately before a 3D object is rendered to a shadow map. - * @remarks This function is called with the following parameters: renderer, scene, camera, shadowCamera, geometry, - * depthMaterial, group. - * Please notice that this callback is only executed for `renderable` 3D objects. Meaning 3D objects which - * define their visual appearance with geometries and materials like instances of {@link Mesh}, {@link Line}, - * {@link Points} or {@link Sprite}. Instances of {@link Object3D}, {@link Group} or {@link Bone} are not renderable - * and thus this callback is not executed for such objects. - */ - onBeforeShadow( - renderer: WebGLRenderer, - scene: Scene, - camera: Camera, - shadowCamera: Camera, - geometry: BufferGeometry, - depthMaterial: Material, - group: Group, - ): void; - - /** - * An optional callback that is executed immediately after a 3D object is rendered to a shadow map. - * @remarks This function is called with the following parameters: renderer, scene, camera, shadowCamera, geometry, - * depthMaterial, group. - * Please notice that this callback is only executed for `renderable` 3D objects. Meaning 3D objects which - * define their visual appearance with geometries and materials like instances of {@link Mesh}, {@link Line}, - * {@link Points} or {@link Sprite}. Instances of {@link Object3D}, {@link Group} or {@link Bone} are not renderable - * and thus this callback is not executed for such objects. - */ - onAfterShadow( - renderer: WebGLRenderer, - scene: Scene, - camera: Camera, - shadowCamera: Camera, - geometry: BufferGeometry, - depthMaterial: Material, - group: Group, - ): void; - - /** - * An optional callback that is executed immediately before a 3D object is rendered. - * @remarks This function is called with the following parameters: renderer, scene, camera, geometry, material, group. - * Please notice that this callback is only executed for `renderable` 3D objects. Meaning 3D objects which - * define their visual appearance with geometries and materials like instances of {@link Mesh}, {@link Line}, - * {@link Points} or {@link Sprite}. Instances of {@link Object3D}, {@link Group} or {@link Bone} are not renderable - * and thus this callback is not executed for such objects. - */ - onBeforeRender( - renderer: WebGLRenderer, - scene: Scene, - camera: Camera, - geometry: BufferGeometry, - material: Material, - group: Group, - ): void; - - /** - * An optional callback that is executed immediately after a 3D object is rendered. - * @remarks This function is called with the following parameters: renderer, scene, camera, geometry, material, group. - * Please notice that this callback is only executed for `renderable` 3D objects. Meaning 3D objects which - * define their visual appearance with geometries and materials like instances of {@link Mesh}, {@link Line}, - * {@link Points} or {@link Sprite}. Instances of {@link Object3D}, {@link Group} or {@link Bone} are not renderable - * and thus this callback is not executed for such objects. - */ - onAfterRender( - renderer: WebGLRenderer, - scene: Scene, - camera: Camera, - geometry: BufferGeometry, - material: Material, - group: Group, - ): void; - - /** - * The default {@link up} direction for objects, also used as the default position for {@link THREE.DirectionalLight | DirectionalLight}, - * {@link THREE.HemisphereLight | HemisphereLight} and {@link THREE.Spotlight | Spotlight} (which creates lights shining from the top down). - * @defaultValue `new THREE.Vector3( 0, 1, 0)` - */ - static DEFAULT_UP: Vector3; - - /** - * The default setting for {@link matrixAutoUpdate} for newly created Object3Ds. - * @defaultValue `true` - */ - static DEFAULT_MATRIX_AUTO_UPDATE: boolean; - - /** - * The default setting for {@link matrixWorldAutoUpdate} for newly created Object3Ds. - * @defaultValue `true` - */ - static DEFAULT_MATRIX_WORLD_AUTO_UPDATE: boolean; - - /** - * Applies the matrix transform to the object and updates the object's position, rotation and scale. - * @param matrix - */ - applyMatrix4(matrix: Matrix4): void; - - /** - * Applies the rotation represented by the quaternion to the object. - * @param quaternion - */ - applyQuaternion(quaternion: Quaternion): this; - - /** - * Calls {@link THREE.Quaternion.setFromAxisAngle | setFromAxisAngle}({@link axis}, {@link angle}) on the {@link quaternion | .quaternion}. - * @param axis A normalized vector in object space. - * @param angle Angle in radians. Expects a `Float` - */ - setRotationFromAxisAngle(axis: Vector3, angle: number): void; - - /** - * Calls {@link THREE.Quaternion.setFromEuler | setFromEuler}({@link euler}) on the {@link quaternion | .quaternion}. - * @param euler Euler angle specifying rotation amount. - */ - setRotationFromEuler(euler: Euler): void; - - /** - * Calls {@link THREE.Quaternion.setFromRotationMatrix | setFromRotationMatrix}({@link m}) on the {@link quaternion | .quaternion}. - * @remarks Note that this assumes that the upper 3x3 of m is a pure rotation matrix (i.e, unscaled). - * @param m Rotate the quaternion by the rotation component of the matrix. - */ - setRotationFromMatrix(m: Matrix4): void; - - /** - * Copy the given {@link THREE.Quaternion | Quaternion} into {@link quaternion | .quaternion}. - * @param q Normalized Quaternion. - */ - setRotationFromQuaternion(q: Quaternion): void; - - /** - * Rotate an object along an axis in object space. - * @remarks The axis is assumed to be normalized. - * @param axis A normalized vector in object space. - * @param angle The angle in radians. Expects a `Float` - */ - rotateOnAxis(axis: Vector3, angle: number): this; - - /** - * Rotate an object along an axis in world space. - * @remarks The axis is assumed to be normalized - * Method Assumes no rotated parent. - * @param axis A normalized vector in world space. - * @param angle The angle in radians. Expects a `Float` - */ - rotateOnWorldAxis(axis: Vector3, angle: number): this; - - /** - * Rotates the object around _x_ axis in local space. - * @param rad The angle to rotate in radians. Expects a `Float` - */ - rotateX(angle: number): this; - - /** - * Rotates the object around _y_ axis in local space. - * @param rad The angle to rotate in radians. Expects a `Float` - */ - rotateY(angle: number): this; - - /** - * Rotates the object around _z_ axis in local space. - * @param rad The angle to rotate in radians. Expects a `Float` - */ - rotateZ(angle: number): this; - - /** - * Translate an object by distance along an axis in object space - * @remarks The axis is assumed to be normalized. - * @param axis A normalized vector in object space. - * @param distance The distance to translate. Expects a `Float` - */ - translateOnAxis(axis: Vector3, distance: number): this; - - /** - * Translates object along x axis in object space by {@link distance} units. - * @param distance Expects a `Float` - */ - translateX(distance: number): this; - - /** - * Translates object along _y_ axis in object space by {@link distance} units. - * @param distance Expects a `Float` - */ - translateY(distance: number): this; - - /** - * Translates object along _z_ axis in object space by {@link distance} units. - * @param distance Expects a `Float` - */ - translateZ(distance: number): this; - - /** - * Converts the vector from this object's local space to world space. - * @param vector A vector representing a position in this object's local space. - */ - localToWorld(vector: Vector3): Vector3; - - /** - * Converts the vector from world space to this object's local space. - * @param vector A vector representing a position in world space. - */ - worldToLocal(vector: Vector3): Vector3; - - /** - * Rotates the object to face a point in world space. - * @remarks This method does not support objects having non-uniformly-scaled parent(s). - * @param vector A vector representing a position in world space to look at. - */ - lookAt(vector: Vector3): void; - /** - * Rotates the object to face a point in world space. - * @remarks This method does not support objects having non-uniformly-scaled parent(s). - * @param x Expects a `Float` - * @param y Expects a `Float` - * @param z Expects a `Float` - */ - lookAt(x: number, y: number, z: number): void; - - /** - * Adds another {@link Object3D} as child of this {@link Object3D}. - * @remarks An arbitrary number of objects may be added - * Any current parent on an {@link object} passed in here will be removed, since an {@link Object3D} can have at most one parent. - * @see {@link attach} - * @see {@link THREE.Group | Group} for info on manually grouping objects. - * @param object - */ - add(...object: Object3D[]): this; - - /** - * Removes a {@link Object3D} as child of this {@link Object3D}. - * @remarks An arbitrary number of objects may be removed. - * @see {@link THREE.Group | Group} for info on manually grouping objects. - * @param object - */ - remove(...object: Object3D[]): this; - - /** - * Removes this object from its current parent. - */ - removeFromParent(): this; - - /** - * Removes all child objects. - */ - clear(): this; - - /** - * Adds a {@link Object3D} as a child of this, while maintaining the object's world transform. - * @remarks Note: This method does not support scene graphs having non-uniformly-scaled nodes(s). - * @see {@link add} - * @param object - */ - attach(object: Object3D): this; - - /** - * Searches through an object and its children, starting with the object itself, and returns the first with a matching id. - * @remarks Note that ids are assigned in chronological order: 1, 2, 3, ..., incrementing by one for each new object. - * @see {@link id} - * @param id Unique number of the object instance. Expects a `Integer` - */ - getObjectById(id: number): Object3D | undefined; - - /** - * Searches through an object and its children, starting with the object itself, and returns the first with a matching name. - * @remarks Note that for most objects the name is an empty string by default - * You will have to set it manually to make use of this method. - * @param name String to match to the children's Object3D.name property. - */ - getObjectByName(name: string): Object3D | undefined; - - /** - * Searches through an object and its children, starting with the object itself, - * and returns the first with a property that matches the value given. - * - * @param name - the property name to search for. - * @param value - value of the given property. - */ - getObjectByProperty(name: string, value: any): Object3D | undefined; - - /** - * Searches through an object and its children, starting with the object itself, - * and returns the first with a property that matches the value given. - * @param name The property name to search for. - * @param value Value of the given property. - * @param optionalTarget target to set the result. Otherwise a new Array is instantiated. If set, you must clear - * this array prior to each call (i.e., array.length = 0;). - */ - getObjectsByProperty(name: string, value: any, optionalTarget?: Object3D[]): Object3D[]; - - /** - * Returns a vector representing the position of the object in world space. - * @param target The result will be copied into this Vector3. - */ - getWorldPosition(target: Vector3): Vector3; - - /** - * Returns a quaternion representing the rotation of the object in world space. - * @param target The result will be copied into this Quaternion. - */ - getWorldQuaternion(target: Quaternion): Quaternion; - - /** - * Returns a vector of the scaling factors applied to the object for each axis in world space. - * @param target The result will be copied into this Vector3. - */ - getWorldScale(target: Vector3): Vector3; - - /** - * Returns a vector representing the direction of object's positive z-axis in world space. - * @param target The result will be copied into this Vector3. - */ - getWorldDirection(target: Vector3): Vector3; - - /** - * Abstract (empty) method to get intersections between a casted ray and this object - * @remarks Subclasses such as {@link THREE.Mesh | Mesh}, {@link THREE.Line | Line}, and {@link THREE.Points | Points} implement this method in order to use raycasting. - * @see {@link THREE.Raycaster | Raycaster} - * @param raycaster - * @param intersects - * @defaultValue `() => {}` - */ - raycast(raycaster: Raycaster, intersects: Intersection[]): void; - - /** - * Executes the callback on this object and all descendants. - * @remarks Note: Modifying the scene graph inside the callback is discouraged. - * @param callback A function with as first argument an {@link Object3D} object. - */ - traverse(callback: (object: Object3D) => any): void; - - /** - * Like traverse, but the callback will only be executed for visible objects - * @remarks Descendants of invisible objects are not traversed. - * Note: Modifying the scene graph inside the callback is discouraged. - * @param callback A function with as first argument an {@link Object3D} object. - */ - traverseVisible(callback: (object: Object3D) => any): void; - - /** - * Executes the callback on all ancestors. - * @remarks Note: Modifying the scene graph inside the callback is discouraged. - * @param callback A function with as first argument an {@link Object3D} object. - */ - traverseAncestors(callback: (object: Object3D) => any): void; - - /** - * Updates local transform. - */ - updateMatrix(): void; - - /** - * Updates the global transform of the object. - * And will update the object descendants if {@link matrixWorldNeedsUpdate | .matrixWorldNeedsUpdate} is set to true or if the {@link force} parameter is set to `true`. - * @param force A boolean that can be used to bypass {@link matrixWorldAutoUpdate | .matrixWorldAutoUpdate}, to recalculate the world matrix of the object and descendants on the current frame. - * Useful if you cannot wait for the renderer to update it on the next frame, assuming {@link matrixWorldAutoUpdate | .matrixWorldAutoUpdate} set to `true`. - */ - updateMatrixWorld(force?: boolean): void; - - /** - * Updates the global transform of the object. - * @param updateParents Recursively updates global transform of ancestors. - * @param updateChildren Recursively updates global transform of descendants. - */ - updateWorldMatrix(updateParents: boolean, updateChildren: boolean): void; - - /** - * Convert the object to three.js {@link https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 | JSON Object/Scene format}. - * @param meta Object containing metadata such as materials, textures or images for the object. - */ - toJSON(meta?: JSONMeta): Object3DJSON; - - /** - * Returns a clone of `this` object and optionally all descendants. - * @param recursive If true, descendants of the object are also cloned. Default `true` - */ - clone(recursive?: boolean): this; - - /** - * Copies the given object into this object. - * @remarks Event listeners and user-defined callbacks ({@link .onAfterRender} and {@link .onBeforeRender}) are not copied. - * @param object - * @param recursive If set to `true`, descendants of the object are copied next to the existing ones. If set to - * `false`, descendants are left unchanged. Default is `true`. - */ - copy(object: Object3D, recursive?: boolean): this; -} diff --git a/src-testing/src/core/Raycaster.d.ts b/src-testing/src/core/Raycaster.d.ts deleted file mode 100644 index 4b6d3746e..000000000 --- a/src-testing/src/core/Raycaster.d.ts +++ /dev/null @@ -1,208 +0,0 @@ -import { Camera } from "../cameras/Camera.js"; -import { Ray } from "../math/Ray.js"; -import { Vector2 } from "../math/Vector2.js"; -import { Vector3 } from "../math/Vector3.js"; -import { XRTargetRaySpace } from "../renderers/webxr/WebXRController.js"; -import { Layers } from "./Layers.js"; -import { Object3D } from "./Object3D.js"; - -export interface Face { - a: number; - b: number; - c: number; - normal: Vector3; - materialIndex: number; -} - -export interface Intersection { - /** Distance between the origin of the ray and the intersection */ - distance: number; - distanceToRay?: number | undefined; - /** Point of intersection, in world coordinates */ - point: Vector3; - index?: number | undefined; - /** Intersected face */ - face?: Face | null | undefined; - /** Index of the intersected face */ - faceIndex?: number | null | undefined; - barycoord?: Vector3 | null; - /** The intersected object */ - object: TIntersected; - uv?: Vector2 | undefined; - uv1?: Vector2 | undefined; - normal?: Vector3; - /** The index number of the instance where the ray intersects the {@link THREE.InstancedMesh | InstancedMesh } */ - instanceId?: number | undefined; - pointOnLine?: Vector3; - batchId?: number; -} - -export interface RaycasterParameters { - Mesh: any; - Line: { threshold: number }; - Line2?: { threshold: number }; - LOD: any; - Points: { threshold: number }; - Sprite: any; -} - -/** - * This class is designed to assist with {@link https://en.wikipedia.org/wiki/Ray_casting | raycasting} - * @remarks - * Raycasting is used for mouse picking (working out what objects in the 3d space the mouse is over) amongst other things. - * @example - * ```typescript - * const raycaster = new THREE.Raycaster(); - * const pointer = new THREE.Vector2(); - * - * function onPointerMove(event) { - * // calculate pointer position in normalized device coordinates (-1 to +1) for both components - * pointer.x = (event.clientX / window.innerWidth) * 2 - 1; - * pointer.y = -(event.clientY / window.innerHeight) * 2 + 1; - * } - * - * function render() { - * // update the picking ray with the camera and pointer position - * raycaster.setFromCamera(pointer, camera); - * // calculate objects intersecting the picking ray - * const intersects = raycaster.intersectObjects(scene.children); - * for (let i = 0; i & lt; intersects.length; i++) { - * intersects[i].object.material.color.set(0xff0000); - * } - * renderer.render(scene, camera); - * } - * window.addEventListener('pointermove', onPointerMove); - * window.requestAnimationFrame(render); - * ``` - * @see Example: {@link https://threejs.org/examples/#webgl_interactive_cubes | Raycasting to a Mesh} - * @see Example: {@link https://threejs.org/examples/#webgl_interactive_cubes_ortho | Raycasting to a Mesh in using an OrthographicCamera} - * @see Example: {@link https://threejs.org/examples/#webgl_interactive_buffergeometry | Raycasting to a Mesh with BufferGeometry} - * @see Example: {@link https://threejs.org/examples/#webgl_instancing_raycast | Raycasting to a InstancedMesh} - * @see Example: {@link https://threejs.org/examples/#webgl_interactive_lines | Raycasting to a Line} - * @see Example: {@link https://threejs.org/examples/#webgl_interactive_raycasting_points | Raycasting to Points} - * @see Example: {@link https://threejs.org/examples/#webgl_geometry_terrain_raycast | Terrain raycasting} - * @see Example: {@link https://threejs.org/examples/#webgl_interactive_voxelpainter | Raycasting to paint voxels} - * @see Example: {@link https://threejs.org/examples/#webgl_raycaster_texture | Raycast to a Texture} - * @see {@link https://threejs.org/docs/index.html#api/en/core/Raycaster | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/Raycaster.js | Source} - */ -export class Raycaster { - /** - * This creates a new {@link Raycaster} object. - * @param origin The origin vector where the ray casts from. Default `new Vector3()` - * @param direction The direction vector that gives direction to the ray. Should be normalized. Default `new Vector3(0, 0, -1)` - * @param near All results returned are further away than near. Near can't be negative. Expects a `Float`. Default `0` - * @param far All results returned are closer than far. Far can't be lower than near. Expects a `Float`. Default `Infinity` - */ - constructor(origin?: Vector3, direction?: Vector3, near?: number, far?: number); - - /** - * The {@link THREE.RaycasterRay | Ray} used for the raycasting. - */ - ray: Ray; - - /** - * The near factor of the raycaster. This value indicates which objects can be discarded based on the distance. - * This value shouldn't be negative and should be smaller than the far property. - * @remarks Expects a `Float` - * @defaultValue `0` - */ - near: number; - - /** - * The far factor of the raycaster. This value indicates which objects can be discarded based on the distance. - * This value shouldn't be negative and should be larger than the near property. - * @remarks Expects a `Float` - * @defaultValue `Infinity` - */ - far: number; - - /** - * The camera to use when raycasting against view-dependent objects such as billboarded objects like {@link THREE.Sprites | Sprites}. - * This field can be set manually or is set when calling {@link setFromCamera}. - * @defaultValue `null` - */ - camera: Camera; - - /** - * Used by {@link Raycaster} to selectively ignore 3D objects when performing intersection tests. - * The following code example ensures that only 3D objects on layer `1` will be honored by the instance of Raycaster. - * ``` - * raycaster.layers.set( 1 ); - * object.layers.enable( 1 ); - * ``` - * @defaultValue `new THREE.Layers()` - See {@link THREE.Layers | Layers}. - */ - layers: Layers; - - /** - * An data object where threshold is the precision of the {@link Raycaster} when intersecting objects, in world units. - * @defaultValue `{ Mesh: {}, Line: { threshold: 1 }, LOD: {}, Points: { threshold: 1 }, Sprite: {} }` - */ - params: RaycasterParameters; - - /** - * Updates the ray with a new origin and direction - * @remarks - * Please note that this method only copies the values from the arguments. - * @param origin The origin vector where the ray casts from. - * @param direction The normalized direction vector that gives direction to the ray. - */ - set(origin: Vector3, direction: Vector3): void; - - /** - * Updates the ray with a new origin and direction. - * @param coords 2D coordinates of the mouse, in normalized device coordinates (NDC)---X and Y components should be between -1 and 1. - * @param camera camera from which the ray should originate - */ - setFromCamera(coords: Vector2, camera: Camera): void; - - /** - * Updates the ray with a new origin and direction. - * @param controller The controller to copy the position and direction from. - */ - setFromXRController(controller: XRTargetRaySpace): this; - - /** - * Checks all intersection between the ray and the object with or without the descendants - * @remarks Intersections are returned sorted by distance, closest first - * @remarks {@link Raycaster} delegates to the {@link Object3D.raycast | raycast} method of the passed object, when evaluating whether the ray intersects the object or not - * This allows {@link THREE.Mesh | meshes} to respond differently to ray casting than {@link THREE.Line | lines} and {@link THREE.Points | pointclouds}. - * **Note** that for meshes, faces must be pointed towards the origin of the {@link Raycaster.ray | ray} in order to be detected; - * intersections of the ray passing through the back of a face will not be detected - * To raycast against both faces of an object, you'll want to set the {@link Mesh.material | material}'s {@link Material.side | side} property to `THREE.DoubleSide`. - * @see {@link intersectObjects | .intersectObjects()}. - * @param object The object to check for intersection with the ray. - * @param recursive If true, it also checks all descendants. Otherwise it only checks intersection with the object. Default `true` - * @param optionalTarget Target to set the result. Otherwise a new {@link Array | Array} is instantiated. - * If set, you must clear this array prior to each call (i.e., array.length = 0;). Default `[]` - * @returns An array of intersections is returned. - */ - intersectObject( - object: Object3D, - recursive?: boolean, - optionalTarget?: Array>, - ): Array>; - - /** - * Checks all intersection between the ray and the objects with or without the descendants - * @remarks Intersections are returned sorted by distance, closest first - * @remarks Intersections are of the same form as those returned by {@link intersectObject | .intersectObject()}. - * @remarks {@link Raycaster} delegates to the {@link Object3D.raycast | raycast} method of the passed object, when evaluating whether the ray intersects the object or not - * This allows {@link THREE.Mesh | meshes} to respond differently to ray casting than {@link THREE.Line | lines} and {@link THREE.Points | pointclouds}. - * **Note** that for meshes, faces must be pointed towards the origin of the {@link Raycaster.ray | ray} in order to be detected; - * intersections of the ray passing through the back of a face will not be detected - * To raycast against both faces of an object, you'll want to set the {@link Mesh.material | material}'s {@link Material.side | side} property to `THREE.DoubleSide`. - * @see {@link intersectObject | .intersectObject()}. - * @param objects The objects to check for intersection with the ray. - * @param recursive If true, it also checks all descendants of the objects. Otherwise it only checks intersection with the objects. Default `true` - * @param optionalTarget Target to set the result. Otherwise a new {@link Array | Array} is instantiated. - * If set, you must clear this array prior to each call (i.e., array.length = 0;). Default `[]` - * @returns An array of intersections is returned. - */ - intersectObjects( - objects: Object3D[], - recursive?: boolean, - optionalTarget?: Array>, - ): Array>; -} diff --git a/src-testing/src/core/RenderTarget.d.ts b/src-testing/src/core/RenderTarget.d.ts deleted file mode 100644 index 2f20cabb5..000000000 --- a/src-testing/src/core/RenderTarget.d.ts +++ /dev/null @@ -1,95 +0,0 @@ -import { - MagnificationTextureFilter, - MinificationTextureFilter, - PixelFormatGPU, - TextureDataType, - Wrapping, -} from "../constants.js"; -import { Vector4 } from "../math/Vector4.js"; -import { DepthTexture } from "../textures/DepthTexture.js"; -import { Texture } from "../textures/Texture.js"; -import { EventDispatcher } from "./EventDispatcher.js"; - -export interface RenderTargetOptions { - wrapS?: Wrapping | undefined; - wrapT?: Wrapping | undefined; - magFilter?: MagnificationTextureFilter | undefined; - minFilter?: MinificationTextureFilter | undefined; - generateMipmaps?: boolean | undefined; // true - format?: number | undefined; // RGBAFormat - type?: TextureDataType | undefined; // UnsignedByteType - anisotropy?: number | undefined; // 1 - colorSpace?: string | undefined; - internalFormat?: PixelFormatGPU | null | undefined; // null - depthBuffer?: boolean | undefined; // true - stencilBuffer?: boolean | undefined; // false - resolveDepthBuffer?: boolean | undefined; // true - resolveStencilBuffer?: boolean | undefined; // true - depthTexture?: DepthTexture | null | undefined; // null - /** - * Defines the count of MSAA samples. Can only be used with WebGL 2. Default is **0**. - * @default 0 - */ - samples?: number | undefined; - count?: number | undefined; -} - -export class RenderTarget extends EventDispatcher<{ dispose: {} }> { - readonly isRenderTarget: true; - - width: number; - height: number; - depth: number; - - scissor: Vector4; - /** - * @default false - */ - scissorTest: boolean; - viewport: Vector4; - textures: TTexture[]; - - /** - * @default true - */ - depthBuffer: boolean; - - /** - * @default false - */ - stencilBuffer: boolean; - - /** - * Defines whether the depth buffer should be resolved when rendering into a multisampled render target. - * @default true - */ - resolveDepthBuffer: boolean; - - /** - * Defines whether the stencil buffer should be resolved when rendering into a multisampled render target. - * This property has no effect when {@link .resolveDepthBuffer} is set to `false`. - * @default true - */ - resolveStencilBuffer: boolean; - - /** - * @default null - */ - depthTexture: DepthTexture | null; - - /** - * Defines the count of MSAA samples. Can only be used with WebGL 2. Default is **0**. - * @default 0 - */ - samples: number; - - constructor(width?: number, height?: number, options?: RenderTargetOptions); - - get texture(): TTexture; - set texture(value: TTexture); - - setSize(width: number, height: number, depth?: number): void; - clone(): this; - copy(source: RenderTarget): this; - dispose(): void; -} diff --git a/src-testing/src/core/Uniform.d.ts b/src-testing/src/core/Uniform.d.ts deleted file mode 100644 index 851ae2bf9..000000000 --- a/src-testing/src/core/Uniform.d.ts +++ /dev/null @@ -1,38 +0,0 @@ -/** - * Uniforms are global GLSL variables. - * They are passed to shader programs. - * @example - * When declaring a uniform of a {@link THREE.ShaderMaterial | ShaderMaterial}, it is declared by value or by object. - * ```typescript - * uniforms: { - * time: { - * value: 1.0 - * }, - * resolution: new Uniform(new Vector2()) - * }; - * ``` - * @see Example: {@link https://threejs.org/examples/#webgl_nodes_materials_instance_uniform | WebGL2 / nodes / materials / instance / uniform} - * @see Example: {@link https://threejs.org/examples/#webgpu_instance_uniform| WebGPU / instance / uniform} - * @see {@link https://threejs.org/docs/index.html#api/en/core/Uniform | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/Uniform.js | Source} - */ -export class Uniform { - /** - * Create a new instance of {@link THREE.Uniform | Uniform} - * @param value An object containing the value to set up the uniform. It's type must be one of the Uniform Types described above. - */ - constructor(value: T); - - /** - * Current value of the uniform. - */ - value: T; - - /** - * Returns a clone of this uniform. - * @remarks - * If the uniform's {@link value} property is an {@link Object | Object} with a `clone()` method, this is used, - * otherwise the value is copied by assignment Array values are **shared** between cloned {@link THREE.UniformUniform | Uniform}s. - */ - clone(): Uniform; -} diff --git a/src-testing/src/core/UniformsGroup.d.ts b/src-testing/src/core/UniformsGroup.d.ts deleted file mode 100644 index 4fb30b2c1..000000000 --- a/src-testing/src/core/UniformsGroup.d.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { Usage } from "../constants.js"; -import { EventDispatcher } from "./EventDispatcher.js"; -import { Uniform } from "./Uniform.js"; - -/** - * @see Example: {@link https://threejs.org/examples/#webgl2_ubo | WebGL2 / UBO} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/core/UniformsGroup.js | Source} - */ -export class UniformsGroup extends EventDispatcher<{ dispose: {} }> { - constructor(); - - readonly isUniformsGroup: true; - - id: number; - - usage: Usage; - - uniforms: Array; - - add(uniform: Uniform | Uniform[]): this; - - remove(uniform: Uniform | Uniform[]): this; - - setName(name: string): this; - - setUsage(value: Usage): this; - - dispose(): this; - - copy(source: UniformsGroup): this; - - clone(): UniformsGroup; -} diff --git a/src-testing/src/extras/Controls.d.ts b/src-testing/src/extras/Controls.d.ts deleted file mode 100644 index 6202a5c0c..000000000 --- a/src-testing/src/extras/Controls.d.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { EventDispatcher } from "../core/EventDispatcher.js"; -import { Object3D } from "../core/Object3D.js"; - -/** - * Abstract base class for controls. - */ -declare abstract class Controls extends EventDispatcher { - /** - * The 3D object that is managed by the controls. - */ - object: Object3D; - - /** - * The HTML element used for event listeners. If not provided via the constructor, {@link .connect} must be called - * after `domElement` has been set. - */ - domElement: HTMLElement | null; - - /** - * When set to `false`, the controls will not respond to user input. Default is `true`. - */ - enabled: boolean; - - /** - * Creates a new instance of {@link Controls}. - * @param object The object the controls should manage (usually the camera). - * @param domElement The HTML element used for event listeners. (optional) - */ - constructor(object: Object3D, domElement?: HTMLElement | null); - - /** - * Connects the controls to the DOM. This method has so called "side effects" since it adds the module's event - * listeners to the DOM. - */ - connect(): void; - - /** - * Disconnects the controls from the DOM. - */ - disconnect(): void; - - /** - * Call this method if you no longer want use to the controls. It frees all internal resources and removes all event - * listeners. - */ - dispose(): void; - - /** - * Controls should implement this method if they have to update their internal state per simulation step. - */ - update(delta: number): void; -} - -export { Controls }; diff --git a/src-testing/src/extras/DataUtils.d.ts b/src-testing/src/extras/DataUtils.d.ts deleted file mode 100644 index fd678dbf4..000000000 --- a/src-testing/src/extras/DataUtils.d.ts +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Returns a half precision floating point value from the given single precision floating point value. - * @param val A single precision floating point value. - * @see {@link https://threejs.org/docs/index.html#api/en/extras/DataUtils | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/DataUtils.js | Source} - */ -declare function toHalfFloat(val: number): number; - -/** - * Returns a single precision floating point value from the given half precision floating point value. - * @param val A half precision floating point value. - * @see {@link https://threejs.org/docs/index.html#api/en/extras/DataUtils | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/DataUtils.js | Source} - */ -declare function fromHalfFloat(val: number): number; - -declare const DataUtils: { - toHalfFloat: typeof toHalfFloat; - fromHalfFloat: typeof fromHalfFloat; -}; - -export { DataUtils, fromHalfFloat, toHalfFloat }; diff --git a/src-testing/src/extras/Earcut.d.ts b/src-testing/src/extras/Earcut.d.ts deleted file mode 100644 index 623b8ee82..000000000 --- a/src-testing/src/extras/Earcut.d.ts +++ /dev/null @@ -1,15 +0,0 @@ -/** - * An implementation of the {@link Earcut} polygon triangulation algorithm - * @remarks - * The code is a port of {@link https://github.com/mapbox/earcut | mapbox/earcut}. - * @see {@link https://threejs.org/docs/index.html#api/en/extras/Earcut | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/Earcut.js | Source} - */ -export const Earcut: { - /** - * Triangulates the given shape definition by returning an array of triangles - * @remarks - * A triangle is defined by three consecutive integers representing vertex indices. - */ - triangulate(data: number[], holeIndices?: number[], dim?: number): number[]; -}; diff --git a/src-testing/src/extras/ImageUtils.d.ts b/src-testing/src/extras/ImageUtils.d.ts deleted file mode 100644 index 798fc3e90..000000000 --- a/src-testing/src/extras/ImageUtils.d.ts +++ /dev/null @@ -1,32 +0,0 @@ -/** - * A class containing utility functions for images. - * @see {@link https://threejs.org/docs/index.html#api/en/extras/ImageUtils | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/ImageUtils.js | Source} - */ -declare class ImageUtils { - /** - * Returns a data URI containing a representation of the given image. - * @param image The image object. - */ - static getDataURL( - image: HTMLImageElement | HTMLCanvasElement | CanvasImageSource | ImageBitmap | ImageData, - ): string; - - /** - * Converts the given sRGB image data to linear color space. - * @param image - */ - static sRGBToLinear(image: HTMLImageElement | HTMLCanvasElement | ImageBitmap): HTMLCanvasElement; - - /** - * Converts the given sRGB image data to linear color space. - * @param image - */ - static sRGBToLinear(image: ImageData): { - data: ImageData["data"]; - width: ImageData["width"]; - height: ImageData["height"]; - }; -} - -export { ImageUtils }; diff --git a/src-testing/src/extras/PMREMGenerator.d.ts b/src-testing/src/extras/PMREMGenerator.d.ts deleted file mode 100644 index 3eb4a15e1..000000000 --- a/src-testing/src/extras/PMREMGenerator.d.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { WebGLRenderer } from "../renderers/WebGLRenderer.js"; -import { WebGLRenderTarget } from "../renderers/WebGLRenderTarget.js"; -import { Scene } from "../scenes/Scene.js"; -import { CubeTexture } from "../textures/CubeTexture.js"; -import { Texture } from "../textures/Texture.js"; - -/** - * This class generates a Prefiltered, Mipmapped Radiance Environment Map (PMREM) from a cubeMap environment texture. - * @remarks - * This allows different levels of blur to be quickly accessed based on material roughness - * Unlike a traditional mipmap chain, it only goes down to the LOD_MIN level (above), and then creates extra even more filtered 'mips' at the same LOD_MIN resolution, - * associated with higher roughness levels - * In this way we maintain resolution to smoothly interpolate diffuse lighting while limiting sampling computation. - * @remarks - * Note: The minimum {@link THREE.MeshStandardMaterial | MeshStandardMaterial}'s roughness depends on the size of the provided texture - * If your render has small dimensions or the shiny parts have a lot of curvature, you may still be able to get away with a smaller texture size. - * - * | texture size | minimum roughness | - * |--------------|--------------------| - * | 16 | 0.21 | - * | 32 | 0.15 | - * | 64 | 0.11 | - * | 128 | 0.076 | - * | 256 | 0.054 | - * | 512 | 0.038 | - * | 1024 | 0.027 | - * - * @see {@link https://threejs.org/docs/index.html#api/en/extras/PMREMGenerator | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/PMREMGenerator.js | Source} - */ -export class PMREMGenerator { - /** - * This constructor creates a new PMREMGenerator. - * @param renderer - */ - constructor(renderer: WebGLRenderer); - - /** - * Generates a PMREM from a supplied Scene, which can be faster than using an image if networking bandwidth is low - * @remarks - * Optional near and far planes ensure the scene is rendered in its entirety (the cubeCamera is placed at the origin). - * @param scene The given scene. - * @param sigma Specifies a blur radius in radians to be applied to the scene before PMREM generation. Default `0`. - * @param near The near plane value. Default `0.1`. - * @param far The far plane value. Default `100`. - */ - fromScene(scene: Scene, sigma?: number, near?: number, far?: number): WebGLRenderTarget; - - /** - * Generates a PMREM from an equirectangular texture, which can be either LDR or HDR. The ideal input image size is - * 1k (1024 x 512), as this matches best with the 256 x 256 cubemap output. The smallest supported equirectangular - * image size is 64 x 32. - */ - fromEquirectangular(equirectangular: Texture, renderTarget?: WebGLRenderTarget | null): WebGLRenderTarget; - - /** - * Generates a PMREM from an cubemap texture, which can be either LDR or HDR. The ideal input cube size is - * 256 x 256, as this matches best with the 256 x 256 cubemap output. The smallest supported cube size is 16 x 16. - */ - fromCubemap(cubemap: CubeTexture, renderTarget?: WebGLRenderTarget | null): WebGLRenderTarget; - - /** - * Pre-compiles the cubemap shader - * @remarks - * You can get faster start-up by invoking this method during your texture's network fetch for increased concurrency. - */ - compileCubemapShader(): void; - - /** - * Pre-compiles the equirectangular shader - * @remarks - * You can get faster start-up by invoking this method during your texture's network fetch for increased concurrency. - */ - compileEquirectangularShader(): void; - - /** - * Frees the GPU-related resources allocated by this instance - * @remarks - * Call this method whenever this instance is no longer used in your app. - */ - dispose(): void; -} diff --git a/src-testing/src/extras/ShapeUtils.d.ts b/src-testing/src/extras/ShapeUtils.d.ts deleted file mode 100644 index 60fe8aaf9..000000000 --- a/src-testing/src/extras/ShapeUtils.d.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { Vector2Like } from "../math/Vector2.js"; - -/** - * A class containing utility functions for shapes. - * @remarks Note that these are all linear functions so it is necessary to calculate separately for x, y (and z, w if present) components of a vector. - * @see {@link https://threejs.org/docs/index.html#api/en/extras/ShapeUtils | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/ShapeUtils.js | Source} - */ -export class ShapeUtils { - /** - * Calculate area of a ( 2D ) contour polygon. - */ - static area(contour: readonly Vector2Like[]): number; - - /** - * Note that this is a linear function so it is necessary to calculate separately for x, y components of a polygon. - * @remarks Used internally by {@link THREE.Path | Path}, {@link THREE.ExtrudeGeometry | ExtrudeGeometry} and {@link THREE.ShapeGeometry | ShapeGeometry}. - */ - static isClockWise(pts: readonly Vector2Like[]): boolean; - - /** - * Used internally by {@link THREE.ExtrudeGeometry | ExtrudeGeometry} and {@link THREE.ShapeGeometry | ShapeGeometry} to calculate faces in shapes with holes. - */ - static triangulateShape(contour: Vector2Like[], holes: Vector2Like[][]): number[][]; -} diff --git a/src-testing/src/extras/TextureUtils.d.ts b/src-testing/src/extras/TextureUtils.d.ts deleted file mode 100644 index 254458b43..000000000 --- a/src-testing/src/extras/TextureUtils.d.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { CompressedPixelFormat, PixelFormat, TextureDataType } from "../constants.js"; -import { Texture } from "../textures/Texture.js"; - -/** - * Scales the texture as large as possible within its surface without cropping or stretching the texture. The method - * preserves the original aspect ratio of the texture. Akin to CSS `object-fit: contain`. - */ -declare function contain(texture: Texture, aspect: number): Texture; - -/** - * Scales the texture to the smallest possible size to fill the surface, leaving no empty space. The method preserves - * the original aspect ratio of the texture. Akin to CSS `object-fit: cover`. - */ -declare function cover(texture: Texture, aspect: number): Texture; - -/** - * Configures the texture to the default transformation. Akin to CSS `object-fit: fill`. - */ -declare function fill(texture: Texture): Texture; - -/** - * Given the width, height, format, and type of a texture. Determines how many bytes must be used to represent the - * texture. - */ -declare function getByteLength( - width: number, - height: number, - format: PixelFormat | CompressedPixelFormat, - type: TextureDataType, -): number; - -/** - * A class containing utility functions for textures. - */ -declare const TextureUtils: { - contain: typeof contain; - cover: typeof cover; - fill: typeof fill; - getByteLength: typeof getByteLength; -}; - -export { contain, cover, fill, getByteLength, TextureUtils }; diff --git a/src-testing/src/extras/core/Curve.d.ts b/src-testing/src/extras/core/Curve.d.ts deleted file mode 100644 index 9e3610903..000000000 --- a/src-testing/src/extras/core/Curve.d.ts +++ /dev/null @@ -1,162 +0,0 @@ -import { Vector2 } from "../../math/Vector2.js"; -import { Vector3 } from "../../math/Vector3.js"; - -export interface CurveJSON { - metadata: { version: number; type: string; generator: string }; - arcLengthDivisions: number; - type: string; -} - -/** - * An abstract base class for creating a {@link Curve} object that contains methods for interpolation - * @remarks - * For an array of Curves see {@link THREE.CurvePath | CurvePath}. - * @remarks - * This following curves inherit from THREE.Curve: - * - * **2D curves** - * - {@link THREE.ArcCurve} - * - {@link THREE.CubicBezierCurve} - * - {@link THREE.EllipseCurve} - * - {@link THREE.LineCurve} - * - {@link THREE.QuadraticBezierCurve} - * - {@link THREE.SplineCurve} - * - * **3D curves** - * - {@link THREE.CatmullRomCurve3} - * - {@link THREE.CubicBezierCurve3} - * - {@link THREE.LineCurve3} - * - {@link THREE.QuadraticBezierCurve3} - * - * @see {@link https://threejs.org/docs/index.html#api/en/extras/core/Curve | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/core/Curve.js | Source} - */ -export abstract class Curve { - protected constructor(); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `Curve` - */ - readonly type: string | "Curve"; - - /** - * This value determines the amount of divisions when calculating the cumulative segment lengths of a {@link Curve} - * via {@link .getLengths}. - * To ensure precision when using methods like {@link .getSpacedPoints}, it is recommended to increase {@link .arcLengthDivisions} if the {@link Curve} is very large. - * @defaultValue `200` - * @remarks Expects a `Integer` - */ - arcLengthDivisions: number; - - /** - * Returns a vector for a given position on the curve. - * @param t A position on the curve. Must be in the range `[ 0, 1 ]`. Expects a `Float` - * @param optionalTarget If specified, the result will be copied into this Vector, otherwise a new Vector will be created. Default `new T`. - */ - getPoint(t: number, optionalTarget?: TVector): TVector; - - /** - * Returns a vector for a given position on the {@link Curve} according to the arc length. - * @param u A position on the {@link Curve} according to the arc length. Must be in the range `[ 0, 1 ]`. Expects a `Float` - * @param optionalTarget If specified, the result will be copied into this Vector, otherwise a new Vector will be created. Default `new T`. - */ - getPointAt(u: number, optionalTarget?: TVector): TVector; - - /** - * Returns a set of divisions `+1` points using {@link .getPoint | getPoint(t)}. - * @param divisions Number of pieces to divide the {@link Curve} into. Expects a `Integer`. Default `5` - */ - getPoints(divisions?: number): TVector[]; - - /** - * Returns a set of divisions `+1` equi-spaced points using {@link .getPointAt | getPointAt(u)}. - * @param divisions Number of pieces to divide the {@link Curve} into. Expects a `Integer`. Default `5` - */ - getSpacedPoints(divisions?: number): TVector[]; - - /** - * Get total {@link Curve} arc length. - */ - getLength(): number; - - /** - * Get list of cumulative segment lengths. - * @param divisions Expects a `Integer` - */ - getLengths(divisions?: number): number[]; - - /** - * Update the cumulative segment distance cache - * @remarks - * The method must be called every time {@link Curve} parameters are changed - * If an updated {@link Curve} is part of a composed {@link Curve} like {@link THREE.CurvePath | CurvePath}, - * {@link .updateArcLengths}() must be called on the composed curve, too. - */ - updateArcLengths(): void; - - /** - * Given u in the range `[ 0, 1 ]`, - * @remarks - * `u` and `t` can then be used to give you points which are equidistant from the ends of the curve, using {@link .getPoint}. - * @param u Expects a `Float` - * @param distance Expects a `Float` - * @returns `t` also in the range `[ 0, 1 ]`. Expects a `Float`. - */ - getUtoTmapping(u: number, distance: number): number; - - /** - * Returns a unit vector tangent at t - * @remarks - * If the derived {@link Curve} does not implement its tangent derivation, two points a small delta apart will be used to find its gradient which seems to give a reasonable approximation. - * @param t A position on the curve. Must be in the range `[ 0, 1 ]`. Expects a `Float` - * @param optionalTarget If specified, the result will be copied into this Vector, otherwise a new Vector will be created. - */ - getTangent(t: number, optionalTarget?: TVector): TVector; - - /** - * Returns tangent at a point which is equidistant to the ends of the {@link Curve} from the point given in {@link .getTangent}. - * @param u A position on the {@link Curve} according to the arc length. Must be in the range `[ 0, 1 ]`. Expects a `Float` - * @param optionalTarget If specified, the result will be copied into this Vector, otherwise a new Vector will be created. - */ - getTangentAt(u: number, optionalTarget?: TVector): TVector; - - /** - * Generates the Frenet Frames - * @remarks - * Requires a {@link Curve} definition in 3D space - * Used in geometries like {@link THREE.TubeGeometry | TubeGeometry} or {@link THREE.ExtrudeGeometry | ExtrudeGeometry}. - * @param segments Expects a `Integer` - * @param closed - */ - computeFrenetFrames( - segments: number, - closed?: boolean, - ): { - tangents: Vector3[]; - normals: Vector3[]; - binormals: Vector3[]; - }; - - /** - * Creates a clone of this instance. - */ - clone(): this; - /** - * Copies another {@link Curve} object to this instance. - * @param source - */ - copy(source: Curve): this; - - /** - * Returns a JSON object representation of this instance. - */ - toJSON(): CurveJSON; - - /** - * Copies the data from the given JSON object to this instance. - * @param json - */ - fromJSON(json: CurveJSON): this; -} diff --git a/src-testing/src/extras/core/CurvePath.d.ts b/src-testing/src/extras/core/CurvePath.d.ts deleted file mode 100644 index 3a8577fd1..000000000 --- a/src-testing/src/extras/core/CurvePath.d.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { Vector2 } from "../../math/Vector2.js"; -import { Vector3 } from "../../math/Vector3.js"; -import { Curve, CurveJSON } from "./Curve.js"; - -export interface CurvePathJSON extends CurveJSON { - autoClose: boolean; - curves: CurveJSON[]; -} - -/** - * Curved Path - a curve path is simply a array of connected curves, but retains the api of a curve. - * @remarks - * A {@link CurvePath} is simply an array of connected curves, but retains the api of a curve. - * @see {@link https://threejs.org/docs/index.html#api/en/extras/core/CurvePath | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/core/CurvePath.js | Source} - */ -export class CurvePath extends Curve { - /** - * The constructor take no parameters. - */ - constructor(); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `CurvePath` - */ - override readonly type: string | "CurvePath"; - - /** - * The array of {@link Curve | Curves}. - * @defaultValue `[]` - */ - curves: Array>; - - /** - * Whether or not to automatically close the path. - * @defaultValue false - */ - autoClose: boolean; - - /** - * Add a curve to the {@link .curves} array. - * @param curve - */ - add(curve: Curve): void; - /** - * Adds a {@link LineCurve | lineCurve} to close the path. - */ - closePath(): this; - - getPoint(t: number, optionalTarget?: TVector): TVector; - - /** - * Get list of cumulative curve lengths of the curves in the {@link .curves} array. - */ - getCurveLengths(): number[]; - - /** - * Returns an array of points representing a sequence of curves - * @remarks - * The `division` parameter defines the number of pieces each curve is divided into - * However, for optimization and quality purposes, the actual sampling resolution for each curve depends on its type - * For example, for a {@link THREE.LineCurve | LineCurve}, the returned number of points is always just 2. - * @param divisions Number of pieces to divide the curve into. Expects a `Integer`. Default `12` - */ - override getPoints(divisions?: number): TVector[]; - - /** - * Returns a set of divisions `+1` equi-spaced points using {@link .getPointAt | getPointAt(u)}. - * @param divisions Number of pieces to divide the curve into. Expects a `Integer`. Default `40` - */ - override getSpacedPoints(divisions?: number): TVector[]; - - toJSON(): CurvePathJSON; - fromJSON(json: CurvePathJSON): this; -} diff --git a/src-testing/src/extras/core/Interpolations.d.ts b/src-testing/src/extras/core/Interpolations.d.ts deleted file mode 100644 index 9f5ed3784..000000000 --- a/src-testing/src/extras/core/Interpolations.d.ts +++ /dev/null @@ -1,36 +0,0 @@ -/** - * Used internally by {@link THREE.SplineCurve | SplineCurve}. - * @param t Interpolation weight. Expects a `Float` - * @param p0 Expects a `Float` - * @param p1 Expects a `Float` - * @param p2 Expects a `Float` - * @param p3 P0, p1, p2, the points defining the spline curve. Expects a `Float` - * @see {@link https://threejs.org/docs/index.html#api/en/extras/core/Interpolations | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/core/Interpolations.js | Source} - */ -declare function CatmullRom(t: number, p0: number, p1: number, p2: number, p3: number): number; - -/** - * Used internally by {@link THREE.QuadraticBezierCurve3 | QuadraticBezierCurve3} and {@link THREE.QuadraticBezierCurve | QuadraticBezierCurve}. - * @param t Interpolation weight. Expects a `Float` - * @param p0 Expects a `Float` - * @param p1 Expects a `Float` - * @param p2 P0, p1, the starting, control and end points defining the curve. Expects a `Float` - * @see {@link https://threejs.org/docs/index.html#api/en/extras/core/Interpolations | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/core/Interpolations.js | Source} - */ -declare function QuadraticBezier(t: number, p0: number, p1: number, p2: number): number; - -/** - * Used internally by {@link THREE.CubicBezierCurve3 | CubicBezierCurve3} and {@link THREE.CubicBezierCurve | CubicBezierCurve}. - * @param t Interpolation weight. Expects a `Float` - * @param p0 Expects a `Float` - * @param p1 Expects a `Float` - * @param p2 Expects a `Float` - * @param p3 P0, p1, p2, the starting, control(twice) and end points defining the curve. Expects a `Float` - * @see {@link https://threejs.org/docs/index.html#api/en/extras/core/Interpolations | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/core/Interpolations.js | Source} - */ -declare function CubicBezier(t: number, p0: number, p1: number, p2: number, p3: number): number; - -export { CatmullRom, CubicBezier, QuadraticBezier }; diff --git a/src-testing/src/extras/core/Path.d.ts b/src-testing/src/extras/core/Path.d.ts deleted file mode 100644 index 28be15b9c..000000000 --- a/src-testing/src/extras/core/Path.d.ts +++ /dev/null @@ -1,166 +0,0 @@ -import { Vector2, Vector2Tuple } from "../../math/Vector2.js"; -import { CurvePath, CurvePathJSON } from "./CurvePath.js"; - -export interface PathJSON extends CurvePathJSON { - currentPoint: Vector2Tuple; -} - -/** - * A 2D {@link Path} representation. - * @remarks - * The class provides methods for creating paths and contours of 2D shapes similar to the 2D Canvas API. - * @example - * ```typescript - * const {@link Path} = new THREE.Path(); - * path.lineTo(0, 0.8); - * path.quadraticCurveTo(0, 1, 0.2, 1); - * path.lineTo(1, 1); - * const points = path.getPoints(); - * const geometry = new THREE.BufferGeometry().setFromPoints(points); - * const material = new THREE.LineBasicMaterial({ - * color: 0xffffff - * }); - * const line = new THREE.Line(geometry, material); - * scene.add(line); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/extras/core/Path | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/core/Path.js | Source} - */ -export class Path extends CurvePath { - /** - * Creates a {@link Path} from the points - * @remarks - * The first point defines the offset, then successive points are added to the {@link CurvePath.curves | curves} array as {@link LineCurve | LineCurves}. - * If no points are specified, an empty {@link Path} is created and the {@link .currentPoint} is set to the origin. - * @param points Array of {@link Vector2 | Vector2s}. - */ - constructor(points?: Vector2[]); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `Path` - */ - override readonly type: string | "Path"; - - /** - * The current offset of the path. Any new {@link THREE.Curve | Curve} added will start here. - * @defaultValue `new THREE.Vector2()` - */ - currentPoint: Vector2; - - /** - * Adds an absolutely positioned {@link THREE.EllipseCurve | EllipseCurve} to the path. - * @param x Expects a `Float` - * @param y X, The absolute center of the arc. Expects a `Float` - * @param radius The radius of the arc. Expects a `Float` - * @param startAngle The start angle in radians. Expects a `Float` - * @param endAngle The end angle in radians. Expects a `Float` - * @param clockwise Sweep the arc clockwise. Default `false` - */ - absarc(aX: number, aY: number, aRadius: number, aStartAngle: number, aEndAngle: number, aClockwise?: boolean): this; - - /** - * Adds an absolutely positioned {@link THREE.EllipseCurve | EllipseCurve} to the path. - * @param x Expects a `Float` - * @param y X, The absolute center of the ellipse. Expects a `Float` - * @param xRadius The radius of the ellipse in the x axis. Expects a `Float` - * @param yRadius The radius of the ellipse in the y axis. Expects a `Float` - * @param startAngle The start angle in radians. Expects a `Float` - * @param endAngle The end angle in radians. Expects a `Float` - * @param clockwise Sweep the ellipse clockwise. Default `false` - * @param rotation The rotation angle of the ellipse in radians, counterclockwise from the positive X axis. Optional, Expects a `Float`. Default `0` - */ - absellipse( - aX: number, - aY: number, - xRadius: number, - yRadius: number, - aStartAngle: number, - aEndAngle: number, - aClockwise?: boolean, - aRotation?: number, - ): this; - - /** - * Adds an {@link THREE.EllipseCurve | EllipseCurve} to the path, positioned relative to {@link .currentPoint}. - * @param x Expects a `Float` - * @param y X, The center of the arc offset from the last call. Expects a `Float` - * @param radius The radius of the arc. Expects a `Float` - * @param startAngle The start angle in radians. Expects a `Float` - * @param endAngle The end angle in radians. Expects a `Float` - * @param clockwise Sweep the arc clockwise. Default `false` - */ - arc(aX: number, aY: number, aRadius: number, aStartAngle: number, aEndAngle: number, aClockwise?: boolean): this; - - /** - * This creates a bezier curve from {@link .currentPoint} with (cp1X, cp1Y) and (cp2X, cp2Y) as control points and updates {@link .currentPoint} to x and y. - * @param cp1X Expects a `Float` - * @param cp1Y Expects a `Float` - * @param cp2X Expects a `Float` - * @param cp2Y Expects a `Float` - * @param x Expects a `Float` - * @param y Expects a `Float` - */ - bezierCurveTo(aCP1x: number, aCP1y: number, aCP2x: number, aCP2y: number, aX: number, aY: number): this; - - /** - * Adds an {@link THREE.EllipseCurve | EllipseCurve} to the path, positioned relative to {@link .currentPoint}. - * @param x Expects a `Float` - * @param y X, The center of the ellipse offset from the last call. Expects a `Float` - * @param xRadius The radius of the ellipse in the x axis. Expects a `Float` - * @param yRadius The radius of the ellipse in the y axis. Expects a `Float` - * @param startAngle The start angle in radians. Expects a `Float` - * @param endAngle The end angle in radians. Expects a `Float` - * @param clockwise Sweep the ellipse clockwise. Default `false` - * @param rotation The rotation angle of the ellipse in radians, counterclockwise from the positive X axis. Optional, Expects a `Float`. Default `0` - */ - ellipse( - aX: number, - aY: number, - xRadius: number, - yRadius: number, - aStartAngle: number, - aEndAngle: number, - aClockwise?: boolean, - aRotation?: number, - ): this; - - /** - * Connects a {@link THREE.LineCurve | LineCurve} from {@link .currentPoint} to x, y onto the path. - * @param x Expects a `Float` - * @param y Expects a `Float` - */ - lineTo(x: number, y: number): this; - - /** - * Move the {@link .currentPoint} to x, y. - * @param x Expects a `Float` - * @param y Expects a `Float` - */ - moveTo(x: number, y: number): this; - - /** - * Creates a quadratic curve from {@link .currentPoint} with cpX and cpY as control point and updates {@link .currentPoint} to x and y. - * @param cpX Expects a `Float` - * @param cpY Expects a `Float` - * @param x Expects a `Float` - * @param y Expects a `Float` - */ - quadraticCurveTo(aCPx: number, aCPy: number, aX: number, aY: number): this; - - /** - * Points are added to the {@link CurvePath.curves | curves} array as {@link THREE.LineCurve | LineCurves}. - * @param vector2s - */ - setFromPoints(vectors: Vector2[]): this; - - /** - * Connects a new {@link THREE.SplineCurve | SplineCurve} onto the path. - * @param points An array of {@link Vector2 | Vector2's} - */ - splineThru(pts: Vector2[]): this; - - toJSON(): PathJSON; - fromJSON(json: PathJSON): this; -} diff --git a/src-testing/src/extras/core/Shape.d.ts b/src-testing/src/extras/core/Shape.d.ts deleted file mode 100644 index 84e5ff37f..000000000 --- a/src-testing/src/extras/core/Shape.d.ts +++ /dev/null @@ -1,86 +0,0 @@ -import { Vector2 } from "../../math/Vector2.js"; -import { Path, PathJSON } from "./Path.js"; - -export interface ShapeJSON extends PathJSON { - uuid: string; - holes: PathJSON[]; -} - -/** - * Defines an arbitrary 2d {@link Shape} plane using paths with optional holes - * @remarks - * It can be used with {@link THREE.ExtrudeGeometry | ExtrudeGeometry}, {@link THREE.ShapeGeometry | ShapeGeometry}, to get points, or to get triangulated faces. - * @example - * ```typescript - * const heartShape = new THREE.Shape(); - * heartShape.moveTo(25, 25); - * heartShape.bezierCurveTo(25, 25, 20, 0, 0, 0); - * heartShape.bezierCurveTo(-30, 0, -30, 35, -30, 35); - * heartShape.bezierCurveTo(-30, 55, -10, 77, 25, 95); - * heartShape.bezierCurveTo(60, 77, 80, 55, 80, 35); - * heartShape.bezierCurveTo(80, 35, 80, 0, 50, 0); - * heartShape.bezierCurveTo(35, 0, 25, 25, 25, 25); - * const extrudeSettings = { - * depth: 8, - * bevelEnabled: true, - * bevelSegments: 2, - * steps: 2, - * bevelSize: 1, - * bevelThickness: 1 - * }; - * const geometry = new THREE.ExtrudeGeometry(heartShape, extrudeSettings); - * const mesh = new THREE.Mesh(geometry, new THREE.MeshPhongMaterial()); - * ``` - * @see Example: {@link https://threejs.org/examples/#webgl_geometry_shapes | geometry / shapes } - * @see Example: {@link https://threejs.org/examples/#webgl_geometry_extrude_shapes | geometry / extrude / shapes } - * @see Example: {@link https://threejs.org/examples/#webgl_geometry_extrude_shapes2 | geometry / extrude / shapes2 } - * @see {@link https://threejs.org/docs/index.html#api/en/extras/core/Shape | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/core/Shape.js | Source} - */ -export class Shape extends Path { - /** - * Creates a {@link Shape} from the points - * @remarks - * The first point defines the offset, then successive points are added to the {@link CurvePath.curves | curves} array as {@link THREE.LineCurve | LineCurves}. - * If no points are specified, an empty {@link Shape} is created and the {@link .currentPoint} is set to the origin. - * @param points Array of {@link Vector2 | Vector2s}. - */ - constructor(points?: Vector2[]); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `Shape` - */ - override readonly type: string | "Shape"; - - /** - * {@link http://en.wikipedia.org/wiki/Universally_unique_identifier | UUID} of this object instance. - * @remarks This gets automatically assigned and shouldn't be edited. - */ - uuid: string; - - /** - * An array of {@link Path | paths} that define the holes in the shape. - * @defaultValue `[]` - */ - holes: Path[]; - - /** - * Call {@link THREE.Curve.getPoints | getPoints} on the {@link Shape} and the {@link holes} array - * @param divisions The fineness of the result. Expects a `Integer` - */ - extractPoints(divisions: number): { - shape: Vector2[]; - holes: Vector2[][]; - }; - - /** - * Get an array of {@link Vector2 | Vector2's} that represent the holes in the shape. - * @param divisions The fineness of the result. Expects a `Integer` - */ - getPointsHoles(divisions: number): Vector2[][]; - - toJSON(): ShapeJSON; - fromJSON(json: ShapeJSON): this; -} diff --git a/src-testing/src/extras/core/ShapePath.d.ts b/src-testing/src/extras/core/ShapePath.d.ts deleted file mode 100644 index 0fcd88312..000000000 --- a/src-testing/src/extras/core/ShapePath.d.ts +++ /dev/null @@ -1,98 +0,0 @@ -import { Color } from "../../math/Color.js"; -import { Vector2 } from "../../math/Vector2.js"; -import { Path } from "./Path.js"; -import { Shape } from "./Shape.js"; - -/** - * This class is used to convert a series of shapes to an array of {@link THREE.Path | Path's}, - * for example an SVG shape to a path. - * @see {@link https://threejs.org/docs/index.html#api/en/extras/core/ShapePath | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/core/ShapePath.js | Source} - */ -export class ShapePath { - /** - * Creates a new {@link ShapePath} - * @remarks - * Unlike a {@link THREE.Path | Path}, no points are passed in as the {@link ShapePath} is designed to be generated after creation. - */ - constructor(); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `ShapePath` - */ - readonly type: "ShapePath"; - - /** - * Array of {@link THREE.Path | Path's}s. - * @defaultValue `[]` - */ - subPaths: Path[]; - - /** - * The current {@link THREE.Path | Path} that is being generated. - * @defaultValue `null` - */ - readonly currentPath: Path | null; - - /** - * {@link THREE.Color | Color} of the shape, by default set to white _(0xffffff)_. - * @defaultValue `new THREE.Color()` - */ - color: Color; - - /** - * Starts a new {@link THREE.Path | Path} and calls {@link THREE.Path.moveTo | Path.moveTo}( x, y ) on that {@link THREE.Path | Path} - * @remarks - * Also points {@link ShapePath.currentPath | currentPath} to that {@link THREE.Path | Path}. - * @param x Expects a `Float` - * @param y Expects a `Float` - */ - moveTo(x: number, y: number): this; - - /** - * This creates a line from the {@link ShapePath.currentPath | currentPath}'s offset to X and Y and updates the offset to X and Y. - * @param x Expects a `Float` - * @param y Expects a `Float` - */ - lineTo(x: number, y: number): this; - - /** - * This creates a quadratic curve from the {@link ShapePath.currentPath | currentPath}'s - * offset to _x_ and _y_ with _cpX_ and _cpY_ as control point and updates the {@link ShapePath.currentPath | currentPath}'s offset to _x_ and _y_. - * @param cpX Expects a `Float` - * @param cpY Expects a `Float` - * @param x Expects a `Float` - * @param y Expects a `Float` - */ - quadraticCurveTo(aCPx: number, aCPy: number, aX: number, aY: number): this; - - /** - * This creates a bezier curve from the {@link ShapePath.currentPath | currentPath}'s - * offset to _x_ and _y_ with _cp1X_, _cp1Y_ and _cp2X_, _cp2Y_ as control points and - * updates the {@link ShapePath.currentPath | currentPath}'s offset to _x_ and _y_. - * @param cp1X Expects a `Float` - * @param cp1Y Expects a `Float` - * @param cp2X Expects a `Float` - * @param cp2Y Expects a `Float` - * @param x Expects a `Float` - * @param y Expects a `Float` - */ - bezierCurveTo(aCP1x: number, aCP1y: number, aCP2x: number, aCP2y: number, aX: number, aY: number): this; - - /** - * Connects a new {@link THREE.SplineCurve | SplineCurve} onto the {@link ShapePath.currentPath | currentPath}. - * @param points An array of {@link THREE.Vector2 | Vector2}s - */ - splineThru(pts: Vector2[]): this; - - /** - * Converts the {@link ShapePath.subPaths | subPaths} array into an array of Shapes - * @remarks - * By default solid shapes are defined clockwise (CW) and holes are defined counterclockwise (CCW) - * If isCCW is set to true, then those are flipped. - * @param isCCW Changes how solids and holes are generated - */ - toShapes(isCCW: boolean): Shape[]; -} diff --git a/src-testing/src/extras/curves/ArcCurve.d.ts b/src-testing/src/extras/curves/ArcCurve.d.ts deleted file mode 100644 index 0932f7ffb..000000000 --- a/src-testing/src/extras/curves/ArcCurve.d.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { EllipseCurve } from "./EllipseCurve.js"; - -/** - * Alias for {@link THREE.EllipseCurve | EllipseCurve}. - * @see {@link https://threejs.org/docs/index.html#api/en/extras/curves/ArcCurve | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/curves/ArcCurve.js | Source} - */ -export class ArcCurve extends EllipseCurve { - /** - * This constructor creates a new {@link ArcCurve}. - * @param aX The X center of the ellipse. Expects a `Float`. Default is `0`. - * @param aY The Y center of the ellipse. Expects a `Float`. Default is `0`. - * @param xRadius The radius of the ellipse in the x direction. Expects a `Float`. Default is `1`. - * @param yRadius The radius of the ellipse in the y direction. Expects a `Float`. Default is `1`. - * @param aStartAngle The start angle of the curve in radians starting from the positive X axis. Default is `0`. - * @param aEndAngle The end angle of the curve in radians starting from the positive X axis. Default is `2 x Math.PI`. - * @param aClockwise Whether the ellipse is drawn clockwise. Default is `false`. - */ - constructor( - aX?: number, - aY?: number, - aRadius?: number, - aStartAngle?: number, - aEndAngle?: number, - aClockwise?: boolean, - ); - - /** - * Read-only flag to check if a given object is of type {@link ArcCurve}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isArcCurve = true; - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `ArcCurve` - */ - override readonly type: string | "ArcCurve"; -} diff --git a/src-testing/src/extras/curves/CatmullRomCurve3.d.ts b/src-testing/src/extras/curves/CatmullRomCurve3.d.ts deleted file mode 100644 index 55088e412..000000000 --- a/src-testing/src/extras/curves/CatmullRomCurve3.d.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { Vector3 } from "../../math/Vector3.js"; -import { Curve } from "../core/Curve.js"; - -export type CurveType = "centripetal" | "chordal" | "catmullrom"; - -/** - * Create a smooth **3D** spline curve from a series of points using the {@link https://en.wikipedia.org/wiki/Centripetal_Catmull-Rom_spline | Catmull-Rom} algorithm. - * @example - * ```typescript - * //Create a closed wavey loop - * const curve = new THREE.CatmullRomCurve3([ - * new THREE.Vector3(-10, 0, 10), - * new THREE.Vector3(-5, 5, 5), - * new THREE.Vector3(0, 0, 0), - * new THREE.Vector3(5, -5, 5), - * new THREE.Vector3(10, 0, 10)]); - * const points = curve.getPoints(50); - * const geometry = new THREE.BufferGeometry().setFromPoints(points); - * const material = new THREE.LineBasicMaterial({ - * color: 0xff0000 - * }); - * // Create the final object to add to the scene - * const curveObject = new THREE.Line(geometry, material); - * ``` - * @see Example: {@link https://threejs.org/examples/#webgl_geometry_extrude_splines | WebGL / geometry / extrude / splines} - * @see {@link https://threejs.org/docs/index.html#api/en/extras/curves/CatmullRomCurve3 | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/curves/CatmullRomCurve3.js | Source} - */ -export class CatmullRomCurve3 extends Curve { - /** - * This constructor creates a new {@link CatmullRomCurve3}. - * @param points An array of {@link THREE.Vector3 | Vector3} points - * @param closed Whether the curve is closed. Default `false` - * @param curveType Type of the curve. Default `centripetal` - * @param tension Tension of the curve. Expects a `Float`. Default `0.5` - */ - constructor(points?: Vector3[], closed?: boolean, curveType?: CurveType, tension?: number); - - /** - * Read-only flag to check if a given object is of type {@link CatmullRomCurve3}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isCatmullRomCurve3 = true; - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `CatmullRomCurve3` - */ - override readonly type: string | "CatmullRomCurve3"; - - /** - * The curve will loop back onto itself when this is true. - * @defaultValue `false` - */ - closed: boolean; - - /** - * The array of {@link THREE.Vector3 | Vector3} points that define the curve. - * @remarks It needs at least two entries. - * @defaultValue `[]` - */ - points: Vector3[]; - - /** - * Possible values are `centripetal`, `chordal` and `catmullrom`. - * @defaultValue `centripetal` - */ - curveType: CurveType; - - /** - * When {@link .curveType} is `catmullrom`, defines catmullrom's tension. - * @remarks Expects a `Float` - */ - tension: number; -} diff --git a/src-testing/src/extras/curves/CubicBezierCurve.d.ts b/src-testing/src/extras/curves/CubicBezierCurve.d.ts deleted file mode 100644 index ae4518312..000000000 --- a/src-testing/src/extras/curves/CubicBezierCurve.d.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { Vector2 } from "../../math/Vector2.js"; -import { Curve } from "../core/Curve.js"; - -/** - * Create a smooth **2D** {@link http://en.wikipedia.org/wiki/B%C3%A9zier_curve#mediaviewer/File:Bezier_curve.svg | cubic bezier curve}, - * defined by a start point, endpoint and two control points. - * @example - * ```typescript - * const curve = new THREE.CubicBezierCurve( - * new THREE.Vector2(-10, 0), - * new THREE.Vector2(-5, 15), - * new THREE.Vector2(20, 15), - * new THREE.Vector2(10, 0)); - * const points = curve.getPoints(50); - * const geometry = new THREE.BufferGeometry().setFromPoints(points); - * const material = new THREE.LineBasicMaterial({ - * color: 0xff0000 - * }); - * // Create the final object to add to the scene - * const curveObject = new THREE.Line(geometry, material); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/extras/curves/CubicBezierCurve | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/curves/CubicBezierCurve.js | Source} - */ -export class CubicBezierCurve extends Curve { - /** - * This constructor creates a new {@link CubicBezierCurve}. - * @param v0 The starting point. Default is `new THREE.Vector2()`. - * @param v1 The first control point. Default is `new THREE.Vector2()`. - * @param v2 The second control point. Default is `new THREE.Vector2()`. - * @param v3 The ending point. Default is `new THREE.Vector2()`. - */ - constructor(v0?: Vector2, v1?: Vector2, v2?: Vector2, v3?: Vector2); - - /** - * Read-only flag to check if a given object is of type {@link CubicBezierCurve}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isCubicBezierCurve = true; - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `CubicBezierCurve` - */ - override readonly type: string | "CubicBezierCurve"; - - /** - * The starting point. - * @defaultValue `new THREE.Vector2()` - */ - v0: Vector2; - - /** - * The first control point. - * @defaultValue `new THREE.Vector2()` - */ - v1: Vector2; - - /** - * The second control point. - * @defaultValue `new THREE.Vector2()` - */ - v2: Vector2; - - /** - * The ending point. - * @defaultValue `new THREE.Vector2()` - */ - v3: Vector2; -} diff --git a/src-testing/src/extras/curves/CubicBezierCurve3.d.ts b/src-testing/src/extras/curves/CubicBezierCurve3.d.ts deleted file mode 100644 index ad8edb356..000000000 --- a/src-testing/src/extras/curves/CubicBezierCurve3.d.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { Vector3 } from "../../math/Vector3.js"; -import { Curve } from "../core/Curve.js"; - -/** - * Create a smooth **3D** {@link http://en.wikipedia.org/wiki/B%C3%A9zier_curve#mediaviewer/File:Bezier_curve.svg | cubic bezier curve}, - * defined by a start point, endpoint and two control points. - * @example - * ```typescript - * const curve = new THREE.CubicBezierCurve( - * new THREE.Vector2(-10, 0), - * new THREE.Vector2(-5, 15), - * new THREE.Vector2(20, 15), - * new THREE.Vector2(10, 0)); - * const points = curve.getPoints(50); - * const geometry = new THREE.BufferGeometry().setFromPoints(points); - * const material = new THREE.LineBasicMaterial({ - * color: 0xff0000 - * }); - * // Create the final object to add to the scene - * const curveObject = new THREE.Line(geometry, material); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/extras/curves/CubicBezierCurve | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/curves/CubicBezierCurve.js | Source} - */ -export class CubicBezierCurve3 extends Curve { - /** - * This constructor creates a new {@link CubicBezierCurve3}. - * @param v0 The starting point. Default is `new THREE.Vector3()`. - * @param v1 The first control point. Default is `new THREE.Vector3()`. - * @param v2 The second control point. Default is `new THREE.Vector3()`. - * @param v3 The ending point. Default is `new THREE.Vector3()`. - */ - constructor(v0?: Vector3, v1?: Vector3, v2?: Vector3, v3?: Vector3); - - /** - * Read-only flag to check if a given object is of type {@link CubicBezierCurve3}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isCubicBezierCurve3 = true; - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `CubicBezierCurve3` - */ - override readonly type: string | "CubicBezierCurve3"; - - /** - * The starting point. - * @defaultValue `new THREE.Vector3()`. - */ - v0: Vector3; - - /** - * The first control point. - * @defaultValue `new THREE.Vector3()`. - */ - v1: Vector3; - - /** - * The second control point. - * @defaultValue `new THREE.Vector3()`. - */ - v2: Vector3; - - /** - * The ending point. - * @defaultValue `new THREE.Vector3()`. - */ - v3: Vector3; -} diff --git a/src-testing/src/extras/curves/Curves.d.ts b/src-testing/src/extras/curves/Curves.d.ts deleted file mode 100644 index 996021d72..000000000 --- a/src-testing/src/extras/curves/Curves.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -export * from "./ArcCurve.js"; -export * from "./CatmullRomCurve3.js"; -export * from "./CubicBezierCurve.js"; -export * from "./CubicBezierCurve3.js"; -export * from "./EllipseCurve.js"; -export * from "./LineCurve.js"; -export * from "./LineCurve3.js"; -export * from "./QuadraticBezierCurve.js"; -export * from "./QuadraticBezierCurve3.js"; -export * from "./SplineCurve.js"; diff --git a/src-testing/src/extras/curves/EllipseCurve.d.ts b/src-testing/src/extras/curves/EllipseCurve.d.ts deleted file mode 100644 index 4d15ca8c2..000000000 --- a/src-testing/src/extras/curves/EllipseCurve.d.ts +++ /dev/null @@ -1,115 +0,0 @@ -import { Vector2 } from "../../math/Vector2.js"; -import { Curve } from "../core/Curve.js"; - -/** - * Creates a 2d curve in the shape of an ellipse - * @remarks - * Setting the {@link xRadius} equal to the {@link yRadius} will result in a circle. - * @example - * ```typescript - * const curve = new THREE.EllipseCurve( - * 0, 0, // ax, aY - * 10, 10, // xRadius, yRadius - * 0, 2 * Math.PI, // aStartAngle, aEndAngle - * false, // aClockwise - * 0 // aRotation - * ); - * const points = curve.getPoints(50); - * const geometry = new THREE.BufferGeometry().setFromPoints(points); - * const material = new THREE.LineBasicMaterial({ color: 0xff0000 }); - * // Create the final object to add to the scene - * const ellipse = new THREE.Line(geometry, material); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/extras/curves/EllipseCurve | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/curves/EllipseCurve.js | Source} - */ -export class EllipseCurve extends Curve { - /** - * This constructor creates a new {@link EllipseCurve}. - * @param aX The X center of the ellipse. Expects a `Float`. Default is `0`. - * @param aY The Y center of the ellipse. Expects a `Float`. Default is `0`. - * @param xRadius The radius of the ellipse in the x direction. Expects a `Float`. Default is `1`. - * @param yRadius The radius of the ellipse in the y direction. Expects a `Float`. Default is `1`. - * @param aStartAngle The start angle of the curve in radians starting from the positive X axis. Default is `0`. - * @param aEndAngle The end angle of the curve in radians starting from the positive X axis. Default is `2 x Math.PI`. - * @param aClockwise Whether the ellipse is drawn clockwise. Default is `false`. - * @param aRotation The rotation angle of the ellipse in radians, counterclockwise from the positive X axis. Default is `0`. - */ - constructor( - aX?: number, - aY?: number, - xRadius?: number, - yRadius?: number, - aStartAngle?: number, - aEndAngle?: number, - aClockwise?: boolean, - aRotation?: number, - ); - - /** - * Read-only flag to check if a given object is of type {@link EllipseCurve}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isEllipseCurve = true; - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `EllipseCurve` - */ - override readonly type: string | "EllipseCurve"; - - /** - * The X center of the ellipse. - * @remarks Expects a `Float` - * @defaultValue `0` - */ - aX: number; - - /** - * The Y center of the ellipse. - * @remarks Expects a `Float` - * @defaultValue `0` - */ - aY: number; - - /** - * The radius of the ellipse in the x direction. - * @defaultValue `1` - */ - xRadius: number; - - /** - * The radius of the ellipse in the y direction. - * @defaultValue `1` - */ - yRadius: number; - - /** - * The start angle of the curve in radians starting from the middle right side. - * @remarks Expects a `Float` - * @defaultValue `0` - */ - aStartAngle: number; - - /** - * The end angle of the curve in radians starting from the middle right side. - * @remarks Expects a `Float` - * @defaultValue `2 * Math.PI` - */ - aEndAngle: number; - - /** - * Whether the ellipse is drawn clockwise. - * @defaultValue `false`` - */ - aClockwise: boolean; - - /** - * The rotation angle of the ellipse in radians, counterclockwise from the positive X axis (optional). - * @remarks Expects a `Float` - * @defaultValue `0` - */ - aRotation: number; -} diff --git a/src-testing/src/extras/curves/LineCurve.d.ts b/src-testing/src/extras/curves/LineCurve.d.ts deleted file mode 100644 index 3bcb000d3..000000000 --- a/src-testing/src/extras/curves/LineCurve.d.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { Vector2 } from "../../math/Vector2.js"; -import { Curve } from "../core/Curve.js"; - -/** - * A curve representing a **2D** line segment. - * @see {@link https://threejs.org/docs/index.html#api/en/extras/curves/LineCurve | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/curves/LineCurve.js | Source} - */ -export class LineCurve extends Curve { - /** - * This constructor creates a new {@link LineCurve}. - * @param v1 The start point. Default is `new THREE.Vector2()`. - * @param v2 The end point. Default is `new THREE.Vector2()`. - */ - constructor(v1?: Vector2, v2?: Vector2); - - /** - * Read-only flag to check if a given object is of type {@link LineCurve}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isLineCurve = true; - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `LineCurve` - */ - override readonly type: string | "LineCurve"; - - /** - * The start point. - * @defaultValue `new THREE.Vector2()` - */ - v1: Vector2; - - /** - * The end point - * @defaultValue `new THREE.Vector2()` - */ - v2: Vector2; -} diff --git a/src-testing/src/extras/curves/LineCurve3.d.ts b/src-testing/src/extras/curves/LineCurve3.d.ts deleted file mode 100644 index c7ae7c301..000000000 --- a/src-testing/src/extras/curves/LineCurve3.d.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { Vector3 } from "../../math/Vector3.js"; -import { Curve } from "../core/Curve.js"; - -/** - * A curve representing a **3D** line segment. - * @see {@link https://threejs.org/docs/index.html#api/en/extras/curves/LineCurve3 | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/curves/LineCurve3.js | Source} - */ -export class LineCurve3 extends Curve { - /** - * This constructor creates a new {@link LineCurve3}. - * @param v1 The start point. Default is `new THREE.Vector3()`. - * @param v2 The end point. Default is `new THREE.Vector3()`. - */ - constructor(v1?: Vector3, v2?: Vector3); - - /** - * Read-only flag to check if a given object is of type {@link LineCurve3}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isLineCurve3 = true; - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `LineCurve3` - */ - override readonly type: string | "LineCurve3"; - - /** - * The start point. - * @defaultValue `new THREE.Vector3()`. - */ - v1: Vector3; - - /** - * The end point. - * @defaultValue `new THREE.Vector3()`. - */ - v2: Vector3; -} diff --git a/src-testing/src/extras/curves/QuadraticBezierCurve.d.ts b/src-testing/src/extras/curves/QuadraticBezierCurve.d.ts deleted file mode 100644 index 8ae4c3213..000000000 --- a/src-testing/src/extras/curves/QuadraticBezierCurve.d.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { Vector2 } from "../../math/Vector2.js"; -import { Curve } from "../core/Curve.js"; - -/** - * Create a smooth **2D** {@link http://en.wikipedia.org/wiki/B%C3%A9zier_curve#mediaviewer/File:B%C3%A9zier_2_big.gif | quadratic bezier curve}, - * defined by a start point, end point and a single control point. - * @example - * ```typescript - * const curve = new THREE.QuadraticBezierCurve( - * new THREE.Vector2(-10, 0), - * new THREE.Vector2(20, 15), - * new THREE.Vector2(10, 0)); - * const points = curve.getPoints(50); - * const geometry = new THREE.BufferGeometry().setFromPoints(points); - * const material = new THREE.LineBasicMaterial({ - * color: 0xff0000 - * }); - * // Create the final object to add to the scene - * const curveObject = new THREE.Line(geometry, material); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/extras/curves/QuadraticBezierCurve | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/curves/QuadraticBezierCurve.js | Source} - */ -export class QuadraticBezierCurve extends Curve { - /** - * This constructor creates a new {@link QuadraticBezierCurve}. - * @param v0 The start point. Default is `new THREE.Vector2()`. - * @param v1 The control point. Default is `new THREE.Vector2()`. - * @param v2 The end point. Default is `new THREE.Vector2()`. - */ - constructor(v0?: Vector2, v1?: Vector2, v2?: Vector2); - - /** - * Read-only flag to check if a given object is of type {@link LineCurve3}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isQuadraticBezierCurve = true; - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `QuadraticBezierCurve` - */ - override readonly type: string | "QuadraticBezierCurve"; - - /** - * The start point. - * @defaultValue `new THREE.Vector2()` - */ - v0: Vector2; - - /** - * The control point. - * @defaultValue `new THREE.Vector2()` - */ - v1: Vector2; - - /** - * The end point. - * @defaultValue `new THREE.Vector2()` - */ - v2: Vector2; -} diff --git a/src-testing/src/extras/curves/QuadraticBezierCurve3.d.ts b/src-testing/src/extras/curves/QuadraticBezierCurve3.d.ts deleted file mode 100644 index 3964af820..000000000 --- a/src-testing/src/extras/curves/QuadraticBezierCurve3.d.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { Vector3 } from "../../math/Vector3.js"; -import { Curve } from "../core/Curve.js"; - -/** - * Create a smooth **3D** {@link http://en.wikipedia.org/wiki/B%C3%A9zier_curve#mediaviewer/File:B%C3%A9zier_2_big.gif | quadratic bezier curve}, - * defined by a start point, end point and a single control point. - * @example - * ```typescript - * const curve = new THREE.QuadraticBezierCurve3( - * new THREE.Vector3(-10, 0, 0), - * new THREE.Vector3(20, 15, 0), - * new THREE.Vector3(10, 0, 0)); - * const points = curve.getPoints(50); - * const geometry = new THREE.BufferGeometry().setFromPoints(points); - * const material = new THREE.LineBasicMaterial({ - * color: 0xff0000 - * }); - * // Create the final object to add to the scene - * const curveObject = new THREE.Line(geometry, material); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/extras/curves/QuadraticBezierCurve3 | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/curves/QuadraticBezierCurve3.js | Source} - */ -export class QuadraticBezierCurve3 extends Curve { - /** - * This constructor creates a new {@link QuadraticBezierCurve}. - * @param v0 The start point. Default is `new THREE.Vector3()`. - * @param v1 The control point. Default is `new THREE.Vector3()`. - * @param v2 The end point. Default is `new THREE.Vector3()`. - */ - constructor(v0?: Vector3, v1?: Vector3, v2?: Vector3); - - /** - * Read-only flag to check if a given object is of type {@link QuadraticBezierCurve3}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isQuadraticBezierCurve3 = true; - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `QuadraticBezierCurve3` - */ - override readonly type: string | "QuadraticBezierCurve3"; - - /** - * The start point. - * @defaultValue `new THREE.Vector3()` - */ - v0: Vector3; - - /** - * The control point. - * @defaultValue `new THREE.Vector3()` - */ - v1: Vector3; - - /** - * The end point. - * @defaultValue `new THREE.Vector3()` - */ - v2: Vector3; -} diff --git a/src-testing/src/extras/curves/SplineCurve.d.ts b/src-testing/src/extras/curves/SplineCurve.d.ts deleted file mode 100644 index c3c56210a..000000000 --- a/src-testing/src/extras/curves/SplineCurve.d.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { Vector2 } from "../../math/Vector2.js"; -import { Curve } from "../core/Curve.js"; - -/** - * Create a smooth **2D** spline curve from a series of points. - * @example - * ```typescript - * // Create a sine-like wave - * const curve = new THREE.SplineCurve([ - * new THREE.Vector2(-10, 0), - * new THREE.Vector2(-5, 5), - * new THREE.Vector2(0, 0), - * new THREE.Vector2(5, -5), - * new THREE.Vector2(10, 0)]); - * const points = curve.getPoints(50); - * const geometry = new THREE.BufferGeometry().setFromPoints(points); - * const material = new THREE.LineBasicMaterial({ - * color: 0xff0000 - * }); - * // Create the final object to add to the scene - * const splineObject = new THREE.Line(geometry, material); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/extras/curves/SplineCurve | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/extras/curves/SplineCurve.js | Source} - */ -export class SplineCurve extends Curve { - /** - * This constructor creates a new {@link SplineCurve}. - * @param points An array of {@link THREE.Vector2 | Vector2} points that define the curve. Default `[]` - */ - constructor(points?: Vector2[]); - - /** - * Read-only flag to check if a given object is of type {@link SplineCurve}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isSplineCurve = true; - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `SplineCurve` - */ - override readonly type: string | "SplineCurve"; - - /** - * The array of {@link THREE.Vector2 | Vector2} points that define the curve. - * @defaultValue `[]` - */ - points: Vector2[]; -} diff --git a/src-testing/src/geometries/BoxGeometry.d.ts b/src-testing/src/geometries/BoxGeometry.d.ts deleted file mode 100644 index 7a756ae56..000000000 --- a/src-testing/src/geometries/BoxGeometry.d.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { BufferGeometry } from "../core/BufferGeometry.js"; - -/** - * {@link BoxGeometry} is a geometry class for a rectangular cuboid with a given 'width', 'height', and 'depth' - * @remarks On creation, the cuboid is centred on the origin, with each edge parallel to one of the axes. - * @example - * ```typescript - * const geometry = new THREE.BoxGeometry(1, 1, 1); - * const material = new THREE.MeshBasicMaterial({ - * color: 0x00ff00 - * }); - * const cube = new THREE.Mesh(geometry, material); - * scene.add(cube); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/geometries/BoxGeometry | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/BoxGeometry.js | Source} - */ -export class BoxGeometry extends BufferGeometry { - /** - * Create a new instance of {@link BoxGeometry} - * @param width Width; that is, the length of the edges parallel to the X axis. Optional; Expects a `Float`. Default `1` - * @param height Height; that is, the length of the edges parallel to the Y axis. Optional; Expects a `Float`. Default `1` - * @param depth Depth; that is, the length of the edges parallel to the Z axis. Optional; Expects a `Float`. Default `1` - * @param widthSegments Number of segmented rectangular faces along the width of the sides. Optional; Expects a `Integer`. Default `1` - * @param heightSegments Number of segmented rectangular faces along the height of the sides. Optional; Expects a `Integer`. Default `1` - * @param depthSegments Number of segmented rectangular faces along the depth of the sides. Optional; Expects a `Integer`. Default `1` - */ - constructor( - width?: number, - height?: number, - depth?: number, - widthSegments?: number, - heightSegments?: number, - depthSegments?: number, - ); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `BoxGeometry` - */ - override readonly type: string | "BoxGeometry"; - - /** - * An object with a property for each of the constructor parameters. - * @remarks Any modification after instantiation does not change the geometry. - */ - readonly parameters: { - readonly width: number; - readonly height: number; - readonly depth: number; - readonly widthSegments: number; - readonly heightSegments: number; - readonly depthSegments: number; - }; - - /** @internal */ - static fromJSON(data: {}): BoxGeometry; -} diff --git a/src-testing/src/geometries/CapsuleGeometry.d.ts b/src-testing/src/geometries/CapsuleGeometry.d.ts deleted file mode 100644 index b20616035..000000000 --- a/src-testing/src/geometries/CapsuleGeometry.d.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { BufferGeometry } from "../core/BufferGeometry.js"; - -/** - * {@link CapsuleGeometry} is a geometry class for a capsule with given radii and height - * @remarks It is constructed using a lathe. - * @example - * ```typescript - * const geometry = new THREE.CapsuleGeometry(1, 1, 4, 8); - * const material = new THREE.MeshBasicMaterial({ - * color: 0x00ff00 - * }); - * const capsule = new THREE.Mesh(geometry, material); - * scene.add(capsule); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/geometries/CapsuleGeometry | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/CapsuleGeometry.js | Source} - */ -export class CapsuleGeometry extends BufferGeometry { - /** - * Create a new instance of {@link CapsuleGeometry} - * @param radius Radius of the capsule. Expects a `Float`. Default `1` - * @param length Length of the middle section. Expects a `Float`. Default `1` - * @param capSegments Number of curve segments used to build the caps. Expects a `Integer`. Default `4` - * @param radialSegments Number of segmented faces around the circumference of the capsule. Expects a `Integer`. Default `8` - */ - constructor(radius?: number, length?: number, capSegments?: number, radialSegments?: number); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `CapsuleGeometry` - */ - override readonly type: string | "CapsuleGeometry"; - - /** - * An object with a property for each of the constructor parameters. - * @remarks Any modification after instantiation does not change the geometry. - */ - readonly parameters: { - readonly radius: number; - readonly length: number; - readonly capSegments: number; - readonly radialSegments: number; - }; - - /** @internal */ - static fromJSON(data: {}): CapsuleGeometry; -} diff --git a/src-testing/src/geometries/CircleGeometry.d.ts b/src-testing/src/geometries/CircleGeometry.d.ts deleted file mode 100644 index b512e4866..000000000 --- a/src-testing/src/geometries/CircleGeometry.d.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { BufferGeometry } from "../core/BufferGeometry.js"; - -/** - * {@link CircleGeometry} is a simple shape of Euclidean geometry - * @remarks - * It is constructed from a number of triangular segments that are oriented around a central point and extend as far out as a given radius - * It is built counter-clockwise from a start angle and a given central angle - * It can also be used to create regular polygons, where the number of segments determines the number of sides. - * @example - * ```typescript - * const geometry = new THREE.CircleGeometry(5, 32); - * const material = new THREE.MeshBasicMaterial({ - * color: 0xffff00 - * }); - * const circle = new THREE.Mesh(geometry, material); - * scene.add(circle); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/geometries/CircleGeometry | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/CircleGeometry.js | Source} - */ -export class CircleGeometry extends BufferGeometry { - /** - * Create a new instance of {@link CircleGeometry} - * @param radius Radius of the circle. Expects a `Float`. Default `1` - * @param segments Number of segments (triangles). Expects a `Integer`. Minimum `3`. Default `32` - * @param thetaStart Start angle for first segment. Expects a `Float`. Default `0`, _(three o'clock position)_. - * @param thetaLength The central angle, often called theta, of the circular sector. Expects a `Float`. Default `Math.PI * 2`, _which makes for a complete circle_. - */ - constructor(radius?: number, segments?: number, thetaStart?: number, thetaLength?: number); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `CircleGeometry` - */ - override readonly type: string | "CircleGeometry"; - - /** - * An object with a property for each of the constructor parameters. - * @remarks Any modification after instantiation does not change the geometry. - */ - readonly parameters: { - readonly radius: number; - readonly segments: number; - readonly thetaStart: number; - readonly thetaLength: number; - }; - - /** @internal */ - static fromJSON(data: {}): CircleGeometry; -} diff --git a/src-testing/src/geometries/ConeGeometry.d.ts b/src-testing/src/geometries/ConeGeometry.d.ts deleted file mode 100644 index 683376429..000000000 --- a/src-testing/src/geometries/ConeGeometry.d.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { CylinderGeometry } from "./CylinderGeometry.js"; - -/** - * A class for generating cone geometries. - * @example - * ```typescript - * const geometry = new THREE.ConeGeometry(5, 20, 32); - * const material = new THREE.MeshBasicMaterial({ - * color: 0xffff00 - * }); - * const cone = new THREE.Mesh(geometry, material); - * scene.add(cone); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/geometries/ConeGeometry | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/ConeGeometry.js | Source} - */ -export class ConeGeometry extends CylinderGeometry { - /** - * Create a new instance of {@link ConeGeometry} - * @param radius Radius of the cone base. Expects a `Float`. Default `1` - * @param height Height of the cone. Expects a `Float`. Default `1` - * @param radialSegments Number of segmented faces around the circumference of the cone. Expects a `Integer`. Default `32` - * @param heightSegments Number of rows of faces along the height of the cone. Expects a `Integer`. Default `1` - * @param openEnded A Boolean indicating whether the base of the cone is open or capped. Default `false`, _meaning capped_. - * @param thetaStart Start angle for first segment. Expects a `Float`. Default `0`, _(three o'clock position)_. - * @param thetaLength The central angle, often called theta, of the circular sector. Expects a `Float`. Default `Math.PI * 2`, _which makes for a complete cone_. - */ - constructor( - radius?: number, - height?: number, - radialSegments?: number, - heightSegments?: number, - openEnded?: boolean, - thetaStart?: number, - thetaLength?: number, - ); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `ConeGeometry` - */ - override readonly type: string | "ConeGeometry"; - - /** - * An object with a property for each of the constructor parameters. - * @remarks {@link radiusTop} and {@link radiusBottom} are from base {@link THREE.CylinderGeometry} class. - * @remarks Any modification after instantiation does not change the geometry. - */ - override readonly parameters: { - readonly radius: number; - readonly radiusTop: number; - readonly radiusBottom: number; - readonly height: number; - readonly radialSegments: number; - readonly heightSegments: number; - readonly openEnded: boolean; - readonly thetaStart: number; - readonly thetaLength: number; - }; - - /** @internal */ - static fromJSON(data: {}): ConeGeometry; -} diff --git a/src-testing/src/geometries/CylinderGeometry.d.ts b/src-testing/src/geometries/CylinderGeometry.d.ts deleted file mode 100644 index 90f1b06f3..000000000 --- a/src-testing/src/geometries/CylinderGeometry.d.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { BufferGeometry } from "../core/BufferGeometry.js"; - -/** - * A class for generating cylinder geometries. - * @example - * ```typescript - * const geometry = new THREE.CylinderGeometry(5, 5, 20, 32); - * const material = new THREE.MeshBasicMaterial({ - * color: 0xffff00 - * }); - * const cylinder = new THREE.Mesh(geometry, material); - * scene.add(cylinder); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/geometries/CylinderGeometry | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/CylinderGeometry.js | Source} - */ -export class CylinderGeometry extends BufferGeometry { - /** - * Create a new instance of {@link CylinderGeometry} - * @param radiusTop Radius of the cylinder at the top. Default `1` - * @param radiusBottom Radius of the cylinder at the bottom. Default `1` - * @param height Height of the cylinder. Default `1` - * @param radialSegments Number of segmented faces around the circumference of the cylinder. Default `32` - * @param heightSegments Number of rows of faces along the height of the cylinder. Expects a `Integer`. Default `1` - * @param openEnded A Boolean indicating whether the ends of the cylinder are open or capped. Default `false`, _meaning capped_. - * @param thetaStart Start angle for first segment. Default `0`, _(three o'clock position)_. - * @param thetaLength The central angle, often called theta, of the circular sector. Default `Math.PI * 2`, _which makes for a complete cylinder. - */ - constructor( - radiusTop?: number, - radiusBottom?: number, - height?: number, - radialSegments?: number, - heightSegments?: number, - openEnded?: boolean, - thetaStart?: number, - thetaLength?: number, - ); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `CylinderGeometry` - */ - override readonly type: string | "CylinderGeometry"; - - /** - * An object with a property for each of the constructor parameters. - * @remarks Any modification after instantiation does not change the geometry. - */ - readonly parameters: { - readonly radiusTop: number; - readonly radiusBottom: number; - readonly height: number; - readonly radialSegments: number; - readonly heightSegments: number; - readonly openEnded: boolean; - readonly thetaStart: number; - readonly thetaLength: number; - }; - - /** @internal */ - static fromJSON(data: any): CylinderGeometry; -} diff --git a/src-testing/src/geometries/DodecahedronGeometry.d.ts b/src-testing/src/geometries/DodecahedronGeometry.d.ts deleted file mode 100644 index e79e5a895..000000000 --- a/src-testing/src/geometries/DodecahedronGeometry.d.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { PolyhedronGeometry } from "./PolyhedronGeometry.js"; - -/** - * A class for generating a dodecahedron geometries. - * @see {@link https://threejs.org/docs/index.html#api/en/geometries/DodecahedronGeometry | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/DodecahedronGeometry.js | Source} - */ -export class DodecahedronGeometry extends PolyhedronGeometry { - /** - * Create a new instance of {@link DodecahedronGeometry} - * @param radius Radius of the dodecahedron. Expects a `Float`. Default `1` - * @param detail Setting this to a value greater than 0 adds vertices making it no longer a dodecahedron. Expects a `Integer`. Default `0` - */ - constructor(radius?: number, detail?: number); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `DodecahedronGeometry` - */ - override readonly type: string | "DodecahedronGeometry"; - - /** @internal */ - static fromJSON(data: {}): DodecahedronGeometry; -} diff --git a/src-testing/src/geometries/EdgesGeometry.d.ts b/src-testing/src/geometries/EdgesGeometry.d.ts deleted file mode 100644 index b901b10d7..000000000 --- a/src-testing/src/geometries/EdgesGeometry.d.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { BufferGeometry } from "../core/BufferGeometry.js"; - -/** - * This can be used as a helper object to view the edges of a {@link THREE.BufferGeometry | geometry}. - * @example - * ```typescript - * const geometry = new THREE.BoxGeometry(100, 100, 100); - * const edges = new THREE.EdgesGeometry(geometry); - * const line = new THREE.LineSegments(edges, new THREE.LineBasicMaterial({ - * color: 0xffffff - * })); - * scene.add(line); - * ``` - * @see Example: {@link https://threejs.org/examples/#webgl_helpers | helpers} - * @see {@link https://threejs.org/docs/index.html#api/en/geometries/EdgesGeometry | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/EdgesGeometry.js | Source} - */ -export class EdgesGeometry extends BufferGeometry { - /** - * Create a new instance of {@link EdgesGeometry} - * @param geometry Any geometry object. Default `null`. - * @param thresholdAngle An edge is only rendered if the angle (in degrees) between the face normals of the adjoining faces exceeds this value. Expects a `Integer`. Default `1` _degree_. - */ - constructor(geometry?: TBufferGeometry | null, thresholdAngle?: number); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `EdgesGeometry` - */ - override readonly type: string | "EdgesGeometry"; - - /** - * An object with a property for each of the constructor parameters. - * @remarks Any modification after instantiation does not change the geometry. - */ - readonly parameters: { - readonly geometry: TBufferGeometry | null; - readonly thresholdAngle: number; - }; -} diff --git a/src-testing/src/geometries/ExtrudeGeometry.d.ts b/src-testing/src/geometries/ExtrudeGeometry.d.ts deleted file mode 100644 index d872b7c21..000000000 --- a/src-testing/src/geometries/ExtrudeGeometry.d.ts +++ /dev/null @@ -1,152 +0,0 @@ -import { BufferGeometry } from "../core/BufferGeometry.js"; -import { Curve } from "../extras/core/Curve.js"; -import { Shape } from "../extras/core/Shape.js"; -import { Vector2 } from "../math/Vector2.js"; -import { Vector3 } from "../math/Vector3.js"; - -export interface ExtrudeGeometryOptions { - /** - * Number of points on the curves. - * Expects a `Integer`. - * @defaultValue `12` - */ - curveSegments?: number | undefined; - - /** - * Number of points used for subdividing segments along the depth of the extruded spline. - * @defaultValue `1` - */ - steps?: number | undefined; - - /** - * Depth to extrude the shape. - * @defaultValue `1` - */ - depth?: number | undefined; - - /** - * Turn on bevel. Applying beveling to the shape. - * @defaultValue `true` - */ - bevelEnabled?: boolean | undefined; - - /** - * How deep into the original shape the bevel goes. - * Expects a `Float`. - * @defaultValue `0.2` - */ - bevelThickness?: number | undefined; - - /** - * Distance from the shape outline that the bevel extends - * Expects a `Float`. - * @defaultValue `bevelThickness - 0.1` - */ - bevelSize?: number | undefined; - - /** - * Distance from the shape outline that the bevel starts. - * Expects a `Float`. - * @defaultValue `0` - */ - bevelOffset?: number | undefined; - - /** - * Number of bevel layers/segments. - * Expects a `Integer`. - * @defaultValue `3` - */ - bevelSegments?: number | undefined; - - /** - * A 3D spline path along which the shape should be extruded. - * @remarks Bevels not supported for path extrusion. - */ - extrudePath?: Curve | undefined; - - /** - * A object that provides UV generator functions. - */ - UVGenerator?: UVGenerator | undefined; -} - -export interface UVGenerator { - generateTopUV( - geometry: ExtrudeGeometry, - vertices: number[], - indexA: number, - indexB: number, - indexC: number, - ): Vector2[]; - generateSideWallUV( - geometry: ExtrudeGeometry, - vertices: number[], - indexA: number, - indexB: number, - indexC: number, - indexD: number, - ): Vector2[]; -} - -/** - * Creates extruded geometry from a path shape. - * @remarks This object extrudes a 2D shape to a 3D geometry. - * @remarks When creating a Mesh with this geometry, if you'd like to have a separate material used for its face and its extruded sides, you can use an array of materials - * @remarks The first material will be applied to the face; the second material will be applied to the sides. - * @example - * ```typescript - * const length = 12, width = 8; - * const shape = new THREE.Shape(); - * shape.moveTo(0, 0); - * shape.lineTo(0, width); - * shape.lineTo(length, width); - * shape.lineTo(length, 0); - * shape.lineTo(0, 0); - * const extrudeSettings = { - * steps: 2, - * depth: 16, - * bevelEnabled: true, - * bevelThickness: 1, - * bevelSize: 1, - * bevelOffset: 0, - * bevelSegments: 1 - * }; - * const geometry = new THREE.ExtrudeGeometry(shape, extrudeSettings); - * const material = new THREE.MeshBasicMaterial({ - * color: 0x00ff00 - * }); - * const mesh = new THREE.Mesh(geometry, material); - * scene.add(mesh); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/geometries/ExtrudeGeometry | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/ExtrudeGeometry.js | Source} - */ -export class ExtrudeGeometry extends BufferGeometry { - /** - * Create a new instance of {@link ExtrudeGeometry} - * @param shapes Shape or an array of shapes. Default `new Shape([new Vector2(0.5, 0.5), new Vector2(-0.5, 0.5), new Vector2(-0.5, -0.5), new Vector2(0.5, -0.5)])`. - * @param options Object that can contain the following parameters. @see {@link ExtrudeGeometryOptions} for defaults. - */ - constructor(shapes?: Shape | Shape[], options?: ExtrudeGeometryOptions); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `ExtrudeGeometry` - */ - override readonly type: string | "ExtrudeGeometry"; - - /** - * An object with a property for each of the constructor parameters. - * @remarks Any modification after instantiation does not change the geometry. - */ - readonly parameters: { - readonly shapes: Shape | Shape[]; - readonly options: ExtrudeGeometryOptions; - }; - - addShape(shape: Shape): void; - - /** @internal */ - static fromJSON(data: {}, shapes: unknown): ExtrudeGeometry; -} diff --git a/src-testing/src/geometries/Geometries.d.ts b/src-testing/src/geometries/Geometries.d.ts deleted file mode 100644 index b1be46c46..000000000 --- a/src-testing/src/geometries/Geometries.d.ts +++ /dev/null @@ -1,21 +0,0 @@ -export * from "./BoxGeometry.js"; -export * from "./CapsuleGeometry.js"; -export * from "./CircleGeometry.js"; -export * from "./ConeGeometry.js"; -export * from "./CylinderGeometry.js"; -export * from "./DodecahedronGeometry.js"; -export * from "./EdgesGeometry.js"; -export * from "./ExtrudeGeometry.js"; -export * from "./IcosahedronGeometry.js"; -export * from "./LatheGeometry.js"; -export * from "./OctahedronGeometry.js"; -export * from "./PlaneGeometry.js"; -export * from "./PolyhedronGeometry.js"; -export * from "./RingGeometry.js"; -export * from "./ShapeGeometry.js"; -export * from "./SphereGeometry.js"; -export * from "./TetrahedronGeometry.js"; -export * from "./TorusGeometry.js"; -export * from "./TorusKnotGeometry.js"; -export * from "./TubeGeometry.js"; -export * from "./WireframeGeometry.js"; diff --git a/src-testing/src/geometries/IcosahedronGeometry.d.ts b/src-testing/src/geometries/IcosahedronGeometry.d.ts deleted file mode 100644 index 4c05b54de..000000000 --- a/src-testing/src/geometries/IcosahedronGeometry.d.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { PolyhedronGeometry } from "./PolyhedronGeometry.js"; - -/** - * A class for generating an icosahedron geometry. - * @see {@link https://threejs.org/docs/index.html#api/en/geometries/IcosahedronGeometry | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/IcosahedronGeometry.js | Source} - */ -export class IcosahedronGeometry extends PolyhedronGeometry { - /** - * Create a new instance of {@link IcosahedronGeometry} - * @param radius Expects a `Float`. Default `1` - * @param detail Setting this to a value greater than 0 adds more vertices making it no longer an icosahedron. - * When detail is greater than 1, it's effectively a sphere. Expects a `Integer`. Default `0` - */ - constructor(radius?: number, detail?: number); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `IcosahedronGeometry` - */ - override readonly type: string | "IcosahedronGeometry"; - - /** @internal */ - static fromJSON(data: {}): IcosahedronGeometry; -} diff --git a/src-testing/src/geometries/LatheGeometry.d.ts b/src-testing/src/geometries/LatheGeometry.d.ts deleted file mode 100644 index f4194e514..000000000 --- a/src-testing/src/geometries/LatheGeometry.d.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { BufferGeometry } from "../core/BufferGeometry.js"; -import { Vector2 } from "../math/Vector2.js"; - -/** - * Creates meshes with axial symmetry like vases - * @remarks - * The lathe rotates around the Y axis. - * @example - * ```typescript - * const points = []; - * for (let i = 0; i & lt; 10; i++) { - * points.push(new THREE.Vector2(Math.sin(i * 0.2) * 10 + 5, (i - 5) * 2)); - * } - * const geometry = new THREE.LatheGeometry(points); - * const material = new THREE.MeshBasicMaterial({ - * color: 0xffff00 - * }); - * const lathe = new THREE.Mesh(geometry, material); - * scene.add(lathe); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/geometries/LatheGeometry | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/LatheGeometry.js | Source} - */ -export class LatheGeometry extends BufferGeometry { - /** - * This creates a {@link LatheGeometry} based on the parameters. - * @param points Array of Vector2s. The x-coordinate of each point must be greater than zero. - * Default `[new Vector2(0, -0.5), new Vector2(0.5, 0), new Vector2(0, 0.5)]` _which creates a simple diamond shape_. - * @param segments The number of circumference segments to generate. Expects a `Integer`. Default `12`. - * @param phiStart The starting angle in radians. Expects a `Float`. Default `0`. - * @param phiLength The radian (0 to 2*PI) range of the lathed section 2*PI is a closed lathe, less than 2PI is a portion. Expects a `Float`. Default `Math.PI * 2`. - */ - constructor(points?: Vector2[], segments?: number, phiStart?: number, phiLength?: number); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `LatheGeometry` - */ - override readonly type: string | "LatheGeometry"; - - /** - * An object with a property for each of the constructor parameters. - * @remarks Any modification after instantiation does not change the geometry. - */ - readonly parameters: { - readonly points: Vector2[]; - readonly segments: number; - readonly phiStart: number; - readonly phiLength: number; - }; - - /** @internal */ - static fromJSON(data: {}): LatheGeometry; -} diff --git a/src-testing/src/geometries/OctahedronGeometry.d.ts b/src-testing/src/geometries/OctahedronGeometry.d.ts deleted file mode 100644 index 09ba0b1e7..000000000 --- a/src-testing/src/geometries/OctahedronGeometry.d.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { PolyhedronGeometry } from "./PolyhedronGeometry.js"; - -/** - * A class for generating an octahedron geometry. - * @see {@link https://threejs.org/docs/index.html#api/en/geometries/OctahedronGeometry | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/OctahedronGeometry.js | Source} - */ -export class OctahedronGeometry extends PolyhedronGeometry { - /** - * Create a new instance of {@link OctahedronGeometry} - * @param radius Radius of the octahedron. Expects a `Float`. Default `1` - * @param detail Setting this to a value greater than zero add vertices making it no longer an octahedron. Expects a `Integer`. Default `0` - */ - constructor(radius?: number, detail?: number); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `OctahedronGeometry` - */ - override readonly type: string | "OctahedronGeometry"; - - /** @internal */ - static fromJSON(data: {}): OctahedronGeometry; -} diff --git a/src-testing/src/geometries/PlaneGeometry.d.ts b/src-testing/src/geometries/PlaneGeometry.d.ts deleted file mode 100644 index fda5f4908..000000000 --- a/src-testing/src/geometries/PlaneGeometry.d.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { BufferGeometry } from "../core/BufferGeometry.js"; - -/** - * A class for generating plane geometries. - * @example - * ```typescript - * const geometry = new THREE.PlaneGeometry(1, 1); - * const material = new THREE.MeshBasicMaterial({ - * color: 0xffff00, - * side: THREE.DoubleSide - * }); - * const plane = new THREE.Mesh(geometry, material); - * scene.add(plane); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/geometries/PlaneGeometry | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/PlaneGeometry.js | Source} - */ -export class PlaneGeometry extends BufferGeometry { - /** - * Create a new instance of {@link PlaneGeometry} - * @param width Width along the X axis. Expects a `Float`. Default `1` - * @param height Height along the Y axis. Expects a `Float`. Default `1` - * @param widthSegments Number of segmented faces along the width of the sides. Expects a `Integer`. Default `1` - * @param heightSegments Number of segmented faces along the height of the sides. Expects a `Integer`. Default `1` - */ - constructor(width?: number, height?: number, widthSegments?: number, heightSegments?: number); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `PlaneGeometry` - */ - override readonly type: string | "PlaneGeometry"; - - /** - * An object with a property for each of the constructor parameters. - * @remarks Any modification after instantiation does not change the geometry. - */ - readonly parameters: { - readonly width: number; - readonly height: number; - readonly widthSegments: number; - readonly heightSegments: number; - }; - - /** @internal */ - static fromJSON(data: {}): PlaneGeometry; -} diff --git a/src-testing/src/geometries/PolyhedronGeometry.d.ts b/src-testing/src/geometries/PolyhedronGeometry.d.ts deleted file mode 100644 index f4c07772b..000000000 --- a/src-testing/src/geometries/PolyhedronGeometry.d.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { BufferGeometry } from "../core/BufferGeometry.js"; - -/** - * A polyhedron is a solid in three dimensions with flat faces - * @remarks - * This class will take an array of vertices, project them onto a sphere, and then divide them up to the desired level of detail - * This class is used by {@link THREE.DodecahedronGeometry | DodecahedronGeometry}, {@link THREE.IcosahedronGeometry | IcosahedronGeometry}, - * {@link THREE.OctahedronGeometry | OctahedronGeometry}, and {@link THREE.TetrahedronGeometry | TetrahedronGeometry} to generate their respective geometries. - * @example - * ```typescript - * const verticesOfCube = [-1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, ]; - * const indicesOfFaces = [ - * 2, 1, 0, 0, 3, 2, - * 0, 4, 7, 7, 3, 0, - * 0, 1, 5, 5, 4, 0, - * 1, 2, 6, 6, 5, 1, - * 2, 3, 7, 7, 6, 2, - * 4, 5, 6, 6, 7, 4]; - * const geometry = new THREE.PolyhedronGeometry(verticesOfCube, indicesOfFaces, 6, 2); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/geometries/PolyhedronGeometry | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/PolyhedronGeometry.js | Source} - */ -export class PolyhedronGeometry extends BufferGeometry { - /** - * Create a new instance of {@link PolyhedronGeometry} - * @param vertices Array of points of the form [1,1,1, -1,-1,-1, ... ]. Default `[]`. - * @param indices Array of indices that make up the faces of the form [0,1,2, 2,3,0, ... ]. Default `[]`. - * @param radius [page:The radius of the final shape Expects a `Float`. Default `1` - * @param detail [page:How many levels to subdivide the geometry. The more detail, the smoother the shape. Expects a `Integer`. Default `0` - */ - constructor(vertices?: number[], indices?: number[], radius?: number, detail?: number); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `PolyhedronGeometry` - */ - override readonly type: string | "PolyhedronGeometry"; - - /** - * An object with a property for each of the constructor parameters. - * @remarks Any modification after instantiation does not change the geometry. - */ - readonly parameters: { - readonly vertices: number[]; - readonly indices: number[]; - readonly radius: number; - readonly detail: number; - }; - - /** @internal */ - static fromJSON(data: {}): PolyhedronGeometry; -} diff --git a/src-testing/src/geometries/RingGeometry.d.ts b/src-testing/src/geometries/RingGeometry.d.ts deleted file mode 100644 index 2cbc63ef4..000000000 --- a/src-testing/src/geometries/RingGeometry.d.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { BufferGeometry } from "../core/BufferGeometry.js"; - -/** - * A class for generating a two-dimensional ring geometry. - * @example - * ```typescript - * const geometry = new THREE.RingGeometry(1, 5, 32); - * const material = new THREE.MeshBasicMaterial({ - * color: 0xffff00, - * side: THREE.DoubleSide - * }); - * const mesh = new THREE.Mesh(geometry, material); - * scene.add(mesh); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/geometries/RingGeometry | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/RingGeometry.js | Source} - */ -export class RingGeometry extends BufferGeometry { - /** - * Create a new instance of {@link RingGeometry} - * @param innerRadius Expects a `Float`. Default `0.5`. - * @param outerRadius Expects a `Float`. Default `1`. - * @param thetaSegments Number of segments. A higher number means the ring will be more round. Minimum is 3. Expects a `Integer`. Default `32`. - * @param phiSegments Number of segments per ring segment. Minimum is `1`. Expects a `Integer`. Default `1`. - * @param thetaStart Starting angle. Expects a `Float`. Default `0`. - * @param thetaLength Central angle. Expects a `Float`. Default `Math.PI * 2`. - */ - constructor( - innerRadius?: number, - outerRadius?: number, - thetaSegments?: number, - phiSegments?: number, - thetaStart?: number, - thetaLength?: number, - ); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `RingGeometry` - */ - override readonly type: string | "RingGeometry"; - - /** - * An object with a property for each of the constructor parameters. - * @remarks Any modification after instantiation does not change the geometry. - */ - readonly parameters: { - readonly innerRadius: number; - readonly outerRadius: number; - readonly thetaSegments: number; - readonly phiSegments: number; - readonly thetaStart: number; - readonly thetaLength: number; - }; - - /** @internal */ - static fromJSON(data: {}): RingGeometry; -} diff --git a/src-testing/src/geometries/ShapeGeometry.d.ts b/src-testing/src/geometries/ShapeGeometry.d.ts deleted file mode 100644 index a3089a645..000000000 --- a/src-testing/src/geometries/ShapeGeometry.d.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { BufferGeometry } from "../core/BufferGeometry.js"; -import { Shape } from "../extras/core/Shape.js"; - -/** - * Creates an one-sided polygonal geometry from one or more path shapes. - * @example - * ```typescript - * const x = 0, y = 0; - * const heartShape = new THREE.Shape(); - * heartShape.moveTo(x + 5, y + 5); - * heartShape.bezierCurveTo(x + 5, y + 5, x + 4, y, x, y); - * heartShape.bezierCurveTo(x - 6, y, x - 6, y + 7, x - 6, y + 7); - * heartShape.bezierCurveTo(x - 6, y + 11, x - 3, y + 15.4, x + 5, y + 19); - * heartShape.bezierCurveTo(x + 12, y + 15.4, x + 16, y + 11, x + 16, y + 7); - * heartShape.bezierCurveTo(x + 16, y + 7, x + 16, y, x + 10, y); - * heartShape.bezierCurveTo(x + 7, y, x + 5, y + 5, x + 5, y + 5); - * const geometry = new THREE.ShapeGeometry(heartShape); - * const material = new THREE.MeshBasicMaterial({ - * color: 0x00ff00 - * }); - * const mesh = new THREE.Mesh(geometry, material); - * scene.add(mesh); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/geometries/ShapeGeometry | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/ShapeGeometry.js | Source} - */ -export class ShapeGeometry extends BufferGeometry { - /** - * Create a new instance of {@link ShapeGeometry} - * @param shapes Array of shapes or a single {@link THREE.Shape | Shape}. Default `new Shape([new Vector2(0, 0.5), new Vector2(-0.5, -0.5), new Vector2(0.5, -0.5)])`, _a single triangle shape_. - * @param curveSegments Number of segments per shape. Expects a `Integer`. Default `12` - */ - constructor(shapes?: Shape | Shape[], curveSegments?: number); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `ShapeGeometry` - */ - override readonly type: string | "ShapeGeometry"; - - /** - * An object with a property for each of the constructor parameters. - * @remarks Any modification after instantiation does not change the geometry. - */ - readonly parameters: { - readonly shapes: Shape | Shape[]; - readonly curveSegments: number; - }; - - /** @internal */ - static fromJSON(data: {}): ShapeGeometry; -} diff --git a/src-testing/src/geometries/SphereGeometry.d.ts b/src-testing/src/geometries/SphereGeometry.d.ts deleted file mode 100644 index b597bb26c..000000000 --- a/src-testing/src/geometries/SphereGeometry.d.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { BufferGeometry } from "../core/BufferGeometry.js"; - -/** - * A class for generating sphere geometries. - * @example - * ```typescript - * const geometry = new THREE.SphereGeometry(15, 32, 16); - * const material = new THREE.MeshBasicMaterial({ - * color: 0xffff00 - * }); - * const sphere = new THREE.Mesh(geometry, material); - * scene.add(sphere); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/geometries/SphereGeometry | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/SphereGeometry.js | Source} - */ -export class SphereGeometry extends BufferGeometry { - /** - * Create a new instance of {@link SphereGeometry} - * @remarks - * The geometry is created by sweeping and calculating vertexes - * around the **Y** axis (horizontal sweep) and the **Z** axis (vertical sweep) - * Thus, incomplete spheres (akin to `'sphere slices'`) can be created - * through the use of different values of {@link phiStart}, {@link phiLength}, {@link thetaStart} and {@link thetaLength}, - * in order to define the points in which we start (or end) calculating those vertices. - * @param radius Sphere radius. Expects a `Float`. Default `1` - * @param widthSegments Number of horizontal segments. Minimum value is 3, and the Expects a `Integer`. Default `32` - * @param heightSegments Number of vertical segments. Minimum value is 2, and the Expects a `Integer`. Default `16` - * @param phiStart Specify horizontal starting angle. Expects a `Float`. Default `0` - * @param phiLength Specify horizontal sweep angle size. Expects a `Float`. Default `Math.PI * 2` - * @param thetaStart Specify vertical starting angle. Expects a `Float`. Default `0` - * @param thetaLength Specify vertical sweep angle size. Expects a `Float`. Default `Math.PI` - */ - constructor( - radius?: number, - widthSegments?: number, - heightSegments?: number, - phiStart?: number, - phiLength?: number, - thetaStart?: number, - thetaLength?: number, - ); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `SphereGeometry` - */ - override readonly type: string | "SphereGeometry"; - - /** - * An object with a property for each of the constructor parameters. - * @remarks Any modification after instantiation does not change the geometry. - */ - readonly parameters: { - readonly radius: number; - readonly widthSegments: number; - readonly heightSegments: number; - readonly phiStart: number; - readonly phiLength: number; - readonly thetaStart: number; - readonly thetaLength: number; - }; - - /** @internal */ - static fromJSON(data: {}): SphereGeometry; -} diff --git a/src-testing/src/geometries/TetrahedronGeometry.d.ts b/src-testing/src/geometries/TetrahedronGeometry.d.ts deleted file mode 100644 index 2dd0fe5b6..000000000 --- a/src-testing/src/geometries/TetrahedronGeometry.d.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { PolyhedronGeometry } from "./PolyhedronGeometry.js"; - -/** - * A class for generating a tetrahedron geometries. - * @see {@link https://threejs.org/docs/index.html#api/en/geometries/TetrahedronGeometry | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/TetrahedronGeometry.js | Source} - */ -export class TetrahedronGeometry extends PolyhedronGeometry { - /** - * Create a new instance of {@link TetrahedronGeometry} - * @param radius Radius of the tetrahedron. Expects a `Float`. Default `1` - * @param detail Setting this to a value greater than 0 adds vertices making it no longer a tetrahedron. Expects a `Integer`. Default `0` - */ - constructor(radius?: number, detail?: number); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `TetrahedronGeometry` - */ - override readonly type: string | "TetrahedronGeometry"; - - /** @internal */ - static fromJSON(data: {}): TetrahedronGeometry; -} diff --git a/src-testing/src/geometries/TorusGeometry.d.ts b/src-testing/src/geometries/TorusGeometry.d.ts deleted file mode 100644 index 47a70ceea..000000000 --- a/src-testing/src/geometries/TorusGeometry.d.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { BufferGeometry } from "../core/BufferGeometry.js"; - -/** - * A class for generating torus geometries. - * @example - * ```typescript - * const geometry = new THREE.TorusGeometry(10, 3, 16, 100); - * const material = new THREE.MeshBasicMaterial({ - * color: 0xffff00 - * }); - * const torus = new THREE.Mesh(geometry, material); - * scene.add(torus); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/geometries/TorusGeometry | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/TorusGeometry.js | Source} - */ -export class TorusGeometry extends BufferGeometry { - /** - * Create a new instance of {@link TorusGeometry} - * @param radius Radius of the torus, from the center of the torus to the center of the tube. Expects a `Float`. Default `1`. - * @param tube Radius of the tube. Expects a `Float`. Default `0.4`. - * @param radialSegments Expects a `Integer`.Default is `12`. - * @param tubularSegments Expects a `Integer`. Default `48`. - * @param arc Central angle. Expects a `Float`. Default `Math.PI * 2` - */ - constructor(radius?: number, tube?: number, radialSegments?: number, tubularSegments?: number, arc?: number); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `TorusGeometry` - */ - override readonly type: string | "TorusGeometry"; - - /** - * An object with a property for each of the constructor parameters. - * @remarks Any modification after instantiation does not change the geometry. - */ - readonly parameters: { - readonly radius: number; - readonly tube: number; - readonly radialSegments: number; - readonly tubularSegments: number; - readonly arc: number; - }; - - /** @internal */ - static fromJSON(data: any): TorusGeometry; -} diff --git a/src-testing/src/geometries/TorusKnotGeometry.d.ts b/src-testing/src/geometries/TorusKnotGeometry.d.ts deleted file mode 100644 index 103b6916e..000000000 --- a/src-testing/src/geometries/TorusKnotGeometry.d.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { BufferGeometry } from "../core/BufferGeometry.js"; - -/** - * Creates a torus knot, the particular shape of which is defined by a pair of coprime integers, p and q - * If p and q are not coprime, the result will be a torus link. - * @example - * ```typescript - * const geometry = new THREE.TorusKnotGeometry(10, 3, 100, 16); - * const material = new THREE.MeshBasicMaterial({ - * color: 0xffff00 - * }); - * const torusKnot = new THREE.Mesh(geometry, material); - * scene.add(torusKnot); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/geometries/TorusKnotGeometry | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/TorusKnotGeometry.js | Source} - */ -export class TorusKnotGeometry extends BufferGeometry { - /** - * Create a new instance of {@link TorusKnotGeometry} - * @param radius Radius of the torus.. Default `1`. - * @param tube Expects a `Float`. Default `0.4`. - * @param tubularSegments Expects a `Integer`. Default `64`. - * @param radialSegments Expects a `Integer`. Default `8`. - * @param p This value determines, how many times the geometry winds around its axis of rotational symmetry. Expects a `Integer`. Default `2`. - * @param q This value determines, how many times the geometry winds around a circle in the interior of the torus. Expects a `Integer`. Default `3`. - */ - constructor( - radius?: number, - tube?: number, - tubularSegments?: number, - radialSegments?: number, - p?: number, - q?: number, - ); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `TorusKnotGeometry` - */ - override readonly type: string | "TorusKnotGeometry"; - - /** - * An object with a property for each of the constructor parameters. - * @remarks Any modification after instantiation does not change the geometry. - */ - readonly parameters: { - readonly radius: number; - readonly tube: number; - readonly tubularSegments: number; - readonly radialSegments: number; - readonly p: number; - readonly q: number; - }; - - /** @internal */ - static fromJSON(data: {}): TorusKnotGeometry; -} diff --git a/src-testing/src/geometries/TubeGeometry.d.ts b/src-testing/src/geometries/TubeGeometry.d.ts deleted file mode 100644 index 37e7129ad..000000000 --- a/src-testing/src/geometries/TubeGeometry.d.ts +++ /dev/null @@ -1,86 +0,0 @@ -import { BufferGeometry } from "../core/BufferGeometry.js"; -import { Curve } from "../extras/core/Curve.js"; -import { Vector3 } from "../math/Vector3.js"; - -/** - * Creates a tube that extrudes along a 3d curve. - * @example - * ```typescript - * class CustomSinCurve extends THREE.Curve { - * constructor(scale = 1) { - * super(); - * this.scale = scale; - * } - * getPoint(t, optionalTarget = new THREE.Vector3()) { - * const tx = t * 3 - 1.5; - * const ty = Math.sin(2 * Math.PI * t); - * const tz = 0; - * return optionalTarget.set(tx, ty, tz).multiplyScalar(this.scale); - * } - * } - * const path = new CustomSinCurve(10); - * const geometry = new THREE.TubeGeometry(path, 20, 2, 8, false); - * const material = new THREE.MeshBasicMaterial({ - * color: 0x00ff00 - * }); - * const mesh = new THREE.Mesh(geometry, material); - * scene.add(mesh); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/geometries/TubeGeometry | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/TubeGeometry.js | Source} - */ -export class TubeGeometry extends BufferGeometry { - /** - * Create a new instance of {@link TubeGeometry} - * @param path A 3D path that inherits from the {@link THREE.Curve | Curve} base class. - * Default {@link THREE.QuadraticBezierCurve3 | new THREE.QuadraticBezierCurve3(new Vector3(-1, -1, 0 ), new Vector3(-1, 1, 0), new Vector3(1, 1, 0))}. - * @param tubularSegments The number of segments that make up the tube. Expects a `Integer`. Default `64`. - * @param radius The radius of the tube. Expects a `Float`. Default `1`. - * @param radialSegments The number of segments that make up the cross-section. Expects a `Integer`. Default `8`. - * @param closed Is the tube open or closed. Default `false`. - */ - constructor( - path?: Curve, - tubularSegments?: number, - radius?: number, - radialSegments?: number, - closed?: boolean, - ); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `TubeGeometry` - */ - override readonly type: string | "TubeGeometry"; - - /** - * An object with a property for each of the constructor parameters. - * @remarks Any modification after instantiation does not change the geometry. - */ - readonly parameters: { - readonly path: Curve; - readonly tubularSegments: number; - readonly radius: number; - readonly radialSegments: number; - readonly closed: boolean; - }; - - /** - * An array of {@link THREE.Vector3 | Vector3} tangents - */ - tangents: Vector3[]; - - /** - * An array of {@link THREE.Vector3 | Vector3} normals - */ - normals: Vector3[]; - - /** - * An array of {@link THREE.Vector3 | Vector3} binormals - */ - binormals: Vector3[]; - - /** @internal */ - static fromJSON(data: {}): TubeGeometry; -} diff --git a/src-testing/src/geometries/WireframeGeometry.d.ts b/src-testing/src/geometries/WireframeGeometry.d.ts deleted file mode 100644 index 6263316a6..000000000 --- a/src-testing/src/geometries/WireframeGeometry.d.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { BufferGeometry } from "../core/BufferGeometry.js"; - -/** - * This can be used as a helper object to view a {@link BufferGeometry | geometry} as a wireframe. - * @example - * ```typescript - * const geometry = new THREE.SphereGeometry(100, 100, 100); - * const wireframe = new THREE.WireframeGeometry(geometry); - * const line = new THREE.LineSegments(wireframe); - * line.material.depthTest = false; - * line.material.opacity = 0.25; - * line.material.transparent = true; - * scene.add(line); - * ``` - * @see Example: {@link https://threejs.org/examples/#webgl_helpers | helpers} - * @see {@link https://threejs.org/docs/index.html#api/en/geometries/WireframeGeometry | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/geometries/WireframeGeometry.js | Source} - */ -export class WireframeGeometry extends BufferGeometry { - /** - * Create a new instance of {@link WireframeGeometry} - * @param geometry Any geometry object. Default `null`. - */ - constructor(geometry?: TBufferGeometry); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `WireframeGeometry` - */ - override readonly type: string | "WireframeGeometry"; - - /** - * An object with a property for each of the constructor parameters. - * @remarks Any modification after instantiation does not change the geometry. - */ - readonly parameters: { - readonly geometry: TBufferGeometry; - }; -} diff --git a/src-testing/src/helpers/ArrowHelper.d.ts b/src-testing/src/helpers/ArrowHelper.d.ts deleted file mode 100644 index 94896123c..000000000 --- a/src-testing/src/helpers/ArrowHelper.d.ts +++ /dev/null @@ -1,93 +0,0 @@ -import { Object3D } from "../core/Object3D.js"; -import { ColorRepresentation } from "../math/Color.js"; -import { Vector3 } from "../math/Vector3.js"; -import { Line } from "../objects/Line.js"; -import { Mesh } from "../objects/Mesh.js"; - -/** - * An 3D arrow object for visualizing directions. - * @example - * ```typescript - * const dir = new THREE.Vector3(1, 2, 0); - * //normalize the direction vector (convert to vector of length 1) - * dir.normalize(); - * const origin = new THREE.Vector3(0, 0, 0); - * const length = 1; - * const hex = 0xffff00; - * const {@link ArrowHelper} = new THREE.ArrowHelper(dir, origin, length, hex); - * scene.add(arrowHelper); - * ``` - * @see Example: {@link https://threejs.org/examples/#webgl_shadowmesh | WebGL / shadowmesh} - * @see {@link https://threejs.org/docs/index.html#api/en/helpers/ArrowHelper | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/helpers/ArrowHelper.js | Source} - */ -export class ArrowHelper extends Object3D { - /** - * Create a new instance of {@link ArrowHelper} - * @param dir Direction from origin. Must be a unit vector. Default `new THREE.Vector3(0, 0, 1)` - * @param origin Point at which the arrow starts. Default `new THREE.Vector3(0, 0, 0)` - * @param length Length of the arrow. Default `1` - * @param hex Hexadecimal value to define color. Default `0xffff00` - * @param headLength The length of the head of the arrow. Default `0.2 * length` - * @param headWidth The width of the head of the arrow. Default `0.2 * headLength` - */ - constructor( - dir?: Vector3, - origin?: Vector3, - length?: number, - color?: ColorRepresentation, - headLength?: number, - headWidth?: number, - ); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @override - * @defaultValue `ArrowHelper` - */ - override readonly type: string | "ArrowHelper"; - - /** - * Contains the line part of the arrowHelper. - */ - line: Line; - - /** - * Contains the cone part of the arrowHelper. - */ - cone: Mesh; - - /** - * Sets the color of the arrowHelper. - * @param color The desired color. - */ - setColor(color: ColorRepresentation): void; - - /** - * @param dir The desired direction. Must be a unit vector. - */ - setDirection(dir: Vector3): void; - - /** - * Sets the length of the arrowhelper. - * @param length The desired length. - * @param headLength The length of the head of the arrow. Default `0.2 * length` - * @param headWidth The width of the head of the arrow. Default `0.2 * headLength` - */ - setLength(length: number, headLength?: number, headWidth?: number): void; - - /** - * Copy the given object into this object - * @remarks Note: event listeners and user-defined callbacks ({@link onAfterRender | .onAfterRender} and {@link onBeforeRender | .onBeforeRender}) are not copied. - * @param source - */ - override copy(source: this): this; - - /** - * Frees the GPU-related resources allocated by this instance - * @remarks - * Call this method whenever this instance is no longer used in your app. - */ - dispose(): void; -} diff --git a/src-testing/src/helpers/AxesHelper.d.ts b/src-testing/src/helpers/AxesHelper.d.ts deleted file mode 100644 index c0633c102..000000000 --- a/src-testing/src/helpers/AxesHelper.d.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { ColorRepresentation } from "../math/Color.js"; -import { LineSegments } from "../objects/LineSegments.js"; - -/** - * An axis object to visualize the 3 axes in a simple way. - * @remarks - * The X axis is red - * The Y axis is green - * The Z axis is blue. - * @example - * ```typescript - * const {@link AxesHelper} = new THREE.AxesHelper(5); - * scene.add(axesHelper); - * ``` - * @see Example: {@link https://threejs.org/examples/#webgl_buffergeometry_compression | WebGL / buffergeometry / compression} - * @see Example: {@link https://threejs.org/examples/#webgl_geometry_convex | WebGL / geometry / convex} - * @see Example: {@link https://threejs.org/examples/#webgl_loader_nrrd | WebGL / loader / nrrd} - * @see {@link https://threejs.org/docs/index.html#api/en/helpers/AxesHelper | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/helpers/AxesHelper.js | Source} - */ -export class AxesHelper extends LineSegments { - /** - * Create a new instance of {@link AxesHelper} - * @param size Size of the lines representing the axes. Default `1` - */ - constructor(size?: number); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @override - * @defaultValue `AxesHelper` - */ - override readonly type: string | "AxesHelper"; - - /** - * Sets the axes colors to {@link Color | xAxisColor}, {@link Color | yAxisColor}, {@link Color | zAxisColor}. - * @param xAxisColor - * @param yAxisColor - * @param zAxisColor - */ - setColors(xAxisColor: ColorRepresentation, yAxisColor: ColorRepresentation, zAxisColor: ColorRepresentation): this; - - /** - * Frees the GPU-related resources allocated by this instance - * @remarks - * Call this method whenever this instance is no longer used in your app. - */ - dispose(): void; -} diff --git a/src-testing/src/helpers/Box3Helper.d.ts b/src-testing/src/helpers/Box3Helper.d.ts deleted file mode 100644 index 78e1c6f82..000000000 --- a/src-testing/src/helpers/Box3Helper.d.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { Box3 } from "../math/Box3.js"; -import { ColorRepresentation } from "../math/Color.js"; -import { LineSegments } from "../objects/LineSegments.js"; - -/** - * Helper object to visualize a {@link THREE.Box3 | Box3}. - * @example - * ```typescript - * const box = new THREE.Box3(); - * box.setFromCenterAndSize(new THREE.Vector3(1, 1, 1), new THREE.Vector3(2, 1, 3)); - * const helper = new THREE.Box3Helper(box, 0xffff00); - * scene.add(helper); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/helpers/Box3Helper | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/helpers/Box3Helper.js | Source} - */ -export class Box3Helper extends LineSegments { - /** - * Creates a new wireframe box that represents the passed Box3. - * @param box The Box3 to show. - * @param color The box's color. Default `0xffff00` - */ - constructor(box: Box3, color?: ColorRepresentation); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @override - * @defaultValue `Box3Helper` - */ - override readonly type: string | "Box3Helper"; - - /** - * The Box3 being visualized. - */ - box: Box3; - - /** - * Frees the GPU-related resources allocated by this instance - * @remarks - * Call this method whenever this instance is no longer used in your app. - */ - dispose(): void; -} diff --git a/src-testing/src/helpers/BoxHelper.d.ts b/src-testing/src/helpers/BoxHelper.d.ts deleted file mode 100644 index d049a5b72..000000000 --- a/src-testing/src/helpers/BoxHelper.d.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { BufferGeometry } from "../core/BufferGeometry.js"; -import { Object3D } from "../core/Object3D.js"; -import { LineBasicMaterial } from "../materials/LineBasicMaterial.js"; -import { ColorRepresentation } from "../math/Color.js"; -import { LineSegments } from "../objects/LineSegments.js"; - -/** - * Helper object to graphically show the world-axis-aligned bounding box around an object - * @remarks - * The actual bounding box is handled with {@link THREE.Box3 | Box3}, this is just a visual helper for debugging - * It can be automatically resized with the {@link THREE.BoxHelper.update | BoxHelper.update} method when the object it's created from is transformed - * Note that the object must have a {@link THREE.BufferGeometry | BufferGeometry} for this to work, so it won't work with {@link Sprite | Sprites}. - * @example - * ```typescript - * const sphere = new THREE.SphereGeometry(); - * const object = new THREE.Mesh(sphere, new THREE.MeshBasicMaterial(0xff0000)); - * const box = new THREE.BoxHelper(object, 0xffff00); - * scene.add(box); - * ``` - * @see Example: {@link https://threejs.org/examples/#webgl_helpers | WebGL / helpers} - * @see Example: {@link https://threejs.org/examples/#webgl_loader_nrrd | WebGL / loader / nrrd} - * @see Example: {@link https://threejs.org/examples/#webgl_buffergeometry_drawrange | WebGL / buffergeometry / drawrange} - * @see {@link https://threejs.org/docs/index.html#api/en/helpers/BoxHelper | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/helpers/BoxHelper.js | Source} - */ -export class BoxHelper extends LineSegments { - /** - * Creates a new wireframe box that bounds the passed object - * @remarks - * Internally this uses {@link THREE.Box3.setFromObject | Box3.setFromObject} to calculate the dimensions - * Note that this includes any children. - * @param object The object3D to show the world-axis-aligned bounding box. - * @param color Hexadecimal value that defines the box's color. Default `0xffff00` - */ - constructor(object: Object3D, color?: ColorRepresentation); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @override - * @defaultValue `BoxHelper` - */ - override readonly type: string | "BoxHelper"; - - /** - * Updates the helper's geometry to match the dimensions of the object, including any children - * @remarks - * See {@link THREE.Box3.setFromObject | Box3.setFromObject}. - */ - update(object?: Object3D): void; - - /** - * Updates the wireframe box for the passed object. - * @param object {@link THREE.Object3D | Object3D} to create the helper of. - */ - setFromObject(object: Object3D): this; - - /** - * Frees the GPU-related resources allocated by this instance - * @remarks - * Call this method whenever this instance is no longer used in your app. - */ - dispose(): void; -} diff --git a/src-testing/src/helpers/CameraHelper.d.ts b/src-testing/src/helpers/CameraHelper.d.ts deleted file mode 100644 index 469dcaa0d..000000000 --- a/src-testing/src/helpers/CameraHelper.d.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { Camera } from "../cameras/Camera.js"; -import { Color } from "../math/Color.js"; -import { Matrix4 } from "../math/Matrix4.js"; -import { LineSegments } from "../objects/LineSegments.js"; - -/** - * This helps with visualizing what a camera contains in its frustum - * @remarks - * It visualizes the frustum of a camera using a {@link THREE.LineSegments | LineSegments}. - * @remarks {@link CameraHelper} must be a child of the scene. - * @example - * ```typescript - * const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); - * const helper = new THREE.CameraHelper(camera); - * scene.add(helper); - * ``` - * @see Example: {@link https://threejs.org/examples/#webgl_camera | WebGL / camera} - * @see Example: {@link https://threejs.org/examples/#webgl_geometry_extrude_splines | WebGL / extrude / splines} - * @see {@link https://threejs.org/docs/index.html#api/en/helpers/CameraHelper | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/helpers/CameraHelper.js | Source} - */ -export class CameraHelper extends LineSegments { - /** - * This create a new {@link CameraHelper} for the specified camera. - * @param camera The camera to visualize. - */ - constructor(camera: Camera); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @override - * @defaultValue `CameraHelper` - */ - override readonly type: string | "CameraHelper"; - - /** - * The camera being visualized. - */ - camera: Camera; - - /** - * This contains the points used to visualize the camera. - */ - pointMap: { [id: string]: number[] }; - - /** - * Reference to the {@link THREE.Camera.matrixWorld | camera.matrixWorld}. - */ - matrix: Matrix4; - - /** - * Is set to `false`, as the helper is using the {@link THREE.Camera.matrixWorld | camera.matrixWorld}. - * @see {@link THREE.Object3D.matrixAutoUpdate | Object3D.matrixAutoUpdate}. - * @defaultValue `false`. - */ - override matrixAutoUpdate: boolean; - - /** - * Defines the colors of the helper. - * @param frustum - * @param cone - * @param up - * @param target - * @param cross - */ - setColors(frustum: Color, cone: Color, up: Color, target: Color, cross: Color): this; - - /** - * Updates the helper based on the projectionMatrix of the camera. - */ - update(): void; - - /** - * Frees the GPU-related resources allocated by this instance - * @remarks - * Call this method whenever this instance is no longer used in your app. - */ - dispose(): void; -} diff --git a/src-testing/src/helpers/DirectionalLightHelper.d.ts b/src-testing/src/helpers/DirectionalLightHelper.d.ts deleted file mode 100644 index 729eccedd..000000000 --- a/src-testing/src/helpers/DirectionalLightHelper.d.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { Object3D } from "../core/Object3D.js"; -import { DirectionalLight } from "../lights/DirectionalLight.js"; -import { ColorRepresentation } from "../math/Color.js"; -import { Matrix4 } from "../math/Matrix4.js"; -import { Line } from "../objects/Line.js"; - -/** - * Helper object to assist with visualizing a {@link THREE.DirectionalLight | DirectionalLight}'s effect on the scene - * @remarks - * This consists of plane and a line representing the light's position and direction. - * @example - * ```typescript - * const light = new THREE.DirectionalLight(0xFFFFFF); - * scene.add(light); - * - * const helper = new THREE.DirectionalLightHelper(light, 5); - * scene.add(helper); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/helpers/DirectionalLightHelper | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/helpers/DirectionalLightHelper.js | Source} - */ -export class DirectionalLightHelper extends Object3D { - /** - * Create a new instance of {@link DirectionalLightHelper} - * @param light The light to be visualized. - * @param size Dimensions of the plane. Default `1` - * @param color If this is not the set the helper will take the color of the light. Default `light.color` - */ - constructor(light: DirectionalLight, size?: number, color?: ColorRepresentation); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @override - * @defaultValue `DirectionalLightHelper` - */ - override readonly type: string | "DirectionalLightHelper"; - - /** - * Contains the line mesh showing the location of the directional light. - */ - lightPlane: Line; - - /** - * Reference to the {@link THREE.DirectionalLight | directionalLight} being visualized. - */ - light: DirectionalLight; - - /** - * Reference to the {@link THREE.DirectionalLight.matrixWorld | light.matrixWorld}. - */ - matrix: Matrix4; - - /** - * Is set to `false`, as the helper is using the {@link THREE.DirectionalLight.matrixWorld | light.matrixWorld}. - * @see {@link THREE.Object3D.matrixAutoUpdate | Object3D.matrixAutoUpdate}. - * @defaultValue `false`. - */ - override matrixAutoUpdate: boolean; - - /** - * The color parameter passed in the constructor. - * @remarks If this is changed, the helper's color will update the next time {@link update} is called. - * @defaultValue `undefined` - */ - color: ColorRepresentation | undefined; - - targetLine: Line; // TODO: Double check if this need to be exposed or not. - - /** - * Updates the helper to match the position and direction of the {@link light | DirectionalLight} being visualized. - */ - update(): void; - - /** - * Frees the GPU-related resources allocated by this instance - * @remarks - * Call this method whenever this instance is no longer used in your app. - */ - dispose(): void; -} diff --git a/src-testing/src/helpers/GridHelper.d.ts b/src-testing/src/helpers/GridHelper.d.ts deleted file mode 100644 index 0b786b992..000000000 --- a/src-testing/src/helpers/GridHelper.d.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { BufferGeometry } from "../core/BufferGeometry.js"; -import { LineBasicMaterial } from "../materials/LineBasicMaterial.js"; -import { ColorRepresentation } from "../math/Color.js"; -import { LineSegments } from "../objects/LineSegments.js"; - -/** - * The {@link GridHelper} is an object to define grids - * @remarks - * Grids are two-dimensional arrays of lines. - * @example - * ```typescript - * const size = 10; - * const divisions = 10; - * const {@link GridHelper} = new THREE.GridHelper(size, divisions); - * scene.add(gridHelper); - * ``` - * @see Example: {@link https://threejs.org/examples/#webgl_helpers | WebGL / helpers} - * @see {@link https://threejs.org/docs/index.html#api/en/helpers/GridHelper | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/helpers/GridHelper.js | Source} - */ -export class GridHelper extends LineSegments { - /** - * Creates a new {@link GridHelper} of size 'size' and divided into 'divisions' segments per side - * @remarks - * Colors are optional. - * @param size The size of the grid. Default `10` - * @param divisions The number of divisions across the grid. Default `10` - * @param colorCenterLine The color of the centerline. This can be a {@link THREE.Color | Color}, a hexadecimal value and an CSS-Color name. Default `0x444444` - * @param colorGrid The color of the lines of the grid. This can be a {@link THREE.Color | Color}, a hexadecimal value and an CSS-Color name. Default `0x888888` - */ - constructor(size?: number, divisions?: number, color1?: ColorRepresentation, color2?: ColorRepresentation); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @override - * @defaultValue `GridHelper` - */ - override readonly type: string | "GridHelper"; - - /** - * Frees the GPU-related resources allocated by this instance - * @remarks - * Call this method whenever this instance is no longer used in your app. - */ - dispose(): void; -} diff --git a/src-testing/src/helpers/HemisphereLightHelper.d.ts b/src-testing/src/helpers/HemisphereLightHelper.d.ts deleted file mode 100644 index 80366b63b..000000000 --- a/src-testing/src/helpers/HemisphereLightHelper.d.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { Object3D } from "../core/Object3D.js"; -import { HemisphereLight } from "../lights/HemisphereLight.js"; -import { MeshBasicMaterial } from "../materials/MeshBasicMaterial.js"; -import { ColorRepresentation } from "../math/Color.js"; -import { Matrix4 } from "../math/Matrix4.js"; - -/** - * Creates a visual aid consisting of a spherical {@link THREE.Mesh | Mesh} for a {@link THREE.HemisphereLight | HemisphereLight}. - * @example - * ```typescript - * const light = new THREE.HemisphereLight(0xffffbb, 0x080820, 1); - * const helper = new THREE.HemisphereLightHelper(light, 5); - * scene.add(helper); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/helpers/HemisphereLightHelper | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/helpers/HemisphereLightHelper.js | Source} - */ -export class HemisphereLightHelper extends Object3D { - /** - * Create a new instance of {@link HemisphereLightHelper} - * @param light The light being visualized. - * @param size Thr sphere size - * @param color If this is not the set the helper will take the color of the light. - */ - constructor(light: HemisphereLight, size: number, color?: ColorRepresentation); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @override - * @defaultValue `HemisphereLightHelper` - */ - override readonly type: string | "HemisphereLightHelper"; - - /** - * Reference to the HemisphereLight being visualized. - */ - light: HemisphereLight; - - /** - * Reference to the {@link THREE.HemisphereLight.matrixWorld | light.matrixWorld}. - */ - matrix: Matrix4; - - /** - * Is set to `false`, as the helper is using the {@link THREE.HemisphereLight.matrixWorld | light.matrixWorld}. - * @see {@link THREE.Object3D.matrixAutoUpdate | Object3D.matrixAutoUpdate}. - * @defaultValue `false`. - */ - override matrixAutoUpdate: boolean; - - material: MeshBasicMaterial; // TODO: Double check if this need to be exposed or not. - - /** - * The color parameter passed in the constructor. - * @remarks If this is changed, the helper's color will update the next time {@link update} is called. - * @defaultValue `undefined` - */ - color: ColorRepresentation | undefined; - - /** - * Updates the helper to match the position and direction of the {@link .light | HemisphereLight}. - */ - update(): void; - - /** - * Frees the GPU-related resources allocated by this instance - * @remarks - * Call this method whenever this instance is no longer used in your app. - */ - dispose(): void; -} diff --git a/src-testing/src/helpers/PlaneHelper.d.ts b/src-testing/src/helpers/PlaneHelper.d.ts deleted file mode 100644 index 43c9821cb..000000000 --- a/src-testing/src/helpers/PlaneHelper.d.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { Plane } from "../math/Plane.js"; -import { LineSegments } from "../objects/LineSegments.js"; - -/** - * Helper object to visualize a {@link THREE.Plane | Plane}. - * @example - * ```typescript - * const plane = new THREE.Plane(new THREE.Vector3(1, 1, 0.2), 3); - * const helper = new THREE.PlaneHelper(plane, 1, 0xffff00); - * scene.add(helper); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/helpers/PlaneHelper | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/helpers/PlaneHelper.js | Source} - */ -export class PlaneHelper extends LineSegments { - /** - * Creates a new wireframe representation of the passed plane. - * @param plane The plane to visualize. - * @param size Side length of plane helper. Expects a `Float`. Default `1` - * @param hex Color. Default `0xffff00` - */ - constructor(plane: Plane, size?: number, hex?: number); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @override - * @defaultValue `PlaneHelper` - */ - override readonly type: string | "PlaneHelper"; - - /** - * The {@link Plane | plane} being visualized. - */ - plane: Plane; - - /** - * The side lengths of plane helper. - * @remarks Expects a `Float` - * @defaultValue `1` - */ - size: number; - - /** - * Frees the GPU-related resources allocated by this instance - * @remarks - * Call this method whenever this instance is no longer used in your app. - */ - dispose(): void; -} diff --git a/src-testing/src/helpers/PointLightHelper.d.ts b/src-testing/src/helpers/PointLightHelper.d.ts deleted file mode 100644 index 7d61da5e3..000000000 --- a/src-testing/src/helpers/PointLightHelper.d.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { Object3D } from "../core/Object3D.js"; -import { PointLight } from "../lights/PointLight.js"; -import { ColorRepresentation } from "../math/Color.js"; -import { Matrix4 } from "../math/Matrix4.js"; - -/** - * This displays a helper object consisting of a spherical {@link THREE.Mesh | Mesh} for visualizing a {@link THREE.PointLight | PointLight}. - * @example - * ```typescript - * const pointLight = new THREE.PointLight(0xff0000, 1, 100); - * pointLight.position.set(10, 10, 10); - * scene.add(pointLight); - * const sphereSize = 1; - * const {@link PointLightHelper} = new THREE.PointLightHelper(pointLight, sphereSize); - * scene.add(pointLightHelper); - * ``` - * @see Example: {@link https://threejs.org/examples/#webgl_helpers | WebGL / helpers} - * @see {@link https://threejs.org/docs/index.html#api/en/helpers/PointLightHelper | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/helpers/PointLightHelper.js | Source} - */ -export class PointLightHelper extends Object3D { - /** - * Create a new instance of {@link PointLightHelper} - * @param light The light to be visualized. - * @param sphereSize The size of the sphere helper. Expects a `Float`. Default `1` - * @param color If this is not the set the helper will take the color of the light. - */ - constructor(light: PointLight, sphereSize?: number, color?: ColorRepresentation); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @override - * @defaultValue `PointLightHelper` - */ - override readonly type: string | "PointLightHelper"; - - /** - * The {@link THREE.PointLight | PointLight} that is being visualized. - */ - light: PointLight; - - /** - * Reference to the {@link THREE.PointLight.matrixWorld | light.matrixWorld}. - */ - matrix: Matrix4; - - /** - * The color parameter passed in the constructor. - * @remarks If this is changed, the helper's color will update the next time {@link update} is called. - * @defaultValue `undefined` - */ - color: ColorRepresentation | undefined; - - /** - * Is set to `false`, as the helper is using the {@link THREE.PointLight.matrixWorld | light.matrixWorld}. - * @see {@link THREE.Object3D.matrixAutoUpdate | Object3D.matrixAutoUpdate}. - * @defaultValue `false`. - */ - override matrixAutoUpdate: boolean; - - /** - * Updates the helper to match the position of the {@link THREE..light | .light}. - */ - update(): void; - - /** - * Frees the GPU-related resources allocated by this instance - * @remarks - * Call this method whenever this instance is no longer used in your app. - */ - dispose(): void; -} diff --git a/src-testing/src/helpers/PolarGridHelper.d.ts b/src-testing/src/helpers/PolarGridHelper.d.ts deleted file mode 100644 index 994d71c94..000000000 --- a/src-testing/src/helpers/PolarGridHelper.d.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { ColorRepresentation } from "../math/Color.js"; -import { LineSegments } from "../objects/LineSegments.js"; - -/** - * The {@link PolarGridHelper} is an object to define polar grids - * @remarks - * Grids are two-dimensional arrays of lines. - * @example - * ```typescript - * const radius = 10; - * const sectors = 16; - * const rings = 8; - * const divisions = 64; - * const helper = new THREE.PolarGridHelper(radius, sectors, rings, divisions); - * scene.add(helper); - * ``` - * @see Example: {@link https://threejs.org/examples/#webgl_helpers | WebGL / helpers} - * @see {@link https://threejs.org/docs/index.html#api/en/helpers/PolarGridHelper | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/helpers/PolarGridHelper.js | Source} - */ -export class PolarGridHelper extends LineSegments { - /** - * Creates a new {@link PolarGridHelper} of radius 'radius' with 'sectors' number of sectors and 'rings' number of rings, where each circle is smoothed into 'divisions' number of line segments. - * @remarks Colors are optional. - * @param radius The radius of the polar grid. This can be any positive number. Default `10`. - * @param sectors The number of sectors the grid will be divided into. This can be any positive integer. Default `16`. - * @param rings The number of rings. This can be any positive integer. Default `8`. - * @param divisions The number of line segments used for each circle. This can be any positive integer that is 3 or greater. Default `64`. - * @param color1 The first color used for grid elements. This can be a {@link THREE.Color | Color}, a hexadecimal value and an CSS-Color name. Default `0x444444`. - * @param color2 The second color used for grid elements. This can be a {@link THREE.Color | Color}, a hexadecimal value and an CSS-Color name. Default `0x888888`. - */ - constructor( - radius?: number, - radials?: number, - circles?: number, - divisions?: number, - color1?: ColorRepresentation, - color2?: ColorRepresentation, - ); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @override - * @defaultValue `PolarGridHelper` - */ - override readonly type: string | "PolarGridHelper"; - - /** - * Frees the GPU-related resources allocated by this instance - * @remarks - * Call this method whenever this instance is no longer used in your app. - */ - dispose(): void; -} diff --git a/src-testing/src/helpers/SkeletonHelper.d.ts b/src-testing/src/helpers/SkeletonHelper.d.ts deleted file mode 100644 index 772ebf30e..000000000 --- a/src-testing/src/helpers/SkeletonHelper.d.ts +++ /dev/null @@ -1,78 +0,0 @@ -import { Object3D } from "../core/Object3D.js"; -import { Matrix4 } from "../math/Matrix4.js"; -import { Bone } from "../objects/Bone.js"; -import { LineSegments } from "../objects/LineSegments.js"; -import { SkinnedMesh } from "../objects/SkinnedMesh.js"; - -/** - * A helper object to assist with visualizing a {@link Skeleton | Skeleton} - * @remarks - * The helper is rendered using a {@link LineBasicMaterial | LineBasicMaterial}. - * @example - * ```typescript - * const helper = new THREE.SkeletonHelper(skinnedMesh); - * scene.add(helper); - * ``` - * @see Example: {@link https://threejs.org/examples/#webgl_animation_skinning_blending | WebGL / animation / skinning / blending} - * @see Example: {@link https://threejs.org/examples/#webgl_animation_skinning_morph | WebGL / animation / skinning / morph} - * @see Example: {@link https://threejs.org/examples/#webgl_loader_bvh | WebGL / loader / bvh } - * @see {@link https://threejs.org/docs/index.html#api/en/helpers/SkeletonHelper | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/helpers/SkeletonHelper.js | Source} - */ -export class SkeletonHelper extends LineSegments { - /** - * Create a new instance of {@link SkeletonHelper} - * @param object Usually an instance of {@link THREE.SkinnedMesh | SkinnedMesh}. - * However, any instance of {@link THREE.Object3D | Object3D} can be used if it represents a hierarchy of {@link Bone | Bone}s (via {@link THREE.Object3D.children | Object3D.children}). - */ - constructor(object: SkinnedMesh | Object3D); - - /** - * Read-only flag to check if a given object is of type {@link SkeletonHelper}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isSkeletonHelper = true; - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @override - * @defaultValue `SkeletonHelper` - */ - override readonly type: string | "SkeletonHelper"; - - /** - * The list of bones that the helper renders as {@link Line | Lines}. - */ - bones: Bone[]; - - /** - * The object passed in the constructor. - */ - root: SkinnedMesh | Object3D; - - /** - * Reference to the {@link THREE.Object3D.matrixWorld | root.matrixWorld}. - */ - matrix: Matrix4; - - /** - * Is set to `false`, as the helper is using the {@link THREE.Object3D.matrixWorld | root.matrixWorld}. - * @see {@link THREE.Object3D.matrixAutoUpdate | Object3D.matrixAutoUpdate}. - * @defaultValue `false`. - */ - override matrixAutoUpdate: boolean; - - /** - * Updates the helper. - */ - update(): void; - - /** - * Frees the GPU-related resources allocated by this instance - * @remarks - * Call this method whenever this instance is no longer used in your app. - */ - dispose(): void; -} diff --git a/src-testing/src/helpers/SpotLightHelper.d.ts b/src-testing/src/helpers/SpotLightHelper.d.ts deleted file mode 100644 index f620ed990..000000000 --- a/src-testing/src/helpers/SpotLightHelper.d.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { Object3D } from "../core/Object3D.js"; -import { Light } from "../lights/Light.js"; -import { ColorRepresentation } from "../math/Color.js"; -import { Matrix4 } from "../math/Matrix4.js"; -import { LineSegments } from "../objects/LineSegments.js"; - -/** - * This displays a cone shaped helper object for a {@link THREE.SpotLight | SpotLight}. - * @example - * ```typescript - * const spotLight = new THREE.SpotLight(0xffffff); - * spotLight.position.set(10, 10, 10); - * scene.add(spotLight); - * const {@link SpotLightHelper} = new THREE.SpotLightHelper(spotLight); - * scene.add(spotLightHelper); - * ``` - * @see Example: {@link https://threejs.org/examples/#webgl_lights_spotlights | WebGL/ lights / spotlights } - * @see {@link https://threejs.org/docs/index.html#api/en/helpers/SpotLightHelper | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/helpers/SpotLightHelper.js | Source} - */ -export class SpotLightHelper extends Object3D { - /** - * Create a new instance of {@link SpotLightHelper} - * @param light The {@link THREE.SpotLight | SpotLight} to be visualized. - * @param color If this is not the set the helper will take the color of the light. Default `light.color` - */ - constructor(light: Light, color?: ColorRepresentation); - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @override - * @defaultValue `SpotLightHelper` - */ - override readonly type: string | "SpotLightHelper"; - - /** - * {@link THREE.LineSegments | LineSegments} used to visualize the light. - */ - cone: LineSegments; - - /** - * Reference to the {@link THREE.SpotLight | SpotLight} being visualized. - */ - light: Light; - - /** - * Reference to the spotLight's {@link Object3D.matrixWorld | matrixWorld}. - */ - matrix: Matrix4; - - /** - * The color parameter passed in the constructor. - * If this is changed, the helper's color will update the next time {@link SpotLightHelper.update | update} is called. - * @defaultValue `undefined` - */ - color: ColorRepresentation | undefined; - - /** - * Is set to `false`, as the helper is using the {@link THREE.Light.matrixWorld | light.matrixWorld}. - * @see {@link THREE.Object3D.matrixAutoUpdate | Object3D.matrixAutoUpdate}. - * @defaultValue `false`. - */ - override matrixAutoUpdate: boolean; - - /** - * Updates the light helper. - */ - update(): void; - - /** - * Frees the GPU-related resources allocated by this instance - * @remarks - * Call this method whenever this instance is no longer used in your app. - */ - dispose(): void; -} diff --git a/src-testing/src/lights/AmbientLight.d.ts b/src-testing/src/lights/AmbientLight.d.ts deleted file mode 100644 index 7000a37e7..000000000 --- a/src-testing/src/lights/AmbientLight.d.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { ColorRepresentation } from "../math/Color.js"; -import { Light } from "./Light.js"; - -/** - * This light globally illuminates all objects in the scene equally. - * @remarks This light cannot be used to cast shadows as it does not have a direction. - * @example - * ```typescript - * const light = new THREE.AmbientLight(0x404040); // soft white light - * scene.add(light); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/lights/AmbientLight | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/lights/AmbientLight.js | Source} - */ -export class AmbientLight extends Light { - /** - * Creates a new {@link AmbientLight}. - * @param color Numeric value of the RGB component of the color. Default `0xffffff` - * @param intensity Numeric value of the light's strength/intensity. Expects a `Float`. Default `1` - */ - constructor(color?: ColorRepresentation, intensity?: number); - - /** - * Read-only flag to check if a given object is of type {@link AmbientLight}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isAmbientLight: true; - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `AmbientLight` - */ - override readonly type: string | "AmbientLight"; -} diff --git a/src-testing/src/lights/DirectionalLight.d.ts b/src-testing/src/lights/DirectionalLight.d.ts deleted file mode 100644 index 3d43b7d89..000000000 --- a/src-testing/src/lights/DirectionalLight.d.ts +++ /dev/null @@ -1,103 +0,0 @@ -import { Object3D } from "../core/Object3D.js"; -import { ColorRepresentation } from "../math/Color.js"; -import { Vector3 } from "../math/Vector3.js"; -import { DirectionalLightShadow } from "./DirectionalLightShadow.js"; -import { Light } from "./Light.js"; - -/** - * A light that gets emitted in a specific direction - * @remarks - * This light will behave as though it is infinitely far away and the rays produced from it are all parallel - * The common use case for this is to simulate daylight; the sun is far enough away that its position can be considered to be infinite, and all light rays coming from it are parallel. - * A common point of confusion for directional lights is that setting the rotation has no effect - * @remarks - * This is because three.js's {@link DirectionalLight} is the equivalent to what is often called a 'Target Direct Light' in other applications. - * This means that its direction is calculated as pointing from the light's {@link THREE.Object3D.position | position} to the {@link THREE.DirectionalLight.target | target}'s - * position (as opposed to a 'Free Direct Light' that just has a rotation component). - * See the {@link THREE.DirectionalLight.target | target} property below for details on updating the target. - * @example - * ```typescript - * // White directional light at half intensity shining from the top. - * const {@link DirectionalLight} = new THREE.DirectionalLight(0xffffff, 0.5); - * scene.add(directionalLight); - * ``` - * @see Example: {@link https://threejs.org/examples/#misc_controls_fly | controls / fly } - * @see Example: {@link https://threejs.org/examples/#webgl_effects_parallaxbarrier | effects / parallaxbarrier } - * @see Example: {@link https://threejs.org/examples/#webgl_effects_stereo | effects / stereo } - * @see Example: {@link https://threejs.org/examples/#webgl_geometry_extrude_splines | geometry / extrude / splines } - * @see Example: {@link https://threejs.org/examples/#webgl_materials_bumpmap | materials / bumpmap } - * @see {@link https://threejs.org/docs/index.html#api/en/lights/DirectionalLight | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/lights/DirectionalLight.js | Source} - */ -export class DirectionalLight extends Light { - /** - * Creates a new {@link DirectionalLight}. - * @param color Hexadecimal color of the light. Default `0xffffff` _(white)_. - * @param intensity Numeric value of the light's strength/intensity. Expects a `Float`. Default `1` - */ - constructor(color?: ColorRepresentation, intensity?: number); - - /** - * Read-only flag to check if a given object is of type {@link DirectionalLight}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isDirectionalLight: true; - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `DirectionalLight` - */ - override readonly type: string | "DirectionalLight"; - - /** - * Whether the object gets rendered into shadow map. - * @remarks - * If set to `true` light will cast dynamic shadows. - * **Warning**: This is expensive and requires tweaking to get shadows looking right. - * @see {@link THREE.DirectionalLightShadow | DirectionalLightShadow} for details. - * @defaultValue `false` - */ - override castShadow: boolean; - - /** - * This is set equal to {@link THREE.Object3D.DEFAULT_UP}, so that the light shines from the top down. - * @defaultValue {@link Object3D.DEFAULT_UP} _(0, 1, 0)_ - */ - override readonly position: Vector3; - - /** - * A {@link THREE.DirectionalLightShadow | DirectionalLightShadow} used to calculate shadows for this light. - * @defaultValue `new THREE.DirectionalLightShadow()` - */ - shadow: DirectionalLightShadow; - - /** - * The {@link DirectionalLight} points from its {@link DirectionalLight.position | position} to target.position. - * @remarks **Note**: For the target's position to be changed to anything other than the default, - * it must be added to the {@link THREE.Scene | scene} using - * ```typescript - * Scene.add( light.target ); - * ``` - * This is so that the target's {@link THREE.Object3D.matrixWorld | matrixWorld} gets automatically updated each frame. - * - * It is also possible to set the target to be another object in the scene (anything with a {@link THREE.Object3D.position | position} property), - * like so: - * ```typescript - * const targetObject = new THREE.Object3D(); - * scene.add(targetObject); - * light.target = targetObject; - * ``` - * The {@link DirectionalLight} will now track the target object. - * @defaultValue `new THREE.Object3D()` at _(0, 0, 0)_ - */ - target: Object3D; - - /** - * Frees the GPU-related resources allocated by this instance - * @remarks - * Call this method whenever this instance is no longer used in your app. - */ - dispose(): void; -} diff --git a/src-testing/src/lights/DirectionalLightShadow.d.ts b/src-testing/src/lights/DirectionalLightShadow.d.ts deleted file mode 100644 index 805e4fa0b..000000000 --- a/src-testing/src/lights/DirectionalLightShadow.d.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { OrthographicCamera } from "../cameras/OrthographicCamera.js"; -import { LightShadow } from "./LightShadow.js"; - -/** - * This is used internally by {@link DirectionalLight | DirectionalLights} for calculating shadows. - * Unlike the other shadow classes, this uses an {@link THREE.OrthographicCamera | OrthographicCamera} to calculate the shadows, - * rather than a {@link THREE.PerspectiveCamera | PerspectiveCamera} - * @remarks - * This is because light rays from a {@link THREE.DirectionalLight | DirectionalLight} are parallel. - * @example - * ```typescript - * //Create a WebGLRenderer and turn on shadows in the renderer - * const renderer = new THREE.WebGLRenderer(); - * renderer.shadowMap.enabled = true; - * renderer.shadowMap.type = THREE.PCFSoftShadowMap; // default THREE.PCFShadowMap - * //Create a DirectionalLight and turn on shadows for the light - * const light = new THREE.DirectionalLight(0xffffff, 1); - * light.position.set(0, 1, 0); //default; light shining from top - * light.castShadow = true; // default false - * scene.add(light); - * //Set up shadow properties for the light - * light.shadow.mapSize.width = 512; // default - * light.shadow.mapSize.height = 512; // default - * light.shadow.camera.near = 0.5; // default - * light.shadow.camera.far = 500; // default - * //Create a sphere that cast shadows (but does not receive them) - * const sphereGeometry = new THREE.SphereGeometry(5, 32, 32); - * const sphereMaterial = new THREE.MeshStandardMaterial({ - * color: 0xff0000 - * }); - * const sphere = new THREE.Mesh(sphereGeometry, sphereMaterial); - * sphere.castShadow = true; //default is false - * sphere.receiveShadow = false; //default - * scene.add(sphere); - * //Create a plane that receives shadows (but does not cast them) - * const planeGeometry = new THREE.PlaneGeometry(20, 20, 32, 32); - * const planeMaterial = new THREE.MeshStandardMaterial({ - * color: 0x00ff00 - * }) - * const plane = new THREE.Mesh(planeGeometry, planeMaterial); - * plane.receiveShadow = true; - * scene.add(plane); - * //Create a helper for the shadow camera (optional) - * const helper = new THREE.CameraHelper(light.shadow.camera); - * scene.add(helper); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/lights/shadows/DirectionalLightShadow | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/lights/DirectionalLightShadow.js | Source} - */ -export class DirectionalLightShadow extends LightShadow { - /** - * Create a new instance of {@link DirectionalLightShadow} - */ - constructor(); - - /** - * Read-only flag to check if a given object is of type {@link DirectionalLightShadow}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isDirectionalLightShadow: true; - - /** - * The light's view of the world. - * @remarks This is used to generate a depth map of the scene; objects behind other objects from the light's perspective will be in shadow. - * @defaultValue is an {@link THREE.OrthographicCamera | OrthographicCamera} with - * {@link OrthographicCamera.left | left} and {@link OrthographicCamera.bottom | bottom} set to -5, - * {@link OrthographicCamera.right | right} and {@link OrthographicCamera.top | top} set to 5, - * the {@link OrthographicCamera.near | near} clipping plane at 0.5 and - * the {@link OrthographicCamera.far | far} clipping plane at 500. - */ - camera: OrthographicCamera; -} diff --git a/src-testing/src/lights/HemisphereLight.d.ts b/src-testing/src/lights/HemisphereLight.d.ts deleted file mode 100644 index 1a796dfc8..000000000 --- a/src-testing/src/lights/HemisphereLight.d.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { Color, ColorRepresentation } from "../math/Color.js"; -import { Vector3 } from "../math/Vector3.js"; -import { Light } from "./Light.js"; - -/** - * A light source positioned directly above the scene, with color fading from the sky color to the ground color. - * @remarks This light cannot be used to cast shadows. - * @example - * ```typescript - * const light = new THREE.HemisphereLight(0xffffbb, 0x080820, 1); - * scene.add(light); - * ``` - * @see Example: {@link https://threejs.org/examples/#webgl_animation_skinning_blending | animation / skinning / blending } - * @see Example: {@link https://threejs.org/examples/#webgl_lights_hemisphere | lights / hemisphere } - * @see Example: {@link https://threejs.org/examples/#misc_controls_pointerlock | controls / pointerlock } - * @see Example: {@link https://threejs.org/examples/#webgl_loader_collada_kinematics | loader / collada / kinematics } - * @see Example: {@link https://threejs.org/examples/#webgl_loader_stl | loader / stl } - * @see {@link https://threejs.org/docs/index.html#api/en/lights/HemisphereLight | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/lights/HemisphereLight.js | Source} - */ -export class HemisphereLight extends Light { - /** - * Creates a new {@link HemisphereLight}. - * @param skyColor Hexadecimal color of the sky. Expects a `Integer`. Default `0xffffff` _(white)_. - * @param groundColor Hexadecimal color of the ground. Expects a `Integer`. Default `0xffffff` _(white)_. - * @param intensity Numeric value of the light's strength/intensity. Expects a `Float`. Default `1`. - */ - constructor(skyColor?: ColorRepresentation, groundColor?: ColorRepresentation, intensity?: number); - - /** - * Read-only flag to check if a given object is of type {@link HemisphereLight}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isHemisphereLight: true; - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `HemisphereLight` - */ - override readonly type: string | "HemisphereLight"; - - /** - * This is set equal to {@link THREE.Object3D.DEFAULT_UP}, so that the light shines from the top down. - * @defaultValue {@link Object3D.DEFAULT_UP} _(0, 1, 0)_ - */ - override readonly position: Vector3; - - /** - * The light's sky color, as passed in the constructor. - * @defaultValue `new THREE.Color()` set to white _(0xffffff)_. - */ - override color: Color; - - /** - * The light's ground color, as passed in the constructor. - * @defaultValue `new THREE.Color()` set to white _(0xffffff)_. - */ - groundColor: Color; -} diff --git a/src-testing/src/lights/Light.d.ts b/src-testing/src/lights/Light.d.ts deleted file mode 100644 index 3ae757e3b..000000000 --- a/src-testing/src/lights/Light.d.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { JSONMeta, Object3D, Object3DJSON } from "../core/Object3D.js"; -import { Color, ColorRepresentation } from "../math/Color.js"; -import { LightShadow, LightShadowJSON } from "./LightShadow.js"; - -export interface LightJSON extends Object3DJSON { - color: number; - intensity: number; - - groundColor?: number; - - distance?: number; - angle?: number; - decay?: number; - penumbra?: number; - - shadow?: LightShadowJSON; - target?: string; -} - -/** - * Abstract base class for lights. - * @remarks All other light types inherit the properties and methods described here. - */ -export abstract class Light extends Object3D { - /** - * Creates a new {@link Light} - * @remarks - * **Note** that this is not intended to be called directly (use one of derived classes instead). - * @param color Hexadecimal color of the light. Default `0xffffff` _(white)_. - * @param intensity Numeric value of the light's strength/intensity. Expects a `Float`. Default `1`. - */ - constructor(color?: ColorRepresentation, intensity?: number); - - /** - * Read-only flag to check if a given object is of type {@link HemisphereLight}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isLight: true; - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `Light` - */ - override readonly type: string | "Light"; - - /** - * Color of the light. \ - * @defaultValue `new THREE.Color(0xffffff)` _(white)_. - */ - color: Color; - - /** - * The light's intensity, or strength. - * The units of intensity depend on the type of light. - * @defaultValue `1` - */ - intensity: number; - - /** - * A {@link THREE.LightShadow | LightShadow} used to calculate shadows for this light. - * @remarks Available only on Light's that support shadows. - */ - shadow: TShadowSupport; - - /** - * Copies value of all the properties from the {@link Light | source} to this instance. - * @param source - * @param recursive - */ - copy(source: this, recursive?: boolean): this; - - /** - * Frees the GPU-related resources allocated by this instance - * @remarks - * Call this method whenever this instance is no longer used in your app. - */ - dispose(): void; - - toJSON(meta?: JSONMeta): LightJSON; -} diff --git a/src-testing/src/lights/LightProbe.d.ts b/src-testing/src/lights/LightProbe.d.ts deleted file mode 100644 index a63ffdc57..000000000 --- a/src-testing/src/lights/LightProbe.d.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { SphericalHarmonics3 } from "../math/SphericalHarmonics3.js"; -import { Light } from "./Light.js"; - -/** - * Light probes are an alternative way of adding light to a 3D scene. - * @remarks - * Unlike classical light sources (e.g - * directional, point or spot lights), light probes do not emit light - * Instead they store information about light passing through 3D space - * During rendering, the light that hits a 3D object is approximated by using the data from the light probe. - * Light probes are usually created from (radiance) environment maps - * The class {@link THREE.LightProbeGenerator | LightProbeGenerator} can be used to create light probes from - * instances of {@link THREE.CubeTexture | CubeTexture} or {@link THREE.WebGLCubeRenderTarget | WebGLCubeRenderTarget} - * However, light estimation data could also be provided in other forms e.g - * by WebXR - * This enables the rendering of augmented reality content that reacts to real world lighting. - * The current probe implementation in three.js supports so-called diffuse light probes - * This type of light probe is functionally equivalent to an irradiance environment map. - * @see Example: {@link https://threejs.org/examples/#webgl_lightprobe | WebGL / light probe } - * @see Example: {@link https://threejs.org/examples/#webgl_lightprobe_cubecamera | WebGL / light probe / cube camera } - * @see {@link https://threejs.org/docs/index.html#api/en/lights/LightProbe | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/lights/LightProbe.js | Source} - */ -export class LightProbe extends Light { - /** - * Creates a new LightProbe. - * @param sh An instance of {@link THREE.SphericalHarmonics3 | SphericalHarmonics3}. Default `new THREE.SphericalHarmonics3()``. - * @param intensity Numeric value of the light probe's intensity. Expects a `Float`. Default `1`. - */ - constructor(sh?: SphericalHarmonics3, intensity?: number); - - /** - * Read-only flag to check if a given object is of type {@link DirectionalLight}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isLightProbe: true; - - /** - * A light probe uses spherical harmonics to encode lighting information. - * @defaultValue `new THREE.SphericalHarmonics3()` - */ - sh: SphericalHarmonics3; - - /** @internal */ - fromJSON(json: {}): LightProbe; -} diff --git a/src-testing/src/lights/LightShadow.d.ts b/src-testing/src/lights/LightShadow.d.ts deleted file mode 100644 index 53c163c3e..000000000 --- a/src-testing/src/lights/LightShadow.d.ts +++ /dev/null @@ -1,169 +0,0 @@ -import { Camera } from "../cameras/Camera.js"; -import { Object3DJSONObject } from "../core/Object3D.js"; -import { Frustum } from "../math/Frustum.js"; -import { Matrix4 } from "../math/Matrix4.js"; -import { Vector2, Vector2Tuple } from "../math/Vector2.js"; -import { Vector4 } from "../math/Vector4.js"; -import { WebGLRenderTarget } from "../renderers/WebGLRenderTarget.js"; -import { Light } from "./Light.js"; - -export interface LightShadowJSON { - intensity?: number; - bias?: number; - normalBias?: number; - radius?: number; - mapSize?: Vector2Tuple; - - camera: Omit; -} - -/** - * Serves as a base class for the other shadow classes. - * @see {@link https://threejs.org/docs/index.html#api/en/lights/shadows/LightShadow | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/lights/LightShadow.js | Source} - */ -export class LightShadow { - /** - * Create a new instance of {@link LightShadow} - * @param camera The light's view of the world. - */ - constructor(camera: TCamera); - - /** - * The light's view of the world. - * @remark This is used to generate a depth map of the scene; objects behind other objects from the light's perspective will be in shadow. - */ - camera: TCamera; - - /** - * The intensity of the shadow. The default is `1`. Valid values are in the range `[0, 1]`. - */ - intensity: number; - - /** - * Shadow map bias, how much to add or subtract from the normalized depth when deciding whether a surface is in shadow. - * @remark The Very tiny adjustments here (in the order of 0.0001) may help reduce artifacts in shadows. - * @remarks Expects a `Float` - * @defaultValue `0` - */ - bias: number; - - /** - * Defines how much the position used to query the shadow map is offset along the object normal. - * @remark The Increasing this value can be used to reduce shadow acne especially in large scenes where light shines onto geometry at a shallow angle. - * @remark The cost is that shadows may appear distorted. - * @remarks Expects a `Float` - * @defaultValue `0` - */ - normalBias: number; - - /** - * Setting this to values greater than 1 will blur the edges of the shadow.toi - * @remark High values will cause unwanted banding effects in the shadows - a greater {@link LightShadow.mapSize | mapSize - * will allow for a higher value to be used here before these effects become visible. - * @remark If {@link THREE.WebGLRenderer.shadowMap.type | WebGLRenderer.shadowMap.type} is set to {@link Renderer | PCFSoftShadowMap}, - * radius has no effect and it is recommended to increase softness by decreasing {@link LightShadow.mapSize | mapSize} instead. - * @remark Note that this has no effect if the {@link THREE.WebGLRenderer.shadowMap | WebGLRenderer.shadowMap}.{@link THREE.WebGLShadowMap.type | type} - * is set to {@link THREE.BasicShadowMap | BasicShadowMap}. - * @remarks Expects a `Float` - * @defaultValue `1` - */ - radius: number; - - /** - * The amount of samples to use when blurring a VSM shadow map. - * @remarks Expects a `Integer` - * @defaultValue `8` - */ - blurSamples: number; - - /** - * A {@link THREE.Vector2 | Vector2} defining the width and height of the shadow map. - * @remarks Higher values give better quality shadows at the cost of computation time. - * @remarks Values must be powers of 2, up to the {@link THREE.WebGLRenderer.capabilities | WebGLRenderer.capabilities}.maxTextureSize for a given device, - * although the width and height don't have to be the same (so, for example, (512, 1024) is valid). - * @defaultValue `new THREE.Vector2(512, 512)` - */ - mapSize: Vector2; - - /** - * The depth map generated using the internal camera; a location beyond a pixel's depth is in shadow. Computed internally during rendering. - * @defaultValue null - */ - map: WebGLRenderTarget | null; - - /** - * The distribution map generated using the internal camera; an occlusion is calculated based on the distribution of depths. Computed internally during rendering. - * @defaultValue null - */ - mapPass: WebGLRenderTarget | null; - - /** - * Model to shadow camera space, to compute location and depth in shadow map. - * Stored in a {@link Matrix4 | Matrix4}. - * @remarks This is computed internally during rendering. - * @defaultValue new THREE.Matrix4() - */ - matrix: Matrix4; - - /** - * Enables automatic updates of the light's shadow. If you do not require dynamic lighting / shadows, you may set this to `false`. - * @defaultValue `true` - */ - autoUpdate: boolean; - - /** - * When set to `true`, shadow maps will be updated in the next `render` call. - * If you have set {@link autoUpdate} to `false`, you will need to set this property to `true` and then make a render call to update the light's shadow. - * @defaultValue `false` - */ - needsUpdate: boolean; - - /** - * Used internally by the renderer to get the number of viewports that need to be rendered for this shadow. - */ - getViewportCount(): number; - - /** - * Copies value of all the properties from the {@link {@link LightShadow} | source} to this Light. - * @param source - */ - copy(source: LightShadow): this; - - /** - * Creates a new {@link LightShadow} with the same properties as this one. - */ - clone(recursive?: boolean): this; - - /** - * Serialize this LightShadow. - */ - toJSON(): LightShadowJSON; - - /** - * Gets the shadow cameras frustum - * @remarks - * Used internally by the renderer to cull objects. - */ - getFrustum(): Frustum; - - /** - * Update the matrices for the camera and shadow, used internally by the renderer. - * @param light The light for which the shadow is being rendered. - */ - updateMatrices(light: Light): void; - - getViewport(viewportIndex: number): Vector4; - - /** - * Used internally by the renderer to extend the shadow map to contain all viewports - */ - getFrameExtents(): Vector2; - - /** - * Frees the GPU-related resources allocated by this instance - * @remarks - * Call this method whenever this instance is no longer used in your app. - */ - dispose(): void; -} diff --git a/src-testing/src/lights/PointLight.d.ts b/src-testing/src/lights/PointLight.d.ts deleted file mode 100644 index c13044e12..000000000 --- a/src-testing/src/lights/PointLight.d.ts +++ /dev/null @@ -1,102 +0,0 @@ -import { ColorRepresentation } from "../math/Color.js"; -import { Light } from "./Light.js"; -import { PointLightShadow } from "./PointLightShadow.js"; - -/** - * A light that gets emitted from a single point in all directions - * @remarks - * A common use case for this is to replicate the light emitted from a bare lightbulb. - * @example - * ```typescript - * const light = new THREE.PointLight(0xff0000, 1, 100); - * light.position.set(50, 50, 50); - * scene.add(light); - * ``` - * @see Example: {@link https://threejs.org/examples/#webgl_lights_pointlights | lights / pointlights } - * @see Example: {@link https://threejs.org/examples/#webgl_effects_anaglyph | effects / anaglyph } - * @see Example: {@link https://threejs.org/examples/#webgl_geometry_text | geometry / text } - * @see Example: {@link https://threejs.org/examples/#webgl_lensflares | lensflares } - * @see {@link https://threejs.org/docs/index.html#api/en/lights/PointLight | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/lights/PointLight.js | Source} - */ -export class PointLight extends Light { - /** - * Creates a new PointLight. - * @param color Hexadecimal color of the light. Default is 0xffffff (white). Expects a `Integer` - * @param intensity Numeric value of the light's strength/intensity. Expects a `Float`. Default `1` - * @param distance Maximum range of the light. Default is 0 (no limit). - * @param decay The amount the light dims along the distance of the light. Expects a `Float`. Default `2` - */ - constructor(color?: ColorRepresentation, intensity?: number, distance?: number, decay?: number); - - /** - * Read-only flag to check if a given object is of type {@link PointLight}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isPointLight: true; - - /** - * @default 'PointLight' - */ - type: string; - - /** - * The light's intensity. - * - * When **{@link WebGLRenderer.useLegacyLights | legacy lighting mode} is disabled** — intensity is the luminous intensity of the light measured in candela (cd). - * @remarks Changing the intensity will also change the light's power. - * @remarks Expects a `Float` - * @defaultValue `1` - */ - intensity: number; - - /** - * When **Default mode** — When distance is zero, light does not attenuate. When distance is non-zero, - * light will attenuate linearly from maximum intensity at the light's position down to zero at this distance from the light. - * - * When **{@link WebGLRenderer.useLegacyLights | legacy lighting mode} is disabled** — When distance is zero, - * light will attenuate according to inverse-square law to infinite distance. - * When distance is non-zero, light will attenuate according to inverse-square law until near the distance cutoff, - * where it will then attenuate quickly and smoothly to 0. Inherently, cutoffs are not physically correct. - * - * @defaultValue `0.0` - * @remarks Expects a `Float` - */ - distance: number; - - /** - * If set to `true` light will cast dynamic shadows. - * **Warning**: This is expensive and requires tweaking to get shadows looking right. - * @see {@link THREE.PointLightShadow | PointLightShadow} for details. - * @defaultValue `false` - */ - castShadow: boolean; - - /** - * The amount the light dims along the distance of the light. - * In context of physically-correct rendering the default value should not be changed. - * @remarks Expects a `Float` - * @defaultValue `2` - */ - decay: number; - - /** - * A {@link THREE.PointLightShadow | PointLightShadow} used to calculate shadows for this light. - * The lightShadow's {@link LightShadow.camera | camera} is set to - * a {@link THREE.PerspectiveCamera | PerspectiveCamera} with {@link PerspectiveCamera.fov | fov} of 90, - * {@link PerspectiveCamera.aspect | aspect} of 1, - * {@link PerspectiveCamera.near | near} clipping plane at 0.5 - * and {@link PerspectiveCamera.far | far} clipping plane at 500. - * @defaultValue new THREE.PointLightShadow() - */ - shadow: PointLightShadow; - - /** - * The light's power. - * When **{@link WebGLRenderer.useLegacyLights | legacy lighting mode} is disabled** — power is the luminous power of the light measured in lumens (lm). - * @remarks Changing the power will also change the light's intensity. - * @remarks Expects a `Float` - */ - power: number; -} diff --git a/src-testing/src/lights/PointLightShadow.d.ts b/src-testing/src/lights/PointLightShadow.d.ts deleted file mode 100644 index 1d0e7e4af..000000000 --- a/src-testing/src/lights/PointLightShadow.d.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { PerspectiveCamera } from "../cameras/PerspectiveCamera.js"; -import { Light } from "./Light.js"; -import { LightShadow } from "./LightShadow.js"; - -/** - * Shadow for {@link THREE.PointLight | PointLight} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/lights/PointLightShadow.js | Source} - */ -export class PointLightShadow extends LightShadow { - /** - * Read-only flag to check if a given object is of type {@link PointLightShadow}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isPointLightShadow = true; - - /** - * Update the matrices for the camera and shadow, used internally by the renderer. - * @param light The light for which the shadow is being rendered. - */ - override updateMatrices(light: Light, viewportIndex?: number): void; -} diff --git a/src-testing/src/lights/RectAreaLight.d.ts b/src-testing/src/lights/RectAreaLight.d.ts deleted file mode 100644 index 2861e9794..000000000 --- a/src-testing/src/lights/RectAreaLight.d.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { ColorRepresentation } from "../math/Color.js"; -import { Light } from "./Light.js"; - -/** - * {@link RectAreaLight} emits light uniformly across the face a rectangular plane - * @remarks - * This light type can be used to simulate light sources such as bright windows or strip lighting. - * Important Notes: - * - There is no shadow support. - * - Only {@link MeshStandardMaterial | MeshStandardMaterial} and {@link MeshPhysicalMaterial | MeshPhysicalMaterial} are supported. - * - You have to include {@link https://threejs.org/examples/jsm/lights/RectAreaLightUniformsLib.js | RectAreaLightUniformsLib} into your scene and call `init()`. - * @example - * ```typescript - * const width = 10; - * const height = 10; - * const intensity = 1; - * const rectLight = new THREE.RectAreaLight(0xffffff, intensity, width, height); - * rectLight.position.set(5, 5, 0); - * rectLight.lookAt(0, 0, 0); - * scene.add(rectLight) - * const rectLightHelper = new RectAreaLightHelper(rectLight); - * rectLight.add(rectLightHelper); - * ``` - * @see Example: {@link https://threejs.org/examples/#webgl_lights_rectarealight | WebGL / {@link RectAreaLight} } - * @see {@link https://threejs.org/docs/index.html#api/en/lights/RectAreaLight | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/lights/RectAreaLight.js | Source} - */ -export class RectAreaLight extends Light { - /** - * Creates a new {@link RectAreaLight}. - * @param color Hexadecimal color of the light. Default `0xffffff` _(white)_. - * @param intensity The light's intensity, or brightness. Expects a `Float`. Default `1` - * @param width Width of the light. Expects a `Float`. Default `10` - * @param height Height of the light. Expects a `Float`. Default `10` - */ - constructor(color?: ColorRepresentation, intensity?: number, width?: number, height?: number); - - /** - * Read-only flag to check if a given object is of type {@link RectAreaLight}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isRectAreaLight: true; - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `RectAreaLight` - */ - override readonly type: string | "RectAreaLight"; - - /** - * The width of the light. - * @remarks Expects a `Float` - * @defaultValue `10` - */ - width: number; - - /** - * The height of the light. - * @remarks Expects a `Float` - * @defaultValue `10` - */ - height: number; - - /** - * The light's intensity. - * @remarks Changing the intensity will also change the light's power. - * When **{@link WebGLRenderer.useLegacyLights | legacy lighting mode} is disabled** — intensity is the luminance (brightness) of the light measured in nits (cd/m^2). - * @remarks Expects a `Float` - * @defaultValue `1` - */ - intensity: number; - - /** - * The light's power. - * @remarks Changing the power will also change the light's intensity. - * When **{@link WebGLRenderer.useLegacyLights | legacy lighting mode} is disabled** — power is the luminous power of the light measured in lumens (lm). - * @remarks Expects a `Float` - */ - power: number; -} diff --git a/src-testing/src/lights/SpotLight.d.ts b/src-testing/src/lights/SpotLight.d.ts deleted file mode 100644 index 7f42488a8..000000000 --- a/src-testing/src/lights/SpotLight.d.ts +++ /dev/null @@ -1,164 +0,0 @@ -import { Object3D } from "../core/Object3D.js"; -import { ColorRepresentation } from "../math/Color.js"; -import { Vector3 } from "../math/Vector3.js"; -import { Texture } from "../textures/Texture.js"; -import { Light } from "./Light.js"; -import { SpotLightShadow } from "./SpotLightShadow.js"; - -/** - * This light gets emitted from a single point in one direction, along a cone that increases in size the further from the light it gets. - * @example - * ```typescript - * // white {@link SpotLight} shining from the side, modulated by a texture, casting a shadow - * const {@link SpotLight} = new THREE.SpotLight(0xffffff); - * spotLight.position.set(100, 1000, 100); - * spotLight.map = new THREE.TextureLoader().load(url); - * spotLight.castShadow = true; - * spotLight.shadow.mapSize.width = 1024; - * spotLight.shadow.mapSize.height = 1024; - * spotLight.shadow.camera.near = 500; - * spotLight.shadow.camera.far = 4000; - * spotLight.shadow.camera.fov = 30; - * scene.add(spotLight); - * ``` - * @see Example: {@link https://threejs.org/examples/#webgl_lights_spotlight | lights / {@link SpotLight} } - * @see Example: {@link https://threejs.org/examples/#webgl_lights_spotlights | lights / spotlights } - * @see {@link https://threejs.org/docs/index.html#api/en/lights/SpotLight | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/lights/SpotLight.js | Source} - */ -export class SpotLight extends Light { - /** - * Creates a new SpotLight. - * @param color Hexadecimal color of the light. Default `0xffffff` _(white)_. - * @param intensity Numeric value of the light's strength/intensity. Expects a `Float`. Default `1`. - * @param distance Maximum range of the light. Default is 0 (no limit). Expects a `Float`. - * @param angle Maximum angle of light dispersion from its direction whose upper bound is Math.PI/2. - * @param penumbra Percent of the {@link SpotLight} cone that is attenuated due to penumbra. Takes values between zero and 1. Expects a `Float`. Default `0`. - * @param decay The amount the light dims along the distance of the light. Expects a `Float`. Default `2`. - */ - constructor( - color?: ColorRepresentation, - intensity?: number, - distance?: number, - angle?: number, - penumbra?: number, - decay?: number, - ); - - /** - * Read-only flag to check if a given object is of type {@link SpotLight}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isSpotLight: true; - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @defaultValue `SpotLight` - */ - override readonly type: string | "SpotLight"; - - /** - * This is set equal to {@link THREE.Object3D.DEFAULT_UP | Object3D.DEFAULT_UP} (0, 1, 0), so that the light shines from the top down. - * @defaultValue `{@link Object3D.DEFAULT_UP}` - */ - readonly position: Vector3; - - /** - * The {@link SpotLight} points from its {@link SpotLight.position | position} to target.position. - * @remarks - * **Note**: For the target's position to be changed to anything other than the default, - * it must be added to the {@link Scene | scene} using - * - * ```typescript - * scene.add( light.target ); - * ``` - * - * This is so that the target's {@link Object3D.matrixWorld | matrixWorld} gets automatically updated each frame. - * It is also possible to set the target to be another object in the scene (anything with a {@link THREE.Object3D.position | position} property), like so: - * ```typescript - * const targetObject = new THREE.Object3D(); - * scene.add(targetObject); - * light.target = targetObject; - * ``` - * The {@link SpotLight} will now track the target object. - * @defaultValue `new THREE.Object3D()` _The default position of the target is *(0, 0, 0)*._ - */ - target: Object3D; - - /** - * If set to `true` light will cast dynamic shadows. - * @remarks **Warning**: This is expensive and requires tweaking to get shadows looking right. the {@link THREE.SpotLightShadow | SpotLightShadow} for details. - * @defaultValue `false` - */ - override castShadow: boolean; - - /** - * The light's intensity. - * @remarks Changing the intensity will also change the light's power. - * When **{@link WebGLRenderer.useLegacyLights | legacy lighting mode} is disabled** — intensity is the luminous intensity of the light measured in candela (cd). - * @remarks Expects a `Float` - * @defaultValue `1` - */ - intensity: number; - - /** - * When **Default mode** — When distance is zero, light does not attenuate. When distance is non-zero, - * light will attenuate linearly from maximum intensity at the light's position down to zero at this distance from the light. - * - * When **{@link WebGLRenderer.useLegacyLights | legacy lighting mode} is disabled** — When distance is zero, - * light will attenuate according to inverse-square law to infinite distance. - * When distance is non-zero, light will attenuate according to inverse-square law until near the distance cutoff, - * where it will then attenuate quickly and smoothly to `0`. Inherently, cutoffs are not physically correct. - * @remarks Expects a `Float` - * @defaultValue `0.0` - */ - distance: number; - - /** - * Maximum extent of the spotlight, in radians, from its direction. - * @remarks Should be no more than `Math.PI/2`. - * @remarks Expects a `Float` - * @defaultValue `Math.PI / 3` - */ - angle: number; - - /** - * The amount the light dims along the distance of the light. - * In context of physically-correct rendering the default value should not be changed. - * @remarks Expects a `Float` - * @defaultValue `2` - */ - decay: number; - - /** - * A {@link THREE.SpotLightShadow | SpotLightShadow} used to calculate shadows for this light. - * @defaultValue `new THREE.SpotLightShadow()` - */ - shadow: SpotLightShadow; - - /** - * The light's power. - * @remarks Changing the power will also change the light's intensity. - * When **{@link WebGLRenderer.useLegacyLights | legacy lighting mode} is disabled** — power is the luminous power of the light measured in lumens (lm). - * @remarks Expects a `Float` - */ - power: number; - - /** - * Percent of the {@link SpotLight} cone that is attenuated due to penumbra. - * @remarks Takes values between zero and 1. - * @remarks Expects a `Float` - * @defaultValue `0.0` - */ - penumbra: number; - - /** - * A {@link THREE.Texture | Texture} used to modulate the color of the light. - * The spot light color is mixed with the _RGB_ value of this texture, with a ratio corresponding to its alpha value. - * The cookie-like masking effect is reproduced using pixel values (0, 0, 0, 1-cookie_value). - * @remarks **Warning**: {@link SpotLight.map} is disabled if {@link SpotLight.castShadow} is `false`. - */ - map: Texture | null; -} diff --git a/src-testing/src/lights/SpotLightShadow.d.ts b/src-testing/src/lights/SpotLightShadow.d.ts deleted file mode 100644 index 77f075c44..000000000 --- a/src-testing/src/lights/SpotLightShadow.d.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { PerspectiveCamera } from "../cameras/PerspectiveCamera.js"; -import { LightShadow } from "./LightShadow.js"; - -/** - * This is used internally by {@link SpotLight | SpotLights} for calculating shadows. - * @example - * ```typescript - * //Create a WebGLRenderer and turn on shadows in the renderer - * const renderer = new THREE.WebGLRenderer(); - * renderer.shadowMap.enabled = true; - * renderer.shadowMap.type = THREE.PCFSoftShadowMap; // default THREE.PCFShadowMap - * //Create a SpotLight and turn on shadows for the light - * const light = new THREE.SpotLight(0xffffff); - * light.castShadow = true; // default false - * scene.add(light); - * //Set up shadow properties for the light - * light.shadow.mapSize.width = 512; // default - * light.shadow.mapSize.height = 512; // default - * light.shadow.camera.near = 0.5; // default - * light.shadow.camera.far = 500; // default - * light.shadow.focus = 1; // default - * //Create a sphere that cast shadows (but does not receive them) - * const sphereGeometry = new THREE.SphereGeometry(5, 32, 32); - * const sphereMaterial = new THREE.MeshStandardMaterial({ - * color: 0xff0000 - * }); - * const sphere = new THREE.Mesh(sphereGeometry, sphereMaterial); - * sphere.castShadow = true; //default is false - * sphere.receiveShadow = false; //default - * scene.add(sphere); - * //Create a plane that receives shadows (but does not cast them) - * const planeGeometry = new THREE.PlaneGeometry(20, 20, 32, 32); - * const planeMaterial = new THREE.MeshStandardMaterial({ - * color: 0x00ff00 - * }) - * const plane = new THREE.Mesh(planeGeometry, planeMaterial); - * plane.receiveShadow = true; - * scene.add(plane); - * //Create a helper for the shadow camera (optional) - * const helper = new THREE.CameraHelper(light.shadow.camera); - * scene.add(helper); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/lights/shadows/SpotLightShadow | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/lights/SpotLightShadow.js | Source} - */ -export class SpotLightShadow extends LightShadow { - /** - * Read-only flag to check if a given object is of type {@link SpotLightShadow}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isSpotLightShadow: true; - - /** - * The light's view of the world. - * @remarks This is used to generate a depth map of the scene; objects behind other objects from the light's perspective will be in shadow. - * @remarks - * The {@link THREE.PerspectiveCamera.fov | fov} will track the {@link THREE.SpotLight.angle | angle} property - * of the owning {@link SpotLight | SpotLight} via the {@link SpotLightShadow.update | update} method. - * Similarly, the {@link THREE.PerspectiveCamera.aspect | aspect} property will track the aspect of the {@link LightShadow.mapSize | mapSize}. - * If the {@link SpotLight.distance | distance} property of the light is set, the {@link THREE.PerspectiveCamera.far | far} clipping plane will track that, otherwise it defaults to `500`. - * @defaultValue is a {@link THREE.PerspectiveCamera | PerspectiveCamera} with {@link THREE.PerspectiveCamera.near | near} clipping plane at `0.5`. - */ - camera: PerspectiveCamera; - - /** - * Used to focus the shadow camera. - * @remarks The camera's field of view is set as a percentage of the spotlight's field-of-view. Range is `[0, 1]`. 0`. - * @defaultValue `1` - */ - focus: number; -} diff --git a/src-testing/src/lights/webgpu/IESSpotLight.d.ts b/src-testing/src/lights/webgpu/IESSpotLight.d.ts deleted file mode 100644 index bf1b66006..000000000 --- a/src-testing/src/lights/webgpu/IESSpotLight.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { Texture } from "../../textures/Texture.js"; -import { SpotLight } from "../SpotLight.js"; - -export default class IESSpotLight extends SpotLight { - iesMap: Texture | null; -} diff --git a/src-testing/src/loaders/AnimationLoader.d.ts b/src-testing/src/loaders/AnimationLoader.d.ts deleted file mode 100644 index 567f30f30..000000000 --- a/src-testing/src/loaders/AnimationLoader.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { AnimationClip } from "../animation/AnimationClip.js"; -import { Loader } from "./Loader.js"; -import { LoadingManager } from "./LoadingManager.js"; - -export class AnimationLoader extends Loader { - constructor(manager?: LoadingManager); - - parse(json: readonly unknown[]): AnimationClip[]; -} diff --git a/src-testing/src/loaders/AudioLoader.d.ts b/src-testing/src/loaders/AudioLoader.d.ts deleted file mode 100644 index 0204bef47..000000000 --- a/src-testing/src/loaders/AudioLoader.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { Loader } from "./Loader.js"; -import { LoadingManager } from "./LoadingManager.js"; - -export class AudioLoader extends Loader { - constructor(manager?: LoadingManager); -} diff --git a/src-testing/src/loaders/BufferGeometryLoader.d.ts b/src-testing/src/loaders/BufferGeometryLoader.d.ts deleted file mode 100644 index 0aa994011..000000000 --- a/src-testing/src/loaders/BufferGeometryLoader.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { BufferGeometry } from "../core/BufferGeometry.js"; -import { InstancedBufferGeometry } from "../core/InstancedBufferGeometry.js"; -import { Loader } from "./Loader.js"; -import { LoadingManager } from "./LoadingManager.js"; - -export class BufferGeometryLoader extends Loader { - constructor(manager?: LoadingManager); - - parse(json: unknown): InstancedBufferGeometry | BufferGeometry; -} diff --git a/src-testing/src/loaders/Cache.d.ts b/src-testing/src/loaders/Cache.d.ts deleted file mode 100644 index 0742af8f5..000000000 --- a/src-testing/src/loaders/Cache.d.ts +++ /dev/null @@ -1,21 +0,0 @@ -declare const Cache: { - /** - * @default false - */ - enabled: boolean; - - /** - * @default {} - */ - files: any; - - add(key: string, file: any): void; - - get(key: string): any; - - remove(key: string): void; - - clear(): void; -}; - -export { Cache }; diff --git a/src-testing/src/loaders/CompressedTextureLoader.d.ts b/src-testing/src/loaders/CompressedTextureLoader.d.ts deleted file mode 100644 index eeca01ded..000000000 --- a/src-testing/src/loaders/CompressedTextureLoader.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { CompressedTexture } from "../textures/CompressedTexture.js"; -import { Loader } from "./Loader.js"; -import { LoadingManager } from "./LoadingManager.js"; - -export class CompressedTextureLoader extends Loader { - constructor(manager?: LoadingManager); - - load( - url: string, - onLoad?: (data: CompressedTexture) => void, - onProgress?: (event: ProgressEvent) => void, - onError?: (err: unknown) => void, - ): CompressedTexture; -} diff --git a/src-testing/src/loaders/CubeTextureLoader.d.ts b/src-testing/src/loaders/CubeTextureLoader.d.ts deleted file mode 100644 index f6cd285c4..000000000 --- a/src-testing/src/loaders/CubeTextureLoader.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { CubeTexture } from "../textures/CubeTexture.js"; -import { Loader } from "./Loader.js"; -import { LoadingManager } from "./LoadingManager.js"; - -export class CubeTextureLoader extends Loader { - constructor(manager?: LoadingManager); - - load( - url: readonly string[], - onLoad?: (data: CubeTexture) => void, - onProgress?: (event: ProgressEvent) => void, - onError?: (err: unknown) => void, - ): CubeTexture; -} diff --git a/src-testing/src/loaders/DataTextureLoader.d.ts b/src-testing/src/loaders/DataTextureLoader.d.ts deleted file mode 100644 index 0cc8d7475..000000000 --- a/src-testing/src/loaders/DataTextureLoader.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { DataTexture } from "../textures/DataTexture.js"; -import { Loader } from "./Loader.js"; -import { LoadingManager } from "./LoadingManager.js"; - -export class DataTextureLoader extends Loader { - constructor(manager?: LoadingManager); - - load( - url: string, - onLoad?: (data: DataTexture, texData: object) => void, - onProgress?: (event: ProgressEvent) => void, - onError?: (err: unknown) => void, - ): DataTexture; -} diff --git a/src-testing/src/loaders/FileLoader.d.ts b/src-testing/src/loaders/FileLoader.d.ts deleted file mode 100644 index 25ceba9cd..000000000 --- a/src-testing/src/loaders/FileLoader.d.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Loader } from "./Loader.js"; -import { LoadingManager } from "./LoadingManager.js"; - -export class FileLoader extends Loader { - constructor(manager?: LoadingManager); - - load( - url: string, - onLoad?: (data: string | ArrayBuffer) => void, - onProgress?: (event: ProgressEvent) => void, - onError?: (err: unknown) => void, - ): void; - - mimeType: string | undefined; - responseType: string | undefined; - - setMimeType(mimeType: string): FileLoader; - setResponseType(responseType: string): FileLoader; -} diff --git a/src-testing/src/loaders/ImageBitmapLoader.d.ts b/src-testing/src/loaders/ImageBitmapLoader.d.ts deleted file mode 100644 index f182d326a..000000000 --- a/src-testing/src/loaders/ImageBitmapLoader.d.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Loader } from "./Loader.js"; -import { LoadingManager } from "./LoadingManager.js"; - -export class ImageBitmapLoader extends Loader { - constructor(manager?: LoadingManager); - - load( - url: string, - onLoad?: (data: ImageBitmap) => void, - onProgress?: (event: ProgressEvent) => void, - onError?: (err: unknown) => void, - ): void; - - /** - * @default { premultiplyAlpha: 'none' } - */ - options: undefined | object; - - readonly isImageBitmapLoader: true; - - setOptions(options: object): ImageBitmapLoader; -} diff --git a/src-testing/src/loaders/ImageLoader.d.ts b/src-testing/src/loaders/ImageLoader.d.ts deleted file mode 100644 index 2189198e4..000000000 --- a/src-testing/src/loaders/ImageLoader.d.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { Loader } from "./Loader.js"; -import { LoadingManager } from "./LoadingManager.js"; - -/** - * A loader for loading an image. - * Unlike other loaders, this one emits events instead of using predefined callbacks. So if you're interested in getting notified when things happen, you need to add listeners to the object. - */ -export class ImageLoader extends Loader { - constructor(manager?: LoadingManager); - - load( - url: string, - onLoad?: (data: HTMLImageElement) => void, - onProgress?: (event: ProgressEvent) => void, - onError?: (err: unknown) => void, - ): HTMLImageElement; -} diff --git a/src-testing/src/loaders/Loader.d.ts b/src-testing/src/loaders/Loader.d.ts deleted file mode 100644 index 0f65e66f3..000000000 --- a/src-testing/src/loaders/Loader.d.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { LoadingManager } from "./LoadingManager.js"; - -/** - * Base class for implementing loaders. - */ -export class Loader { - constructor(manager?: LoadingManager); - - /** - * @default 'anonymous' - */ - crossOrigin: string; - - /** - * @default false - */ - withCredentials: boolean; - - /** - * @default '' - */ - path: string; - - /** - * @default '' - */ - resourcePath: string; - manager: LoadingManager; - - /** - * @default {} - */ - requestHeader: { [header: string]: string }; - - load( - url: TUrl, - onLoad: (data: TData) => void, - onProgress?: (event: ProgressEvent) => void, - onError?: (err: unknown) => void, - ): void; - loadAsync(url: TUrl, onProgress?: (event: ProgressEvent) => void): Promise; - - setCrossOrigin(crossOrigin: string): this; - setWithCredentials(value: boolean): this; - setPath(path: string): this; - setResourcePath(resourcePath: string): this; - setRequestHeader(requestHeader: { [header: string]: string }): this; - - static DEFAULT_MATERIAL_NAME: string; -} diff --git a/src-testing/src/loaders/LoaderUtils.d.ts b/src-testing/src/loaders/LoaderUtils.d.ts deleted file mode 100644 index 2f00baeff..000000000 --- a/src-testing/src/loaders/LoaderUtils.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -export class LoaderUtils { - /** - * @deprecated decodeText() has been deprecated with r165 and will be removed with r175. Use TextDecoder instead. - */ - static decodeText(array: BufferSource): string; - - static extractUrlBase(url: string): string; - - static resolveURL(url: string, path: string): string; -} diff --git a/src-testing/src/loaders/LoadingManager.d.ts b/src-testing/src/loaders/LoadingManager.d.ts deleted file mode 100644 index ab5b546cd..000000000 --- a/src-testing/src/loaders/LoadingManager.d.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { Loader } from "./Loader.js"; - -export const DefaultLoadingManager: LoadingManager; - -/** - * Handles and keeps track of loaded and pending data. - */ -export class LoadingManager { - constructor( - onLoad?: () => void, - onProgress?: (url: string, loaded: number, total: number) => void, - onError?: (url: string) => void, - ); - - /** - * Will be called when loading of an item starts. - * @param url The url of the item that started loading. - * @param loaded The number of items already loaded so far. - * @param total The total amount of items to be loaded. - */ - onStart?: ((url: string, loaded: number, total: number) => void) | undefined; - - /** - * Will be called when all items finish loading. - * The default is a function with empty body. - */ - onLoad: () => void; - - /** - * Will be called for each loaded item. - * The default is a function with empty body. - * @param url The url of the item just loaded. - * @param loaded The number of items already loaded so far. - * @param total The total amount of items to be loaded. - */ - onProgress: (url: string, loaded: number, total: number) => void; - - /** - * Will be called when item loading fails. - * The default is a function with empty body. - * @param url The url of the item that errored. - */ - onError: (url: string) => void; - - /** - * If provided, the callback will be passed each resource URL before a request is sent. - * The callback may return the original URL, or a new URL to override loading behavior. - * This behavior can be used to load assets from .ZIP files, drag-and-drop APIs, and Data URIs. - * @param callback URL modifier callback. Called with url argument, and must return resolvedURL. - */ - setURLModifier(callback?: (url: string) => string): this; - - /** - * Given a URL, uses the URL modifier callback (if any) and returns a resolved URL. - * If no URL modifier is set, returns the original URL. - * @param url the url to load - */ - resolveURL(url: string): string; - - itemStart(url: string): void; - itemEnd(url: string): void; - itemError(url: string): void; - - // handlers - - addHandler(regex: RegExp, loader: Loader): this; - removeHandler(regex: RegExp): this; - getHandler(file: string): Loader | null; -} diff --git a/src-testing/src/loaders/MaterialLoader.d.ts b/src-testing/src/loaders/MaterialLoader.d.ts deleted file mode 100644 index 742c22a04..000000000 --- a/src-testing/src/loaders/MaterialLoader.d.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { Material } from "../materials/Material.js"; -import { Texture } from "../textures/Texture.js"; -import { Loader } from "./Loader.js"; -import { LoadingManager } from "./LoadingManager.js"; - -export class MaterialLoader extends Loader { - /** - * @default {} - */ - textures: { [key: string]: Texture }; - - constructor(manager?: LoadingManager); - - parse(json: unknown): Material; - - setTextures(textures: { [key: string]: Texture }): this; - - createMaterialFromType(type: string): Material; - - static createMaterialFromType(type: string): Material; -} diff --git a/src-testing/src/loaders/ObjectLoader.d.ts b/src-testing/src/loaders/ObjectLoader.d.ts deleted file mode 100644 index 306c75700..000000000 --- a/src-testing/src/loaders/ObjectLoader.d.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { AnimationClip } from "../animation/AnimationClip.js"; -import { BufferGeometry } from "../core/BufferGeometry.js"; -import { InstancedBufferGeometry } from "../core/InstancedBufferGeometry.js"; -import { Object3D } from "../core/Object3D.js"; -import { Material } from "../materials/Material.js"; -import { Source } from "../textures/Source.js"; -import { Texture } from "../textures/Texture.js"; -import { Loader } from "./Loader.js"; -import { LoadingManager } from "./LoadingManager.js"; - -export class ObjectLoader extends Loader { - constructor(manager?: LoadingManager); - - load( - url: string, - onLoad?: (data: Object3D) => void, - onProgress?: (event: ProgressEvent) => void, - onError?: (err: unknown) => void, - ): void; - - parse(json: unknown, onLoad?: (object: Object3D) => void): Object3D; - parseAsync(json: unknown): Promise; - parseGeometries(json: unknown): { [key: string]: InstancedBufferGeometry | BufferGeometry }; - parseMaterials(json: unknown, textures: { [key: string]: Texture }): { [key: string]: Material }; - parseAnimations(json: unknown): { [key: string]: AnimationClip }; - parseImages(json: unknown, onLoad?: () => void): { [key: string]: Source }; - parseImagesAsync(json: unknown): Promise<{ [key: string]: Source }>; - parseTextures(json: unknown, images: { [key: string]: Source }): { [key: string]: Texture }; - parseObject( - data: unknown, - geometries: { [key: string]: InstancedBufferGeometry | BufferGeometry }, - materials: { [key: string]: Material }, - animations: { [key: string]: AnimationClip }, - ): Object3D; -} diff --git a/src-testing/src/loaders/TextureLoader.d.ts b/src-testing/src/loaders/TextureLoader.d.ts deleted file mode 100644 index 3cc07f5c3..000000000 --- a/src-testing/src/loaders/TextureLoader.d.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Texture } from "../textures/Texture.js"; -import { Loader } from "./Loader.js"; -import { LoadingManager } from "./LoadingManager.js"; - -/** - * Class for loading a texture. - * Unlike other loaders, this one emits events instead of using predefined callbacks. So if you're interested in getting notified when things happen, you need to add listeners to the object. - */ -export class TextureLoader extends Loader { - constructor(manager?: LoadingManager); - - load( - url: string, - onLoad?: (data: Texture) => void, - onProgress?: (event: ProgressEvent) => void, - onError?: (err: unknown) => void, - ): Texture; -} diff --git a/src-testing/src/loaders/nodes/NodeLoader.d.ts b/src-testing/src/loaders/nodes/NodeLoader.d.ts deleted file mode 100644 index 9083b2315..000000000 --- a/src-testing/src/loaders/nodes/NodeLoader.d.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { Node } from "../../nodes/Nodes.js"; -import { Texture } from "../../textures/Texture.js"; -import { Loader } from "../Loader.js"; -import { LoadingManager } from "../LoadingManager.js"; - -export interface NodeLoaderResult { - [hash: string]: Node; -} - -export default class NodeLoader extends Loader { - textures: { [key: string]: Texture }; - nodes: { [type: string]: Node }; - - constructor(manager?: LoadingManager); - - parseNodes(json: unknown): NodeLoaderResult; - parse(json: unknown): Node; - setTextures(textures: { [key: string]: Texture }): this; - setNodes(value: { [type: string]: Node }): this; - createNodeFromType(type: string): Node; -} diff --git a/src-testing/src/loaders/nodes/NodeMaterialLoader.d.ts b/src-testing/src/loaders/nodes/NodeMaterialLoader.d.ts deleted file mode 100644 index 89dee9c6a..000000000 --- a/src-testing/src/loaders/nodes/NodeMaterialLoader.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -import NodeMaterial from "../../materials/nodes/NodeMaterial.js"; -import { MaterialLoader } from "../MaterialLoader.js"; -import { NodeLoaderResult } from "./NodeLoader.js"; - -export default class NodeMaterialLoader extends MaterialLoader { - nodes: NodeLoaderResult; - nodeMaterials: { [type: string]: NodeMaterial }; - - setNodes(value: NodeLoaderResult): this; - setNodeMaterials(value: { [type: string]: NodeMaterial }): this; -} diff --git a/src-testing/src/loaders/nodes/NodeObjectLoader.d.ts b/src-testing/src/loaders/nodes/NodeObjectLoader.d.ts deleted file mode 100644 index 0dbcef8a5..000000000 --- a/src-testing/src/loaders/nodes/NodeObjectLoader.d.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Material } from "../../materials/Material.js"; -import NodeMaterial from "../../materials/nodes/NodeMaterial.js"; -import { Node } from "../../nodes/Nodes.js"; -import { Texture } from "../../textures/Texture.js"; -import { LoadingManager } from "../LoadingManager.js"; -import { ObjectLoader } from "../ObjectLoader.js"; -import { NodeLoaderResult } from "./NodeLoader.js"; - -export default class NodeObjectLoader extends ObjectLoader { - nodes: { [type: string]: Node }; - nodeMaterials: { [type: string]: NodeMaterial }; - - constructor(manager?: LoadingManager); - - setNodes(value: { [type: string]: Node }): this; - - setNodeMaterials(value: { [type: string]: NodeMaterial }): this; - - parseNodes(json: unknown, textures: { [key: string]: Texture }): NodeLoaderResult; - - parseMaterials(json: unknown, textures: { [key: string]: Texture }): { [key: string]: Material }; -} diff --git a/src-testing/src/materials/LineBasicMaterial.d.ts b/src-testing/src/materials/LineBasicMaterial.d.ts deleted file mode 100644 index 7f8bac230..000000000 --- a/src-testing/src/materials/LineBasicMaterial.d.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { Color, ColorRepresentation } from "../math/Color.js"; -import { Texture } from "../textures/Texture.js"; -import { Material, MaterialParameters } from "./Material.js"; - -export interface LineBasicMaterialParameters extends MaterialParameters { - color?: ColorRepresentation | undefined; - fog?: boolean | undefined; - linewidth?: number | undefined; - linecap?: string | undefined; - linejoin?: string | undefined; -} - -export class LineBasicMaterial extends Material { - constructor(parameters?: LineBasicMaterialParameters); - - /** - * Read-only flag to check if a given object is of type {@link LineBasicMaterial}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isLineBasicMaterial: true; - - /** - * @default 0xffffff - */ - color: Color; - - /** - * Whether the material is affected by fog. Default is true. - * @default true - */ - fog: boolean; - - /** - * @default 1 - */ - linewidth: number; - - /** - * @default 'round' - */ - linecap: string; - - /** - * @default 'round' - */ - linejoin: string; - - /** - * Sets the color of the lines using data from a {@link Texture}. - */ - map: Texture | null; - - setValues(parameters: LineBasicMaterialParameters): void; -} diff --git a/src-testing/src/materials/LineDashedMaterial.d.ts b/src-testing/src/materials/LineDashedMaterial.d.ts deleted file mode 100644 index 514bb3f93..000000000 --- a/src-testing/src/materials/LineDashedMaterial.d.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { LineBasicMaterial, LineBasicMaterialParameters } from "./LineBasicMaterial.js"; - -export interface LineDashedMaterialParameters extends LineBasicMaterialParameters { - scale?: number | undefined; - dashSize?: number | undefined; - gapSize?: number | undefined; -} - -export class LineDashedMaterial extends LineBasicMaterial { - constructor(parameters?: LineDashedMaterialParameters); - - /** - * Read-only flag to check if a given object is of type {@link LineDashedMaterial}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isLineDashedMaterial: true; - - /** - * @default 1 - */ - scale: number; - - /** - * @default 1 - */ - dashSize: number; - - /** - * @default 1 - */ - gapSize: number; - - setValues(parameters: LineDashedMaterialParameters): void; -} diff --git a/src-testing/src/materials/Material.d.ts b/src-testing/src/materials/Material.d.ts deleted file mode 100644 index 731bcc89e..000000000 --- a/src-testing/src/materials/Material.d.ts +++ /dev/null @@ -1,629 +0,0 @@ -import { Camera } from "../cameras/Camera.js"; -import { - Blending, - BlendingDstFactor, - BlendingEquation, - BlendingSrcFactor, - Combine, - DepthModes, - NormalMapTypes, - PixelFormat, - Side, - StencilFunc, - StencilOp, -} from "../constants.js"; -import { BufferGeometry } from "../core/BufferGeometry.js"; -import { EventDispatcher } from "../core/EventDispatcher.js"; -import { JSONMeta, Object3D } from "../core/Object3D.js"; -import { Color, ColorRepresentation } from "../math/Color.js"; -import { Plane } from "../math/Plane.js"; -import { Group } from "../objects/Group.js"; -import { WebGLProgramParametersWithUniforms } from "../renderers/webgl/WebGLPrograms.js"; -import { WebGLRenderer } from "../renderers/WebGLRenderer.js"; -import { Scene } from "../scenes/Scene.js"; -import { EulerTuple, SourceJSON, TextureJSON, Vector2Tuple } from "../Three.js"; - -export interface MaterialParameters { - alphaHash?: boolean | undefined; - alphaTest?: number | undefined; - alphaToCoverage?: boolean | undefined; - blendAlpha?: number | undefined; - blendColor?: ColorRepresentation | undefined; - blendDst?: BlendingDstFactor | undefined; - blendDstAlpha?: number | undefined; - blendEquation?: BlendingEquation | undefined; - blendEquationAlpha?: number | undefined; - blending?: Blending | undefined; - blendSrc?: BlendingSrcFactor | BlendingDstFactor | undefined; - blendSrcAlpha?: number | undefined; - clipIntersection?: boolean | undefined; - clippingPlanes?: Plane[] | undefined; - clipShadows?: boolean | undefined; - colorWrite?: boolean | undefined; - defines?: any; - depthFunc?: DepthModes | undefined; - depthTest?: boolean | undefined; - depthWrite?: boolean | undefined; - name?: string | undefined; - opacity?: number | undefined; - polygonOffset?: boolean | undefined; - polygonOffsetFactor?: number | undefined; - polygonOffsetUnits?: number | undefined; - precision?: "highp" | "mediump" | "lowp" | null | undefined; - premultipliedAlpha?: boolean | undefined; - forceSinglePass?: boolean | undefined; - dithering?: boolean | undefined; - side?: Side | undefined; - shadowSide?: Side | undefined; - toneMapped?: boolean | undefined; - transparent?: boolean | undefined; - vertexColors?: boolean | undefined; - visible?: boolean | undefined; - format?: PixelFormat | undefined; - stencilWrite?: boolean | undefined; - stencilFunc?: StencilFunc | undefined; - stencilRef?: number | undefined; - stencilWriteMask?: number | undefined; - stencilFuncMask?: number | undefined; - stencilFail?: StencilOp | undefined; - stencilZFail?: StencilOp | undefined; - stencilZPass?: StencilOp | undefined; - userData?: Record | undefined; -} - -export interface MaterialJSON { - metadata: { version: number; type: string; generator: string }; - - uuid: string; - type: string; - - name?: string; - - color?: number; - roughness?: number; - metalness?: number; - - sheen?: number; - sheenColor?: number; - sheenRoughness?: number; - emissive?: number; - emissiveIntensity?: number; - - specular?: number; - specularIntensity?: number; - specularColor?: number; - shininess?: number; - clearcoat?: number; - clearcoatRoughness?: number; - clearcoatMap?: string; - clearcoatRoughnessMap?: string; - clearcoatNormalMap?: string; - clearcoatNormalScale?: Vector2Tuple; - - dispersion?: number; - - iridescence?: number; - iridescenceIOR?: number; - iridescenceThicknessRange?: number; - iridescenceMap?: string; - iridescenceThicknessMap?: string; - - anisotropy?: number; - anisotropyRotation?: number; - anisotropyMap?: string; - - map?: string; - matcap?: string; - alphaMap?: string; - - lightMap?: string; - lightMapIntensity?: number; - - aoMap?: string; - aoMapIntensity?: number; - - bumpMap?: string; - bumpScale?: number; - - normalMap?: string; - normalMapType?: NormalMapTypes; - normalScale?: Vector2Tuple; - - displacementMap?: string; - displacementScale?: number; - displacementBias?: number; - - roughnessMap?: string; - metalnessMap?: string; - - emissiveMap?: string; - specularMap?: string; - specularIntensityMap?: string; - specularColorMap?: string; - - envMap?: string; - combine?: Combine; - - envMapRotation?: EulerTuple; - envMapIntensity?: number; - reflectivity?: number; - refractionRatio?: number; - - gradientMap?: string; - - transmission?: number; - transmissionMap?: string; - thickness?: number; - thicknessMap?: string; - attenuationDistance?: number; - attenuationColor?: number; - - size?: number; - shadowSide?: number; - sizeAttenuation?: boolean; - - blending?: Blending; - side?: Side; - vertexColors?: boolean; - - opacity?: number; - transparent?: boolean; - - blendSrc?: BlendingSrcFactor; - blendDst?: BlendingDstFactor; - blendEquation?: BlendingEquation; - blendSrcAlpha?: number | null; - blendDstAlpha?: number | null; - blendEquationAlpha?: number | null; - blendColor?: number; - blendAlpha?: number; - - depthFunc?: DepthModes; - depthTest?: boolean; - depthWrite?: boolean; - colorWrite?: boolean; - - stencilWriteMask?: number; - stencilFunc?: StencilFunc; - stencilRef?: number; - stencilFuncMask?: number; - stencilFail?: StencilOp; - stencilZFail?: StencilOp; - stencilZPass?: StencilOp; - stencilWrite?: boolean; - - rotation?: number; - - polygonOffset?: boolean; - polygonOffsetFactor?: number; - polygonOffsetUnits?: number; - - linewidth?: number; - dashSize?: number; - gapSize?: number; - scale?: number; - - dithering?: boolean; - - alphaTest?: number; - alphaHash?: boolean; - alphaToCoverage?: boolean; - premultipliedAlpha?: boolean; - forceSinglePass?: boolean; - - wireframe?: boolean; - wireframeLinewidth?: number; - wireframeLinecap?: string; - wireframeLinejoin?: string; - - flatShading?: boolean; - - visible?: boolean; - - toneMapped?: boolean; - - fog?: boolean; - - userData?: Record; - - textures?: Array>; - images?: SourceJSON[]; -} - -/** - * Materials describe the appearance of objects. They are defined in a (mostly) renderer-independent way, so you don't have to rewrite materials if you decide to use a different renderer. - */ -export class Material extends EventDispatcher<{ dispose: {} }> { - static get type(): string; - - get type(): string; - - constructor(); - - /** - * Read-only flag to check if a given object is of type {@link Material}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isMaterial: true; - - /** - * Enables alpha hashed transparency, an alternative to {@link .transparent} or {@link .alphaTest}. The material - * will not be rendered if opacity is lower than a random threshold. Randomization introduces some grain or noise, - * but approximates alpha blending without the associated problems of sorting. Using TAARenderPass can reduce the - * resulting noise. - */ - alphaHash: boolean; - - /** - * Enables alpha to coverage. Can only be used with MSAA-enabled rendering contexts (meaning when the renderer was - * created with *antialias* parameter set to `true`). Enabling this will smooth aliasing on clip plane edges and - * alphaTest-clipped edges. - * @default false - */ - alphaToCoverage: boolean; - - /** - * Represents the alpha value of the constant blend color. This property has only an effect when using custom - * blending with {@link ConstantAlphaFactor} or {@link OneMinusConstantAlphaFactor}. - * @default 0 - */ - blendAlpha: number; - - /** - * Represent the RGB values of the constant blend color. This property has only an effect when using custom - * blending with {@link ConstantColorFactor} or {@link OneMinusConstantColorFactor}. - * @default 0x000000 - */ - blendColor: Color; - - /** - * Blending destination. It's one of the blending mode constants defined in Three.js. Default is {@link OneMinusSrcAlphaFactor}. - * @default THREE.OneMinusSrcAlphaFactor - */ - blendDst: BlendingDstFactor; - - /** - * The tranparency of the .blendDst. Default is null. - * @default null - */ - blendDstAlpha: number | null; - - /** - * Blending equation to use when applying blending. It's one of the constants defined in Three.js. Default is {@link AddEquation}. - * @default THREE.AddEquation - */ - blendEquation: BlendingEquation; - - /** - * The tranparency of the .blendEquation. Default is null. - * @default null - */ - blendEquationAlpha: number | null; - - /** - * Which blending to use when displaying objects with this material. Default is {@link NormalBlending}. - * @default THREE.NormalBlending - */ - blending: Blending; - - /** - * Blending source. It's one of the blending mode constants defined in Three.js. Default is {@link SrcAlphaFactor}. - * @default THREE.SrcAlphaFactor - */ - blendSrc: BlendingSrcFactor | BlendingDstFactor; - - /** - * The tranparency of the .blendSrc. Default is null. - * @default null - */ - blendSrcAlpha: number | null; - - /** - * Changes the behavior of clipping planes so that only their intersection is clipped, rather than their union. Default is false. - * @default false - */ - clipIntersection: boolean; - - /** - * User-defined clipping planes specified as THREE.Plane objects in world space. - * These planes apply to the objects this material is attached to. - * Points in space whose signed distance to the plane is negative are clipped (not rendered). - * See the WebGL / clipping /intersection example. Default is null. - * @default null - */ - clippingPlanes: Plane[] | null; - - /** - * Defines whether to clip shadows according to the clipping planes specified on this material. Default is false. - * @default false - */ - clipShadows: boolean; - - /** - * Whether to render the material's color. This can be used in conjunction with a mesh's .renderOrder property to create invisible objects that occlude other objects. Default is true. - * @default true - */ - colorWrite: boolean; - - /** - * Custom defines to be injected into the shader. These are passed in form of an object literal, with key/value pairs. { MY_CUSTOM_DEFINE: '' , PI2: Math.PI * 2 }. - * The pairs are defined in both vertex and fragment shaders. Default is undefined. - * @default undefined - */ - defines: undefined | { [key: string]: any }; - - /** - * Which depth function to use. Default is {@link LessEqualDepth}. See the depth mode constants for all possible values. - * @default THREE.LessEqualDepth - */ - depthFunc: DepthModes; - - /** - * Whether to have depth test enabled when rendering this material. When the depth test is disabled, the depth write - * will also be implicitly disabled. - * @default true - */ - depthTest: boolean; - - /** - * Whether rendering this material has any effect on the depth buffer. Default is true. - * When drawing 2D overlays it can be useful to disable the depth writing in order to layer several things together without creating z-index artifacts. - * @default true - */ - depthWrite: boolean; - - /** - * Unique number of this material instance. - */ - id: number; - - /** - * Whether rendering this material has any effect on the stencil buffer. Default is *false*. - * @default false - */ - stencilWrite: boolean; - - /** - * The stencil comparison function to use. Default is {@link AlwaysStencilFunc}. See stencil operation constants for all possible values. - * @default THREE.AlwaysStencilFunc - */ - stencilFunc: StencilFunc; - - /** - * The value to use when performing stencil comparisons or stencil operations. Default is *0*. - * @default 0 - */ - stencilRef: number; - - /** - * The bit mask to use when writing to the stencil buffer. Default is *0xFF*. - * @default 0xff - */ - stencilWriteMask: number; - - /** - * The bit mask to use when comparing against the stencil buffer. Default is *0xFF*. - * @default 0xff - */ - stencilFuncMask: number; - - /** - * Which stencil operation to perform when the comparison function returns false. Default is {@link KeepStencilOp}. See the stencil operation constants for all possible values. - * @default THREE.KeepStencilOp - */ - stencilFail: StencilOp; - - /** - * Which stencil operation to perform when the comparison function returns true but the depth test fails. - * Default is {@link KeepStencilOp}. - * See the stencil operation constants for all possible values. - * @default THREE.KeepStencilOp - */ - stencilZFail: StencilOp; - - /** - * Which stencil operation to perform when the comparison function returns true and the depth test passes. - * Default is {@link KeepStencilOp}. - * See the stencil operation constants for all possible values. - * @default THREE.KeepStencilOp - */ - stencilZPass: StencilOp; - - /** - * Material name. Default is an empty string. - * @default '' - */ - name: string; - - /** - * Opacity. Default is 1. - * @default 1 - */ - opacity: number; - - /** - * Whether to use polygon offset. Default is false. This corresponds to the POLYGON_OFFSET_FILL WebGL feature. - * @default false - */ - polygonOffset: boolean; - - /** - * Sets the polygon offset factor. Default is 0. - * @default 0 - */ - polygonOffsetFactor: number; - - /** - * Sets the polygon offset units. Default is 0. - * @default 0 - */ - polygonOffsetUnits: number; - - /** - * Override the renderer's default precision for this material. Can be "highp", "mediump" or "lowp". Defaults is null. - * @default null - */ - precision: "highp" | "mediump" | "lowp" | null; - - /** - * Whether to premultiply the alpha (transparency) value. See WebGL / Materials / Transparency for an example of the difference. Default is false. - * @default false - */ - premultipliedAlpha: boolean; - - /** - * @default false - */ - forceSinglePass: boolean; - - /** - * Whether to apply dithering to the color to remove the appearance of banding. Default is false. - * @default false - */ - dithering: boolean; - - /** - * Defines which of the face sides will be rendered - front, back or both. - * Default is {@link THREE.FrontSide}. Other options are {@link THREE.BackSide} and {@link THREE.DoubleSide}. - * - * @default {@link THREE.FrontSide} - */ - side: Side; - - /** - * Defines which of the face sides will cast shadows. Default is *null*. - * If *null*, the value is opposite that of side, above. - * @default null - */ - shadowSide: Side | null; - - /** - * Defines whether this material is tone mapped according to the renderer's - * {@link WebGLRenderer.toneMapping toneMapping} setting. It is ignored when rendering to a render target or using - * post processing. - * @default true - */ - toneMapped: boolean; - - /** - * Defines whether this material is transparent. This has an effect on rendering as transparent objects need special treatment and are rendered after non-transparent objects. - * When set to true, the extent to which the material is transparent is controlled by setting it's .opacity property. - * @default false - */ - transparent: boolean; - - /** - * UUID of this material instance. This gets automatically assigned, so this shouldn't be edited. - */ - uuid: string; - - /** - * Defines whether vertex coloring is used. Default is false. - * @default false - */ - vertexColors: boolean; - - /** - * Defines whether this material is visible. Default is true. - * @default true - */ - visible: boolean; - - /** - * An object that can be used to store custom data about the Material. It should not hold references to functions as these will not be cloned. - * @default {} - */ - userData: Record; - - /** - * This starts at 0 and counts how many times .needsUpdate is set to true. - * @default 0 - */ - version: number; - - /** - * Gets the alpha value to be used when running an alpha test. Default is 0. - * @default 0 - */ - get alphaTest(): number; - - /** - * Sets the alpha value to be used when running an alpha test. Default is 0. - * @default 0 - */ - set alphaTest(value: number); - - /** - * An optional callback that is executed immediately before the material is used to render a 3D object. - * Unlike properties, the callback is not supported by {@link .clone()}, {@link .copy()} and {@link .toJSON()}. - * This callback is only supported in `WebGLRenderer` (not `WebGPURenderer`). - */ - onBeforeRender( - renderer: WebGLRenderer, - scene: Scene, - camera: Camera, - geometry: BufferGeometry, - object: Object3D, - group: Group, - ): void; - - /** - * An optional callback that is executed immediately before the shader program is compiled. - * This function is called with the shader source code as a parameter. - * Useful for the modification of built-in materials. - * Unlike properties, the callback is not supported by {@link .clone()}, {@link .copy()} and {@link .toJSON()}. - * This callback is only supported in `WebGLRenderer` (not `WebGPURenderer`). - * @param parameters WebGL program parameters - * @param renderer WebGLRenderer context that is initializing the material - */ - onBeforeCompile(parameters: WebGLProgramParametersWithUniforms, renderer: WebGLRenderer): void; - - /** - * In case onBeforeCompile is used, this callback can be used to identify values of settings used in onBeforeCompile, so three.js can reuse a cached shader or recompile the shader as needed. - */ - customProgramCacheKey(): string; - - /** - * Sets the properties based on the values. - * @param values A container with parameters. - */ - setValues(values: MaterialParameters): void; - - /** - * Convert the material to three.js JSON format. - * @param meta Object containing metadata such as textures or images for the material. - */ - toJSON(meta?: JSONMeta): MaterialJSON; - - /** - * Return a new material with the same parameters as this material. - */ - clone(): this; - - /** - * Copy the parameters from the passed material into this material. - * @param material - */ - copy(material: Material): this; - - /** - * Frees the GPU-related resources allocated by this instance. Call this method whenever this instance is no longer - * used in your app. - * - * Material textures must be disposed of by the dispose() method of {@link Texture}. - */ - dispose(): void; - - /** - * Specifies that the material needs to be updated, WebGL wise. Set it to true if you made changes that need to be reflected in WebGL. - * This property is automatically set to true when instancing a new material. - * @default false - */ - set needsUpdate(value: boolean); - - /** - * @deprecated onBuild() has been removed. - */ - onBuild(object: Object3D, parameters: WebGLProgramParametersWithUniforms, renderer: WebGLRenderer): void; -} diff --git a/src-testing/src/materials/Materials.d.ts b/src-testing/src/materials/Materials.d.ts deleted file mode 100644 index dbca5e5b7..000000000 --- a/src-testing/src/materials/Materials.d.ts +++ /dev/null @@ -1,18 +0,0 @@ -export * from "./LineBasicMaterial.js"; -export * from "./LineDashedMaterial.js"; -export * from "./Material.js"; -export * from "./MeshBasicMaterial.js"; -export * from "./MeshDepthMaterial.js"; -export * from "./MeshDistanceMaterial.js"; -export * from "./MeshLambertMaterial.js"; -export * from "./MeshMatcapMaterial.js"; -export * from "./MeshNormalMaterial.js"; -export * from "./MeshPhongMaterial.js"; -export * from "./MeshPhysicalMaterial.js"; -export * from "./MeshStandardMaterial.js"; -export * from "./MeshToonMaterial.js"; -export * from "./PointsMaterial.js"; -export * from "./RawShaderMaterial.js"; -export * from "./ShaderMaterial.js"; -export * from "./ShadowMaterial.js"; -export * from "./SpriteMaterial.js"; diff --git a/src-testing/src/materials/MeshBasicMaterial.d.ts b/src-testing/src/materials/MeshBasicMaterial.d.ts deleted file mode 100644 index 37ca083d7..000000000 --- a/src-testing/src/materials/MeshBasicMaterial.d.ts +++ /dev/null @@ -1,134 +0,0 @@ -import { Combine } from "../constants.js"; -import { Color, ColorRepresentation } from "../math/Color.js"; -import { Euler } from "../math/Euler.js"; -import { Texture } from "../textures/Texture.js"; -import { Material, MaterialParameters } from "./Material.js"; - -/** - * parameters is an object with one or more properties defining the material's appearance. - */ -export interface MeshBasicMaterialParameters extends MaterialParameters { - color?: ColorRepresentation | undefined; - opacity?: number | undefined; - map?: Texture | null | undefined; - lightMap?: Texture | null; - lightMapIntensity?: number | undefined; - aoMap?: Texture | null | undefined; - aoMapIntensity?: number | undefined; - specularMap?: Texture | null | undefined; - alphaMap?: Texture | null | undefined; - fog?: boolean | undefined; - envMap?: Texture | null | undefined; - envMapRotation?: Euler | undefined; - combine?: Combine | undefined; - reflectivity?: number | undefined; - refractionRatio?: number | undefined; - wireframe?: boolean | undefined; - wireframeLinewidth?: number | undefined; - wireframeLinecap?: string | undefined; - wireframeLinejoin?: string | undefined; -} - -export class MeshBasicMaterial extends Material { - constructor(parameters?: MeshBasicMaterialParameters); - - /** - * Read-only flag to check if a given object is of type {@link MeshBasicMaterial}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isMeshBasicMaterial: true; - - /** - * @default new THREE.Color( 0xffffff ) - */ - color: Color; - - /** - * @default null - */ - map: Texture | null; - - /** - * @default null - */ - lightMap: Texture | null; - - /** - * @default 1 - */ - lightMapIntensity: number; - - /** - * @default null - */ - aoMap: Texture | null; - - /** - * @default 1 - */ - aoMapIntensity: number; - - /** - * @default null - */ - specularMap: Texture | null; - - /** - * @default null - */ - alphaMap: Texture | null; - - /** - * @default null - */ - envMap: Texture | null; - - /** - * The rotation of the environment map in radians. Default is `(0,0,0)`. - */ - envMapRotation: Euler; - - /** - * @default THREE.MultiplyOperation - */ - combine: Combine; - - /** - * @default 1 - */ - reflectivity: number; - - /** - * @default 0.98 - */ - refractionRatio: number; - - /** - * @default false - */ - wireframe: boolean; - - /** - * @default 1 - */ - wireframeLinewidth: number; - - /** - * @default 'round' - */ - wireframeLinecap: string; - - /** - * @default 'round' - */ - wireframeLinejoin: string; - - /** - * Whether the material is affected by fog. Default is true. - * @default fog - */ - fog: boolean; - - setValues(parameters: MeshBasicMaterialParameters): void; -} diff --git a/src-testing/src/materials/MeshDepthMaterial.d.ts b/src-testing/src/materials/MeshDepthMaterial.d.ts deleted file mode 100644 index dcdcd18b6..000000000 --- a/src-testing/src/materials/MeshDepthMaterial.d.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { DepthPackingStrategies } from "../constants.js"; -import { Texture } from "../textures/Texture.js"; -import { Material, MaterialParameters } from "./Material.js"; - -export interface MeshDepthMaterialParameters extends MaterialParameters { - map?: Texture | null | undefined; - alphaMap?: Texture | null | undefined; - depthPacking?: DepthPackingStrategies | undefined; - displacementMap?: Texture | null | undefined; - displacementScale?: number | undefined; - displacementBias?: number | undefined; - wireframe?: boolean | undefined; - wireframeLinewidth?: number | undefined; -} - -export class MeshDepthMaterial extends Material { - constructor(parameters?: MeshDepthMaterialParameters); - /** - * Read-only flag to check if a given object is of type {@link MeshDepthMaterial}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isMeshDepthMaterial: true; - - /** - * @default null - */ - map: Texture | null; - - /** - * @default null - */ - alphaMap: Texture | null; - - /** - * @default THREE.BasicDepthPacking - */ - depthPacking: DepthPackingStrategies; - - /** - * @default null - */ - displacementMap: Texture | null; - - /** - * @default 1 - */ - displacementScale: number; - - /** - * @default 0 - */ - displacementBias: number; - - /** - * @default false - */ - wireframe: boolean; - - /** - * @default 1 - */ - wireframeLinewidth: number; - - /** - * @default false - */ - fog: boolean; - - setValues(parameters: MeshDepthMaterialParameters): void; -} diff --git a/src-testing/src/materials/MeshDistanceMaterial.d.ts b/src-testing/src/materials/MeshDistanceMaterial.d.ts deleted file mode 100644 index 4e6a8754b..000000000 --- a/src-testing/src/materials/MeshDistanceMaterial.d.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { Vector3 } from "../math/Vector3.js"; -import { Texture } from "../textures/Texture.js"; -import { Material, MaterialParameters } from "./Material.js"; - -export interface MeshDistanceMaterialParameters extends MaterialParameters { - map?: Texture | null | undefined; - alphaMap?: Texture | null | undefined; - displacementMap?: Texture | null | undefined; - displacementScale?: number | undefined; - displacementBias?: number | undefined; - farDistance?: number | undefined; - nearDistance?: number | undefined; - referencePosition?: Vector3 | undefined; -} - -export class MeshDistanceMaterial extends Material { - constructor(parameters?: MeshDistanceMaterialParameters); - - /** - * Read-only flag to check if a given object is of type {@link MeshDistanceMaterial}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isMeshDistanceMaterial: true; - - /** - * @default null - */ - map: Texture | null; - - /** - * @default null - */ - alphaMap: Texture | null; - - /** - * @default null - */ - displacementMap: Texture | null; - - /** - * @default 1 - */ - displacementScale: number; - - /** - * @default 0 - */ - displacementBias: number; - - /** - * @default false - */ - fog: boolean; - - setValues(parameters: MeshDistanceMaterialParameters): void; -} diff --git a/src-testing/src/materials/MeshLambertMaterial.d.ts b/src-testing/src/materials/MeshLambertMaterial.d.ts deleted file mode 100644 index 868fbbbe0..000000000 --- a/src-testing/src/materials/MeshLambertMaterial.d.ts +++ /dev/null @@ -1,199 +0,0 @@ -import { Combine, NormalMapTypes } from "../constants.js"; -import { Color, ColorRepresentation } from "../math/Color.js"; -import { Euler } from "../math/Euler.js"; -import { Vector2 } from "../math/Vector2.js"; -import { Texture } from "../textures/Texture.js"; -import { Material, MaterialParameters } from "./Material.js"; - -export interface MeshLambertMaterialParameters extends MaterialParameters { - bumpMap?: Texture | undefined; - bumpScale?: number | undefined; - color?: ColorRepresentation | undefined; - displacementMap?: Texture | undefined; - displacementScale?: number | undefined; - displacementBias?: number | undefined; - emissive?: ColorRepresentation | undefined; - emissiveIntensity?: number | undefined; - emissiveMap?: Texture | null | undefined; - flatShading?: boolean | undefined; - map?: Texture | null | undefined; - lightMap?: Texture | null | undefined; - lightMapIntensity?: number | undefined; - normalMap?: Texture | undefined; - normalScale?: Vector2 | undefined; - aoMap?: Texture | null | undefined; - aoMapIntensity?: number | undefined; - specularMap?: Texture | null | undefined; - alphaMap?: Texture | null | undefined; - envMap?: Texture | null | undefined; - envMapRotation?: Euler | undefined; - combine?: Combine | undefined; - reflectivity?: number | undefined; - refractionRatio?: number | undefined; - wireframe?: boolean | undefined; - wireframeLinewidth?: number | undefined; - wireframeLinecap?: string | undefined; - wireframeLinejoin?: string | undefined; - fog?: boolean | undefined; -} - -export class MeshLambertMaterial extends Material { - constructor(parameters?: MeshLambertMaterialParameters); - - /** - * Read-only flag to check if a given object is of type {@link MeshLambertMaterial}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isMeshLambertMaterial: true; - - /** - * @default new THREE.Color( 0xffffff ) - */ - color: Color; - - /** - * @default null - */ - bumpMap: Texture | null; - - /** - * @default 1 - */ - bumpScale: number; - - /** - * @default null - */ - displacementMap: Texture | null; - - /** - * @default 1 - */ - displacementScale: number; - - /** - * @default 0 - */ - displacementBias: number; - - /** - * @default new THREE.Color( 0x000000 ) - */ - emissive: Color; - - /** - * @default 1 - */ - emissiveIntensity: number; - - /** - * @default null - */ - emissiveMap: Texture | null; - - /** - * @default false - */ - flatShading: boolean; - - /** - * @default null - */ - map: Texture | null; - - /** - * @default null - */ - lightMap: Texture | null; - - /** - * @default 1 - */ - lightMapIntensity: number; - - /** - * @default null - */ - normalMap: Texture | null; - - normalMapType: NormalMapTypes; - - /** - * @default new THREE.Vector2( 1, 1 ) - */ - normalScale: Vector2; - - /** - * @default null - */ - aoMap: Texture | null; - - /** - * @default 1 - */ - aoMapIntensity: number; - - /** - * @default null - */ - specularMap: Texture | null; - - /** - * @default null - */ - alphaMap: Texture | null; - - /** - * @default null - */ - envMap: Texture | null; - - /** - * The rotation of the environment map in radians. Default is `(0,0,0)`. - */ - envMapRotation: Euler; - - /** - * @default THREE.MultiplyOperation - */ - combine: Combine; - - /** - * @default 1 - */ - reflectivity: number; - - /** - * @default 0.98 - */ - refractionRatio: number; - - /** - * @default false - */ - wireframe: boolean; - - /** - * @default 1 - */ - wireframeLinewidth: number; - - /** - * @default 'round' - */ - wireframeLinecap: string; - - /** - * @default 'round' - */ - wireframeLinejoin: string; - - /** - * Whether the material is affected by fog. Default is true. - * @default fog - */ - fog: boolean; - - setValues(parameters: MeshLambertMaterialParameters): void; -} diff --git a/src-testing/src/materials/MeshMatcapMaterial.d.ts b/src-testing/src/materials/MeshMatcapMaterial.d.ts deleted file mode 100644 index 7f7334d4b..000000000 --- a/src-testing/src/materials/MeshMatcapMaterial.d.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { NormalMapTypes } from "../constants.js"; -import { Color, ColorRepresentation } from "../math/Color.js"; -import { Vector2 } from "../math/Vector2.js"; -import { Texture } from "../textures/Texture.js"; -import { Material, MaterialParameters } from "./Material.js"; - -export interface MeshMatcapMaterialParameters extends MaterialParameters { - color?: ColorRepresentation | undefined; - matcap?: Texture | null | undefined; - map?: Texture | null | undefined; - bumpMap?: Texture | null | undefined; - bumpScale?: number | undefined; - normalMap?: Texture | null | undefined; - normalMapType?: NormalMapTypes | undefined; - normalScale?: Vector2 | undefined; - displacementMap?: Texture | null | undefined; - displacementScale?: number | undefined; - displacementBias?: number | undefined; - alphaMap?: Texture | null | undefined; - fog?: boolean | undefined; - flatShading?: boolean | undefined; -} - -export class MeshMatcapMaterial extends Material { - constructor(parameters?: MeshMatcapMaterialParameters); - - /** - * Read-only flag to check if a given object is of type {@link MeshMatcapMaterial}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isMeshMatcapMaterial: true; - - /** - * @default { 'MATCAP': '' } - */ - defines: { [key: string]: any }; - - /** - * @default new THREE.Color( 0xffffff ) - */ - color: Color; - - /** - * @default null - */ - matcap: Texture | null; - - /** - * @default null - */ - map: Texture | null; - - /** - * @default null - */ - bumpMap: Texture | null; - - /** - * @default 1 - */ - bumpScale: number; - - /** - * @default null - */ - normalMap: Texture | null; - - /** - * @default THREE.TangentSpaceNormalMap - */ - normalMapType: NormalMapTypes; - - /** - * @default new Vector2( 1, 1 ) - */ - normalScale: Vector2; - - /** - * @default null - */ - displacementMap: Texture | null; - - /** - * @default 1 - */ - displacementScale: number; - - /** - * @default 0 - */ - displacementBias: number; - - /** - * @default null - */ - alphaMap: Texture | null; - - /** - * Define whether the material is rendered with flat shading. Default is false. - * @default false - */ - flatShading: boolean; - - /** - * Whether the material is affected by fog. Default is true. - * @default fog - */ - fog: boolean; - - setValues(parameters: MeshMatcapMaterialParameters): void; -} diff --git a/src-testing/src/materials/MeshNormalMaterial.d.ts b/src-testing/src/materials/MeshNormalMaterial.d.ts deleted file mode 100644 index 715ada4e6..000000000 --- a/src-testing/src/materials/MeshNormalMaterial.d.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { NormalMapTypes } from "../constants.js"; -import { Vector2 } from "../math/Vector2.js"; -import { Texture } from "../textures/Texture.js"; -import { Material, MaterialParameters } from "./Material.js"; - -export interface MeshNormalMaterialParameters extends MaterialParameters { - bumpMap?: Texture | null | undefined; - bumpScale?: number | undefined; - normalMap?: Texture | null | undefined; - normalMapType?: NormalMapTypes | undefined; - normalScale?: Vector2 | undefined; - displacementMap?: Texture | null | undefined; - displacementScale?: number | undefined; - displacementBias?: number | undefined; - wireframe?: boolean | undefined; - wireframeLinewidth?: number | undefined; - - flatShading?: boolean | undefined; -} - -export class MeshNormalMaterial extends Material { - constructor(parameters?: MeshNormalMaterialParameters); - - /** - * Read-only flag to check if a given object is of type {@link MeshNormalMaterial}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isMeshNormalMaterial: true; - - /** - * @default null - */ - bumpMap: Texture | null; - - /** - * @default 1 - */ - bumpScale: number; - - /** - * @default null - */ - normalMap: Texture | null; - - /** - * @default THREE.TangentSpaceNormalMap - */ - normalMapType: NormalMapTypes; - - /** - * @default new THREE.Vector2( 1, 1 ) - */ - normalScale: Vector2; - - /** - * @default null - */ - displacementMap: Texture | null; - - /** - * @default 1 - */ - displacementScale: number; - - /** - * @default 0 - */ - displacementBias: number; - - /** - * @default false - */ - wireframe: boolean; - - /** - * @default 1 - */ - wireframeLinewidth: number; - - /** - * Define whether the material is rendered with flat shading. Default is false. - * @default false - */ - flatShading: boolean; - - setValues(parameters: MeshNormalMaterialParameters): void; -} diff --git a/src-testing/src/materials/MeshPhongMaterial.d.ts b/src-testing/src/materials/MeshPhongMaterial.d.ts deleted file mode 100644 index 2b002524b..000000000 --- a/src-testing/src/materials/MeshPhongMaterial.d.ts +++ /dev/null @@ -1,223 +0,0 @@ -import { Combine, NormalMapTypes } from "../constants.js"; -import { Color, ColorRepresentation } from "../math/Color.js"; -import { Euler } from "../math/Euler.js"; -import { Vector2 } from "../math/Vector2.js"; -import { Texture } from "../textures/Texture.js"; -import { Material, MaterialParameters } from "./Material.js"; - -export interface MeshPhongMaterialParameters extends MaterialParameters { - /** geometry color in hexadecimal. Default is 0xffffff. */ - color?: ColorRepresentation | undefined; - specular?: ColorRepresentation | undefined; - shininess?: number | undefined; - opacity?: number | undefined; - map?: Texture | null | undefined; - lightMap?: Texture | null | undefined; - lightMapIntensity?: number | undefined; - aoMap?: Texture | null | undefined; - aoMapIntensity?: number | undefined; - emissive?: ColorRepresentation | undefined; - emissiveIntensity?: number | undefined; - emissiveMap?: Texture | null | undefined; - bumpMap?: Texture | null | undefined; - bumpScale?: number | undefined; - normalMap?: Texture | null | undefined; - normalMapType?: NormalMapTypes | undefined; - normalScale?: Vector2 | undefined; - displacementMap?: Texture | null | undefined; - displacementScale?: number | undefined; - displacementBias?: number | undefined; - specularMap?: Texture | null | undefined; - alphaMap?: Texture | null | undefined; - envMap?: Texture | null | undefined; - envMapRotation?: Euler | undefined; - combine?: Combine | undefined; - reflectivity?: number | undefined; - refractionRatio?: number | undefined; - wireframe?: boolean | undefined; - wireframeLinewidth?: number | undefined; - wireframeLinecap?: string | undefined; - wireframeLinejoin?: string | undefined; - fog?: boolean | undefined; - flatShading?: boolean | undefined; -} - -export class MeshPhongMaterial extends Material { - constructor(parameters?: MeshPhongMaterialParameters); - - /** - * Read-only flag to check if a given object is of type {@link MeshPhongMaterial}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isMeshPhongMaterial: true; - - /** - * @default new THREE.Color( 0xffffff ) - */ - color: Color; - - /** - * @default new THREE.Color( 0x111111 ) - */ - specular: Color; - - /** - * @default 30 - */ - shininess: number; - - /** - * @default null - */ - map: Texture | null; - - /** - * @default null - */ - lightMap: Texture | null; - - /** - * @default null - */ - lightMapIntensity: number; - - /** - * @default null - */ - aoMap: Texture | null; - - /** - * @default null - */ - aoMapIntensity: number; - - /** - * @default new THREE.Color( 0x000000 ) - */ - emissive: Color; - - /** - * @default 1 - */ - emissiveIntensity: number; - - /** - * @default null - */ - emissiveMap: Texture | null; - - /** - * @default null - */ - bumpMap: Texture | null; - - /** - * @default 1 - */ - bumpScale: number; - - /** - * @default null - */ - normalMap: Texture | null; - - /** - * @default THREE.TangentSpaceNormalMap - */ - normalMapType: NormalMapTypes; - - /** - * @default new Vector2( 1, 1 ) - */ - normalScale: Vector2; - - /** - * @default null - */ - displacementMap: Texture | null; - - /** - * @default 1 - */ - displacementScale: number; - - /** - * @default 0 - */ - displacementBias: number; - - /** - * @default null - */ - specularMap: Texture | null; - - /** - * @default null - */ - alphaMap: Texture | null; - - /** - * @default null - */ - envMap: Texture | null; - - /** - * The rotation of the environment map in radians. Default is `(0,0,0)`. - */ - envMapRotation: Euler; - - /** - * @default THREE.MultiplyOperation - */ - combine: Combine; - - /** - * @default 1 - */ - reflectivity: number; - - /** - * @default 0.98 - */ - refractionRatio: number; - - /** - * @default false - */ - wireframe: boolean; - - /** - * @default 1 - */ - wireframeLinewidth: number; - - /** - * @default 'round' - */ - wireframeLinecap: string; - - /** - * @default 'round' - */ - wireframeLinejoin: string; - - /** - * Define whether the material is rendered with flat shading. Default is false. - * @default false - */ - flatShading: boolean; - - /** - * @deprecated Use {@link MeshStandardMaterial THREE.MeshStandardMaterial} instead. - */ - metal: boolean; - - /** - * Whether the material is affected by fog. Default is true. - * @default fog - */ - fog: boolean; - - setValues(parameters: MeshPhongMaterialParameters): void; -} diff --git a/src-testing/src/materials/MeshPhysicalMaterial.d.ts b/src-testing/src/materials/MeshPhysicalMaterial.d.ts deleted file mode 100644 index f201ad662..000000000 --- a/src-testing/src/materials/MeshPhysicalMaterial.d.ts +++ /dev/null @@ -1,231 +0,0 @@ -import { Color, ColorRepresentation } from "../math/Color.js"; -import { Vector2 } from "../math/Vector2.js"; -import { Texture } from "../textures/Texture.js"; -import { MeshStandardMaterial, MeshStandardMaterialParameters } from "./MeshStandardMaterial.js"; - -export interface MeshPhysicalMaterialParameters extends MeshStandardMaterialParameters { - anisotropyRotation?: number | undefined; - anisotropyMap?: Texture | null | undefined; - - clearcoatMap?: Texture | null | undefined; - clearcoatRoughness?: number | undefined; - clearcoatRoughnessMap?: Texture | null | undefined; - clearcoatNormalScale?: Vector2 | undefined; - clearcoatNormalMap?: Texture | null | undefined; - - ior?: number | undefined; - - reflectivity?: number | undefined; - - iridescenceMap?: Texture | null | undefined; - iridescenceIOR?: number | undefined; - iridescenceThicknessRange?: [number, number] | undefined; - iridescenceThicknessMap?: Texture | null | undefined; - - sheenColor?: ColorRepresentation | undefined; - sheenColorMap?: Texture | null | undefined; - sheenRoughness?: number | undefined; - sheenRoughnessMap?: Texture | null | undefined; - - transmissionMap?: Texture | null | undefined; - - thickness?: number | undefined; - thicknessMap?: Texture | null | undefined; - attenuationDistance?: number | undefined; - attenuationColor?: ColorRepresentation | undefined; - - specularIntensity?: number | undefined; - specularIntensityMap?: Texture | null | undefined; - specularColor?: ColorRepresentation | undefined; - specularColorMap?: Texture | null | undefined; - - anisotropy?: number | undefined; - clearcoat?: number | undefined; - iridescence?: number | undefined; - dispersion?: number | undefined; - sheen?: number | undefined; - transmission?: number | undefined; -} - -export class MeshPhysicalMaterial extends MeshStandardMaterial { - constructor(parameters?: MeshPhysicalMaterialParameters); - - /** - * Read-only flag to check if a given object is of type {@link MeshPhysicalMaterial}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isMeshPhysicalMaterial: true; - - /** - * @default { 'STANDARD': '', 'PHYSICAL': '' } - */ - defines: { [key: string]: any }; - - /** - * @default 0 - */ - anisotropyRotation?: number; - - /** - * @default null - */ - anisotropyMap?: Texture | null; - - /** - * @default null - */ - clearcoatMap: Texture | null; - - /** - * @default 0 - */ - clearcoatRoughness: number; - - /** - * @default null - */ - clearcoatRoughnessMap: Texture | null; - - /** - * @default new THREE.Vector2( 1, 1 ) - */ - clearcoatNormalScale: Vector2; - - /** - * @default null - */ - clearcoatNormalMap: Texture | null; - - /** - * @default 1.5 - */ - ior: number; - - /** - * @default 0.5 - */ - get reflectivity(): number; - set reflectivity(reflectivity: number); - - /** - * @default null - */ - iridescenceMap: Texture | null; - - /** - * @default 1.3 - */ - iridescenceIOR: number; - - /** - * @default [100, 400] - */ - iridescenceThicknessRange: [number, number]; - - /** - * @default null - */ - iridescenceThicknessMap: Texture | null; - - /** - * @default Color( 0x000000 ) - */ - sheenColor: Color; - - /** - * @default null - */ - sheenColorMap: Texture | null; - - /** - * @default 1.0 - */ - sheenRoughness: number; - - /** - * @default null - */ - sheenRoughnessMap: Texture | null; - - /** - * @default null - */ - transmissionMap: Texture | null; - - /** - * @default 0.01 - */ - thickness: number; - - /** - * @default null - */ - thicknessMap: Texture | null; - - /** - * @default 0.0 - */ - attenuationDistance: number; - - /** - * @default Color( 1, 1, 1 ) - */ - attenuationColor: Color; - - /** - * @default 1.0 - */ - specularIntensity: number; - - /** - * @default null - */ - specularIntensityMap: Texture | null; - - /** - * @default Color(1, 1, 1) - */ - specularColor: Color; - - /** - * @default null - */ - specularColorMap: Texture | null; - - /** - * @default 0 - */ - get anisotropy(): number; - set anisotropy(value: number); - - /** - * @default 0 - */ - get clearcoat(): number; - set clearcoat(value: number); - - /** - * @default 0 - */ - get iridescence(): number; - set iridescence(value: number); - - /** - * @default 0 - */ - get dispersion(): number; - set dispersion(value: number); - - /** - * @default 0.0 - */ - get sheen(): number; - set sheen(value: number); - - /** - * @default 0 - */ - get transmission(): number; - set transmission(value: number); -} diff --git a/src-testing/src/materials/MeshStandardMaterial.d.ts b/src-testing/src/materials/MeshStandardMaterial.d.ts deleted file mode 100644 index b4493a1d7..000000000 --- a/src-testing/src/materials/MeshStandardMaterial.d.ts +++ /dev/null @@ -1,213 +0,0 @@ -import { NormalMapTypes } from "../constants.js"; -import { Color, ColorRepresentation } from "../math/Color.js"; -import { Euler } from "../math/Euler.js"; -import { Vector2 } from "../math/Vector2.js"; -import { Texture } from "../textures/Texture.js"; -import { Material, MaterialParameters } from "./Material.js"; - -export interface MeshStandardMaterialParameters extends MaterialParameters { - color?: ColorRepresentation | undefined; - roughness?: number | undefined; - metalness?: number | undefined; - map?: Texture | null | undefined; - lightMap?: Texture | null | undefined; - lightMapIntensity?: number | undefined; - aoMap?: Texture | null | undefined; - aoMapIntensity?: number | undefined; - emissive?: ColorRepresentation | undefined; - emissiveIntensity?: number | undefined; - emissiveMap?: Texture | null | undefined; - bumpMap?: Texture | null | undefined; - bumpScale?: number | undefined; - normalMap?: Texture | null | undefined; - normalMapType?: NormalMapTypes | undefined; - normalScale?: Vector2 | undefined; - displacementMap?: Texture | null | undefined; - displacementScale?: number | undefined; - displacementBias?: number | undefined; - roughnessMap?: Texture | null | undefined; - metalnessMap?: Texture | null | undefined; - alphaMap?: Texture | null | undefined; - envMap?: Texture | null | undefined; - envMapRotation?: Euler | undefined; - envMapIntensity?: number | undefined; - wireframe?: boolean | undefined; - wireframeLinewidth?: number | undefined; - fog?: boolean | undefined; - flatShading?: boolean | undefined; -} - -export class MeshStandardMaterial extends Material { - constructor(parameters?: MeshStandardMaterialParameters); - - /** - * Read-only flag to check if a given object is of type {@link MeshStandardMaterial}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isMeshStandardMaterial: true; - - /** - * @default { 'STANDARD': '' } - */ - defines: { [key: string]: any }; - - /** - * @default new THREE.Color( 0xffffff ) - */ - color: Color; - - /** - * @default 1 - */ - roughness: number; - - /** - * @default 0 - */ - metalness: number; - - /** - * @default null - */ - map: Texture | null; - - /** - * @default null - */ - lightMap: Texture | null; - - /** - * @default 1 - */ - lightMapIntensity: number; - - /** - * @default null - */ - aoMap: Texture | null; - - /** - * @default 1 - */ - aoMapIntensity: number; - - /** - * @default new THREE.Color( 0x000000 ) - */ - emissive: Color; - - /** - * @default 1 - */ - emissiveIntensity: number; - - /** - * @default null - */ - emissiveMap: Texture | null; - - /** - * @default null - */ - bumpMap: Texture | null; - - /** - * @default 1 - */ - bumpScale: number; - - /** - * @default null - */ - normalMap: Texture | null; - - /** - * @default THREE.TangentSpaceNormalMap - */ - normalMapType: NormalMapTypes; - - /** - * @default new THREE.Vector2( 1, 1 ) - */ - normalScale: Vector2; - - /** - * @default null - */ - displacementMap: Texture | null; - - /** - * @default 1 - */ - displacementScale: number; - - /** - * @default 0 - */ - displacementBias: number; - - /** - * @default null - */ - roughnessMap: Texture | null; - - /** - * @default null - */ - metalnessMap: Texture | null; - - /** - * @default null - */ - alphaMap: Texture | null; - - /** - * @default null - */ - envMap: Texture | null; - - /** - * The rotation of the environment map in radians. Default is `(0,0,0)`. - */ - envMapRotation: Euler; - - /** - * @default 1 - */ - envMapIntensity: number; - - /** - * @default false - */ - wireframe: boolean; - - /** - * @default 1 - */ - wireframeLinewidth: number; - - /** - * @default 'round' - */ - wireframeLinecap: string; - - /** - * @default 'round' - */ - wireframeLinejoin: string; - - /** - * Define whether the material is rendered with flat shading. Default is false. - * @default false - */ - flatShading: boolean; - - /** - * Whether the material is affected by fog. Default is true. - * @default fog - */ - fog: boolean; - - setValues(parameters: MeshStandardMaterialParameters): void; -} diff --git a/src-testing/src/materials/MeshToonMaterial.d.ts b/src-testing/src/materials/MeshToonMaterial.d.ts deleted file mode 100644 index 14c71b27a..000000000 --- a/src-testing/src/materials/MeshToonMaterial.d.ts +++ /dev/null @@ -1,173 +0,0 @@ -import { NormalMapTypes } from "../constants.js"; -import { Color, ColorRepresentation } from "../math/Color.js"; -import { Vector2 } from "../math/Vector2.js"; -import { Texture } from "../textures/Texture.js"; -import { Material, MaterialParameters } from "./Material.js"; - -export interface MeshToonMaterialParameters extends MaterialParameters { - /** geometry color in hexadecimal. Default is 0xffffff. */ - color?: ColorRepresentation | undefined; - opacity?: number | undefined; - gradientMap?: Texture | null | undefined; - map?: Texture | null | undefined; - lightMap?: Texture | null | undefined; - lightMapIntensity?: number | undefined; - aoMap?: Texture | null | undefined; - aoMapIntensity?: number | undefined; - emissive?: ColorRepresentation | undefined; - emissiveIntensity?: number | undefined; - emissiveMap?: Texture | null | undefined; - bumpMap?: Texture | null | undefined; - bumpScale?: number | undefined; - normalMap?: Texture | null | undefined; - normalMapType?: NormalMapTypes | undefined; - normalScale?: Vector2 | undefined; - displacementMap?: Texture | null | undefined; - displacementScale?: number | undefined; - displacementBias?: number | undefined; - alphaMap?: Texture | null | undefined; - wireframe?: boolean | undefined; - wireframeLinewidth?: number | undefined; - wireframeLinecap?: string | undefined; - wireframeLinejoin?: string | undefined; - fog?: boolean | undefined; -} - -export class MeshToonMaterial extends Material { - constructor(parameters?: MeshToonMaterialParameters); - - /** - * Read-only flag to check if a given object is of type {@link MeshToonMaterial}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isMeshToonMaterial: true; - - /** - * @default { 'TOON': '' } - */ - defines: { [key: string]: any }; - - /** - * @default new THREE.Color( 0xffffff ) - */ - color: Color; - - /** - * @default null - */ - gradientMap: Texture | null; - - /** - * @default null - */ - map: Texture | null; - - /** - * @default null - */ - lightMap: Texture | null; - - /** - * @default 1 - */ - lightMapIntensity: number; - - /** - * @default null - */ - aoMap: Texture | null; - - /** - * @default 1 - */ - aoMapIntensity: number; - - /** - * @default new THREE.Color( 0x000000 ) - */ - emissive: Color; - - /** - * @default 1 - */ - emissiveIntensity: number; - - /** - * @default null - */ - emissiveMap: Texture | null; - - /** - * @default null - */ - bumpMap: Texture | null; - - /** - * @default 1 - */ - bumpScale: number; - - /** - * @default null - */ - normalMap: Texture | null; - - /** - * @default THREE.TangentSpaceNormalMap - */ - normalMapType: NormalMapTypes; - - /** - * @default new THREE.Vector2( 1, 1 ) - */ - normalScale: Vector2; - - /** - * @default null - */ - displacementMap: Texture | null; - - /** - * @default 1 - */ - displacementScale: number; - - /** - * @default 0 - */ - displacementBias: number; - - /** - * @default null - */ - alphaMap: Texture | null; - - /** - * @default false - */ - wireframe: boolean; - - /** - * @default 1 - */ - wireframeLinewidth: number; - - /** - * @default 'round' - */ - wireframeLinecap: string; - - /** - * @default 'round' - */ - wireframeLinejoin: string; - - /** - * Whether the material is affected by fog. Default is true. - * @default fog - */ - fog: boolean; - - setValues(parameters: MeshToonMaterialParameters): void; -} diff --git a/src-testing/src/materials/PointsMaterial.d.ts b/src-testing/src/materials/PointsMaterial.d.ts deleted file mode 100644 index a47a0817b..000000000 --- a/src-testing/src/materials/PointsMaterial.d.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { Color, ColorRepresentation } from "../math/Color.js"; -import { Texture } from "../textures/Texture.js"; -import { Material, MaterialParameters } from "./Material.js"; - -export interface PointsMaterialParameters extends MaterialParameters { - color?: ColorRepresentation | undefined; - map?: Texture | null | undefined; - alphaMap?: Texture | null | undefined; - size?: number | undefined; - sizeAttenuation?: boolean | undefined; - fog?: boolean | undefined; -} - -export class PointsMaterial extends Material { - constructor(parameters?: PointsMaterialParameters); - - /** - * Read-only flag to check if a given object is of type {@link PointsMaterial}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isPointsMaterial: true; - - /** - * @default new THREE.Color( 0xffffff ) - */ - color: Color; - - /** - * @default null - */ - map: Texture | null; - - /** - * @default null - */ - alphaMap: Texture | null; - - /** - * @default 1 - */ - size: number; - - /** - * @default true - */ - sizeAttenuation: boolean; - - /** - * Whether the material is affected by fog. Default is true. - * @default fog - */ - fog: boolean; - - setValues(parameters: PointsMaterialParameters): void; -} diff --git a/src-testing/src/materials/RawShaderMaterial.d.ts b/src-testing/src/materials/RawShaderMaterial.d.ts deleted file mode 100644 index 6ff6b67f0..000000000 --- a/src-testing/src/materials/RawShaderMaterial.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { ShaderMaterial, ShaderMaterialParameters } from "./ShaderMaterial.js"; - -export class RawShaderMaterial extends ShaderMaterial { - constructor(parameters?: ShaderMaterialParameters); - - /** - * Read-only flag to check if a given object is of type {@link RawShaderMaterial}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isRawShaderMaterial: true; -} diff --git a/src-testing/src/materials/ShaderMaterial.d.ts b/src-testing/src/materials/ShaderMaterial.d.ts deleted file mode 100644 index 53e07a821..000000000 --- a/src-testing/src/materials/ShaderMaterial.d.ts +++ /dev/null @@ -1,162 +0,0 @@ -import { GLSLVersion } from "../constants.js"; -import { JSONMeta } from "../core/Object3D.js"; -import { UniformsGroup } from "../core/UniformsGroup.js"; -import { Matrix3, Matrix3Tuple } from "../math/Matrix3.js"; -import { Matrix4, Matrix4Tuple } from "../math/Matrix4.js"; -import { Vector2Tuple } from "../math/Vector2.js"; -import { Vector3Tuple } from "../math/Vector3.js"; -import { Vector4Tuple } from "../math/Vector4.js"; -import { IUniform } from "../renderers/shaders/UniformsLib.js"; -import { Material, MaterialJSON, MaterialParameters } from "./Material.js"; - -export interface ShaderMaterialParameters extends MaterialParameters { - uniforms?: { [uniform: string]: IUniform } | undefined; - uniformsGroups?: UniformsGroup[] | undefined; - vertexShader?: string | undefined; - fragmentShader?: string | undefined; - linewidth?: number | undefined; - wireframe?: boolean | undefined; - wireframeLinewidth?: number | undefined; - lights?: boolean | undefined; - clipping?: boolean | undefined; - fog?: boolean | undefined; - extensions?: - | { - clipCullDistance?: boolean | undefined; - multiDraw?: boolean | undefined; - } - | undefined; - glslVersion?: GLSLVersion | undefined; -} - -export type ShaderMaterialUniformJSON = { - type: "t"; - value: string; -} | { - type: "c"; - value: number; -} | { - type: "v2"; - value: Vector2Tuple; -} | { - type: "v3"; - value: Vector3Tuple; -} | { - type: "v4"; - value: Vector4Tuple; -} | { - type: "m3"; - value: Matrix3Tuple; -} | { - type: "m4"; - value: Matrix4Tuple; -} | { - value: unknown; -}; - -export interface ShaderMaterialJSON extends MaterialJSON { - glslVersion: number | null; - uniforms: Record; - - defines?: Record; - - vertexShader: string; - ragmentShader: string; - - lights: boolean; - clipping: boolean; - - extensions?: Record; -} - -export class ShaderMaterial extends Material { - constructor(parameters?: ShaderMaterialParameters); - - /** - * Read-only flag to check if a given object is of type {@link ShaderMaterial}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isShaderMaterial: true; - - /** - * @default {} - */ - defines: { [key: string]: any }; - - /** - * @default {} - */ - uniforms: { [uniform: string]: IUniform }; - - uniformsGroups: UniformsGroup[]; - - vertexShader: string; - - fragmentShader: string; - - /** - * @default 1 - */ - linewidth: number; - - /** - * @default false - */ - wireframe: boolean; - - /** - * @default 1 - */ - wireframeLinewidth: number; - - /** - * @default false - */ - fog: boolean; - - /** - * @default false - */ - lights: boolean; - - /** - * @default false - */ - clipping: boolean; - - /** - * @default { - * clipCullDistance: false, - * multiDraw: false - * } - */ - extensions: { - clipCullDistance: boolean; - multiDraw: boolean; - }; - - /** - * @default { 'color': [ 1, 1, 1 ], 'uv': [ 0, 0 ], 'uv1': [ 0, 0 ] } - */ - defaultAttributeValues: any; - - /** - * @default undefined - */ - index0AttributeName: string | undefined; - - /** - * @default false - */ - uniformsNeedUpdate: boolean; - - /** - * @default null - */ - glslVersion: GLSLVersion | null; - - setValues(parameters: ShaderMaterialParameters): void; - - toJSON(meta?: JSONMeta): ShaderMaterialJSON; -} diff --git a/src-testing/src/materials/ShadowMaterial.d.ts b/src-testing/src/materials/ShadowMaterial.d.ts deleted file mode 100644 index fc7a7ae06..000000000 --- a/src-testing/src/materials/ShadowMaterial.d.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { Color, ColorRepresentation } from "../math/Color.js"; -import { Material, MaterialParameters } from "./Material.js"; - -export interface ShadowMaterialParameters extends MaterialParameters { - color?: ColorRepresentation | undefined; - fog?: boolean | undefined; -} - -export class ShadowMaterial extends Material { - constructor(parameters?: ShadowMaterialParameters); - - /** - * Read-only flag to check if a given object is of type {@link ShadowMaterial}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isShadowMaterial: true; - - /** - * @default new THREE.Color( 0x000000 ) - */ - color: Color; - - /** - * @default true - */ - transparent: boolean; - - /** - * Whether the material is affected by fog. Default is true. - * @default fog - */ - fog: boolean; -} diff --git a/src-testing/src/materials/SpriteMaterial.d.ts b/src-testing/src/materials/SpriteMaterial.d.ts deleted file mode 100644 index 4fa5db8a0..000000000 --- a/src-testing/src/materials/SpriteMaterial.d.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { Color, ColorRepresentation } from "../math/Color.js"; -import { Texture } from "../textures/Texture.js"; -import { Material, MaterialParameters } from "./Material.js"; - -export interface SpriteMaterialParameters extends MaterialParameters { - color?: ColorRepresentation | undefined; - map?: Texture | null | undefined; - alphaMap?: Texture | null | undefined; - rotation?: number | undefined; - sizeAttenuation?: boolean | undefined; - fog?: boolean | undefined; -} - -export class SpriteMaterial extends Material { - constructor(parameters?: SpriteMaterialParameters); - /** - * Read-only flag to check if a given object is of type {@link SpriteMaterial}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isSpriteMaterial: true; - - /** - * @default new THREE.Color( 0xffffff ) - */ - color: Color; - - /** - * @default null - */ - map: Texture | null; - - /** - * @default null - */ - alphaMap: Texture | null; - - /** - * @default 0 - */ - rotation: number; - - /** - * @default true - */ - sizeAttenuation: boolean; - - /** - * @default true - */ - transparent: boolean; - - /** - * Whether the material is affected by fog. Default is true. - * @default fog - */ - fog: boolean; - - setValues(parameters: SpriteMaterialParameters): void; - copy(source: SpriteMaterial): this; -} diff --git a/src-testing/src/materials/nodes/InstancedPointsNodeMaterial.d.ts b/src-testing/src/materials/nodes/InstancedPointsNodeMaterial.d.ts deleted file mode 100644 index 9784e7f52..000000000 --- a/src-testing/src/materials/nodes/InstancedPointsNodeMaterial.d.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { Color } from "../../math/Color.js"; -import Node from "../../nodes/core/Node.js"; -import { Texture } from "../../textures/Texture.js"; -import { PointsMaterialParameters } from "../PointsMaterial.js"; -import NodeMaterial, { NodeMaterialParameters } from "./NodeMaterial.js"; - -export interface InstancedPointsNodeMaterialParameters extends NodeMaterialParameters, PointsMaterialParameters { - useAlphaToCoverage?: boolean | undefined; - useColor?: boolean | undefined; - pointWidth?: number | undefined; - pointColorNode?: Node | null | undefined; - pointWidthNode?: Node | null | undefined; -} - -declare class InstancedPointsNodeMaterial extends NodeMaterial { - useAlphaToCoverage: boolean; - useColor: boolean | undefined; - pointWidth: number; - pointColorNode: Node | null; - pointWidthNode: Node | null; - - // Properties from LineDashedMaterial - readonly isPointsMaterial: true; - color: Color; - map: Texture | null; - alphaMap: Texture | null; - size: number; - sizeAttenuation: boolean; - - constructor(params?: InstancedPointsNodeMaterialParameters); -} - -export default InstancedPointsNodeMaterial; diff --git a/src-testing/src/materials/nodes/Line2NodeMaterial.d.ts b/src-testing/src/materials/nodes/Line2NodeMaterial.d.ts deleted file mode 100644 index 13c65ffd6..000000000 --- a/src-testing/src/materials/nodes/Line2NodeMaterial.d.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { Color } from "../../math/Color.js"; -import Node from "../../nodes/core/Node.js"; -import { Texture } from "../../textures/Texture.js"; -import { LineDashedMaterialParameters } from "../LineDashedMaterial.js"; -import NodeMaterial, { NodeMaterialParameters } from "./NodeMaterial.js"; - -export interface Line2NodeMaterialParameters extends NodeMaterialParameters, LineDashedMaterialParameters { - dashed?: boolean | undefined; -} - -export default class Line2NodeMaterial extends NodeMaterial { - lights: boolean; - - // Properties from LineDashedMaterial - readonly isLineDashedMaterial: true; - scale: number; - dashSize: number; - gapSize: number; - - // Properties from LineBasicMaterial - readonly isLineBasicMaterial: true; - color: Color; - fog: boolean; - linewidth: number; - linecap: string; - linejoin: string; - map: Texture | null; - - useAlphaToCoverage: boolean; - useColor: boolean; - useDash: boolean; - useWorldUnits: boolean; - - dashOffset: number; - lineWidth: number; - - lineColorNode: Node | null; - - offsetNode: Node | null; - dashScaleNode: Node | null; - dashSizeNode: Node | null; - gapSizeNode: Node | null; - - constructor(parameters?: Line2NodeMaterialParameters); - - setupShaders(): void; - - get worldUnits(): boolean; - set worldUnits(value: boolean); - - get dashed(): boolean; - set dashed(value: boolean); -} diff --git a/src-testing/src/materials/nodes/LineBasicNodeMaterial.d.ts b/src-testing/src/materials/nodes/LineBasicNodeMaterial.d.ts deleted file mode 100644 index 84b8db897..000000000 --- a/src-testing/src/materials/nodes/LineBasicNodeMaterial.d.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Color } from "../../math/Color.js"; -import { Texture } from "../../textures/Texture.js"; -import { LineBasicMaterialParameters } from "../LineBasicMaterial.js"; -import NodeMaterial, { NodeMaterialParameters } from "./NodeMaterial.js"; - -export interface LineBasicNodeMaterialParameters extends NodeMaterialParameters, LineBasicMaterialParameters { -} - -export default class LineBasicNodeMaterial extends NodeMaterial { - readonly isLineBasicNodeMaterial: true; - - // Properties from LineBasicMaterial - readonly isLineBasicMaterial: true; - color: Color; - fog: boolean; - linewidth: number; - linecap: string; - linejoin: string; - map: Texture | null; - - constructor(parameters?: LineBasicNodeMaterialParameters); -} diff --git a/src-testing/src/materials/nodes/LineDashedNodeMaterial.d.ts b/src-testing/src/materials/nodes/LineDashedNodeMaterial.d.ts deleted file mode 100644 index 10715e2cd..000000000 --- a/src-testing/src/materials/nodes/LineDashedNodeMaterial.d.ts +++ /dev/null @@ -1,29 +0,0 @@ -import Node from "../../nodes/core/Node.js"; -import { LineDashedMaterialParameters } from "../LineDashedMaterial.js"; -import NodeMaterial, { NodeMaterialParameters } from "./NodeMaterial.js"; - -export interface LineDashedNodeMaterialParameters extends NodeMaterialParameters, LineDashedMaterialParameters { - offsetNode?: Node | null | undefined; - dashScaleNode?: Node | null | undefined; - dashSizeNode?: Node | null | undefined; - gapSizeNode?: Node | null | undefined; -} - -declare class LineDashedNodeMaterial extends NodeMaterial { - readonly isLineDashedNodeMaterial: true; - - offsetNode: Node | null; - dashScaleNode: Node | null; - dashSizeNode: Node | null; - gapSizeNode: Node | null; - - // Properties from LineDashedMaterial - readonly isLineDashedMaterial: true; - scale: number; - dashSize: number; - gapSize: number; - - constructor(parameters?: LineDashedMaterialParameters); -} - -export default LineDashedNodeMaterial; diff --git a/src-testing/src/materials/nodes/MeshBasicNodeMaterial.d.ts b/src-testing/src/materials/nodes/MeshBasicNodeMaterial.d.ts deleted file mode 100644 index 515fa5f67..000000000 --- a/src-testing/src/materials/nodes/MeshBasicNodeMaterial.d.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { Combine } from "../../constants.js"; -import { Color } from "../../math/Color.js"; -import { Euler } from "../../math/Euler.js"; -import { Texture } from "../../textures/Texture.js"; -import { MeshBasicMaterialParameters } from "../MeshBasicMaterial.js"; -import NodeMaterial, { NodeMaterialParameters } from "./NodeMaterial.js"; - -export interface MeshBasicNodeMaterialParameters extends NodeMaterialParameters, MeshBasicMaterialParameters { -} - -export default class MeshBasicNodeMaterial extends NodeMaterial { - readonly isMeshBasicNodeMaterial: true; - - // Properties from MeshBasicMaterial - readonly isMeshBasicMaterial: true; - color: Color; - map: Texture | null; - lightMap: Texture | null; - lightMapIntensity: number; - aoMap: Texture | null; - aoMapIntensity: number; - specularMap: Texture | null; - alphaMap: Texture | null; - envMap: Texture | null; - envMapRotation: Euler; - combine: Combine; - reflectivity: number; - refractionRatio: number; - wireframe: boolean; - wireframeLinewidth: number; - wireframeLinecap: string; - wireframeLinejoin: string; - fog: boolean; - - constructor(parameters?: MeshBasicNodeMaterialParameters); -} diff --git a/src-testing/src/materials/nodes/MeshLambertNodeMaterial.d.ts b/src-testing/src/materials/nodes/MeshLambertNodeMaterial.d.ts deleted file mode 100644 index aedda10a7..000000000 --- a/src-testing/src/materials/nodes/MeshLambertNodeMaterial.d.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { Combine, NormalMapTypes } from "../../constants.js"; -import { Color } from "../../math/Color.js"; -import { Euler } from "../../math/Euler.js"; -import { Vector2 } from "../../math/Vector2.js"; -import { Texture } from "../../textures/Texture.js"; -import { MeshLambertMaterialParameters } from "../MeshLambertMaterial.js"; -import NodeMaterial, { NodeMaterialParameters } from "./NodeMaterial.js"; - -export interface MeshLambertNodeMaterialParameters extends NodeMaterialParameters, MeshLambertMaterialParameters {} - -declare class MeshLambertNodeMaterial extends NodeMaterial { - readonly isMeshLambertNodeMaterial: true; - - // Properties from MeshLambertMaterial - readonly isMeshLambertMaterial: true; - color: Color; - bumpMap: Texture | null; - bumpScale: number; - displacementMap: Texture | null; - displacementScale: number; - displacementBias: number; - emissive: Color; - emissiveIntensity: number; - emissiveMap: Texture | null; - flatShading: boolean; - map: Texture | null; - lightMap: Texture | null; - lightMapIntensity: number; - normalMap: Texture | null; - normalMapType: NormalMapTypes; - normalScale: Vector2; - aoMap: Texture | null; - aoMapIntensity: number; - specularMap: Texture | null; - alphaMap: Texture | null; - envMap: Texture | null; - envMapRotation: Euler; - combine: Combine; - reflectivity: number; - refractionRatio: number; - wireframe: boolean; - wireframeLinewidth: number; - wireframeLinecap: string; - wireframeLinejoin: string; - - constructor(parameters?: MeshLambertNodeMaterialParameters); -} - -export default MeshLambertNodeMaterial; diff --git a/src-testing/src/materials/nodes/MeshMatcapNodeMaterial.d.ts b/src-testing/src/materials/nodes/MeshMatcapNodeMaterial.d.ts deleted file mode 100644 index cc0d2f9a0..000000000 --- a/src-testing/src/materials/nodes/MeshMatcapNodeMaterial.d.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { NormalMapTypes } from "../../constants.js"; -import { Color } from "../../math/Color.js"; -import { Vector2 } from "../../math/Vector2.js"; -import { Texture } from "../../textures/Texture.js"; -import { MeshMatcapMaterialParameters } from "../MeshMatcapMaterial.js"; -import NodeMaterial, { NodeMaterialParameters } from "./NodeMaterial.js"; - -export interface MeshMatcapNodeMaterialParameters extends NodeMaterialParameters, MeshMatcapMaterialParameters { -} - -export default class MeshMatcapNodeMaterial extends NodeMaterial { - readonly isMeshMatcapNodeMaterial: true; - - // Properties from MeshMatcapMaterial - readonly isMeshMatcapMaterial: true; - color: Color; - matcap: Texture | null; - map: Texture | null; - bumpMap: Texture | null; - bumpScale: number; - normalMap: Texture | null; - normalMapType: NormalMapTypes; - normalScale: Vector2; - displacementMap: Texture | null; - displacementScale: number; - displacementBias: number; - alphaMap: Texture | null; - flatShading: boolean; - fog: boolean; - - constructor(parameters?: MeshMatcapNodeMaterialParameters); -} diff --git a/src-testing/src/materials/nodes/MeshNormalNodeMaterial.d.ts b/src-testing/src/materials/nodes/MeshNormalNodeMaterial.d.ts deleted file mode 100644 index 761998bac..000000000 --- a/src-testing/src/materials/nodes/MeshNormalNodeMaterial.d.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { NormalMapTypes } from "../../constants.js"; -import { Vector2 } from "../../math/Vector2.js"; -import { Texture } from "../../textures/Texture.js"; -import { MeshNormalMaterialParameters } from "../MeshNormalMaterial.js"; -import NodeMaterial, { NodeMaterialParameters } from "./NodeMaterial.js"; - -export interface MeshBasicNodeMaterialParameters extends NodeMaterialParameters, MeshNormalMaterialParameters { -} - -export default class MeshNormalNodeMaterial extends NodeMaterial { - readonly isMeshNormalNodeMaterial: true; - - // Properties from MeshNormalMaterial - readonly isMeshNormalMaterial: true; - bumpMap: Texture | null; - bumpScale: number; - normalMap: Texture | null; - normalMapType: NormalMapTypes; - normalScale: Vector2; - displacementMap: Texture | null; - displacementScale: number; - displacementBias: number; - wireframe: boolean; - wireframeLinewidth: number; - flatShading: boolean; - - constructor(parameters?: MeshBasicNodeMaterialParameters); -} diff --git a/src-testing/src/materials/nodes/MeshPhongNodeMaterial.d.ts b/src-testing/src/materials/nodes/MeshPhongNodeMaterial.d.ts deleted file mode 100644 index 3680e533c..000000000 --- a/src-testing/src/materials/nodes/MeshPhongNodeMaterial.d.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { Combine, NormalMapTypes } from "../../constants.js"; -import { Color } from "../../math/Color.js"; -import { Euler } from "../../math/Euler.js"; -import { Vector2 } from "../../math/Vector2.js"; -import Node from "../../nodes/core/Node.js"; -import { Texture } from "../../textures/Texture.js"; -import { MeshPhongMaterialParameters } from "../MeshPhongMaterial.js"; -import NodeMaterial, { NodeMaterialParameters } from "./NodeMaterial.js"; - -export interface MeshPhongNodeMaterialParameters extends NodeMaterialParameters, MeshPhongMaterialParameters { -} - -export default class MeshPhongNodeMaterial extends NodeMaterial { - readonly isMeshPhongNodeMaterial: true; - - shininessNode: Node | null; - specularNode: Node | null; - - // Properties from MeshPhongMaterial - readonly isMeshPhongMaterial: true; - color: Color; - specular: Color; - shininess: number; - map: Texture | null; - lightMap: Texture | null; - lightMapIntensity: number; - aoMap: Texture | null; - aoMapIntensity: number; - emissive: Color; - emissiveIntensity: number; - emissiveMap: Texture | null; - bumpMap: Texture | null; - bumpScale: number; - normalMap: Texture | null; - normalMapType: NormalMapTypes; - normalScale: Vector2; - displacementMap: Texture | null; - displacementScale: number; - displacementBias: number; - specularMap: Texture | null; - alphaMap: Texture | null; - envMap: Texture | null; - envMapRotation: Euler; - combine: Combine; - reflectivity: number; - refractionRatio: number; - wireframe: boolean; - wireframeLinewidth: number; - wireframeLinecap: string; - wireframeLinejoin: string; - flatShading: boolean; - metal: boolean; - fog: boolean; - - constructor(parameters?: MeshPhongNodeMaterialParameters); -} diff --git a/src-testing/src/materials/nodes/MeshPhysicalNodeMaterial.d.ts b/src-testing/src/materials/nodes/MeshPhysicalNodeMaterial.d.ts deleted file mode 100644 index e7da3ee90..000000000 --- a/src-testing/src/materials/nodes/MeshPhysicalNodeMaterial.d.ts +++ /dev/null @@ -1,93 +0,0 @@ -import { Color } from "../../math/Color.js"; -import { Vector2 } from "../../math/Vector2.js"; -import Node from "../../nodes/core/Node.js"; -import { ShaderNodeObject } from "../../nodes/tsl/TSLCore.js"; -import { Texture } from "../../textures/Texture.js"; -import { MeshPhysicalMaterialParameters } from "../MeshPhysicalMaterial.js"; -import MeshStandardNodeMaterial, { MeshStandardNodeMaterialParameters } from "./MeshStandardNodeMaterial.js"; - -export interface MeshPhysicalNodeMaterialParameters - extends MeshStandardNodeMaterialParameters, MeshPhysicalMaterialParameters -{ -} - -export default class MeshPhysicalNodeMaterial extends MeshStandardNodeMaterial { - readonly isMeshPhysicalNodeMaterial: true; - - clearcoatNode: Node | null; - clearcoatRoughnessNode: Node | null; - clearcoatNormalNode: Node | null; - - sheenNode: Node | null; - sheenRoughnessNode: Node | null; - - iridescenceNode: Node | null; - iridescenceIORNode: Node | null; - iridescenceThicknessNode: Node | null; - - iorNode: Node | null; - - specularIntensityNode: Node | null; - specularColorNode: Node | null; - - transmissionNode: Node | null; - thicknessNode: Node | null; - attenuationDistanceNode: Node | null; - attenuationColorNode: Node | null; - dispersionNode: Node | null; - - anisotropyNode: Node | null; - - // Properties from MeshPhysicalMaterial - readonly isMeshPhysicalMaterial: true; - anisotropyRotation: number; - anisotropyMap: Texture | null; - clearcoatMap: Texture | null; - clearcoatRoughness: number; - clearcoatRoughnessMap: Texture | null; - clearcoatNormalScale: Vector2; - clearcoatNormalMap: Texture | null; - ior: number; - get reflectivity(): number; - set reflectivity(reflectivity: number); - iridescenceMap: Texture | null; - iridescenceIOR: number; - iridescenceThicknessRange: [number, number]; - iridescenceThicknessMap: Texture | null; - sheenColor: Color; - sheenColorMap: Texture | null; - sheenRoughness: number; - sheenRoughnessMap: Texture | null; - transmissionMap: Texture | null; - thickness: number; - thicknessMap: Texture | null; - attenuationDistance: number; - attenuationColor: Color; - specularIntensity: number; - specularIntensityMap: Texture | null; - specularColor: Color; - specularColorMap: Texture | null; - get anisotropy(): number; - set anisotropy(value: number); - get clearcoat(): number; - set clearcoat(value: number); - get iridescence(): number; - set iridescence(value: number); - get dispersion(): number; - set dispersion(value: number); - get sheen(): number; - set sheen(value: number); - get transmission(): number; - set transmission(value: number); - - constructor(parameters?: MeshPhysicalNodeMaterialParameters); - - get useClearcoat(): boolean; - get useIridescence(): boolean; - get useSheen(): boolean; - get useAnisotropy(): boolean; - get useTransmission(): boolean; - get useDispersion(): boolean; - - setupClearcoatNormal(): ShaderNodeObject; -} diff --git a/src-testing/src/materials/nodes/MeshSSSNodeMaterial.d.ts b/src-testing/src/materials/nodes/MeshSSSNodeMaterial.d.ts deleted file mode 100644 index bccbec30c..000000000 --- a/src-testing/src/materials/nodes/MeshSSSNodeMaterial.d.ts +++ /dev/null @@ -1,16 +0,0 @@ -import ConstNode from "../../nodes/core/ConstNode.js"; -import Node from "../../nodes/core/Node.js"; -import MeshPhysicalNodeMaterial, { MeshPhysicalNodeMaterialParameters } from "./MeshPhysicalNodeMaterial.js"; - -export default class MeshSSSNodeMaterial extends MeshPhysicalNodeMaterial { - thicknessColorNode: Node | null; - thicknessDistortionNode: ConstNode; - thicknessAmbientNode: ConstNode; - thicknessAttenuationNode: ConstNode; - thicknessPowerNode: ConstNode; - thicknessScaleNode: ConstNode; - - constructor(parameters?: MeshPhysicalNodeMaterialParameters); - - get useSSS(): boolean; -} diff --git a/src-testing/src/materials/nodes/MeshStandardNodeMaterial.d.ts b/src-testing/src/materials/nodes/MeshStandardNodeMaterial.d.ts deleted file mode 100644 index 9c3329042..000000000 --- a/src-testing/src/materials/nodes/MeshStandardNodeMaterial.d.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { NormalMapTypes } from "../../constants.js"; -import { Color } from "../../math/Color.js"; -import { Euler } from "../../math/Euler.js"; -import { Vector2 } from "../../math/Vector2.js"; -import Node from "../../nodes/core/Node.js"; -import { Texture } from "../../textures/Texture.js"; -import { MeshStandardMaterialParameters } from "../MeshStandardMaterial.js"; -import NodeMaterial, { NodeMaterialParameters } from "./NodeMaterial.js"; - -export interface MeshStandardNodeMaterialParameters extends NodeMaterialParameters, MeshStandardMaterialParameters { -} - -export default class MeshStandardNodeMaterial extends NodeMaterial { - readonly isMeshStandardNodeMaterial: true; - - emissiveNode: Node | null; - - metalnessNode: Node | null; - roughnessNode: Node | null; - - // Properties from MeshStandardMaterial - readonly isMeshStandardMaterial: true; - color: Color; - roughness: number; - metalness: number; - map: Texture | null; - lightMap: Texture | null; - lightMapIntensity: number; - aoMap: Texture | null; - aoMapIntensity: number; - emissive: Color; - emissiveIntensity: number; - emissiveMap: Texture | null; - bumpMap: Texture | null; - bumpScale: number; - normalMap: Texture | null; - normalMapType: NormalMapTypes; - normalScale: Vector2; - displacementMap: Texture | null; - displacementScale: number; - displacementBias: number; - roughnessMap: Texture | null; - metalnessMap: Texture | null; - alphaMap: Texture | null; - envMap: Texture | null; - envMapRotation: Euler; - envMapIntensity: number; - wireframe: boolean; - wireframeLinewidth: number; - wireframeLinecap: string; - wireframeLinejoin: string; - flatShading: boolean; - fog: boolean; - - constructor(parameters?: MeshStandardNodeMaterialParameters); -} diff --git a/src-testing/src/materials/nodes/MeshToonNodeMaterial.d.ts b/src-testing/src/materials/nodes/MeshToonNodeMaterial.d.ts deleted file mode 100644 index e1dee0fb3..000000000 --- a/src-testing/src/materials/nodes/MeshToonNodeMaterial.d.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { NormalMapTypes } from "../../constants.js"; -import { Color } from "../../math/Color.js"; -import { Vector2 } from "../../math/Vector2.js"; -import { Texture } from "../../textures/Texture.js"; -import { MeshToonMaterialParameters } from "../MeshToonMaterial.js"; -import NodeMaterial, { NodeMaterialParameters } from "./NodeMaterial.js"; - -export interface MeshToonNodeMaterialParameters extends NodeMaterialParameters, MeshToonMaterialParameters { -} - -export default class MeshToonNodeMaterial extends NodeMaterial { - readonly isMeshToonNodeMaterial: true; - - // Properties from MeshToonMaterial - readonly isMeshToonMaterial: true; - color: Color; - gradientMap: Texture | null; - map: Texture | null; - lightMap: Texture | null; - lightMapIntensity: number; - aoMap: Texture | null; - aoMapIntensity: number; - emissive: Color; - emissiveIntensity: number; - emissiveMap: Texture | null; - bumpMap: Texture | null; - bumpScale: number; - normalMap: Texture | null; - normalMapType: NormalMapTypes; - normalScale: Vector2; - displacementMap: Texture | null; - displacementScale: number; - displacementBias: number; - alphaMap: Texture | null; - wireframe: boolean; - wireframeLinewidth: number; - wireframeLinecap: string; - wireframeLinejoin: string; - fog: boolean; - - constructor(parameters?: MeshToonNodeMaterialParameters); -} diff --git a/src-testing/src/materials/nodes/NodeMaterial.ts b/src-testing/src/materials/nodes/NodeMaterial.ts deleted file mode 100644 index 3c77c74e6..000000000 --- a/src-testing/src/materials/nodes/NodeMaterial.ts +++ /dev/null @@ -1,535 +0,0 @@ -import { Material } from '../Material.js'; -import { NormalBlending } from '../../constants.js'; - -import { getNodeChildren, getCacheKey } from '../../nodes/core/NodeUtils.js'; -import { attribute } from '../../nodes/core/AttributeNode.js'; -import { output, diffuseColor, emissive, varyingProperty } from '../../nodes/core/PropertyNode.js'; -import { - materialAlphaTest, - materialColor, - materialOpacity, - materialEmissive, - materialNormal, - materialLightMap, - materialAOMap, -} from '../../nodes/accessors/MaterialNode.js'; -import { modelViewProjection } from '../../nodes/accessors/ModelViewProjectionNode.js'; -import { normalLocal } from '../../nodes/accessors/Normal.js'; -import { instance } from '../../nodes/accessors/InstanceNode.js'; -import { batch } from '../../nodes/accessors/BatchNode.js'; -import { materialReference } from '../../nodes/accessors/MaterialReferenceNode.js'; -import { positionLocal, positionView } from '../../nodes/accessors/Position.js'; -import { skinningReference } from '../../nodes/accessors/SkinningNode.js'; -import { morphReference } from '../../nodes/accessors/MorphNode.js'; -import { mix } from '../../nodes/math/MathNode.js'; -import { float, vec3, vec4 } from '../../nodes/tsl/TSLBase.js'; -import AONode from '../../nodes/lighting/AONode.js'; -import { lightingContext } from '../../nodes/lighting/LightingContextNode.js'; -import IrradianceNode from '../../nodes/lighting/IrradianceNode.js'; -import { - depth, - perspectiveDepthToLogarithmicDepth, - viewZToOrthographicDepth, -} from '../../nodes/display/ViewportDepthNode.js'; -import { cameraFar, cameraNear } from '../../nodes/accessors/Camera.js'; -import { clipping, clippingAlpha } from '../../nodes/accessors/ClippingNode.js'; -import NodeMaterialObserver from './manager/NodeMaterialObserver.js'; - -class NodeMaterial extends Material { - static get type() { - return 'NodeMaterial'; - } - - constructor() { - super(); - - this.isNodeMaterial = true; - - this.type = this.constructor.type; - - this.forceSinglePass = false; - - this.fog = true; - this.lights = false; - - this.lightsNode = null; - this.envNode = null; - this.aoNode = null; - - this.colorNode = null; - this.normalNode = null; - this.opacityNode = null; - this.backdropNode = null; - this.backdropAlphaNode = null; - this.alphaTestNode = null; - - this.positionNode = null; - this.geometryNode = null; - - this.depthNode = null; - this.shadowNode = null; - this.shadowPositionNode = null; - - this.outputNode = null; - this.mrtNode = null; - - this.fragmentNode = null; - this.vertexNode = null; - } - - customProgramCacheKey() { - return this.type + getCacheKey(this); - } - - build(builder) { - this.setup(builder); - } - - setupObserver(builder) { - return new NodeMaterialObserver(builder); - } - - setup(builder) { - builder.context.setupNormal = () => this.setupNormal(builder); - - // < VERTEX STAGE > - - builder.addStack(); - - builder.stack.outputNode = this.vertexNode || this.setupPosition(builder); - - if (this.geometryNode !== null) { - builder.stack.outputNode = builder.stack.outputNode.bypass(this.geometryNode); - } - - builder.addFlow('vertex', builder.removeStack()); - - // < FRAGMENT STAGE > - - builder.addStack(); - - let resultNode; - - const clippingNode = this.setupClipping(builder); - - if (this.depthWrite === true) this.setupDepth(builder); - - if (this.fragmentNode === null) { - this.setupDiffuseColor(builder); - this.setupVariants(builder); - - const outgoingLightNode = this.setupLighting(builder); - - if (clippingNode !== null) builder.stack.add(clippingNode); - - // force unsigned floats - useful for RenderTargets - - const basicOutput = vec4(outgoingLightNode, diffuseColor.a).max(0); - - resultNode = this.setupOutput(builder, basicOutput); - - // OUTPUT NODE - - output.assign(resultNode); - - // - - if (this.outputNode !== null) resultNode = this.outputNode; - - // MRT - - const renderTarget = builder.renderer.getRenderTarget(); - - if (renderTarget !== null) { - const mrt = builder.renderer.getMRT(); - const materialMRT = this.mrtNode; - - if (mrt !== null) { - resultNode = mrt; - - if (materialMRT !== null) { - resultNode = mrt.merge(materialMRT); - } - } else if (materialMRT !== null) { - resultNode = materialMRT; - } - } - } else { - let fragmentNode = this.fragmentNode; - - if (fragmentNode.isOutputStructNode !== true) { - fragmentNode = vec4(fragmentNode); - } - - resultNode = this.setupOutput(builder, fragmentNode); - } - - builder.stack.outputNode = resultNode; - - builder.addFlow('fragment', builder.removeStack()); - - // < MONITOR > - - builder.monitor = this.setupObserver(builder); - } - - setupClipping(builder) { - if (builder.clippingContext === null) return null; - - const { globalClippingCount, localClippingCount } = builder.clippingContext; - - let result = null; - - if (globalClippingCount || localClippingCount) { - const samples = builder.renderer.samples; - - if (this.alphaToCoverage && samples > 1) { - // to be added to flow when the color/alpha value has been determined - result = clippingAlpha(); - } else { - builder.stack.add(clipping()); - } - } - - return result; - } - - setupDepth(builder) { - const { renderer, camera } = builder; - - // Depth - - let depthNode = this.depthNode; - - if (depthNode === null) { - const mrt = renderer.getMRT(); - - if (mrt && mrt.has('depth')) { - depthNode = mrt.get('depth'); - } else if (renderer.logarithmicDepthBuffer === true) { - if (camera.isPerspectiveCamera) { - depthNode = perspectiveDepthToLogarithmicDepth(modelViewProjection().w, cameraNear, cameraFar); - } else { - depthNode = viewZToOrthographicDepth(positionView.z, cameraNear, cameraFar); - } - } - } - - if (depthNode !== null) { - depth.assign(depthNode).append(); - } - } - - setupPosition(builder) { - const { object } = builder; - const geometry = object.geometry; - - builder.addStack(); - - // Vertex - - if (geometry.morphAttributes.position || geometry.morphAttributes.normal || geometry.morphAttributes.color) { - morphReference(object).append(); - } - - if (object.isSkinnedMesh === true) { - skinningReference(object).append(); - } - - if (this.displacementMap) { - const displacementMap = materialReference('displacementMap', 'texture'); - const displacementScale = materialReference('displacementScale', 'float'); - const displacementBias = materialReference('displacementBias', 'float'); - - positionLocal.addAssign( - normalLocal.normalize().mul(displacementMap.x.mul(displacementScale).add(displacementBias)), - ); - } - - if (object.isBatchedMesh) { - batch(object).append(); - } - - if (object.instanceMatrix && object.instanceMatrix.isInstancedBufferAttribute === true) { - instance(object).append(); - } - - if (this.positionNode !== null) { - positionLocal.assign(this.positionNode); - } - - const mvp = modelViewProjection(); - - builder.context.vertex = builder.removeStack(); - builder.context.mvp = mvp; - - return mvp; - } - - setupDiffuseColor({ object, geometry }) { - let colorNode = this.colorNode ? vec4(this.colorNode) : materialColor; - - // VERTEX COLORS - - if (this.vertexColors === true && geometry.hasAttribute('color')) { - colorNode = vec4(colorNode.xyz.mul(attribute('color', 'vec3')), colorNode.a); - } - - // Instanced colors - - if (object.instanceColor) { - const instanceColor = varyingProperty('vec3', 'vInstanceColor'); - - colorNode = instanceColor.mul(colorNode); - } - - if (object.isBatchedMesh && object._colorsTexture) { - const batchColor = varyingProperty('vec3', 'vBatchColor'); - - colorNode = batchColor.mul(colorNode); - } - - // COLOR - - diffuseColor.assign(colorNode); - - // OPACITY - - const opacityNode = this.opacityNode ? float(this.opacityNode) : materialOpacity; - diffuseColor.a.assign(diffuseColor.a.mul(opacityNode)); - - // ALPHA TEST - - if (this.alphaTestNode !== null || this.alphaTest > 0) { - const alphaTestNode = this.alphaTestNode !== null ? float(this.alphaTestNode) : materialAlphaTest; - - diffuseColor.a.lessThanEqual(alphaTestNode).discard(); - } - - if (this.transparent === false && this.blending === NormalBlending && this.alphaToCoverage === false) { - diffuseColor.a.assign(1.0); - } - } - - setupVariants(/*builder*/) { - // Interface function. - } - - setupOutgoingLight() { - return this.lights === true ? vec3(0) : diffuseColor.rgb; - } - - setupNormal() { - return this.normalNode ? vec3(this.normalNode) : materialNormal; - } - - setupEnvironment(/*builder*/) { - let node = null; - - if (this.envNode) { - node = this.envNode; - } else if (this.envMap) { - node = this.envMap.isCubeTexture - ? materialReference('envMap', 'cubeTexture') - : materialReference('envMap', 'texture'); - } - - return node; - } - - setupLightMap(builder) { - let node = null; - - if (builder.material.lightMap) { - node = new IrradianceNode(materialLightMap); - } - - return node; - } - - setupLights(builder) { - const materialLightsNode = []; - - // - - const envNode = this.setupEnvironment(builder); - - if (envNode && envNode.isLightingNode) { - materialLightsNode.push(envNode); - } - - const lightMapNode = this.setupLightMap(builder); - - if (lightMapNode && lightMapNode.isLightingNode) { - materialLightsNode.push(lightMapNode); - } - - if (this.aoNode !== null || builder.material.aoMap) { - const aoNode = this.aoNode !== null ? this.aoNode : materialAOMap; - - materialLightsNode.push(new AONode(aoNode)); - } - - let lightsN = this.lightsNode || builder.lightsNode; - - if (materialLightsNode.length > 0) { - lightsN = builder.renderer.lighting.createNode([...lightsN.getLights(), ...materialLightsNode]); - } - - return lightsN; - } - - setupLightingModel(/*builder*/) { - // Interface function. - } - - setupLighting(builder) { - const { material } = builder; - const { backdropNode, backdropAlphaNode, emissiveNode } = this; - - // OUTGOING LIGHT - - const lights = this.lights === true || this.lightsNode !== null; - - const lightsNode = lights ? this.setupLights(builder) : null; - - let outgoingLightNode = this.setupOutgoingLight(builder); - - if (lightsNode && lightsNode.getScope().hasLights) { - const lightingModel = this.setupLightingModel(builder); - - outgoingLightNode = lightingContext(lightsNode, lightingModel, backdropNode, backdropAlphaNode); - } else if (backdropNode !== null) { - outgoingLightNode = vec3( - backdropAlphaNode !== null ? mix(outgoingLightNode, backdropNode, backdropAlphaNode) : backdropNode, - ); - } - - // EMISSIVE - - if ( - (emissiveNode && emissiveNode.isNode === true) || - (material.emissive && material.emissive.isColor === true) - ) { - emissive.assign(vec3(emissiveNode ? emissiveNode : materialEmissive)); - - outgoingLightNode = outgoingLightNode.add(emissive); - } - - return outgoingLightNode; - } - - setupOutput(builder, outputNode) { - // FOG - - if (this.fog === true) { - const fogNode = builder.fogNode; - - if (fogNode) outputNode = vec4(fogNode.mix(outputNode.rgb, fogNode.colorNode), outputNode.a); - } - - return outputNode; - } - - setDefaultValues(material) { - // This approach is to reuse the native refreshUniforms* - // and turn available the use of features like transmission and environment in core - - for (const property in material) { - const value = material[property]; - - if (this[property] === undefined) { - this[property] = value; - - if (value && value.clone) this[property] = value.clone(); - } - } - - const descriptors = Object.getOwnPropertyDescriptors(material.constructor.prototype); - - for (const key in descriptors) { - if ( - Object.getOwnPropertyDescriptor(this.constructor.prototype, key) === undefined && - descriptors[key].get !== undefined - ) { - Object.defineProperty(this.constructor.prototype, key, descriptors[key]); - } - } - } - - toJSON(meta) { - const isRoot = meta === undefined || typeof meta === 'string'; - - if (isRoot) { - meta = { - textures: {}, - images: {}, - nodes: {}, - }; - } - - const data = Material.prototype.toJSON.call(this, meta); - const nodeChildren = getNodeChildren(this); - - data.inputNodes = {}; - - for (const { property, childNode } of nodeChildren) { - data.inputNodes[property] = childNode.toJSON(meta).uuid; - } - - // TODO: Copied from Object3D.toJSON - - function extractFromCache(cache) { - const values = []; - - for (const key in cache) { - const data = cache[key]; - delete data.metadata; - values.push(data); - } - - return values; - } - - if (isRoot) { - const textures = extractFromCache(meta.textures); - const images = extractFromCache(meta.images); - const nodes = extractFromCache(meta.nodes); - - if (textures.length > 0) data.textures = textures; - if (images.length > 0) data.images = images; - if (nodes.length > 0) data.nodes = nodes; - } - - return data; - } - - copy(source) { - this.lightsNode = source.lightsNode; - this.envNode = source.envNode; - - this.colorNode = source.colorNode; - this.normalNode = source.normalNode; - this.opacityNode = source.opacityNode; - this.backdropNode = source.backdropNode; - this.backdropAlphaNode = source.backdropAlphaNode; - this.alphaTestNode = source.alphaTestNode; - - this.positionNode = source.positionNode; - this.geometryNode = source.geometryNode; - - this.depthNode = source.depthNode; - this.shadowNode = source.shadowNode; - this.shadowPositionNode = source.shadowPositionNode; - - this.outputNode = source.outputNode; - this.mrtNode = source.mrtNode; - - this.fragmentNode = source.fragmentNode; - this.vertexNode = source.vertexNode; - - return super.copy(source); - } -} - -export default NodeMaterial; diff --git a/src-testing/src/materials/nodes/NodeMaterials.d.ts b/src-testing/src/materials/nodes/NodeMaterials.d.ts deleted file mode 100644 index 395273cd9..000000000 --- a/src-testing/src/materials/nodes/NodeMaterials.d.ts +++ /dev/null @@ -1,18 +0,0 @@ -export { default as InstancedPointsNodeMaterial } from "./InstancedPointsNodeMaterial.js"; -export { default as Line2NodeMaterial } from "./Line2NodeMaterial.js"; -export { default as LineBasicNodeMaterial } from "./LineBasicNodeMaterial.js"; -export { default as LineDashedNodeMaterial } from "./LineDashedNodeMaterial.js"; -export { default as MeshBasicNodeMaterial } from "./MeshBasicNodeMaterial.js"; -export { default as MeshLambertNodeMaterial } from "./MeshLambertNodeMaterial.js"; -export { default as MeshMatcapNodeMaterial } from "./MeshMatcapNodeMaterial.js"; -export { default as MeshNormalNodeMaterial } from "./MeshNormalNodeMaterial.js"; -export { default as MeshPhongNodeMaterial } from "./MeshPhongNodeMaterial.js"; -export { default as MeshPhysicalNodeMaterial } from "./MeshPhysicalNodeMaterial.js"; -export { default as MeshSSSNodeMaterial } from "./MeshSSSNodeMaterial.js"; -export { default as MeshStandardNodeMaterial } from "./MeshStandardNodeMaterial.js"; -export { default as MeshToonNodeMaterial } from "./MeshToonNodeMaterial.js"; -export { default as NodeMaterial } from "./NodeMaterial.js"; -export { default as PointsNodeMaterial } from "./PointsNodeMaterial.js"; -export { default as ShadowNodeMaterial } from "./ShadowNodeMaterial.js"; -export { default as SpriteNodeMaterial } from "./SpriteNodeMaterial.js"; -export { default as VolumeNodeMaterial } from "./VolumeNodeMaterial.js"; diff --git a/src-testing/src/materials/nodes/PointsNodeMaterial.d.ts b/src-testing/src/materials/nodes/PointsNodeMaterial.d.ts deleted file mode 100644 index 836f55a6d..000000000 --- a/src-testing/src/materials/nodes/PointsNodeMaterial.d.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { Color } from "../../math/Color.js"; -import { Texture } from "../../textures/Texture.js"; -import { PointsMaterialParameters } from "../PointsMaterial.js"; -import NodeMaterial, { NodeMaterialParameters } from "./NodeMaterial.js"; - -export interface PointsNodeMaterialParameters extends NodeMaterialParameters, PointsMaterialParameters { -} - -export default class PointsNodeMaterial extends NodeMaterial { - readonly isPointsNodeMaterial: true; - - // Properties from PointsMaterial - readonly isPointsMaterial: true; - color: Color; - map: Texture | null; - alphaMap: Texture | null; - size: number; - sizeAttenuation: boolean; - - constructor(parameters?: PointsNodeMaterialParameters); -} diff --git a/src-testing/src/materials/nodes/ShadowNodeMaterial.d.ts b/src-testing/src/materials/nodes/ShadowNodeMaterial.d.ts deleted file mode 100644 index c53d92437..000000000 --- a/src-testing/src/materials/nodes/ShadowNodeMaterial.d.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { Color } from "../../math/Color.js"; -import { ShadowMaterialParameters } from "../ShadowMaterial.js"; -import NodeMaterial, { NodeMaterialParameters } from "./NodeMaterial.js"; - -export interface ShadowNodeMaterialParameters extends NodeMaterialParameters, ShadowMaterialParameters { -} - -export default class ShadowNodeMaterial extends NodeMaterial { - readonly isShadowNodeMaterial: true; - - // Properties from ShadowMaterial - readonly isShadowMaterial: true; - color: Color; - fog: boolean; - - constructor(parameters?: ShadowNodeMaterialParameters); -} diff --git a/src-testing/src/materials/nodes/SpriteNodeMaterial.d.ts b/src-testing/src/materials/nodes/SpriteNodeMaterial.d.ts deleted file mode 100644 index e34845d78..000000000 --- a/src-testing/src/materials/nodes/SpriteNodeMaterial.d.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Color } from "../../math/Color.js"; -import Node from "../../nodes/core/Node.js"; -import { Texture } from "../../textures/Texture.js"; -import { SpriteMaterialParameters } from "../SpriteMaterial.js"; -import NodeMaterial, { NodeMaterialParameters } from "./NodeMaterial.js"; - -export interface SpriteNodeMaterialParameters extends NodeMaterialParameters, SpriteMaterialParameters { -} - -export default class SpriteNodeMaterial extends NodeMaterial { - isSpriteNodeMaterial: true; - - rotationNode: Node | null; - scaleNode: Node | null; - - // Properties from SpriteMaterial - readonly isSpriteMaterial: true; - color: Color; - map: Texture | null; - alphaMap: Texture | null; - rotation: number; - sizeAttenuation: boolean; - fog: boolean; - - constructor(parameters?: SpriteNodeMaterialParameters); -} diff --git a/src-testing/src/materials/nodes/VolumeNodeMaterial.d.ts b/src-testing/src/materials/nodes/VolumeNodeMaterial.d.ts deleted file mode 100644 index 4f2c6e260..000000000 --- a/src-testing/src/materials/nodes/VolumeNodeMaterial.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import Node from "../../nodes/core/Node.js"; -import NodeMaterial, { NodeMaterialParameters } from "./NodeMaterial.js"; - -export default class VolumeNodeMaterial extends NodeMaterial { - lights: boolean; - readonly isVolumeNodeMaterial: true; - testNode: Node | null; - - constructor(parameters?: NodeMaterialParameters); -} diff --git a/src-testing/src/materials/nodes/manager/NodeMaterialObserver.ts b/src-testing/src/materials/nodes/manager/NodeMaterialObserver.ts deleted file mode 100644 index 8ab1a6d67..000000000 --- a/src-testing/src/materials/nodes/manager/NodeMaterialObserver.ts +++ /dev/null @@ -1,308 +0,0 @@ -const refreshUniforms = [ - 'alphaMap', - 'alphaTest', - 'anisotropy', - 'anisotropyMap', - 'anisotropyRotation', - 'aoMap', - 'attenuationColor', - 'attenuationDistance', - 'bumpMap', - 'clearcoat', - 'clearcoatMap', - 'clearcoatNormalMap', - 'clearcoatNormalScale', - 'clearcoatRoughness', - 'color', - 'dispersion', - 'displacementMap', - 'emissive', - 'emissiveMap', - 'envMap', - 'gradientMap', - 'ior', - 'iridescence', - 'iridescenceIOR', - 'iridescenceMap', - 'iridescenceThicknessMap', - 'lightMap', - 'map', - 'matcap', - 'metalness', - 'metalnessMap', - 'normalMap', - 'normalScale', - 'opacity', - 'roughness', - 'roughnessMap', - 'sheen', - 'sheenColor', - 'sheenColorMap', - 'sheenRoughnessMap', - 'shininess', - 'specular', - 'specularColor', - 'specularColorMap', - 'specularIntensity', - 'specularIntensityMap', - 'specularMap', - 'thickness', - 'transmission', - 'transmissionMap', -]; - -class NodeMaterialObserver { - constructor(builder) { - this.renderObjects = new WeakMap(); - this.hasNode = this.containsNode(builder); - this.hasAnimation = builder.object.isSkinnedMesh === true; - this.refreshUniforms = refreshUniforms; - this.renderId = 0; - } - - firstInitialization(renderObject) { - const hasInitialized = this.renderObjects.has(renderObject); - - if (hasInitialized === false) { - this.getRenderObjectData(renderObject); - - return true; - } - - return false; - } - - getRenderObjectData(renderObject) { - let data = this.renderObjects.get(renderObject); - - if (data === undefined) { - const { geometry, material } = renderObject; - - data = { - material: this.getMaterialData(material), - geometry: { - attributes: this.getAttributesData(geometry.attributes), - indexVersion: geometry.index ? geometry.index.version : null, - drawRange: { start: geometry.drawRange.start, count: geometry.drawRange.count }, - }, - worldMatrix: renderObject.object.matrixWorld.clone(), - }; - - if (renderObject.object.center) { - data.center = renderObject.object.center.clone(); - } - - if (renderObject.object.morphTargetInfluences) { - data.morphTargetInfluences = renderObject.object.morphTargetInfluences.slice(); - } - - if (renderObject.bundle !== null) { - data.version = renderObject.bundle.version; - } - - this.renderObjects.set(renderObject, data); - } - - return data; - } - - getAttributesData(attributes) { - const attributesData = {}; - - for (const name in attributes) { - const attribute = attributes[name]; - - attributesData[name] = { - version: attribute.version, - }; - } - - return attributesData; - } - - containsNode(builder) { - const material = builder.material; - - for (const property in material) { - if (material[property] && material[property].isNode) return true; - } - - if (builder.renderer.nodes.modelViewMatrix !== null || builder.renderer.nodes.modelNormalViewMatrix !== null) - return true; - - return false; - } - - getMaterialData(material) { - const data = {}; - - for (const property of this.refreshUniforms) { - const value = material[property]; - - if (value === null || value === undefined) continue; - - if (typeof value === 'object' && value.clone !== undefined) { - if (value.isTexture === true) { - data[property] = { id: value.id, version: value.version }; - } else { - data[property] = value.clone(); - } - } else { - data[property] = value; - } - } - - return data; - } - - equals(renderObject) { - const { object, material, geometry } = renderObject; - - const renderObjectData = this.getRenderObjectData(renderObject); - - // world matrix - - if (renderObjectData.worldMatrix.equals(object.matrixWorld) !== true) { - renderObjectData.worldMatrix.copy(object.matrixWorld); - - return false; - } - - // material - - const materialData = renderObjectData.material; - - for (const property in materialData) { - const value = materialData[property]; - const mtlValue = material[property]; - - if (value.equals !== undefined) { - if (value.equals(mtlValue) === false) { - value.copy(mtlValue); - - return false; - } - } else if (mtlValue.isTexture === true) { - if (value.id !== mtlValue.id || value.version !== mtlValue.version) { - value.id = mtlValue.id; - value.version = mtlValue.version; - - return false; - } - } else if (value !== mtlValue) { - materialData[property] = mtlValue; - - return false; - } - } - - // geometry - - const storedGeometryData = renderObjectData.geometry; - const attributes = geometry.attributes; - const storedAttributes = storedGeometryData.attributes; - - const storedAttributeNames = Object.keys(storedAttributes); - const currentAttributeNames = Object.keys(attributes); - - if (storedAttributeNames.length !== currentAttributeNames.length) { - renderObjectData.geometry.attributes = this.getAttributesData(attributes); - return false; - } - - // Compare each attribute - for (const name of storedAttributeNames) { - const storedAttributeData = storedAttributes[name]; - const attribute = attributes[name]; - - if (attribute === undefined) { - // Attribute was removed - delete storedAttributes[name]; - return false; - } - - if (storedAttributeData.version !== attribute.version) { - storedAttributeData.version = attribute.version; - return false; - } - } - - // Check index - const index = geometry.index; - const storedIndexVersion = storedGeometryData.indexVersion; - const currentIndexVersion = index ? index.version : null; - - if (storedIndexVersion !== currentIndexVersion) { - storedGeometryData.indexVersion = currentIndexVersion; - return false; - } - - // Check drawRange - if ( - storedGeometryData.drawRange.start !== geometry.drawRange.start || - storedGeometryData.drawRange.count !== geometry.drawRange.count - ) { - storedGeometryData.drawRange.start = geometry.drawRange.start; - storedGeometryData.drawRange.count = geometry.drawRange.count; - return false; - } - - // morph targets - - if (renderObjectData.morphTargetInfluences) { - let morphChanged = false; - - for (let i = 0; i < renderObjectData.morphTargetInfluences.length; i++) { - if (renderObjectData.morphTargetInfluences[i] !== object.morphTargetInfluences[i]) { - morphChanged = true; - } - } - - if (morphChanged) return true; - } - - // center - - if (renderObjectData.center) { - if (renderObjectData.center.equals(object.center) === false) { - renderObjectData.center.copy(object.center); - - return true; - } - } - - // bundle - - if (renderObject.bundle !== null) { - renderObjectData.version = renderObject.bundle.version; - } - - return true; - } - - needsRefresh(renderObject, nodeFrame) { - if (this.hasNode || this.hasAnimation || this.firstInitialization(renderObject)) return true; - - const { renderId } = nodeFrame; - - if (this.renderId !== renderId) { - this.renderId = renderId; - - return true; - } - - const isStatic = renderObject.object.static === true; - const isBundle = - renderObject.bundle !== null && - renderObject.bundle.static === true && - this.getRenderObjectData(renderObject).version === renderObject.bundle.version; - - if (isStatic || isBundle) return false; - - const notEqual = this.equals(renderObject) !== true; - - return notEqual; - } -} - -export default NodeMaterialObserver; diff --git a/src-testing/src/math/Box2.d.ts b/src-testing/src/math/Box2.d.ts deleted file mode 100644 index de05083d0..000000000 --- a/src-testing/src/math/Box2.d.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { Vector2 } from "./Vector2.js"; - -// Math ////////////////////////////////////////////////////////////////////////////////// - -export class Box2 { - constructor(min?: Vector2, max?: Vector2); - - /** - * @default new THREE.Vector2( + Infinity, + Infinity ) - */ - min: Vector2; - - /** - * @default new THREE.Vector2( - Infinity, - Infinity ) - */ - max: Vector2; - - set(min: Vector2, max: Vector2): Box2; - setFromPoints(points: Vector2[]): Box2; - setFromCenterAndSize(center: Vector2, size: Vector2): Box2; - clone(): this; - copy(box: Box2): this; - makeEmpty(): Box2; - isEmpty(): boolean; - getCenter(target: Vector2): Vector2; - getSize(target: Vector2): Vector2; - expandByPoint(point: Vector2): Box2; - expandByVector(vector: Vector2): Box2; - expandByScalar(scalar: number): Box2; - containsPoint(point: Vector2): boolean; - containsBox(box: Box2): boolean; - getParameter(point: Vector2, target: Vector2): Vector2; - intersectsBox(box: Box2): boolean; - clampPoint(point: Vector2, target: Vector2): Vector2; - distanceToPoint(point: Vector2): number; - intersect(box: Box2): Box2; - union(box: Box2): Box2; - translate(offset: Vector2): Box2; - equals(box: Box2): boolean; - /** - * @deprecated Use {@link Box2#isEmpty .isEmpty()} instead. - */ - empty(): any; - /** - * @deprecated Use {@link Box2#intersectsBox .intersectsBox()} instead. - */ - isIntersectionBox(b: any): any; -} diff --git a/src-testing/src/math/Box3.d.ts b/src-testing/src/math/Box3.d.ts deleted file mode 100644 index 2e7b11bc9..000000000 --- a/src-testing/src/math/Box3.d.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { BufferAttribute } from "../core/BufferAttribute.js"; -import { Object3D } from "../core/Object3D.js"; -import { Matrix4 } from "./Matrix4.js"; -import { Plane } from "./Plane.js"; -import { Sphere } from "./Sphere.js"; -import { Triangle } from "./Triangle.js"; -import { Vector3 } from "./Vector3.js"; - -export class Box3 { - constructor(min?: Vector3, max?: Vector3); - - /** - * @default new THREE.Vector3( + Infinity, + Infinity, + Infinity ) - */ - min: Vector3; - - /** - * @default new THREE.Vector3( - Infinity, - Infinity, - Infinity ) - */ - max: Vector3; - readonly isBox3: true; - - set(min: Vector3, max: Vector3): this; - setFromArray(array: ArrayLike): this; - setFromBufferAttribute(bufferAttribute: BufferAttribute): this; - setFromPoints(points: Vector3[]): this; - setFromCenterAndSize(center: Vector3, size: Vector3): this; - setFromObject(object: Object3D, precise?: boolean): this; - clone(): this; - copy(box: Box3): this; - makeEmpty(): this; - isEmpty(): boolean; - getCenter(target: Vector3): Vector3; - getSize(target: Vector3): Vector3; - expandByPoint(point: Vector3): this; - expandByVector(vector: Vector3): this; - expandByScalar(scalar: number): this; - expandByObject(object: Object3D, precise?: boolean): this; - containsPoint(point: Vector3): boolean; - containsBox(box: Box3): boolean; - getParameter(point: Vector3, target: Vector3): Vector3; - intersectsBox(box: Box3): boolean; - intersectsSphere(sphere: Sphere): boolean; - intersectsPlane(plane: Plane): boolean; - intersectsTriangle(triangle: Triangle): boolean; - clampPoint(point: Vector3, target: Vector3): Vector3; - distanceToPoint(point: Vector3): number; - getBoundingSphere(target: Sphere): Sphere; - intersect(box: Box3): this; - union(box: Box3): this; - applyMatrix4(matrix: Matrix4): this; - translate(offset: Vector3): this; - equals(box: Box3): boolean; - /** - * @deprecated Use {@link Box3#isEmpty .isEmpty()} instead. - */ - empty(): any; - /** - * @deprecated Use {@link Box3#intersectsBox .intersectsBox()} instead. - */ - isIntersectionBox(b: any): any; - /** - * @deprecated Use {@link Box3#intersectsSphere .intersectsSphere()} instead. - */ - isIntersectionSphere(s: any): any; -} diff --git a/src-testing/src/math/Color.d.ts b/src-testing/src/math/Color.d.ts deleted file mode 100644 index a0e265f83..000000000 --- a/src-testing/src/math/Color.d.ts +++ /dev/null @@ -1,375 +0,0 @@ -import { Matrix3 } from "./Matrix3.js"; -import { Vector3 } from "./Vector3.js"; - -import { BufferAttribute } from "../core/BufferAttribute.js"; -import { InterleavedBufferAttribute } from "../core/InterleavedBufferAttribute.js"; - -export { SRGBToLinear } from "./ColorManagement.js"; - -declare const _colorKeywords: { - aliceblue: 0xf0f8ff; - antiquewhite: 0xfaebd7; - aqua: 0x00ffff; - aquamarine: 0x7fffd4; - azure: 0xf0ffff; - beige: 0xf5f5dc; - bisque: 0xffe4c4; - black: 0x000000; - blanchedalmond: 0xffebcd; - blue: 0x0000ff; - blueviolet: 0x8a2be2; - brown: 0xa52a2a; - burlywood: 0xdeb887; - cadetblue: 0x5f9ea0; - chartreuse: 0x7fff00; - chocolate: 0xd2691e; - coral: 0xff7f50; - cornflowerblue: 0x6495ed; - cornsilk: 0xfff8dc; - crimson: 0xdc143c; - cyan: 0x00ffff; - darkblue: 0x00008b; - darkcyan: 0x008b8b; - darkgoldenrod: 0xb8860b; - darkgray: 0xa9a9a9; - darkgreen: 0x006400; - darkgrey: 0xa9a9a9; - darkkhaki: 0xbdb76b; - darkmagenta: 0x8b008b; - darkolivegreen: 0x556b2f; - darkorange: 0xff8c00; - darkorchid: 0x9932cc; - darkred: 0x8b0000; - darksalmon: 0xe9967a; - darkseagreen: 0x8fbc8f; - darkslateblue: 0x483d8b; - darkslategray: 0x2f4f4f; - darkslategrey: 0x2f4f4f; - darkturquoise: 0x00ced1; - darkviolet: 0x9400d3; - deeppink: 0xff1493; - deepskyblue: 0x00bfff; - dimgray: 0x696969; - dimgrey: 0x696969; - dodgerblue: 0x1e90ff; - firebrick: 0xb22222; - floralwhite: 0xfffaf0; - forestgreen: 0x228b22; - fuchsia: 0xff00ff; - gainsboro: 0xdcdcdc; - ghostwhite: 0xf8f8ff; - gold: 0xffd700; - goldenrod: 0xdaa520; - gray: 0x808080; - green: 0x008000; - greenyellow: 0xadff2f; - grey: 0x808080; - honeydew: 0xf0fff0; - hotpink: 0xff69b4; - indianred: 0xcd5c5c; - indigo: 0x4b0082; - ivory: 0xfffff0; - khaki: 0xf0e68c; - lavender: 0xe6e6fa; - lavenderblush: 0xfff0f5; - lawngreen: 0x7cfc00; - lemonchiffon: 0xfffacd; - lightblue: 0xadd8e6; - lightcoral: 0xf08080; - lightcyan: 0xe0ffff; - lightgoldenrodyellow: 0xfafad2; - lightgray: 0xd3d3d3; - lightgreen: 0x90ee90; - lightgrey: 0xd3d3d3; - lightpink: 0xffb6c1; - lightsalmon: 0xffa07a; - lightseagreen: 0x20b2aa; - lightskyblue: 0x87cefa; - lightslategray: 0x778899; - lightslategrey: 0x778899; - lightsteelblue: 0xb0c4de; - lightyellow: 0xffffe0; - lime: 0x00ff00; - limegreen: 0x32cd32; - linen: 0xfaf0e6; - magenta: 0xff00ff; - maroon: 0x800000; - mediumaquamarine: 0x66cdaa; - mediumblue: 0x0000cd; - mediumorchid: 0xba55d3; - mediumpurple: 0x9370db; - mediumseagreen: 0x3cb371; - mediumslateblue: 0x7b68ee; - mediumspringgreen: 0x00fa9a; - mediumturquoise: 0x48d1cc; - mediumvioletred: 0xc71585; - midnightblue: 0x191970; - mintcream: 0xf5fffa; - mistyrose: 0xffe4e1; - moccasin: 0xffe4b5; - navajowhite: 0xffdead; - navy: 0x000080; - oldlace: 0xfdf5e6; - olive: 0x808000; - olivedrab: 0x6b8e23; - orange: 0xffa500; - orangered: 0xff4500; - orchid: 0xda70d6; - palegoldenrod: 0xeee8aa; - palegreen: 0x98fb98; - paleturquoise: 0xafeeee; - palevioletred: 0xdb7093; - papayawhip: 0xffefd5; - peachpuff: 0xffdab9; - peru: 0xcd853f; - pink: 0xffc0cb; - plum: 0xdda0dd; - powderblue: 0xb0e0e6; - purple: 0x800080; - rebeccapurple: 0x663399; - red: 0xff0000; - rosybrown: 0xbc8f8f; - royalblue: 0x4169e1; - saddlebrown: 0x8b4513; - salmon: 0xfa8072; - sandybrown: 0xf4a460; - seagreen: 0x2e8b57; - seashell: 0xfff5ee; - sienna: 0xa0522d; - silver: 0xc0c0c0; - skyblue: 0x87ceeb; - slateblue: 0x6a5acd; - slategray: 0x708090; - slategrey: 0x708090; - snow: 0xfffafa; - springgreen: 0x00ff7f; - steelblue: 0x4682b4; - tan: 0xd2b48c; - teal: 0x008080; - thistle: 0xd8bfd8; - tomato: 0xff6347; - turquoise: 0x40e0d0; - violet: 0xee82ee; - wheat: 0xf5deb3; - white: 0xffffff; - whitesmoke: 0xf5f5f5; - yellow: 0xffff00; - yellowgreen: 0x9acd32; -}; - -export type ColorRepresentation = Color | string | number; - -export interface HSL { - h: number; - s: number; - l: number; -} - -export interface RGB { - r: number; - g: number; - b: number; -} - -/** - * Class representing a color. - * - * A Color instance is represented by RGB components in the linear working color space, which defaults to - * `LinearSRGBColorSpace`. Inputs conventionally using `SRGBColorSpace` (such as hexadecimals and CSS strings) are - * converted to the working color space automatically. - * - * ``` - * // converted automatically from SRGBColorSpace to LinearSRGBColorSpace - * const color = new THREE.Color().setHex( 0x112233 ); - * ``` - * - * Source color spaces may be specified explicitly, to ensure correct conversions. - * - * ``` - * // assumed already LinearSRGBColorSpace; no conversion - * const color = new THREE.Color().setRGB( 0.5, 0.5, 0.5 ); - * - * // converted explicitly from SRGBColorSpace to LinearSRGBColorSpace - * const color = new THREE.Color().setRGB( 0.5, 0.5, 0.5, SRGBColorSpace ); - * ``` - * - * If THREE.ColorManagement is disabled, no conversions occur. For details, see Color management. - * - * Iterating through a Color instance will yield its components (r, g, b) in the corresponding order. - */ -export class Color { - constructor(color?: ColorRepresentation); - constructor(r: number, g: number, b: number); - - readonly isColor: true; - - /** - * Red channel value between `0.0` and `1.0`. Default is `1`. - * @default 1 - */ - r: number; - - /** - * Green channel value between `0.0` and `1.0`. Default is `1`. - * @default 1 - */ - g: number; - - /** - * Blue channel value between `0.0` and `1.0`. Default is `1`. - * @default 1 - */ - b: number; - - set(...args: [color: ColorRepresentation] | [r: number, g: number, b: number]): this; - - /** - * Sets this color's {@link r}, {@link g} and {@link b} components from the x, y, and z components of the specified - * {@link Vector3 | vector}. - */ - setFromVector3(vector: Vector3): this; - - setScalar(scalar: number): Color; - setHex(hex: number, colorSpace?: string): Color; - - /** - * Sets this color from RGB values. - * @param r Red channel value between 0 and 1. - * @param g Green channel value between 0 and 1. - * @param b Blue channel value between 0 and 1. - */ - setRGB(r: number, g: number, b: number, colorSpace?: string): Color; - - /** - * Sets this color from HSL values. - * Based on MochiKit implementation by Bob Ippolito. - * - * @param h Hue channel value between 0 and 1. - * @param s Saturation value channel between 0 and 1. - * @param l Value channel value between 0 and 1. - */ - setHSL(h: number, s: number, l: number, colorSpace?: string): Color; - - /** - * Sets this color from a CSS context style string. - * @param contextStyle Color in CSS context style format. - */ - setStyle(style: string, colorSpace?: string): Color; - - /** - * Sets this color from a color name. - * Faster than {@link Color#setStyle .setStyle()} method if you don't need the other CSS-style formats. - * @param style Color name in X11 format. - */ - setColorName(style: string, colorSpace?: string): Color; - - /** - * Clones this color. - */ - clone(): this; - - /** - * Copies given color. - * @param color Color to copy. - */ - copy(color: Color): this; - - /** - * Copies given color making conversion from `SRGBColorSpace` to `LinearSRGBColorSpace`. - * @param color Color to copy. - */ - copySRGBToLinear(color: Color): Color; - - /** - * Copies given color making conversion from `LinearSRGBColorSpace` to `SRGBColorSpace`. - * @param color Color to copy. - */ - copyLinearToSRGB(color: Color): Color; - - /** - * Converts this color from `SRGBColorSpace` to `LinearSRGBColorSpace`. - */ - convertSRGBToLinear(): Color; - - /** - * Converts this color from `LinearSRGBColorSpace` to `SRGBColorSpace`. - */ - convertLinearToSRGB(): Color; - - /** - * Returns the hexadecimal value of this color. - */ - getHex(colorSpace?: string): number; - - /** - * Returns the string formated hexadecimal value of this color. - */ - getHexString(colorSpace?: string): string; - - getHSL(target: HSL, colorSpace?: string): HSL; - - getRGB(target: RGB, colorSpace?: string): RGB; - - /** - * Returns the value of this color in CSS context style. - * Example: rgb(r, g, b) - */ - getStyle(colorSpace?: string): string; - - offsetHSL(h: number, s: number, l: number): this; - - add(color: Color): this; - addColors(color1: Color, color2: Color): this; - addScalar(s: number): this; - - /** - * Applies the transform {@link Matrix3 | m} to this color's RGB components. - */ - applyMatrix3(m: Matrix3): this; - - sub(color: Color): this; - multiply(color: Color): this; - multiplyScalar(s: number): this; - lerp(color: Color, alpha: number): this; - lerpColors(color1: Color, color2: Color, alpha: number): this; - lerpHSL(color: Color, alpha: number): this; - equals(color: Color): boolean; - - /** - * Sets this color's red, green and blue value from the provided array or array-like. - * @param array the source array or array-like. - * @param offset (optional) offset into the array-like. Default is 0. - */ - fromArray(array: number[] | ArrayLike, offset?: number): this; - - /** - * Returns an array [red, green, blue], or copies red, green and blue into the provided array. - * @param array (optional) array to store the color to. If this is not provided, a new array will be created. - * @param offset (optional) optional offset into the array. - * @return The created or provided array. - */ - toArray(array?: number[], offset?: number): number[]; - - /** - * Copies red, green and blue into the provided array-like. - * @param array array-like to store the color to. - * @param offset (optional) optional offset into the array-like. - * @return The provided array-like. - */ - toArray(xyz: ArrayLike, offset?: number): ArrayLike; - - /** - * This method defines the serialization result of Color. - * @return The color as a hexadecimal value. - */ - toJSON(): number; - - fromBufferAttribute(attribute: BufferAttribute | InterleavedBufferAttribute, index: number): this; - - [Symbol.iterator](): Generator; - - /** - * List of X11 color names. - */ - static NAMES: typeof _colorKeywords; -} diff --git a/src-testing/src/math/ColorManagement.d.ts b/src-testing/src/math/ColorManagement.d.ts deleted file mode 100644 index eaa520d8c..000000000 --- a/src-testing/src/math/ColorManagement.d.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { ColorSpaceTransfer } from "../constants.js"; -import { Color } from "./Color.js"; -import { Matrix3 } from "./Matrix3.js"; -import { Vector3 } from "./Vector3.js"; - -export interface ColorSpaceDefinition { - primaries: [number, number, number, number, number, number]; - whitePoint: [number, number]; - transfer: ColorSpaceTransfer; - toXYZ: Matrix3; - fromXYZ: Matrix3; - luminanceCoefficients: [number, number, number]; - workingColorSpaceConfig?: { unpackColorSpace: string }; - outputColorSpaceConfig?: { drawingBufferColorSpace: string }; -} - -export interface ColorManagement { - /** - * @default true - */ - enabled: boolean; - - /** - * @default LinearSRGBColorSpace - */ - workingColorSpace: string; - - spaces: Record; - - convert: (color: Color, sourceColorSpace: string, targetColorSpace: string) => Color; - - fromWorkingColorSpace: (color: Color, targetColorSpace: string) => Color; - - toWorkingColorSpace: (color: Color, sourceColorSpace: string) => Color; - - getPrimaries: (colorSpace: string) => [number, number, number, number, number, number]; - - getTransfer: (colorSpace: string) => ColorSpaceTransfer; - - getLuminanceCoefficients: (target: Vector3, colorSpace?: string) => [number, number, number]; - - define: (colorSpaces: Record) => void; -} - -export const ColorManagement: ColorManagement; - -export function SRGBToLinear(c: number): number; - -export function LinearToSRGB(c: number): number; diff --git a/src-testing/src/math/Cylindrical.d.ts b/src-testing/src/math/Cylindrical.d.ts deleted file mode 100644 index 6764f8154..000000000 --- a/src-testing/src/math/Cylindrical.d.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Vector3 } from "./Vector3.js"; - -export class Cylindrical { - constructor(radius?: number, theta?: number, y?: number); - - /** - * @default 1 - */ - radius: number; - - /** - * @default 0 - */ - theta: number; - - /** - * @default 0 - */ - y: number; - - clone(): this; - copy(other: Cylindrical): this; - set(radius: number, theta: number, y: number): this; - setFromVector3(vec3: Vector3): this; - setFromCartesianCoords(x: number, y: number, z: number): this; -} diff --git a/src-testing/src/math/Euler.d.ts b/src-testing/src/math/Euler.d.ts deleted file mode 100644 index 81be13d82..000000000 --- a/src-testing/src/math/Euler.d.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { Matrix4 } from "./Matrix4.js"; -import { Quaternion } from "./Quaternion.js"; -import { Vector3 } from "./Vector3.js"; - -export type EulerOrder = "XYZ" | "YXZ" | "ZXY" | "ZYX" | "YZX" | "XZY"; - -export type EulerTuple = [x: number, y: number, z: number, order?: EulerOrder]; - -export class Euler { - constructor(x?: number, y?: number, z?: number, order?: EulerOrder); - - /** - * @default 0 - */ - x: number; - - /** - * @default 0 - */ - y: number; - - /** - * @default 0 - */ - z: number; - - /** - * @default THREE.Euler.DEFAULT_ORDER - */ - order: EulerOrder; - readonly isEuler: true; - - _onChangeCallback: () => void; - - set(x: number, y: number, z: number, order?: EulerOrder): Euler; - clone(): this; - copy(euler: Euler): this; - setFromRotationMatrix(m: Matrix4, order?: EulerOrder, update?: boolean): Euler; - setFromQuaternion(q: Quaternion, order?: EulerOrder, update?: boolean): Euler; - setFromVector3(v: Vector3, order?: EulerOrder): Euler; - reorder(newOrder: EulerOrder): Euler; - equals(euler: Euler): boolean; - fromArray(array: EulerTuple): Euler; - toArray(array?: Partial, offset?: number): EulerTuple; - _onChange(callback: () => void): this; - - static DEFAULT_ORDER: "XYZ"; - - [Symbol.iterator](): Generator; -} diff --git a/src-testing/src/math/Frustum.d.ts b/src-testing/src/math/Frustum.d.ts deleted file mode 100644 index 364c8e926..000000000 --- a/src-testing/src/math/Frustum.d.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { CoordinateSystem } from "../constants.js"; -import { Object3D } from "../core/Object3D.js"; -import { Sprite } from "../objects/Sprite.js"; -import { Box3 } from "./Box3.js"; -import { Matrix4 } from "./Matrix4.js"; -import { Plane } from "./Plane.js"; -import { Sphere } from "./Sphere.js"; -import { Vector3 } from "./Vector3.js"; - -/** - * Frustums are used to determine what is inside the camera's field of view. They help speed up the rendering process. - */ -export class Frustum { - constructor(p0?: Plane, p1?: Plane, p2?: Plane, p3?: Plane, p4?: Plane, p5?: Plane); - - /** - * Array of 6 vectors. - */ - planes: Plane[]; - - set(p0: Plane, p1: Plane, p2: Plane, p3: Plane, p4: Plane, p5: Plane): Frustum; - clone(): this; - copy(frustum: Frustum): this; - setFromProjectionMatrix(m: Matrix4, coordinateSystem?: CoordinateSystem): this; - intersectsObject(object: Object3D): boolean; - intersectsSprite(sprite: Sprite): boolean; - intersectsSphere(sphere: Sphere): boolean; - intersectsBox(box: Box3): boolean; - containsPoint(point: Vector3): boolean; -} diff --git a/src-testing/src/math/Interpolant.d.ts b/src-testing/src/math/Interpolant.d.ts deleted file mode 100644 index 9d2b1aced..000000000 --- a/src-testing/src/math/Interpolant.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -export abstract class Interpolant { - constructor(parameterPositions: any, sampleValues: any, sampleSize: number, resultBuffer?: any); - - parameterPositions: any; - sampleValues: any; - valueSize: number; - resultBuffer: any; - - evaluate(time: number): any; -} diff --git a/src-testing/src/math/Line3.d.ts b/src-testing/src/math/Line3.d.ts deleted file mode 100644 index ab7e749bc..000000000 --- a/src-testing/src/math/Line3.d.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { Matrix4 } from "./Matrix4.js"; -import { Vector3 } from "./Vector3.js"; - -export class Line3 { - constructor(start?: Vector3, end?: Vector3); - - /** - * @default new THREE.Vector3() - */ - start: Vector3; - - /** - * @default new THREE.Vector3() - */ - end: Vector3; - - set(start?: Vector3, end?: Vector3): Line3; - clone(): this; - copy(line: Line3): this; - getCenter(target: Vector3): Vector3; - delta(target: Vector3): Vector3; - distanceSq(): number; - distance(): number; - at(t: number, target: Vector3): Vector3; - closestPointToPointParameter(point: Vector3, clampToLine?: boolean): number; - closestPointToPoint(point: Vector3, clampToLine: boolean, target: Vector3): Vector3; - applyMatrix4(matrix: Matrix4): Line3; - equals(line: Line3): boolean; -} diff --git a/src-testing/src/math/MathUtils.d.ts b/src-testing/src/math/MathUtils.d.ts deleted file mode 100644 index 48f10a3c3..000000000 --- a/src-testing/src/math/MathUtils.d.ts +++ /dev/null @@ -1,137 +0,0 @@ -import { Quaternion } from "./Quaternion.js"; - -/** - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/math/MathUtils.js|src/math/MathUtils.js} - */ - -export const DEG2RAD: number; - -export const RAD2DEG: number; - -export function generateUUID(): string; - -/** - * Clamps the x to be between a and b. - * - * @param value Value to be clamped. - * @param min Minimum value. - * @param max Maximum value. - */ -export function clamp(value: number, min: number, max: number): number; - -export function euclideanModulo(n: number, m: number): number; - -/** - * Linear mapping of x from range [a1, a2] to range [b1, b2]. - * - * @param x Value to be mapped. - * @param a1 Minimum value for range A. - * @param a2 Maximum value for range A. - * @param b1 Minimum value for range B. - * @param b2 Maximum value for range B. - */ -export function mapLinear(x: number, a1: number, a2: number, b1: number, b2: number): number; - -export function inverseLerp(x: number, y: number, t: number): number; - -/** - * Returns a value linearly interpolated from two known points based - * on the given interval - t = 0 will return x and t = 1 will return y. - * - * @param x Start point. - * @param y End point. - * @param t interpolation factor in the closed interval [0, 1] - */ -export function lerp(x: number, y: number, t: number): number; - -/** - * Smoothly interpolate a number from x toward y in a spring-like - * manner using the dt to maintain frame rate independent movement. - * - * @param x Current point. - * @param y Target point. - * @param lambda A higher lambda value will make the movement more sudden, and a lower value will make the movement more gradual. - * @param dt Delta time in seconds. - */ -export function damp(x: number, y: number, lambda: number, dt: number): number; - -/** - * Returns a value that alternates between 0 and length. - * - * @param x The value to pingpong. - * @param length The positive value the export function will pingpong to. Default is 1. - */ -export function pingpong(x: number, length?: number): number; - -export function smoothstep(x: number, min: number, max: number): number; - -export function smootherstep(x: number, min: number, max: number): number; - -/** - * Random integer from low to high interval. - */ -export function randInt(low: number, high: number): number; - -/** - * Random float from low to high interval. - */ -export function randFloat(low: number, high: number): number; - -/** - * Random float from - range / 2 to range / 2 interval. - */ -export function randFloatSpread(range: number): number; - -/** - * Deterministic pseudo-random float in the interval [ 0, 1 ]. - */ -export function seededRandom(seed?: number): number; - -export function degToRad(degrees: number): number; - -export function radToDeg(radians: number): number; - -export function isPowerOfTwo(value: number): boolean; - -export function ceilPowerOfTwo(value: number): number; - -export function floorPowerOfTwo(value: number): number; - -export function setQuaternionFromProperEuler(q: Quaternion, a: number, b: number, c: number, order: string): void; - -export function denormalize( - value: number, - array: Float32Array | Uint32Array | Uint16Array | Uint8Array | Int32Array | Int16Array | Int8Array, -): number; - -export function normalize( - value: number, - array: Float32Array | Uint32Array | Uint16Array | Uint8Array | Int32Array | Int16Array | Int8Array, -): number; - -export const MathUtils: { - DEG2RAD: typeof DEG2RAD; - RAD2DEG: typeof RAD2DEG; - generateUUID: typeof generateUUID; - clamp: typeof clamp; - euclideanModulo: typeof euclideanModulo; - mapLinear: typeof mapLinear; - inverseLerp: typeof inverseLerp; - lerp: typeof lerp; - damp: typeof damp; - pingpong: typeof pingpong; - smoothstep: typeof smoothstep; - smootherstep: typeof smootherstep; - randInt: typeof randInt; - randFloat: typeof randFloat; - randFloatSpread: typeof randFloatSpread; - seededRandom: typeof seededRandom; - degToRad: typeof degToRad; - radToDeg: typeof radToDeg; - isPowerOfTwo: typeof isPowerOfTwo; - ceilPowerOfTwo: typeof ceilPowerOfTwo; - floorPowerOfTwo: typeof floorPowerOfTwo; - setQuaternionFromProperEuler: typeof setQuaternionFromProperEuler; - normalize: typeof normalize; - denormalize: typeof denormalize; -}; diff --git a/src-testing/src/math/Matrix2.d.ts b/src-testing/src/math/Matrix2.d.ts deleted file mode 100644 index 40ed4c8aa..000000000 --- a/src-testing/src/math/Matrix2.d.ts +++ /dev/null @@ -1,53 +0,0 @@ -export type Matrix2Tuple = [ - n11: number, - n12: number, - n21: number, - n22: number, -]; - -/** - * A class representing a 2x2 {@link https://en.wikipedia.org/wiki/Matrix_(mathematics) matrix}. - * - * @example - * const m = new Matrix2(); - */ -export class Matrix2 { - readonly isMatrix2: true; - - /** - * A {@link https://en.wikipedia.org/wiki/Row-_and_column-major_order column-major} list of matrix values. - */ - elements: Matrix2Tuple; - - /** - * Creates a 2x2 {@link https://en.wikipedia.org/wiki/Identity_matrix identity matrix}. - */ - constructor(); - - /** - * Creates a 2x2 matrix with the given arguments in row-major order. - */ - constructor(n11: number, n12: number, n21: number, n22: number); - - /** - * Resets this matrix to the 2x2 identity matrix: - */ - identity(): this; - - /** - * Sets the elements of this matrix based on an array in - * {@link https://en.wikipedia.org/wiki/Row-_and_column-major_order#Column-major_order column-major} format. - * - * @param array the array to read the elements from - * @param offset (optional) index of first element in the array. Default is `0`. - */ - fromArray(array: ArrayLike, offset?: number): this; - - /** - * Sets the 2x2 matrix values to the given - * {@link https://en.wikipedia.org/wiki/Row-_and_column-major_order row-major} sequence of values: - * [n11, n12, - * n21, n22] - */ - set(n11: number, n12: number, n21: number, n22: number): this; -} diff --git a/src-testing/src/math/Matrix3.d.ts b/src-testing/src/math/Matrix3.d.ts deleted file mode 100644 index 0b593fcb8..000000000 --- a/src-testing/src/math/Matrix3.d.ts +++ /dev/null @@ -1,184 +0,0 @@ -// https://threejs.org/docs/#api/en/math/Matrix3 - -import { Matrix4 } from "./Matrix4.js"; -import { Vector2 } from "./Vector2.js"; -import { Vector3 } from "./Vector3.js"; - -export type Matrix3Tuple = [ - n11: number, - n12: number, - n13: number, - n21: number, - n22: number, - n23: number, - n31: number, - n32: number, - n33: number, -]; - -export class Matrix3 { - readonly isMatrix3: true; - - /** - * Array with matrix values. - * @default [1, 0, 0, 0, 1, 0, 0, 0, 1] - */ - elements: Matrix3Tuple; - - /** - * Creates an identity matrix. - */ - constructor(); - /** - * Creates a 3x3 matrix with the given arguments in row-major order. - */ - constructor( - n11: number, - n12: number, - n13: number, - n21: number, - n22: number, - n23: number, - n31: number, - n32: number, - n33: number, - ); - - set( - n11: number, - n12: number, - n13: number, - n21: number, - n22: number, - n23: number, - n31: number, - n32: number, - n33: number, - ): Matrix3; - - identity(): this; - - copy(m: Matrix3): this; - - extractBasis(xAxis: Vector3, yAxis: Vector3, zAxis: Vector3): this; - - setFromMatrix4(m: Matrix4): Matrix3; - - /** - * Multiplies this matrix by m. - */ - multiply(m: Matrix3): this; - - premultiply(m: Matrix3): this; - - /** - * Sets this matrix to a x b. - */ - multiplyMatrices(a: Matrix3, b: Matrix3): this; - - multiplyScalar(s: number): this; - - determinant(): number; - - /** - * Inverts this matrix in place. - */ - invert(): this; - - /** - * Transposes this matrix in place. - */ - transpose(): this; - - getNormalMatrix(matrix4: Matrix4): this; - - /** - * Transposes this matrix into the supplied array r, and returns itself. - */ - transposeIntoArray(r: number[]): this; - - setUvTransform(tx: number, ty: number, sx: number, sy: number, rotation: number, cx: number, cy: number): this; - - scale(sx: number, sy: number): this; - - rotate(theta: number): this; - - translate(tx: number, ty: number): this; - - /** - * Sets this matrix as a 2D translation transform: - * - * ``` - * 1, 0, x, - * 0, 1, y, - * 0, 0, 1 - * ``` - * - * @param v the amount to translate. - */ - makeTranslation(v: Vector2): this; - /** - * Sets this matrix as a 2D translation transform: - * - * ``` - * 1, 0, x, - * 0, 1, y, - * 0, 0, 1 - * ``` - * - * @param x the amount to translate in the X axis. - * @param y the amount to translate in the Y axis. - */ - makeTranslation(x: number, y: number): this; - - /** - * Sets this matrix as a 2D rotational transformation by theta radians. The resulting matrix will be: - * - * ``` - * cos(θ) -sin(θ) 0 - * sin(θ) cos(θ) 0 - * 0 0 1 - * ``` - * - * @param theta Rotation angle in radians. Positive values rotate counterclockwise. - */ - makeRotation(theta: number): this; - - /** - * Sets this matrix as a 2D scale transform: - * - * ``` - * x, 0, 0, - * 0, y, 0, - * 0, 0, 1 - * ``` - * - * @param x the amount to scale in the X axis. - * @param y the amount to scale in the Y axis. - */ - makeScale(x: number, y: number): this; - - equals(matrix: Matrix3): boolean; - - /** - * Sets the values of this matrix from the provided array or array-like. - * @param array the source array or array-like. - * @param offset (optional) offset into the array-like. Default is 0. - */ - fromArray(array: ArrayLike, offset?: number): this; - - /** - * Writes the elements of this matrix to an array in - * {@link https://en.wikipedia.org/wiki/Row-_and_column-major_order#Column-major_order column-major} format. - */ - toArray(): Matrix3Tuple; - /** - * Writes the elements of this matrix to an array in - * {@link https://en.wikipedia.org/wiki/Row-_and_column-major_order#Column-major_order column-major} format. - * @param array array to store the resulting vector in. If not given a new array will be created. - * @param offset (optional) offset in the array at which to put the result. - */ - toArray>(array: TArray, offset?: number): TArray; - - clone(): this; -} diff --git a/src-testing/src/math/Matrix4.d.ts b/src-testing/src/math/Matrix4.d.ts deleted file mode 100644 index 9ef2a9ceb..000000000 --- a/src-testing/src/math/Matrix4.d.ts +++ /dev/null @@ -1,284 +0,0 @@ -import { CoordinateSystem } from "../constants.js"; -import { Euler } from "./Euler.js"; -import { Matrix3 } from "./Matrix3.js"; -import { Quaternion } from "./Quaternion.js"; -import { Vector3 } from "./Vector3.js"; - -export type Matrix4Tuple = [ - n11: number, - n12: number, - n13: number, - n14: number, - n21: number, - n22: number, - n23: number, - n24: number, - n31: number, - n32: number, - n33: number, - n34: number, - n41: number, - n42: number, - n43: number, - n44: number, -]; - -/** - * A 4x4 Matrix. - * - * @example - * // Simple rig for rotating around 3 axes - * const m = new THREE.Matrix4(); - * const m1 = new THREE.Matrix4(); - * const m2 = new THREE.Matrix4(); - * const m3 = new THREE.Matrix4(); - * const alpha = 0; - * const beta = Math.PI; - * const gamma = Math.PI/2; - * m1.makeRotationX( alpha ); - * m2.makeRotationY( beta ); - * m3.makeRotationZ( gamma ); - * m.multiplyMatrices( m1, m2 ); - * m.multiply( m3 ); - */ -export class Matrix4 { - readonly isMatrix4: true; - - /** - * Array with matrix values. - * @default [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] - */ - elements: Matrix4Tuple; - - /** - * Creates an identity matrix. - */ - constructor(); - /** - * Creates a 4x4 matrix with the given arguments in row-major order. - */ - constructor( - n11: number, - n12: number, - n13: number, - n14: number, - n21: number, - n22: number, - n23: number, - n24: number, - n31: number, - n32: number, - n33: number, - n34: number, - n41: number, - n42: number, - n43: number, - n44: number, - ); - - /** - * Sets all fields of this matrix. - */ - set( - n11: number, - n12: number, - n13: number, - n14: number, - n21: number, - n22: number, - n23: number, - n24: number, - n31: number, - n32: number, - n33: number, - n34: number, - n41: number, - n42: number, - n43: number, - n44: number, - ): this; - - /** - * Resets this matrix to identity. - */ - identity(): this; - - clone(): Matrix4; - - copy(m: Matrix4): this; - - copyPosition(m: Matrix4): this; - - /** - * Set the upper 3x3 elements of this matrix to the values of the Matrix3 m. - */ - setFromMatrix3(m: Matrix3): this; - - extractBasis(xAxis: Vector3, yAxis: Vector3, zAxis: Vector3): this; - - makeBasis(xAxis: Vector3, yAxis: Vector3, zAxis: Vector3): this; - - /** - * Copies the rotation component of the supplied matrix m into this matrix rotation component. - */ - extractRotation(m: Matrix4): this; - - makeRotationFromEuler(euler: Euler): this; - - makeRotationFromQuaternion(q: Quaternion): this; - - /** - * Constructs a rotation matrix, looking from eye towards center with defined up vector. - */ - lookAt(eye: Vector3, target: Vector3, up: Vector3): this; - - /** - * Multiplies this matrix by m. - */ - multiply(m: Matrix4): this; - - premultiply(m: Matrix4): this; - - /** - * Sets this matrix to a x b. - */ - multiplyMatrices(a: Matrix4, b: Matrix4): this; - - /** - * Multiplies this matrix by s. - */ - multiplyScalar(s: number): this; - - /** - * Computes determinant of this matrix. - * Based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm - */ - determinant(): number; - - /** - * Transposes this matrix. - */ - transpose(): this; - - /** - * Sets the position component for this matrix from vector v. - */ - setPosition(v: Vector3): this; - setPosition(x: number, y: number, z: number): this; - - /** - * Inverts this matrix. - */ - invert(): this; - - /** - * Multiplies the columns of this matrix by vector v. - */ - scale(v: Vector3): this; - - getMaxScaleOnAxis(): number; - - /** - * Sets this matrix as translation transform. - */ - makeTranslation(v: Vector3): this; - makeTranslation(x: number, y: number, z: number): this; - - /** - * Sets this matrix as rotation transform around x axis by theta radians. - * - * @param theta Rotation angle in radians. - */ - makeRotationX(theta: number): this; - - /** - * Sets this matrix as rotation transform around y axis by theta radians. - * - * @param theta Rotation angle in radians. - */ - makeRotationY(theta: number): this; - - /** - * Sets this matrix as rotation transform around z axis by theta radians. - * - * @param theta Rotation angle in radians. - */ - makeRotationZ(theta: number): this; - - /** - * Sets this matrix as rotation transform around axis by angle radians. - * Based on http://www.gamedev.net/reference/articles/article1199.asp. - * - * @param axis Rotation axis. - * @param angle Rotation angle in radians. - */ - makeRotationAxis(axis: Vector3, angle: number): this; - - /** - * Sets this matrix as scale transform. - */ - makeScale(x: number, y: number, z: number): this; - - /** - * Sets this matrix as shear transform. - */ - makeShear(xy: number, xz: number, yx: number, yz: number, zx: number, zy: number): this; - - /** - * Sets this matrix to the transformation composed of translation, rotation and scale. - */ - compose(position: Vector3, quaternion: Quaternion, scale: Vector3): this; - - /** - * Decomposes this matrix into it's position, quaternion and scale components. - */ - decompose(position: Vector3, quaternion: Quaternion, scale: Vector3): this; - - /** - * Creates a perspective projection matrix. - */ - makePerspective( - left: number, - right: number, - top: number, - bottom: number, - near: number, - far: number, - coordinateSystem?: CoordinateSystem, - ): this; - - /** - * Creates an orthographic projection matrix. - */ - makeOrthographic( - left: number, - right: number, - top: number, - bottom: number, - near: number, - far: number, - coordinateSystem?: CoordinateSystem, - ): this; - - equals(matrix: Matrix4): boolean; - - /** - * Sets the values of this matrix from the provided array or array-like. - * @param array the source array or array-like. - * @param offset (optional) offset into the array-like. Default is 0. - */ - fromArray(array: ArrayLike, offset?: number): this; - - /** - * Writes the elements of this matrix to an array in - * {@link https://en.wikipedia.org/wiki/Row-_and_column-major_order#Column-major_order column-major} format. - */ - toArray(): Matrix4Tuple; - /** - * Writes the elements of this matrix to an array in - * {@link https://en.wikipedia.org/wiki/Row-_and_column-major_order#Column-major_order column-major} format. - * @param array array to store the resulting vector in. - * @param offset (optional) offset in the array at which to put the result. - */ - toArray>(array: TArray, offset?: number): TArray; -} diff --git a/src-testing/src/math/Plane.d.ts b/src-testing/src/math/Plane.d.ts deleted file mode 100644 index 59fa23912..000000000 --- a/src-testing/src/math/Plane.d.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { Box3 } from "./Box3.js"; -import { Line3 } from "./Line3.js"; -import { Matrix3 } from "./Matrix3.js"; -import { Matrix4 } from "./Matrix4.js"; -import { Sphere } from "./Sphere.js"; -import { Vector3 } from "./Vector3.js"; - -export class Plane { - constructor(normal?: Vector3, constant?: number); - - /** - * @default new THREE.Vector3( 1, 0, 0 ) - */ - normal: Vector3; - - /** - * @default 0 - */ - constant: number; - - readonly isPlane: true; - - set(normal: Vector3, constant: number): Plane; - setComponents(x: number, y: number, z: number, w: number): Plane; - setFromNormalAndCoplanarPoint(normal: Vector3, point: Vector3): Plane; - setFromCoplanarPoints(a: Vector3, b: Vector3, c: Vector3): Plane; - clone(): this; - copy(plane: Plane): this; - normalize(): Plane; - negate(): Plane; - distanceToPoint(point: Vector3): number; - distanceToSphere(sphere: Sphere): number; - projectPoint(point: Vector3, target: Vector3): Vector3; - intersectLine(line: Line3, target: Vector3): Vector3 | null; - intersectsLine(line: Line3): boolean; - intersectsBox(box: Box3): boolean; - intersectsSphere(sphere: Sphere): boolean; - coplanarPoint(target: Vector3): Vector3; - applyMatrix4(matrix: Matrix4, optionalNormalMatrix?: Matrix3): Plane; - translate(offset: Vector3): Plane; - equals(plane: Plane): boolean; - - /** - * @deprecated Use {@link Plane#intersectsLine .intersectsLine()} instead. - */ - isIntersectionLine(l: any): any; -} diff --git a/src-testing/src/math/Quaternion.d.ts b/src-testing/src/math/Quaternion.d.ts deleted file mode 100644 index 7485b6956..000000000 --- a/src-testing/src/math/Quaternion.d.ts +++ /dev/null @@ -1,189 +0,0 @@ -import { BufferAttribute } from "../core/BufferAttribute.js"; -import { InterleavedBufferAttribute } from "../core/InterleavedBufferAttribute.js"; -import { Euler } from "./Euler.js"; -import { Matrix4 } from "./Matrix4.js"; -import { Vector3, Vector3Like } from "./Vector3.js"; - -export interface QuaternionLike { - readonly x: number; - readonly y: number; - readonly z: number; - readonly w: number; -} - -export type QuaternionTuple = [x: number, y: number, z: number, w: number]; - -/** - * Implementation of a quaternion. This is used for rotating things without incurring in the dreaded gimbal lock issue, amongst other advantages. - * - * @example - * const quaternion = new THREE.Quaternion(); - * quaternion.setFromAxisAngle( new THREE.Vector3( 0, 1, 0 ), Math.PI / 2 ); - * const vector = new THREE.Vector3( 1, 0, 0 ); - * vector.applyQuaternion( quaternion ); - */ -export class Quaternion { - /** - * @param x x coordinate - * @param y y coordinate - * @param z z coordinate - * @param w w coordinate - */ - constructor(x?: number, y?: number, z?: number, w?: number); - - /** - * @default 0 - */ - x: number; - - /** - * @default 0 - */ - y: number; - - /** - * @default 0 - */ - z: number; - - /** - * @default 1 - */ - w: number; - readonly isQuaternion: true; - - /** - * Sets values of this quaternion. - */ - set(x: number, y: number, z: number, w: number): this; - - /** - * Clones this quaternion. - */ - clone(): this; - - /** - * Copies values of q to this quaternion. - */ - copy(q: QuaternionLike): this; - - /** - * Sets this quaternion from rotation specified by Euler angles. - */ - setFromEuler(euler: Euler, update?: boolean): this; - - /** - * Sets this quaternion from rotation specified by axis and angle. - * Adapted from http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm. - * Axis have to be normalized, angle is in radians. - */ - setFromAxisAngle(axis: Vector3Like, angle: number): this; - - /** - * Sets this quaternion from rotation component of m. Adapted from http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm. - */ - setFromRotationMatrix(m: Matrix4): this; - setFromUnitVectors(vFrom: Vector3, vTo: Vector3Like): this; - angleTo(q: Quaternion): number; - rotateTowards(q: Quaternion, step: number): this; - - identity(): this; - - /** - * Inverts this quaternion. - */ - invert(): this; - - conjugate(): this; - dot(v: Quaternion): number; - lengthSq(): number; - - /** - * Computes length of this quaternion. - */ - length(): number; - - /** - * Normalizes this quaternion. - */ - normalize(): this; - - /** - * Multiplies this quaternion by b. - */ - multiply(q: Quaternion): this; - premultiply(q: Quaternion): this; - - /** - * Sets this quaternion to a x b - * Adapted from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm. - */ - multiplyQuaternions(a: Quaternion, b: Quaternion): this; - - slerp(qb: Quaternion, t: number): this; - slerpQuaternions(qa: Quaternion, qb: Quaternion, t: number): this; - equals(v: Quaternion): boolean; - - /** - * Sets this quaternion's x, y, z and w value from the provided array or array-like. - * @param array the source array or array-like. - * @param offset (optional) offset into the array. Default is 0. - */ - fromArray(array: number[] | ArrayLike, offset?: number): this; - - /** - * Returns an array [x, y, z, w], or copies x, y, z and w into the provided array. - * @param array (optional) array to store the quaternion to. If this is not provided, a new array will be created. - * @param offset (optional) optional offset into the array. - * @return The created or provided array. - */ - toArray(array?: number[], offset?: number): number[]; - toArray(array?: QuaternionTuple, offset?: 0): QuaternionTuple; - - /** - * Copies x, y, z and w into the provided array-like. - * @param array array-like to store the quaternion to. - * @param offset (optional) optional offset into the array. - * @return The provided array-like. - */ - toArray(array: ArrayLike, offset?: number): ArrayLike; - - /** - * This method defines the serialization result of Quaternion. - * @return The numerical elements of this quaternion in an array of format [x, y, z, w]. - */ - toJSON(): [number, number, number, number]; - - /** - * Sets x, y, z, w properties of this quaternion from the attribute. - * @param attribute the source attribute. - * @param index index in the attribute. - */ - fromBufferAttribute(attribute: BufferAttribute | InterleavedBufferAttribute, index: number): this; - - _onChange(callback: () => void): this; - _onChangeCallback: () => void; - - static slerpFlat( - dst: number[], - dstOffset: number, - src0: number[], - srcOffset: number, - src1: number[], - stcOffset1: number, - t: number, - ): void; - - static multiplyQuaternionsFlat( - dst: number[], - dstOffset: number, - src0: number[], - srcOffset: number, - src1: number[], - stcOffset1: number, - ): number[]; - - random(): this; - - [Symbol.iterator](): Generator; -} diff --git a/src-testing/src/math/Ray.d.ts b/src-testing/src/math/Ray.d.ts deleted file mode 100644 index 98b9fd70f..000000000 --- a/src-testing/src/math/Ray.d.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { Box3 } from "./Box3.js"; -import { Matrix4 } from "./Matrix4.js"; -import { Plane } from "./Plane.js"; -import { Sphere } from "./Sphere.js"; -import { Vector3 } from "./Vector3.js"; - -export class Ray { - constructor(origin?: Vector3, direction?: Vector3); - - /** - * @default new THREE.Vector3() - */ - origin: Vector3; - - /** - * @default new THREE.Vector3( 0, 0, - 1 ) - */ - direction: Vector3; - - set(origin: Vector3, direction: Vector3): Ray; - clone(): this; - copy(ray: Ray): this; - at(t: number, target: Vector3): Vector3; - lookAt(v: Vector3): Ray; - recast(t: number): Ray; - closestPointToPoint(point: Vector3, target: Vector3): Vector3; - distanceToPoint(point: Vector3): number; - distanceSqToPoint(point: Vector3): number; - distanceSqToSegment( - v0: Vector3, - v1: Vector3, - optionalPointOnRay?: Vector3, - optionalPointOnSegment?: Vector3, - ): number; - intersectSphere(sphere: Sphere, target: Vector3): Vector3 | null; - intersectsSphere(sphere: Sphere): boolean; - distanceToPlane(plane: Plane): number; - intersectPlane(plane: Plane, target: Vector3): Vector3 | null; - intersectsPlane(plane: Plane): boolean; - intersectBox(box: Box3, target: Vector3): Vector3 | null; - intersectsBox(box: Box3): boolean; - intersectTriangle(a: Vector3, b: Vector3, c: Vector3, backfaceCulling: boolean, target: Vector3): Vector3 | null; - applyMatrix4(matrix4: Matrix4): Ray; - equals(ray: Ray): boolean; - - /** - * @deprecated Use {@link Ray#intersectsBox .intersectsBox()} instead. - */ - isIntersectionBox(b: any): any; - - /** - * @deprecated Use {@link Ray#intersectsPlane .intersectsPlane()} instead. - */ - isIntersectionPlane(p: any): any; - - /** - * @deprecated Use {@link Ray#intersectsSphere .intersectsSphere()} instead. - */ - isIntersectionSphere(s: any): any; -} diff --git a/src-testing/src/math/Sphere.d.ts b/src-testing/src/math/Sphere.d.ts deleted file mode 100644 index a423a6f97..000000000 --- a/src-testing/src/math/Sphere.d.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { Box3 } from "./Box3.js"; -import { Matrix4 } from "./Matrix4.js"; -import { Plane } from "./Plane.js"; -import { Vector3 } from "./Vector3.js"; - -export class Sphere { - constructor(center?: Vector3, radius?: number); - - /** - * Read-only flag to check if a given object is of type {@link Sphere}. - */ - readonly isSphere: true; - - /** - * @default new Vector3() - */ - center: Vector3; - - /** - * @default 1 - */ - radius: number; - - set(center: Vector3, radius: number): Sphere; - setFromPoints(points: Vector3[], optionalCenter?: Vector3): Sphere; - clone(): this; - copy(sphere: Sphere): this; - expandByPoint(point: Vector3): this; - isEmpty(): boolean; - makeEmpty(): this; - containsPoint(point: Vector3): boolean; - distanceToPoint(point: Vector3): number; - intersectsSphere(sphere: Sphere): boolean; - intersectsBox(box: Box3): boolean; - intersectsPlane(plane: Plane): boolean; - clampPoint(point: Vector3, target: Vector3): Vector3; - getBoundingBox(target: Box3): Box3; - applyMatrix4(matrix: Matrix4): Sphere; - translate(offset: Vector3): Sphere; - equals(sphere: Sphere): boolean; - union(sphere: Sphere): this; - - /** - * @deprecated Use {@link Sphere#isEmpty .isEmpty()} instead. - */ - empty(): any; -} diff --git a/src-testing/src/math/Spherical.d.ts b/src-testing/src/math/Spherical.d.ts deleted file mode 100644 index 8d4815a17..000000000 --- a/src-testing/src/math/Spherical.d.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { Vector3 } from "./Vector3.js"; - -export class Spherical { - constructor(radius?: number, phi?: number, theta?: number); - - /** - * @default 1 - */ - radius: number; - - /** - * @default 0 - */ - phi: number; - - /** - * @default 0 - */ - theta: number; - - set(radius: number, phi: number, theta: number): this; - clone(): this; - copy(other: Spherical): this; - makeSafe(): this; - setFromVector3(v: Vector3): this; - setFromCartesianCoords(x: number, y: number, z: number): this; -} diff --git a/src-testing/src/math/SphericalHarmonics3.d.ts b/src-testing/src/math/SphericalHarmonics3.d.ts deleted file mode 100644 index 5981a0b48..000000000 --- a/src-testing/src/math/SphericalHarmonics3.d.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { Vector3 } from "./Vector3.js"; - -export class SphericalHarmonics3 { - constructor(); - - /** - * @default [new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3(), - * new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3()] - */ - coefficients: Vector3[]; - readonly isSphericalHarmonics3: true; - - set(coefficients: Vector3[]): SphericalHarmonics3; - zero(): SphericalHarmonics3; - add(sh: SphericalHarmonics3): SphericalHarmonics3; - addScaledSH(sh: SphericalHarmonics3, s: number): SphericalHarmonics3; - scale(s: number): SphericalHarmonics3; - lerp(sh: SphericalHarmonics3, alpha: number): SphericalHarmonics3; - equals(sh: SphericalHarmonics3): boolean; - copy(sh: SphericalHarmonics3): SphericalHarmonics3; - clone(): this; - - /** - * Sets the values of this spherical harmonics from the provided array or array-like. - * @param array the source array or array-like. - * @param offset (optional) offset into the array. Default is 0. - */ - fromArray(array: number[] | ArrayLike, offset?: number): this; - - /** - * Returns an array with the values of this spherical harmonics, or copies them into the provided array. - * @param array (optional) array to store the spherical harmonics to. If this is not provided, a new array will be created. - * @param offset (optional) optional offset into the array. - * @return The created or provided array. - */ - toArray(array?: number[], offset?: number): number[]; - - /** - * Returns an array with the values of this spherical harmonics, or copies them into the provided array-like. - * @param array array-like to store the spherical harmonics to. - * @param offset (optional) optional offset into the array-like. - * @return The provided array-like. - */ - toArray(array: ArrayLike, offset?: number): ArrayLike; - - getAt(normal: Vector3, target: Vector3): Vector3; - getIrradianceAt(normal: Vector3, target: Vector3): Vector3; - - static getBasisAt(normal: Vector3, shBasis: number[]): void; -} diff --git a/src-testing/src/math/Triangle.d.ts b/src-testing/src/math/Triangle.d.ts deleted file mode 100644 index 9f0e7935b..000000000 --- a/src-testing/src/math/Triangle.d.ts +++ /dev/null @@ -1,110 +0,0 @@ -import { Box3 } from "./Box3.js"; -import { Plane } from "./Plane.js"; -import { Vector2 } from "./Vector2.js"; -import { Vector3 } from "./Vector3.js"; -import { Vector4 } from "./Vector4.js"; - -import { BufferAttribute } from "../core/BufferAttribute.js"; -import { InterleavedBufferAttribute } from "../core/InterleavedBufferAttribute.js"; - -export class Triangle { - constructor(a?: Vector3, b?: Vector3, c?: Vector3); - - /** - * @default new THREE.Vector3() - */ - a: Vector3; - - /** - * @default new THREE.Vector3() - */ - b: Vector3; - - /** - * @default new THREE.Vector3() - */ - c: Vector3; - - set(a: Vector3, b: Vector3, c: Vector3): Triangle; - setFromPointsAndIndices(points: Vector3[], i0: number, i1: number, i2: number): this; - setFromAttributeAndIndices( - attribute: BufferAttribute | InterleavedBufferAttribute, - i0: number, - i1: number, - i2: number, - ): this; - clone(): this; - copy(triangle: Triangle): this; - getArea(): number; - getMidpoint(target: Vector3): Vector3; - getNormal(target: Vector3): Vector3; - getPlane(target: Plane): Plane; - getBarycoord(point: Vector3, target: Vector3): Vector3 | null; - getInterpolation(point: Vector3, v1: Vector2, v2: Vector2, v3: Vector2, target: Vector2): Vector2 | null; - getInterpolation(point: Vector3, v1: Vector3, v2: Vector3, v3: Vector3, target: Vector3): Vector3 | null; - getInterpolation(point: Vector3, v1: Vector4, v2: Vector4, v3: Vector4, target: Vector4): Vector4 | null; - containsPoint(point: Vector3): boolean; - intersectsBox(box: Box3): boolean; - isFrontFacing(direction: Vector3): boolean; - closestPointToPoint(point: Vector3, target: Vector3): Vector3; - equals(triangle: Triangle): boolean; - - static getNormal(a: Vector3, b: Vector3, c: Vector3, target: Vector3): Vector3; - static getBarycoord(point: Vector3, a: Vector3, b: Vector3, c: Vector3, target: Vector3): Vector3 | null; - static containsPoint(point: Vector3, a: Vector3, b: Vector3, c: Vector3): boolean; - static getInterpolation( - point: Vector3, - p1: Vector3, - p2: Vector3, - p3: Vector3, - v1: Vector2, - v2: Vector2, - v3: Vector2, - target: Vector2, - ): Vector2 | null; - static getInterpolation( - point: Vector3, - p1: Vector3, - p2: Vector3, - p3: Vector3, - v1: Vector3, - v2: Vector3, - v3: Vector3, - target: Vector3, - ): Vector3 | null; - static getInterpolation( - point: Vector3, - p1: Vector3, - p2: Vector3, - p3: Vector3, - v1: Vector4, - v2: Vector4, - v3: Vector4, - target: Vector4, - ): Vector4 | null; - static getInterpolatedAttribute( - attr: BufferAttribute, - i1: number, - i2: number, - i3: number, - barycoord: Vector3, - target: Vector2, - ): Vector2; - static getInterpolatedAttribute( - attr: BufferAttribute, - i1: number, - i2: number, - i3: number, - barycoord: Vector3, - target: Vector3, - ): Vector3; - static getInterpolatedAttribute( - attr: BufferAttribute, - i1: number, - i2: number, - i3: number, - barycoord: Vector3, - target: Vector4, - ): Vector4; - static isFrontFacing(a: Vector3, b: Vector3, c: Vector3, direction: Vector3): boolean; -} diff --git a/src-testing/src/math/Vector2.d.ts b/src-testing/src/math/Vector2.d.ts deleted file mode 100644 index fd2a84a1d..000000000 --- a/src-testing/src/math/Vector2.d.ts +++ /dev/null @@ -1,321 +0,0 @@ -import { BufferAttribute } from "../core/BufferAttribute.js"; -import { Matrix3 } from "./Matrix3.js"; - -export type Vector2Tuple = [x: number, y: number]; - -export interface Vector2Like { - readonly x: number; - readonly y: number; -} - -/** - * 2D vector. - */ -export class Vector2 { - constructor(x?: number, y?: number); - - /** - * @default 0 - */ - x: number; - - /** - * @default 0 - */ - y: number; - width: number; - height: number; - readonly isVector2: true; - - /** - * Sets value of this vector. - */ - set(x: number, y: number): this; - - /** - * Sets the x and y values of this vector both equal to scalar. - */ - setScalar(scalar: number): this; - - /** - * Sets X component of this vector. - */ - setX(x: number): this; - - /** - * Sets Y component of this vector. - */ - setY(y: number): this; - - /** - * Sets a component of this vector. - */ - setComponent(index: number, value: number): this; - - /** - * Gets a component of this vector. - */ - getComponent(index: number): number; - - /** - * Returns a new Vector2 instance with the same `x` and `y` values. - */ - clone(): this; - - /** - * Copies value of v to this vector. - */ - copy(v: Vector2Like): this; - - /** - * Adds v to this vector. - */ - add(v: Vector2Like): this; - - /** - * Adds the scalar value s to this vector's x and y values. - */ - addScalar(s: number): this; - - /** - * Sets this vector to a + b. - */ - addVectors(a: Vector2Like, b: Vector2Like): this; - - /** - * Adds the multiple of v and s to this vector. - */ - addScaledVector(v: Vector2Like, s: number): this; - - /** - * Subtracts v from this vector. - */ - sub(v: Vector2Like): this; - - /** - * Subtracts s from this vector's x and y components. - */ - subScalar(s: number): this; - - /** - * Sets this vector to a - b. - */ - subVectors(a: Vector2Like, b: Vector2Like): this; - - /** - * Multiplies this vector by v. - */ - multiply(v: Vector2Like): this; - - /** - * Multiplies this vector by scalar s. - */ - multiplyScalar(scalar: number): this; - - /** - * Divides this vector by v. - */ - divide(v: Vector2Like): this; - - /** - * Divides this vector by scalar s. - * Set vector to ( 0, 0 ) if s == 0. - */ - divideScalar(s: number): this; - - /** - * Multiplies this vector (with an implicit 1 as the 3rd component) by m. - */ - applyMatrix3(m: Matrix3): this; - - /** - * If this vector's x or y value is greater than v's x or y value, replace that value with the corresponding min value. - */ - min(v: Vector2Like): this; - - /** - * If this vector's x or y value is less than v's x or y value, replace that value with the corresponding max value. - */ - max(v: Vector2Like): this; - - /** - * If this vector's x or y value is greater than the max vector's x or y value, it is replaced by the corresponding value. - * If this vector's x or y value is less than the min vector's x or y value, it is replaced by the corresponding value. - * @param min the minimum x and y values. - * @param max the maximum x and y values in the desired range. - */ - clamp(min: Vector2Like, max: Vector2Like): this; - - /** - * If this vector's x or y values are greater than the max value, they are replaced by the max value. - * If this vector's x or y values are less than the min value, they are replaced by the min value. - * @param min the minimum value the components will be clamped to. - * @param max the maximum value the components will be clamped to. - */ - clampScalar(min: number, max: number): this; - - /** - * If this vector's length is greater than the max value, it is replaced by the max value. - * If this vector's length is less than the min value, it is replaced by the min value. - * @param min the minimum value the length will be clamped to. - * @param max the maximum value the length will be clamped to. - */ - clampLength(min: number, max: number): this; - - /** - * The components of the vector are rounded down to the nearest integer value. - */ - floor(): this; - - /** - * The x and y components of the vector are rounded up to the nearest integer value. - */ - ceil(): this; - - /** - * The components of the vector are rounded to the nearest integer value. - */ - round(): this; - - /** - * The components of the vector are rounded towards zero (up if negative, down if positive) to an integer value. - */ - roundToZero(): this; - - /** - * Inverts this vector. - */ - negate(): this; - - /** - * Computes dot product of this vector and v. - */ - dot(v: Vector2Like): number; - - /** - * Computes cross product of this vector and v. - */ - cross(v: Vector2Like): number; - - /** - * Computes squared length of this vector. - */ - lengthSq(): number; - - /** - * Computes length of this vector. - */ - length(): number; - - /** - * Computes the Manhattan length of this vector. - * - * see {@link http://en.wikipedia.org/wiki/Taxicab_geometry|Wikipedia: Taxicab Geometry} - */ - manhattanLength(): number; - - /** - * Normalizes this vector. - */ - normalize(): this; - - /** - * computes the angle in radians with respect to the positive x-axis - */ - angle(): number; - - /** - * Returns the angle between this vector and vector {@link Vector2 | v} in radians. - */ - angleTo(v: Vector2): number; - - /** - * Computes distance of this vector to v. - */ - distanceTo(v: Vector2Like): number; - - /** - * Computes squared distance of this vector to v. - */ - distanceToSquared(v: Vector2Like): number; - - /** - * Computes the Manhattan length (distance) from this vector to the given vector v - * - * see {@link http://en.wikipedia.org/wiki/Taxicab_geometry|Wikipedia: Taxicab Geometry} - */ - manhattanDistanceTo(v: Vector2Like): number; - - /** - * Normalizes this vector and multiplies it by l. - */ - setLength(length: number): this; - - /** - * Linearly interpolates between this vector and v, where alpha is the distance along the line - alpha = 0 will be this vector, and alpha = 1 will be v. - * @param v vector to interpolate towards. - * @param alpha interpolation factor in the closed interval [0, 1]. - */ - lerp(v: Vector2Like, alpha: number): this; - - /** - * Sets this vector to be the vector linearly interpolated between v1 and v2 where alpha is the distance along the line connecting the two vectors - alpha = 0 will be v1, and alpha = 1 will be v2. - * @param v1 the starting vector. - * @param v2 vector to interpolate towards. - * @param alpha interpolation factor in the closed interval [0, 1]. - */ - lerpVectors(v1: Vector2Like, v2: Vector2Like, alpha: number): this; - - /** - * Checks for strict equality of this vector and v. - */ - equals(v: Vector2Like): boolean; - - /** - * Sets this vector's x and y value from the provided array or array-like. - * @param array the source array or array-like. - * @param offset (optional) offset into the array. Default is 0. - */ - fromArray(array: number[] | ArrayLike, offset?: number): this; - - /** - * Returns an array [x, y], or copies x and y into the provided array. - * @param array (optional) array to store the vector to. If this is not provided, a new array will be created. - * @param offset (optional) optional offset into the array. - * @return The created or provided array. - */ - toArray(array?: number[], offset?: number): number[]; - toArray(array?: Vector2Tuple, offset?: 0): Vector2Tuple; - - /** - * Copies x and y into the provided array-like. - * @param array array-like to store the vector to. - * @param offset (optional) optional offset into the array. - * @return The provided array-like. - */ - toArray(array: ArrayLike, offset?: number): ArrayLike; - - /** - * Sets this vector's x and y values from the attribute. - * @param attribute the source attribute. - * @param index index in the attribute. - */ - fromBufferAttribute(attribute: BufferAttribute, index: number): this; - - /** - * Rotates the vector around center by angle radians. - * @param center the point around which to rotate. - * @param angle the angle to rotate, in radians. - */ - rotateAround(center: Vector2Like, angle: number): this; - - /** - * Sets this vector's x and y from Math.random - */ - random(): this; - - /** - * Iterating through a Vector2 instance will yield its components (x, y) in the corresponding order. - */ - [Symbol.iterator](): Iterator; -} diff --git a/src-testing/src/math/Vector3.d.ts b/src-testing/src/math/Vector3.d.ts deleted file mode 100644 index 56e907ceb..000000000 --- a/src-testing/src/math/Vector3.d.ts +++ /dev/null @@ -1,301 +0,0 @@ -import { Camera } from "../cameras/Camera.js"; -import { BufferAttribute } from "../core/BufferAttribute.js"; -import { InterleavedBufferAttribute } from "../core/InterleavedBufferAttribute.js"; -import { RGB } from "./Color.js"; -import { Cylindrical } from "./Cylindrical.js"; -import { Euler } from "./Euler.js"; -import { Matrix3 } from "./Matrix3.js"; -import { Matrix4 } from "./Matrix4.js"; -import { QuaternionLike } from "./Quaternion.js"; -import { Spherical } from "./Spherical.js"; - -export type Vector3Tuple = [number, number, number]; - -export interface Vector3Like { - readonly x: number; - readonly y: number; - readonly z: number; -} - -/** - * 3D vector. - * - * see {@link https://github.com/mrdoob/three.js/blob/master/src/math/Vector3.js} - * - * @example - * const a = new THREE.Vector3( 1, 0, 0 ); - * const b = new THREE.Vector3( 0, 1, 0 ); - * const c = new THREE.Vector3(); - * c.crossVectors( a, b ); - */ -export class Vector3 { - constructor(x?: number, y?: number, z?: number); - - /** - * @default 0 - */ - x: number; - - /** - * @default 0 - */ - y: number; - - /** - * @default 0 - */ - z: number; - readonly isVector3: true; - - /** - * Sets value of this vector. - */ - set(x: number, y: number, z: number): this; - - /** - * Sets all values of this vector. - */ - setScalar(scalar: number): this; - - /** - * Sets x value of this vector. - */ - setX(x: number): this; - - /** - * Sets y value of this vector. - */ - setY(y: number): this; - - /** - * Sets z value of this vector. - */ - setZ(z: number): this; - - setComponent(index: number, value: number): this; - - getComponent(index: number): number; - - /** - * Clones this vector. - */ - clone(): this; - - /** - * Copies value of v to this vector. - */ - copy(v: Vector3Like): this; - - /** - * Adds v to this vector. - */ - add(v: Vector3Like): this; - - addScalar(s: number): this; - - /** - * Sets this vector to a + b. - */ - addVectors(a: Vector3Like, b: Vector3Like): this; - - addScaledVector(v: Vector3, s: number): this; - - /** - * Subtracts v from this vector. - */ - sub(a: Vector3Like): this; - - subScalar(s: number): this; - - /** - * Sets this vector to a - b. - */ - subVectors(a: Vector3Like, b: Vector3Like): this; - - multiply(v: Vector3Like): this; - - /** - * Multiplies this vector by scalar s. - */ - multiplyScalar(s: number): this; - - multiplyVectors(a: Vector3Like, b: Vector3Like): this; - - applyEuler(euler: Euler): this; - - applyAxisAngle(axis: Vector3, angle: number): this; - - applyMatrix3(m: Matrix3): this; - - applyNormalMatrix(m: Matrix3): this; - - applyMatrix4(m: Matrix4): this; - - applyQuaternion(q: QuaternionLike): this; - - project(camera: Camera): this; - - unproject(camera: Camera): this; - - transformDirection(m: Matrix4): this; - - divide(v: Vector3Like): this; - - /** - * Divides this vector by scalar s. - * Set vector to ( 0, 0, 0 ) if s == 0. - */ - divideScalar(s: number): this; - - min(v: Vector3Like): this; - - max(v: Vector3Like): this; - - clamp(min: Vector3Like, max: Vector3Like): this; - - clampScalar(min: number, max: number): this; - - clampLength(min: number, max: number): this; - - floor(): this; - - ceil(): this; - - round(): this; - - roundToZero(): this; - - /** - * Inverts this vector. - */ - negate(): this; - - /** - * Computes dot product of this vector and v. - */ - dot(v: Vector3Like): number; - - /** - * Computes squared length of this vector. - */ - lengthSq(): number; - - /** - * Computes length of this vector. - */ - length(): number; - - /** - * Computes the Manhattan length of this vector. - * - * see {@link http://en.wikipedia.org/wiki/Taxicab_geometry|Wikipedia: Taxicab Geometry} - */ - manhattanLength(): number; - - /** - * Normalizes this vector. - */ - normalize(): this; - - /** - * Normalizes this vector and multiplies it by l. - */ - setLength(l: number): this; - lerp(v: Vector3Like, alpha: number): this; - - lerpVectors(v1: Vector3Like, v2: Vector3Like, alpha: number): this; - - /** - * Sets this vector to cross product of itself and v. - */ - cross(a: Vector3Like): this; - - /** - * Sets this vector to cross product of a and b. - */ - crossVectors(a: Vector3Like, b: Vector3Like): this; - projectOnVector(v: Vector3): this; - projectOnPlane(planeNormal: Vector3): this; - reflect(vector: Vector3Like): this; - angleTo(v: Vector3): number; - - /** - * Computes distance of this vector to v. - */ - distanceTo(v: Vector3Like): number; - - /** - * Computes squared distance of this vector to v. - */ - distanceToSquared(v: Vector3Like): number; - - /** - * Computes the Manhattan length (distance) from this vector to the given vector v - * - * see {@link http://en.wikipedia.org/wiki/Taxicab_geometry|Wikipedia: Taxicab Geometry} - */ - manhattanDistanceTo(v: Vector3Like): number; - - setFromSpherical(s: Spherical): this; - setFromSphericalCoords(r: number, phi: number, theta: number): this; - setFromCylindrical(s: Cylindrical): this; - setFromCylindricalCoords(radius: number, theta: number, y: number): this; - setFromMatrixPosition(m: Matrix4): this; - setFromMatrixScale(m: Matrix4): this; - setFromMatrixColumn(matrix: Matrix4, index: number): this; - setFromMatrix3Column(matrix: Matrix3, index: number): this; - - /** - * Sets this vector's {@link x}, {@link y} and {@link z} components from the x, y, and z components of the specified {@link Euler Euler Angle}. - */ - setFromEuler(e: Euler): this; - - /** - * Sets this vector's {@link x}, {@link y} and {@link z} components from the r, g, and b components of the specified - * {@link Color | color}. - */ - setFromColor(color: RGB): this; - - /** - * Checks for strict equality of this vector and v. - */ - equals(v: Vector3Like): boolean; - - /** - * Sets this vector's x, y and z value from the provided array or array-like. - * @param array the source array or array-like. - * @param offset (optional) offset into the array. Default is 0. - */ - fromArray(array: number[] | ArrayLike, offset?: number): this; - - /** - * Returns an array [x, y, z], or copies x, y and z into the provided array. - * @param array (optional) array to store the vector to. If this is not provided, a new array will be created. - * @param offset (optional) optional offset into the array. - * @return The created or provided array. - */ - toArray(array?: number[], offset?: number): number[]; - toArray(array?: Vector3Tuple, offset?: 0): Vector3Tuple; - - /** - * Copies x, y and z into the provided array-like. - * @param array array-like to store the vector to. - * @param offset (optional) optional offset into the array-like. - * @return The provided array-like. - */ - toArray(array: ArrayLike, offset?: number): ArrayLike; - - fromBufferAttribute(attribute: BufferAttribute | InterleavedBufferAttribute, index: number): this; - - /** - * Sets this vector's x, y and z from Math.random - */ - random(): this; - - randomDirection(): this; - - /** - * Iterating through a Vector3 instance will yield its components (x, y, z) in the corresponding order. - */ - [Symbol.iterator](): Iterator; -} diff --git a/src-testing/src/math/Vector4.d.ts b/src-testing/src/math/Vector4.d.ts deleted file mode 100644 index 88cf74ff2..000000000 --- a/src-testing/src/math/Vector4.d.ts +++ /dev/null @@ -1,239 +0,0 @@ -import { BufferAttribute } from "../core/BufferAttribute.js"; -import { Matrix4 } from "./Matrix4.js"; -import { QuaternionLike } from "./Quaternion.js"; - -export type Vector4Tuple = [number, number, number, number]; - -export interface Vector4Like { - readonly x: number; - readonly y: number; - readonly z: number; - readonly w: number; -} - -/** - * 4D vector. - */ -export class Vector4 { - constructor(x?: number, y?: number, z?: number, w?: number); - - /** - * @default 0 - */ - x: number; - - /** - * @default 0 - */ - y: number; - - /** - * @default 0 - */ - z: number; - - /** - * @default 0 - */ - w: number; - - width: number; - height: number; - readonly isVector4: true; - - /** - * Sets value of this vector. - */ - set(x: number, y: number, z: number, w: number): this; - - /** - * Sets all values of this vector. - */ - setScalar(scalar: number): this; - - /** - * Sets X component of this vector. - */ - setX(x: number): this; - - /** - * Sets Y component of this vector. - */ - setY(y: number): this; - - /** - * Sets Z component of this vector. - */ - setZ(z: number): this; - - /** - * Sets w component of this vector. - */ - setW(w: number): this; - - setComponent(index: number, value: number): this; - - getComponent(index: number): number; - - /** - * Clones this vector. - */ - clone(): this; - - /** - * Copies value of v to this vector. - */ - copy(v: Vector4Like): this; - - /** - * Adds v to this vector. - */ - add(v: Vector4Like): this; - - addScalar(scalar: number): this; - - /** - * Sets this vector to a + b. - */ - addVectors(a: Vector4Like, b: Vector4Like): this; - - addScaledVector(v: Vector4Like, s: number): this; - /** - * Subtracts v from this vector. - */ - sub(v: Vector4Like): this; - - subScalar(s: number): this; - - /** - * Sets this vector to a - b. - */ - subVectors(a: Vector4Like, b: Vector4Like): this; - - multiply(v: Vector4Like): this; - - /** - * Multiplies this vector by scalar s. - */ - multiplyScalar(s: number): this; - - applyMatrix4(m: Matrix4): this; - - /** - * Divides this vector by scalar s. - * Set vector to ( 0, 0, 0 ) if s == 0. - */ - divideScalar(s: number): this; - - /** - * http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm - * @param q is assumed to be normalized - */ - setAxisAngleFromQuaternion(q: QuaternionLike): this; - - /** - * http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/index.htm - * @param m assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) - */ - setAxisAngleFromRotationMatrix(m: Matrix4): this; - - /** - * Sets this vector to the position elements of the - * [transformation matrix]{@link https://en.wikipedia.org/wiki/Transformation_matrix} m. - */ - setFromMatrixPosition(m: Matrix4): this; - - min(v: Vector4Like): this; - max(v: Vector4Like): this; - clamp(min: Vector4Like, max: Vector4Like): this; - clampScalar(min: number, max: number): this; - floor(): this; - ceil(): this; - round(): this; - roundToZero(): this; - - /** - * Inverts this vector. - */ - negate(): this; - - /** - * Computes dot product of this vector and v. - */ - dot(v: Vector4Like): number; - - /** - * Computes squared length of this vector. - */ - lengthSq(): number; - - /** - * Computes length of this vector. - */ - length(): number; - - /** - * Computes the Manhattan length of this vector. - * - * see {@link http://en.wikipedia.org/wiki/Taxicab_geometry|Wikipedia: Taxicab Geometry} - */ - manhattanLength(): number; - - /** - * Normalizes this vector. - */ - normalize(): this; - - /** - * Normalizes this vector and multiplies it by l. - */ - setLength(length: number): this; - - /** - * Linearly interpolate between this vector and v with alpha factor. - */ - lerp(v: Vector4Like, alpha: number): this; - - lerpVectors(v1: Vector4Like, v2: Vector4Like, alpha: number): this; - - /** - * Checks for strict equality of this vector and v. - */ - equals(v: Vector4Like): boolean; - - /** - * Sets this vector's x, y, z and w value from the provided array or array-like. - * @param array the source array or array-like. - * @param offset (optional) offset into the array. Default is 0. - */ - fromArray(array: number[] | ArrayLike, offset?: number): this; - - /** - * Returns an array [x, y, z, w], or copies x, y, z and w into the provided array. - * @param array (optional) array to store the vector to. If this is not provided, a new array will be created. - * @param offset (optional) optional offset into the array. - * @return The created or provided array. - */ - toArray(array?: number[], offset?: number): number[]; - toArray(array?: Vector4Tuple, offset?: 0): Vector4Tuple; - - /** - * Copies x, y, z and w into the provided array-like. - * @param array array-like to store the vector to. - * @param offset (optional) optional offset into the array-like. - * @return The provided array-like. - */ - toArray(array: ArrayLike, offset?: number): ArrayLike; - - fromBufferAttribute(attribute: BufferAttribute, index: number): this; - - /** - * Sets this vector's x, y, z and w from Math.random - */ - random(): this; - - /** - * Iterating through a Vector4 instance will yield its components (x, y, z, w) in the corresponding order. - */ - [Symbol.iterator](): Iterator; -} diff --git a/src-testing/src/math/interpolants/CubicInterpolant.d.ts b/src-testing/src/math/interpolants/CubicInterpolant.d.ts deleted file mode 100644 index 282b98d7e..000000000 --- a/src-testing/src/math/interpolants/CubicInterpolant.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { Interpolant } from "../Interpolant.js"; - -export class CubicInterpolant extends Interpolant { - constructor(parameterPositions: any, samplesValues: any, sampleSize: number, resultBuffer?: any); - - interpolate_(i1: number, t0: number, t: number, t1: number): any; -} diff --git a/src-testing/src/math/interpolants/DiscreteInterpolant.d.ts b/src-testing/src/math/interpolants/DiscreteInterpolant.d.ts deleted file mode 100644 index 28bd458b8..000000000 --- a/src-testing/src/math/interpolants/DiscreteInterpolant.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { Interpolant } from "../Interpolant.js"; - -export class DiscreteInterpolant extends Interpolant { - constructor(parameterPositions: any, samplesValues: any, sampleSize: number, resultBuffer?: any); - - interpolate_(i1: number, t0: number, t: number, t1: number): any; -} diff --git a/src-testing/src/math/interpolants/LinearInterpolant.d.ts b/src-testing/src/math/interpolants/LinearInterpolant.d.ts deleted file mode 100644 index e6ff11c0b..000000000 --- a/src-testing/src/math/interpolants/LinearInterpolant.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { Interpolant } from "../Interpolant.js"; - -export class LinearInterpolant extends Interpolant { - constructor(parameterPositions: any, samplesValues: any, sampleSize: number, resultBuffer?: any); - - interpolate_(i1: number, t0: number, t: number, t1: number): any; -} diff --git a/src-testing/src/math/interpolants/QuaternionLinearInterpolant.d.ts b/src-testing/src/math/interpolants/QuaternionLinearInterpolant.d.ts deleted file mode 100644 index dccb66976..000000000 --- a/src-testing/src/math/interpolants/QuaternionLinearInterpolant.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { Interpolant } from "../Interpolant.js"; - -export class QuaternionLinearInterpolant extends Interpolant { - constructor(parameterPositions: any, samplesValues: any, sampleSize: number, resultBuffer?: any); - - interpolate_(i1: number, t0: number, t: number, t1: number): any; -} diff --git a/src-testing/src/nodes/Nodes.ts b/src-testing/src/nodes/Nodes.ts deleted file mode 100644 index 648eec734..000000000 --- a/src-testing/src/nodes/Nodes.ts +++ /dev/null @@ -1,144 +0,0 @@ -// constants -export * from './core/constants.js'; - -// core -export { default as AssignNode } from './core/AssignNode.js'; -export { default as AttributeNode } from './core/AttributeNode.js'; -export { default as BypassNode } from './core/BypassNode.js'; -export { default as CacheNode } from './core/CacheNode.js'; -export { default as ConstNode } from './core/ConstNode.js'; -export { default as ContextNode } from './core/ContextNode.js'; -export { default as IndexNode } from './core/IndexNode.js'; -export { default as LightingModel } from './core/LightingModel.js'; -export { default as Node } from './core/Node.js'; -export { default as VarNode } from './core/VarNode.js'; -export { default as NodeAttribute } from './core/NodeAttribute.js'; -export { default as NodeBuilder } from './core/NodeBuilder.js'; -export { default as NodeCache } from './core/NodeCache.js'; -export { default as NodeCode } from './core/NodeCode.js'; -export { default as NodeFrame } from './core/NodeFrame.js'; -export { default as NodeFunctionInput } from './core/NodeFunctionInput.js'; -export { default as NodeUniform } from './core/NodeUniform.js'; -export { default as NodeVar } from './core/NodeVar.js'; -export { default as NodeVarying } from './core/NodeVarying.js'; -export { default as ParameterNode } from './core/ParameterNode.js'; -export { default as PropertyNode } from './core/PropertyNode.js'; -export { default as StackNode } from './core/StackNode.js'; -export { default as TempNode } from './core/TempNode.js'; -export { default as UniformGroupNode } from './core/UniformGroupNode.js'; -export { default as UniformNode } from './core/UniformNode.js'; -export { default as VaryingNode } from './core/VaryingNode.js'; -export { default as OutputStructNode } from './core/OutputStructNode.js'; -export { default as MRTNode } from './core/MRTNode.js'; - -import * as NodeUtils from './core/NodeUtils.js'; -export { NodeUtils }; - -// utils -export { default as ArrayElementNode } from './utils/ArrayElementNode.js'; -export { default as ConvertNode } from './utils/ConvertNode.js'; -export { default as EquirectUVNode } from './utils/EquirectUVNode.js'; -export { default as FunctionOverloadingNode } from './utils/FunctionOverloadingNode.js'; -export { default as JoinNode } from './utils/JoinNode.js'; -export { default as LoopNode } from './utils/LoopNode.js'; -export { default as MatcapUVNode } from './utils/MatcapUVNode.js'; -export { default as MaxMipLevelNode } from './utils/MaxMipLevelNode.js'; -export { default as RemapNode } from './utils/RemapNode.js'; -export { default as RotateNode } from './utils/RotateNode.js'; -export { default as SetNode } from './utils/SetNode.js'; -export { default as SplitNode } from './utils/SplitNode.js'; -export { default as SpriteSheetUVNode } from './utils/SpriteSheetUVNode.js'; -export { default as StorageArrayElementNode } from './utils/StorageArrayElementNode.js'; -export { default as TriplanarTexturesNode } from './utils/TriplanarTexturesNode.js'; -export { default as ReflectorNode } from './utils/ReflectorNode.js'; -export { default as RTTNode } from './utils/RTTNode.js'; - -// accessors -export { default as UniformArrayNode } from './accessors/UniformArrayNode.js'; -export { default as BufferAttributeNode } from './accessors/BufferAttributeNode.js'; -export { default as BufferNode } from './accessors/BufferNode.js'; -export { default as VertexColorNode } from './accessors/VertexColorNode.js'; -export { default as CubeTextureNode } from './accessors/CubeTextureNode.js'; -export { default as InstanceNode } from './accessors/InstanceNode.js'; -export { default as BatchNode } from './accessors/BatchNode.js'; -export { default as MaterialNode } from './accessors/MaterialNode.js'; -export { default as MaterialReferenceNode } from './accessors/MaterialReferenceNode.js'; -export { default as RendererReferenceNode } from './accessors/RendererReferenceNode.js'; -export { default as MorphNode } from './accessors/MorphNode.js'; -export { default as ModelNode } from './accessors/ModelNode.js'; -export { default as ModelViewProjectionNode } from './accessors/ModelViewProjectionNode.js'; -export { default as Object3DNode } from './accessors/Object3DNode.js'; -export { default as PointUVNode } from './accessors/PointUVNode.js'; -export { default as ReferenceNode } from './accessors/ReferenceNode.js'; -export { default as SkinningNode } from './accessors/SkinningNode.js'; -export { default as SceneNode } from './accessors/SceneNode.js'; -export { default as StorageBufferNode } from './accessors/StorageBufferNode.js'; -export { default as TextureNode } from './accessors/TextureNode.js'; -export { default as TextureSizeNode } from './accessors/TextureSizeNode.js'; -export { default as StorageTextureNode } from './accessors/StorageTextureNode.js'; -export { default as Texture3DNode } from './accessors/Texture3DNode.js'; -export { default as UserDataNode } from './accessors/UserDataNode.js'; - -// display -export { default as BumpMapNode } from './display/BumpMapNode.js'; -export { default as ColorSpaceNode } from './display/ColorSpaceNode.js'; -export { default as FrontFacingNode } from './display/FrontFacingNode.js'; -export { default as NormalMapNode } from './display/NormalMapNode.js'; -export { default as PosterizeNode } from './display/PosterizeNode.js'; -export { default as ToneMappingNode } from './display/ToneMappingNode.js'; -export { default as ScreenNode } from './display/ScreenNode.js'; -export { default as ViewportTextureNode } from './display/ViewportTextureNode.js'; -export { default as ViewportSharedTextureNode } from './display/ViewportSharedTextureNode.js'; -export { default as ViewportDepthTextureNode } from './display/ViewportDepthTextureNode.js'; -export { default as ViewportDepthNode } from './display/ViewportDepthNode.js'; -export { default as RenderOutputNode } from './display/RenderOutputNode.js'; -export { default as PassNode } from './display/PassNode.js'; -export { default as ToonOutlinePassNode } from './display/ToonOutlinePassNode.js'; - -// code -export { default as ExpressionNode } from './code/ExpressionNode.js'; -export { default as CodeNode } from './code/CodeNode.js'; -export { default as FunctionCallNode } from './code/FunctionCallNode.js'; -export { default as FunctionNode } from './code/FunctionNode.js'; -export { default as ScriptableNode } from './code/ScriptableNode.js'; -export { default as ScriptableValueNode } from './code/ScriptableValueNode.js'; - -// fog -export { default as FogNode } from './fog/FogNode.js'; -export { default as FogRangeNode } from './fog/FogRangeNode.js'; -export { default as FogExp2Node } from './fog/FogExp2Node.js'; - -// geometry -export { default as RangeNode } from './geometry/RangeNode.js'; - -// gpgpu -export { default as ComputeNode } from './gpgpu/ComputeNode.js'; - -// lighting -export { default as PointLightNode } from './lighting/PointLightNode.js'; -export { default as DirectionalLightNode } from './lighting/DirectionalLightNode.js'; -export { default as RectAreaLightNode } from './lighting/RectAreaLightNode.js'; -export { default as SpotLightNode } from './lighting/SpotLightNode.js'; -export { default as IESSpotLightNode } from './lighting/IESSpotLightNode.js'; -export { default as AmbientLightNode } from './lighting/AmbientLightNode.js'; -export { default as LightsNode } from './lighting/LightsNode.js'; -export { default as LightingNode } from './lighting/LightingNode.js'; -export { default as LightingContextNode } from './lighting/LightingContextNode.js'; -export { default as HemisphereLightNode } from './lighting/HemisphereLightNode.js'; -export { default as LightProbeNode } from './lighting/LightProbeNode.js'; -export { default as EnvironmentNode } from './lighting/EnvironmentNode.js'; -export { default as BasicEnvironmentNode } from './lighting/BasicEnvironmentNode.js'; -export { default as IrradianceNode } from './lighting/IrradianceNode.js'; -export { default as AONode } from './lighting/AONode.js'; -export { default as AnalyticLightNode } from './lighting/AnalyticLightNode.js'; -export { default as ShadowNode } from './lighting/ShadowNode.js'; - -// pmrem -export { default as PMREMNode } from './pmrem/PMREMNode.js'; - -// parsers -export { default as GLSLNodeParser } from './parsers/GLSLNodeParser.js'; // @TODO: Move to jsm/renderers/webgl. - -// lighting models -export { default as PhongLightingModel } from './functions/PhongLightingModel.js'; -export { default as PhysicalLightingModel } from './functions/PhysicalLightingModel.js'; diff --git a/src-testing/src/nodes/TSL.d.ts b/src-testing/src/nodes/TSL.d.ts deleted file mode 100644 index e3e3e439b..000000000 --- a/src-testing/src/nodes/TSL.d.ts +++ /dev/null @@ -1,156 +0,0 @@ -// constants -export * from "./core/constants.js"; - -// core -export * from "./core/AssignNode.js"; -export * from "./core/AttributeNode.js"; -export * from "./core/BypassNode.js"; -export * from "./core/CacheNode.js"; -export * from "./core/ContextNode.js"; -export * from "./core/IndexNode.js"; -export * from "./core/MRTNode.js"; -export * from "./core/OutputStructNode.js"; -export * from "./core/ParameterNode.js"; -export * from "./core/PropertyNode.js"; -export * from "./core/StackNode.js"; -export * from "./core/UniformGroupNode.js"; -export * from "./core/UniformNode.js"; -export * from "./core/VaryingNode.js"; - -// math -export * from "./math/Hash.js"; -export * from "./math/MathUtils.js"; -export * from "./math/TriNoise3D.js"; - -// utils -export * from "./utils/EquirectUVNode.js"; -export * from "./utils/FunctionOverloadingNode.js"; -export * from "./utils/LoopNode.js"; -export * from "./utils/MatcapUVNode.js"; -export * from "./utils/MaxMipLevelNode.js"; -export * from "./utils/Oscillators.js"; -export * from "./utils/Packing.js"; -export * from "./utils/PostProcessingUtils.js"; -export * from "./utils/ReflectorNode.js"; -export * from "./utils/RemapNode.js"; -export * from "./utils/RotateNode.js"; -export * from "./utils/RTTNode.js"; -export * from "./utils/SpriteSheetUVNode.js"; -export * from "./utils/SpriteUtils.js"; -export * from "./utils/Timer.js"; -export * from "./utils/TriplanarTexturesNode.js"; -export * from "./utils/UVUtils.js"; -export * from "./utils/ViewportUtils.js"; - -// three.js shading language -export * from "./tsl/TSLBase.js"; - -// accessors -export * from "./accessors/AccessorsUtils.js"; -export * from "./accessors/BatchNode.js"; -export * from "./accessors/Bitangent.js"; -export * from "./accessors/BufferAttributeNode.js"; -export * from "./accessors/BufferNode.js"; -export * from "./accessors/Camera.js"; -export * from "./accessors/CubeTextureNode.js"; -export * from "./accessors/InstanceNode.js"; -export * from "./accessors/MaterialNode.js"; -export * from "./accessors/MaterialProperties.js"; -export * from "./accessors/MaterialReferenceNode.js"; -export * from "./accessors/ModelNode.js"; -export * from "./accessors/ModelViewProjectionNode.js"; -export * from "./accessors/MorphNode.js"; -export * from "./accessors/Normal.js"; -export * from "./accessors/Object3DNode.js"; -export * from "./accessors/PointUVNode.js"; -export * from "./accessors/Position.js"; -export * from "./accessors/ReferenceNode.js"; -export * from "./accessors/ReflectVector.js"; -export * from "./accessors/RendererReferenceNode.js"; -export * from "./accessors/SceneNode.js"; -export * from "./accessors/SkinningNode.js"; -export * from "./accessors/StorageBufferNode.js"; -export * from "./accessors/StorageTextureNode.js"; -export * from "./accessors/Tangent.js"; -export * from "./accessors/Texture3DNode.js"; -export * from "./accessors/TextureBicubic.js"; -export * from "./accessors/TextureNode.js"; -export * from "./accessors/TextureSizeNode.js"; -export * from "./accessors/UniformArrayNode.js"; -export * from "./accessors/UserDataNode.js"; -export * from "./accessors/UV.js"; -export * from "./accessors/VelocityNode.js"; -export * from "./accessors/VertexColorNode.js"; - -// display -export * from "./display/BlendMode.js"; -export * from "./display/BumpMapNode.js"; -export * from "./display/ColorAdjustment.js"; -export * from "./display/ColorSpaceNode.js"; -export * from "./display/FrontFacingNode.js"; -export * from "./display/NormalMapNode.js"; -export * from "./display/PosterizeNode.js"; -export * from "./display/RenderOutputNode.js"; -export * from "./display/ScreenNode.js"; -export * from "./display/ToneMappingNode.js"; -export * from "./display/ToonOutlinePassNode.js"; -export * from "./display/ViewportDepthNode.js"; -export * from "./display/ViewportDepthTextureNode.js"; -export * from "./display/ViewportSharedTextureNode.js"; -export * from "./display/ViewportTextureNode.js"; - -export * from "./display/PassNode.js"; - -export * from "./display/ColorSpaceFunctions.js"; -export * from "./display/ToneMappingFunctions.js"; - -// code -export * from "./code/CodeNode.js"; -export * from "./code/ExpressionNode.js"; -export * from "./code/FunctionCallNode.js"; -export * from "./code/FunctionNode.js"; -export * from "./code/ScriptableNode.js"; -export * from "./code/ScriptableValueNode.js"; - -// fog -export * from "./fog/FogExp2Node.js"; -export * from "./fog/FogNode.js"; -export * from "./fog/FogRangeNode.js"; - -// geometry -export * from "./geometry/RangeNode.js"; - -// gpgpu -export * from "./gpgpu/ComputeNode.js"; - -// lighting -export * from "./lighting/LightingContextNode.js"; -export * from "./lighting/LightNode.js"; -export * from "./lighting/LightsNode.js"; -export * from "./lighting/PointLightNode.js"; -export * from "./lighting/ShadowNode.js"; - -// pmrem -export * from "./pmrem/PMREMNode.js"; -export * from "./pmrem/PMREMUtils.js"; - -// procedural -export * from "./procedural/Checker.js"; - -// materialX -export * from "./materialx/MaterialXNodes.js"; - -// functions -export { default as BRDF_GGX } from "./functions/BSDF/BRDF_GGX.js"; -export { default as BRDF_Lambert } from "./functions/BSDF/BRDF_Lambert.js"; -export { default as D_GGX } from "./functions/BSDF/D_GGX.js"; -export { default as DFGApprox } from "./functions/BSDF/DFGApprox.js"; -export { default as F_Schlick } from "./functions/BSDF/F_Schlick.js"; -export { default as Schlick_to_F0 } from "./functions/BSDF/Schlick_to_F0.js"; -export { default as V_GGX_SmithCorrelated } from "./functions/BSDF/V_GGX_SmithCorrelated.js"; - -export * from "./lighting/LightUtils.js"; - -export { default as getGeometryRoughness } from "./functions/material/getGeometryRoughness.js"; -export { default as getRoughness } from "./functions/material/getRoughness.js"; -export { default as getShIrradianceAt } from "./functions/material/getShIrradianceAt.js"; diff --git a/src-testing/src/nodes/accessors/AccessorsUtils.d.ts b/src-testing/src/nodes/accessors/AccessorsUtils.d.ts deleted file mode 100644 index e42044673..000000000 --- a/src-testing/src/nodes/accessors/AccessorsUtils.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -export const TBNViewMatrix: ShaderNodeObject; - -export const parallaxDirection: ShaderNodeObject; -export const parallaxUV: (uv: ShaderNodeObject, scale: NodeRepresentation) => ShaderNodeObject; - -export const transformedBentNormalView: ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/BatchNode.d.ts b/src-testing/src/nodes/accessors/BatchNode.d.ts deleted file mode 100644 index 51db8b6bb..000000000 --- a/src-testing/src/nodes/accessors/BatchNode.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { BatchedMesh } from "../../objects/BatchedMesh.js"; -import Node from "../core/Node.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -export default class BatchNode extends Node { - batchMesh: BatchedMesh; - - batchingIdNode: Node | null; - - constructor(batchMesh: BatchedMesh); -} - -export const batch: (batchMesh: BatchedMesh) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/Bitangent.d.ts b/src-testing/src/nodes/accessors/Bitangent.d.ts deleted file mode 100644 index bcdc4d6e2..000000000 --- a/src-testing/src/nodes/accessors/Bitangent.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import MathNode from "../math/MathNode.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -export const bitangentGeometry: ShaderNodeObject; -export const bitangentLocal: ShaderNodeObject; -export const bitangentView: ShaderNodeObject; -export const bitangentWorld: ShaderNodeObject; -export const transformedBitangentView: ShaderNodeObject; -export const transformedBitangentWorld: ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/BufferAttributeNode.ts b/src-testing/src/nodes/accessors/BufferAttributeNode.ts deleted file mode 100644 index 97456dbc2..000000000 --- a/src-testing/src/nodes/accessors/BufferAttributeNode.ts +++ /dev/null @@ -1,135 +0,0 @@ -import InputNode from '../core/InputNode.js'; -import { nodeObject, addMethodChaining } from '../tsl/TSLCore.js'; -import { varying } from '../core/VaryingNode.js'; - -import { InterleavedBufferAttribute } from '../../core/InterleavedBufferAttribute.js'; -import { InterleavedBuffer } from '../../core/InterleavedBuffer.js'; -import { StaticDrawUsage, DynamicDrawUsage } from '../../constants.js'; - -class BufferAttributeNode extends InputNode { - static get type() { - return 'BufferAttributeNode'; - } - - constructor(value, bufferType = null, bufferStride = 0, bufferOffset = 0) { - super(value, bufferType); - - this.isBufferNode = true; - - this.bufferType = bufferType; - this.bufferStride = bufferStride; - this.bufferOffset = bufferOffset; - - this.usage = StaticDrawUsage; - this.instanced = false; - - this.attribute = null; - - this.global = true; - - if (value && value.isBufferAttribute === true) { - this.attribute = value; - this.usage = value.usage; - this.instanced = value.isInstancedBufferAttribute; - } - } - - getHash(builder) { - if (this.bufferStride === 0 && this.bufferOffset === 0) { - let bufferData = builder.globalCache.getData(this.value); - - if (bufferData === undefined) { - bufferData = { - node: this, - }; - - builder.globalCache.setData(this.value, bufferData); - } - - return bufferData.node.uuid; - } - - return this.uuid; - } - - getNodeType(builder) { - if (this.bufferType === null) { - this.bufferType = builder.getTypeFromAttribute(this.attribute); - } - - return this.bufferType; - } - - setup(builder) { - if (this.attribute !== null) return; - - const type = this.getNodeType(builder); - const array = this.value; - const itemSize = builder.getTypeLength(type); - const stride = this.bufferStride || itemSize; - const offset = this.bufferOffset; - - const buffer = array.isInterleavedBuffer === true ? array : new InterleavedBuffer(array, stride); - const bufferAttribute = new InterleavedBufferAttribute(buffer, itemSize, offset); - - buffer.setUsage(this.usage); - - this.attribute = bufferAttribute; - this.attribute.isInstancedBufferAttribute = this.instanced; // @TODO: Add a possible: InstancedInterleavedBufferAttribute - } - - generate(builder) { - const nodeType = this.getNodeType(builder); - - const nodeAttribute = builder.getBufferAttributeFromNode(this, nodeType); - const propertyName = builder.getPropertyName(nodeAttribute); - - let output = null; - - if (builder.shaderStage === 'vertex' || builder.shaderStage === 'compute') { - this.name = propertyName; - - output = propertyName; - } else { - const nodeVarying = varying(this); - - output = nodeVarying.build(builder, nodeType); - } - - return output; - } - - getInputType(/*builder*/) { - return 'bufferAttribute'; - } - - setUsage(value) { - this.usage = value; - - if (this.attribute && this.attribute.isBufferAttribute === true) { - this.attribute.usage = value; - } - - return this; - } - - setInstanced(value) { - this.instanced = value; - - return this; - } -} - -export default BufferAttributeNode; - -export const bufferAttribute = (array, type, stride, offset) => - nodeObject(new BufferAttributeNode(array, type, stride, offset)); -export const dynamicBufferAttribute = (array, type, stride, offset) => - bufferAttribute(array, type, stride, offset).setUsage(DynamicDrawUsage); - -export const instancedBufferAttribute = (array, type, stride, offset) => - bufferAttribute(array, type, stride, offset).setInstanced(true); -export const instancedDynamicBufferAttribute = (array, type, stride, offset) => - dynamicBufferAttribute(array, type, stride, offset).setInstanced(true); - -addMethodChaining('toAttribute', bufferNode => bufferAttribute(bufferNode.value)); diff --git a/src-testing/src/nodes/accessors/BufferNode.d.ts b/src-testing/src/nodes/accessors/BufferNode.d.ts deleted file mode 100644 index 4db9ccccd..000000000 --- a/src-testing/src/nodes/accessors/BufferNode.d.ts +++ /dev/null @@ -1,17 +0,0 @@ -import UniformNode from "../core/UniformNode.js"; -import { NodeOrType, ShaderNodeObject } from "../tsl/TSLCore.js"; - -export default class BufferNode extends UniformNode { - isBufferNode: true; - - bufferType: string; - bufferCount: number; - - constructor(value: unknown, bufferType: string, bufferCount?: number); -} - -export const buffer: ( - value: unknown, - nodeOrType: NodeOrType, - count: number, -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/Camera.d.ts b/src-testing/src/nodes/accessors/Camera.d.ts deleted file mode 100644 index 6fd332889..000000000 --- a/src-testing/src/nodes/accessors/Camera.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Matrix3 } from "../../math/Matrix3.js"; -import { Matrix4 } from "../../math/Matrix4.js"; -import { Vector3 } from "../../math/Vector3.js"; -import UniformNode from "../core/UniformNode.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -export const cameraNear: ShaderNodeObject>; -export const cameraFar: ShaderNodeObject>; -export const cameraProjectionMatrix: ShaderNodeObject>; -export const cameraProjectionMatrixInverse: ShaderNodeObject>; -export const cameraViewMatrix: ShaderNodeObject>; -export const cameraWorldMatrix: ShaderNodeObject>; -export const cameraNormalMatrix: ShaderNodeObject>; -export const cameraPosition: ShaderNodeObject>; diff --git a/src-testing/src/nodes/accessors/ClippingNode.d.ts b/src-testing/src/nodes/accessors/ClippingNode.d.ts deleted file mode 100644 index bb2cac1cd..000000000 --- a/src-testing/src/nodes/accessors/ClippingNode.d.ts +++ /dev/null @@ -1,16 +0,0 @@ -import Node from "../core/Node.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -export type ClippingNodeScope = typeof ClippingNode.ALPHA_TO_COVERAGE | typeof ClippingNode.DEFAULT; - -export default class ClippingNode extends Node { - scope: ClippingNodeScope; - - constructor(scope?: ClippingNodeScope); - - static ALPHA_TO_COVERAGE: "alphaToCoverage"; - static DEFAULT: "default"; -} - -export const clipping: () => ShaderNodeObject; -export const clippingAlpha: () => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/CubeTextureNode.d.ts b/src-testing/src/nodes/accessors/CubeTextureNode.d.ts deleted file mode 100644 index c25d51999..000000000 --- a/src-testing/src/nodes/accessors/CubeTextureNode.d.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { CubeTexture } from "../../textures/CubeTexture.js"; -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; -import TextureNode from "./TextureNode.js"; - -declare class CubeTextureNode extends TextureNode { - isCubeTextureNode: boolean; - uvNode: ShaderNodeObject | null; - levelNode: ShaderNodeObject | null; - - constructor( - value: CubeTexture, - uvNode?: ShaderNodeObject | null, - levelNode?: ShaderNodeObject | null, - biasNode?: ShaderNodeObject | null, - ); - - getDefaultUV(): Node; -} - -export default CubeTextureNode; - -export const cubeTexture: ( - value: CubeTexture, - uvNode?: NodeRepresentation, - levelNode?: NodeRepresentation, - biasNode?: NodeRepresentation, -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/InstanceNode.d.ts b/src-testing/src/nodes/accessors/InstanceNode.d.ts deleted file mode 100644 index c6cd43993..000000000 --- a/src-testing/src/nodes/accessors/InstanceNode.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { InstancedMesh } from "../../objects/InstancedMesh.js"; -import Node from "../core/Node.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -export default class InstanceNode extends Node { - instanceMesh: InstancedMesh; - instanceMatrixNode: Node | null; - instanceColorNode: Node | null; - - constructor(instanceMesh: InstancedMesh); -} - -export const instance: (instanceMesh: InstancedMesh) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/MaterialNode.d.ts b/src-testing/src/nodes/accessors/MaterialNode.d.ts deleted file mode 100644 index a29160b0e..000000000 --- a/src-testing/src/nodes/accessors/MaterialNode.d.ts +++ /dev/null @@ -1,129 +0,0 @@ -import { Vector2 } from "../../math/Vector2.js"; -import Node from "../core/Node.js"; -import UniformNode from "../core/UniformNode.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -export type MaterialNodeScope = - | typeof MaterialNode.ALPHA_TEST - | typeof MaterialNode.COLOR - | typeof MaterialNode.OPACITY - | typeof MaterialNode.SHININESS - | typeof MaterialNode.SPECULAR - | typeof MaterialNode.SPECULAR_STRENGTH - | typeof MaterialNode.SPECULAR_INTENSITY - | typeof MaterialNode.SPECULAR_COLOR - | typeof MaterialNode.REFLECTIVITY - | typeof MaterialNode.ROUGHNESS - | typeof MaterialNode.METALNESS - | typeof MaterialNode.NORMAL - | typeof MaterialNode.CLEARCOAT - | typeof MaterialNode.CLEARCOAT_ROUGHNESS - | typeof MaterialNode.CLEARCOAT_NORMAL - | typeof MaterialNode.EMISSIVE - | typeof MaterialNode.ROTATION - | typeof MaterialNode.SHEEN - | typeof MaterialNode.SHEEN_ROUGHNESS - | typeof MaterialNode.ANISOTROPY - | typeof MaterialNode.IRIDESCENCE - | typeof MaterialNode.IRIDESCENCE_IOR - | typeof MaterialNode.IRIDESCENCE_THICKNESS - | typeof MaterialNode.IOR - | typeof MaterialNode.TRANSMISSION - | typeof MaterialNode.THICKNESS - | typeof MaterialNode.ATTENUATION_DISTANCE - | typeof MaterialNode.ATTENUATION_COLOR - | typeof MaterialNode.LINE_SCALE - | typeof MaterialNode.LINE_DASH_SIZE - | typeof MaterialNode.LINE_GAP_SIZE - | typeof MaterialNode.LINE_WIDTH - | typeof MaterialNode.LINE_DASH_OFFSET - | typeof MaterialNode.POINT_WIDTH - | typeof MaterialNode.DISPERSION - | typeof MaterialNode.LIGHT_MAP - | typeof MaterialNode.AO_MAP - | typeof MaterialNode.REFRACTION_RATIO; - -export default class MaterialNode extends Node { - static ALPHA_TEST: "alphaTest"; - static COLOR: "color"; - static OPACITY: "opacity"; - static SHININESS: "shininess"; - static SPECULAR: "specular"; - static SPECULAR_STRENGTH: "specularStrength"; - static SPECULAR_INTENSITY: "specularIntensity"; - static SPECULAR_COLOR: "specularColor"; - static REFLECTIVITY: "reflectivity"; - static ROUGHNESS: "roughness"; - static METALNESS: "metalness"; - static NORMAL: "normal"; - static CLEARCOAT: "clearcoat"; - static CLEARCOAT_ROUGHNESS: "clearcoatRoughness"; - static CLEARCOAT_NORMAL: "clearcoatNormal"; - static EMISSIVE: "emissive"; - static ROTATION: "rotation"; - static SHEEN: "sheen"; - static SHEEN_ROUGHNESS: "sheenRoughness"; - static ANISOTROPY: "anisotropy"; - static IRIDESCENCE: "iridescence"; - static IRIDESCENCE_IOR: "iridescenceIOR"; - static IRIDESCENCE_THICKNESS: "iridescenceThickness"; - static IOR: "ior"; - static TRANSMISSION: "transmission"; - static THICKNESS: "thickness"; - static ATTENUATION_DISTANCE: "attenuationDistance"; - static ATTENUATION_COLOR: "attenuationColor"; - static LINE_SCALE: "scale"; - static LINE_DASH_SIZE: "dashSize"; - static LINE_GAP_SIZE: "gapSize"; - static LINE_WIDTH: "linewidth"; - static LINE_DASH_OFFSET: "dashOffset"; - static POINT_WIDTH: "pointWidth"; - static DISPERSION: "dispersion"; - static LIGHT_MAP: "light"; - static AO_MAP: "ao"; - static REFRACTION_RATIO: "refractionRatio"; - - scope: MaterialNodeScope; - constructor(scope?: MaterialNodeScope); -} - -export const materialAlphaTest: ShaderNodeObject; -export const materialColor: ShaderNodeObject; -export const materialShininess: ShaderNodeObject; -export const materialEmissive: ShaderNodeObject; -export const materialOpacity: ShaderNodeObject; -export const materialSpecular: ShaderNodeObject; - -export const materialSpecularIntensity: ShaderNodeObject; -export const materialSpecularColor: ShaderNodeObject; - -export const materialSpecularStrength: ShaderNodeObject; -export const materialReflectivity: ShaderNodeObject; -export const materialRoughness: ShaderNodeObject; -export const materialMetalness: ShaderNodeObject; -export const materialNormal: ShaderNodeObject; -export const materialClearcoat: ShaderNodeObject; -export const materialClearcoatRoughness: ShaderNodeObject; -export const materialClearcoatNormal: ShaderNodeObject; -export const materialRotation: ShaderNodeObject; -export const materialSheen: ShaderNodeObject; -export const materialSheenRoughness: ShaderNodeObject; -export const materialAnisotropy: ShaderNodeObject; -export const materialIridescence: ShaderNodeObject; -export const materialIridescenceIOR: ShaderNodeObject; -export const materialIridescenceThickness: ShaderNodeObject; -export const materialTransmission: ShaderNodeObject; -export const materialThickness: ShaderNodeObject; -export const materialIOR: ShaderNodeObject; -export const materialAttenuationDistance: ShaderNodeObject; -export const materialAttenuationColor: ShaderNodeObject; -export const materialLineScale: ShaderNodeObject; -export const materialLineDashSize: ShaderNodeObject; -export const materialLineGapSize: ShaderNodeObject; -export const materialLineWidth: ShaderNodeObject; -export const materialLineDashOffset: ShaderNodeObject; -export const materialPointWidth: ShaderNodeObject; -export const materialDispersion: ShaderNodeObject; -export const materialLightMap: ShaderNodeObject; -export const materialAOMap: ShaderNodeObject; -export const materialAnisotropyVector: ShaderNodeObject>; diff --git a/src-testing/src/nodes/accessors/MaterialProperties.d.ts b/src-testing/src/nodes/accessors/MaterialProperties.d.ts deleted file mode 100644 index 3e07ecf0b..000000000 --- a/src-testing/src/nodes/accessors/MaterialProperties.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -import UniformNode from "../core/UniformNode.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -export const materialRefractionRatio: ShaderNodeObject>; diff --git a/src-testing/src/nodes/accessors/MaterialReferenceNode.d.ts b/src-testing/src/nodes/accessors/MaterialReferenceNode.d.ts deleted file mode 100644 index 7b0cdf4ac..000000000 --- a/src-testing/src/nodes/accessors/MaterialReferenceNode.d.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Material } from "../../materials/Material.js"; -import { NodeOrType, ShaderNodeObject } from "../tsl/TSLCore.js"; -import ReferenceNode from "./ReferenceNode.js"; - -export default class MaterialReferenceNode extends ReferenceNode { - readonly isMaterialReferenceNode: true; - - constructor(property: string, inputType: string, material?: Material | null); -} - -export const materialReference: ( - name: string, - nodeOrType: NodeOrType, - material?: Material | null, -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/ModelNode.d.ts b/src-testing/src/nodes/accessors/ModelNode.d.ts deleted file mode 100644 index 12280a2b6..000000000 --- a/src-testing/src/nodes/accessors/ModelNode.d.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { Matrix4 } from "../../math/Matrix4.js"; -import Node from "../core/Node.js"; -import { UniformNode } from "../Nodes.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; -import Object3DNode from "./Object3DNode.js"; - -/** - * Similar to {@link Object3DNode} but the object comes from {@link NodeFrame} - */ -export default class ModelNode extends Object3DNode { - constructor(scope: string); -} - -export const modelDirection: ShaderNodeObject; -export const modelWorldMatrix: ShaderNodeObject; -export const modelPosition: ShaderNodeObject; -export const modelScale: ShaderNodeObject; -export const modelViewPosition: ShaderNodeObject; -export const modelNormalMatrix: ShaderNodeObject; -export const modelWorldMatrixInverse: ShaderNodeObject>; -export const modelViewMatrix: ShaderNodeObject; - -export const highPrecisionModelViewMatrix: ShaderNodeObject; -export const highPrecisionModelNormalViewMatrix: ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/ModelViewProjectionNode.d.ts b/src-testing/src/nodes/accessors/ModelViewProjectionNode.d.ts deleted file mode 100644 index 18302d638..000000000 --- a/src-testing/src/nodes/accessors/ModelViewProjectionNode.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -export default class ModelViewProjectionNode extends Node { - constructor(positionNode?: Node); -} - -export const modelViewProjection: (position?: NodeRepresentation) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/MorphNode.d.ts b/src-testing/src/nodes/accessors/MorphNode.d.ts deleted file mode 100644 index 8987acf6e..000000000 --- a/src-testing/src/nodes/accessors/MorphNode.d.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Mesh } from "../../objects/Mesh.js"; -import Node from "../core/Node.js"; -import UniformNode from "../core/UniformNode.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -declare class MorphNode extends Node { - mesh: Mesh; - morphBaseInfluence: UniformNode; - - constructor(mesh: Mesh); -} - -export default MorphNode; - -export const morphReference: (mesh: Mesh) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/Normal.d.ts b/src-testing/src/nodes/accessors/Normal.d.ts deleted file mode 100644 index 706130a8d..000000000 --- a/src-testing/src/nodes/accessors/Normal.d.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { Matrix4 } from "../../math/Matrix4.js"; -import AttributeNode from "../core/AttributeNode.js"; -import Node from "../core/Node.js"; -import VarNode from "../core/VarNode.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -export const normalGeometry: ShaderNodeObject; - -export const normalLocal: ShaderNodeObject; - -export const normalFlat: ShaderNodeObject; - -export const normalView: ShaderNodeObject; - -export const normalWorld: ShaderNodeObject; - -export const transformedNormalView: ShaderNodeObject; - -export const transformedNormalWorld: ShaderNodeObject; - -export const transformedClearcoatNormalView: ShaderNodeObject; - -export const transformNormal: (normal: Node, matrix?: Node) => ShaderNodeObject; - -export const transformNormalToView: (normal: Node) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/Object3DNode.d.ts b/src-testing/src/nodes/accessors/Object3DNode.d.ts deleted file mode 100644 index 21e6776c9..000000000 --- a/src-testing/src/nodes/accessors/Object3DNode.d.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Object3D } from "../../core/Object3D.js"; -import Node from "../core/Node.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -export default class Object3DNode extends Node { - scope: string; - object3d: Object3D | null; - - constructor(scope: string, object3d?: Object3D | null); - - static WORLD_MATRIX: "worldMatrix"; - static POSITION: "position"; - static SCALE: "scale"; - static VIEW_POSITION: "viewPosition"; - static DIRECTION: "direction"; -} - -export const objectDirection: (object3d: Object3D) => ShaderNodeObject; -export const objectWorldMatrix: (object3d: Object3D) => ShaderNodeObject; -export const objectPosition: (object3d: Object3D) => ShaderNodeObject; -export const objectScale: (object3d: Object3D) => ShaderNodeObject; -export const objectViewPosition: (object3d: Object3D) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/PointUVNode.d.ts b/src-testing/src/nodes/accessors/PointUVNode.d.ts deleted file mode 100644 index 2220e5563..000000000 --- a/src-testing/src/nodes/accessors/PointUVNode.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import Node from "../core/Node.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -export default class PointUVNode extends Node { - isPointUVNode: true; - - constructor(); -} - -export const pointUV: ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/Position.d.ts b/src-testing/src/nodes/accessors/Position.d.ts deleted file mode 100644 index a9f6fc811..000000000 --- a/src-testing/src/nodes/accessors/Position.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import Node from "../core/Node.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -export const positionGeometry: ShaderNodeObject; -export const positionLocal: ShaderNodeObject; -export const positionPrevious: ShaderNodeObject; -export const positionWorld: ShaderNodeObject; -export const positionWorldDirection: ShaderNodeObject; -export const positionView: ShaderNodeObject; -export const positionViewDirection: ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/ReferenceBaseNode.d.ts b/src-testing/src/nodes/accessors/ReferenceBaseNode.d.ts deleted file mode 100644 index 586fde349..000000000 --- a/src-testing/src/nodes/accessors/ReferenceBaseNode.d.ts +++ /dev/null @@ -1,27 +0,0 @@ -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -declare class ReferenceBaseNode extends Node { - property: string; - uniformType: string; - object: T; - count: number | null; - - properties: string[]; - reference: T | null; - node: Node | null; - - constructor(property: string, uniformType: string, object?: T | null, count?: number | null); - - setNodeType(uniformType: string): void; -} - -export default ReferenceBaseNode; - -export const reference: (name: string, type: string, object: T) => ShaderNodeObject>; -export const referenceBuffer: ( - name: string, - type: string, - count: number, - object: T, -) => ShaderNodeObject>; diff --git a/src-testing/src/nodes/accessors/ReferenceNode.d.ts b/src-testing/src/nodes/accessors/ReferenceNode.d.ts deleted file mode 100644 index 1dea4d31f..000000000 --- a/src-testing/src/nodes/accessors/ReferenceNode.d.ts +++ /dev/null @@ -1,29 +0,0 @@ -import Node from "../core/Node.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -declare class ReferenceNode extends Node { - property: string; - - uniformType: string; - - object: T; - count: number | null; - - properties: string[]; - reference: T | null; - node: Node | null; - - constructor(property: string, uniformType: string, object?: T | null, count?: number | null); - - setNodeType(uniformType: string): void; -} - -export default ReferenceNode; - -export const reference: (name: string, type: string, object: T) => ShaderNodeObject>; -export const referenceBuffer: ( - name: string, - type: string, - count: number, - object: T, -) => ShaderNodeObject>; diff --git a/src-testing/src/nodes/accessors/ReflectVector.d.ts b/src-testing/src/nodes/accessors/ReflectVector.d.ts deleted file mode 100644 index 4978b4975..000000000 --- a/src-testing/src/nodes/accessors/ReflectVector.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import Node from "../core/Node.js"; -import VarNode from "../core/VarNode.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -export const reflectView: ShaderNodeObject; -export const refractView: ShaderNodeObject; - -export const reflectVector: ShaderNodeObject; -export const refractVector: ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/RendererReferenceNode.d.ts b/src-testing/src/nodes/accessors/RendererReferenceNode.d.ts deleted file mode 100644 index 0e100b049..000000000 --- a/src-testing/src/nodes/accessors/RendererReferenceNode.d.ts +++ /dev/null @@ -1,15 +0,0 @@ -import Renderer from "../../renderers/common/Renderer.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; -import ReferenceNode from "./ReferenceNode.js"; - -export default class RendererReferenceNode extends ReferenceNode { - renderer: Renderer | null; - - constructor(property: string, inputType: string, renderer?: Renderer | null); -} - -export const rendererReference: ( - name: string, - type: string, - renderer?: Renderer | null, -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/SceneNode.d.ts b/src-testing/src/nodes/accessors/SceneNode.d.ts deleted file mode 100644 index 34bdea1be..000000000 --- a/src-testing/src/nodes/accessors/SceneNode.d.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Scene } from "../../scenes/Scene.js"; -import Node from "../core/Node.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -export type SceneNodeScope = typeof SceneNode.BACKGROUND_BLURRINESS | typeof SceneNode.BACKGROUND_INTENSITY; - -declare class SceneNode extends Node { - scope: SceneNodeScope; - scene: Scene | null; - - constructor(scope?: SceneNodeScope, scene?: Scene | null); - - static BACKGROUND_BLURRINESS: "backgroundBlurriness"; - static BACKGROUND_INTENSITY: "backgroundIntensity"; -} - -export default SceneNode; - -export const backgroundBlurriness: ShaderNodeObject; -export const backgroundIntensity: ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/SkinningNode.d.ts b/src-testing/src/nodes/accessors/SkinningNode.d.ts deleted file mode 100644 index 3bef01c33..000000000 --- a/src-testing/src/nodes/accessors/SkinningNode.d.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { SkinnedMesh } from "../../objects/SkinnedMesh.js"; -import Node from "../core/Node.js"; -import NodeBuilder from "../core/NodeBuilder.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -export default class SkinningNode extends Node { - skinnedMesh: SkinnedMesh; - useReference: boolean; - - skinIndexNode: Node; - skinWeightNode: Node; - - bindMatrixNode: Node; - bindMatrixInverseNode: Node; - boneMatricesNode: Node; - previousBoneMatricesNode: Node | null; - - constructor(skinnedMesh: SkinnedMesh, useReference?: boolean); - - getSkinnedPosition(boneMatrices?: Node, position?: Node): ShaderNodeObject; - - getSkinnedNormal(boneMatrices?: Node, normal?: Node): ShaderNodeObject; - - getPreviousSkinnedPosition(builder: NodeBuilder): ShaderNodeObject; - - needsPreviousBoneMatrices(builder: NodeBuilder): boolean; -} - -export const skinning: (skinnedMesh: SkinnedMesh) => ShaderNodeObject; -export const skinningReference: (skinnedMesh: SkinnedMesh) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/StorageBufferNode.d.ts b/src-testing/src/nodes/accessors/StorageBufferNode.d.ts deleted file mode 100644 index d56cac59a..000000000 --- a/src-testing/src/nodes/accessors/StorageBufferNode.d.ts +++ /dev/null @@ -1,38 +0,0 @@ -import StorageBufferAttribute from "../../renderers/common/StorageBufferAttribute.js"; -import StorageInstancedBufferAttribute from "../../renderers/common/StorageInstancedBufferAttribute.js"; -import { GPUBufferBindingType } from "../../renderers/webgpu/utils/WebGPUConstants.js"; -import { NodeOrType, NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; -import StorageArrayElementNode from "../utils/StorageArrayElementNode.js"; -import BufferNode from "./BufferNode.js"; - -export default class StorageBufferNode extends BufferNode { - readonly isStorageBufferNode: true; - bufferObject: boolean; - - access: GPUBufferBindingType; - - constructor( - value: StorageBufferAttribute | StorageInstancedBufferAttribute, - bufferType: string, - bufferCount?: number, - ); - - element(indexNode: NodeRepresentation): ShaderNodeObject; - - setBufferObject(value: boolean): this; - - setAccess(value: GPUBufferBindingType): this; - - toReadOnly(): this; -} - -export const storage: ( - value: StorageBufferAttribute | StorageInstancedBufferAttribute, - nodeOrType: NodeOrType, - count: number, -) => ShaderNodeObject; -export const storageObject: ( - value: StorageBufferAttribute | StorageInstancedBufferAttribute, - nodeOrType: NodeOrType, - count: number, -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/StorageTextureNode.d.ts b/src-testing/src/nodes/accessors/StorageTextureNode.d.ts deleted file mode 100644 index 0b4acdceb..000000000 --- a/src-testing/src/nodes/accessors/StorageTextureNode.d.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { GPUStorageTextureAccess } from "../../renderers/webgpu/utils/WebGPUConstants.js"; -import { Texture } from "../../textures/Texture.js"; -import Node from "../core/Node.js"; -import NodeBuilder from "../core/NodeBuilder.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; -import TextureNode from "./TextureNode.js"; - -export default class StorageTextureNode extends TextureNode { - storeNode: Node | null; - - readonly isStorageTextureNode: true; - - access: GPUStorageTextureAccess; - - constructor( - value: Texture, - uvNode?: ShaderNodeObject | null, - storeNode?: Node | null, - ); - - setAccess(value: GPUStorageTextureAccess): this; - - toReadOnly(): this; - - toWriteOnly(): this; - - generateStore(builder: NodeBuilder): void; -} - -export const storageTexture: ( - value: Texture, - uvNode?: NodeRepresentation, - storeNode?: NodeRepresentation, -) => ShaderNodeObject; - -export const textureStore: ( - value: Texture, - uvNode?: NodeRepresentation, - storeNode?: NodeRepresentation, -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/Tangent.d.ts b/src-testing/src/nodes/accessors/Tangent.d.ts deleted file mode 100644 index 94ec48330..000000000 --- a/src-testing/src/nodes/accessors/Tangent.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -import AttributeNode from "../core/AttributeNode.js"; -import VarNode from "../core/VarNode.js"; -import VaryingNode from "../core/VaryingNode.js"; -import MathNode from "../math/MathNode.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -export const tangentGeometry: ShaderNodeObject; -export const tangentLocal: ShaderNodeObject; -export const tangentView: ShaderNodeObject; -export const tangentWorld: ShaderNodeObject; -export const transformedTangentView: ShaderNodeObject; -export const transformedTangentWorld: ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/Texture3DNode.d.ts b/src-testing/src/nodes/accessors/Texture3DNode.d.ts deleted file mode 100644 index da589f034..000000000 --- a/src-testing/src/nodes/accessors/Texture3DNode.d.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { CubeTexture } from "../../textures/CubeTexture.js"; -import { Texture } from "../../textures/Texture.js"; -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; -import TextureNode from "./TextureNode.js"; - -export default class Texture3DNode extends TextureNode { - readonly isTexture3DNode: true; - - constructor(value: Texture, uvNode?: ShaderNodeObject | null, levelNode?: ShaderNodeObject | null); -} - -export const texture3D: ( - value: Texture, - uvNode?: NodeRepresentation, - levelNode?: NodeRepresentation, -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/TextureBicubic.d.ts b/src-testing/src/nodes/accessors/TextureBicubic.d.ts deleted file mode 100644 index b55ca57e9..000000000 --- a/src-testing/src/nodes/accessors/TextureBicubic.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -export const textureBicubic: (textureNode: Node, lodNode?: NodeRepresentation) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/TextureNode.ts b/src-testing/src/nodes/accessors/TextureNode.ts deleted file mode 100644 index f97a04d11..000000000 --- a/src-testing/src/nodes/accessors/TextureNode.ts +++ /dev/null @@ -1,370 +0,0 @@ -import UniformNode, { uniform } from '../core/UniformNode.js'; -import { uv } from './UV.js'; -import { textureSize } from './TextureSizeNode.js'; -import { colorSpaceToWorking } from '../display/ColorSpaceNode.js'; -import { expression } from '../code/ExpressionNode.js'; -import { maxMipLevel } from '../utils/MaxMipLevelNode.js'; -import { nodeProxy, vec3, nodeObject, int } from '../tsl/TSLBase.js'; -import { NodeUpdateType } from '../core/constants.js'; - -import { IntType, UnsignedIntType } from '../../constants.js'; - -class TextureNode extends UniformNode { - static get type() { - return 'TextureNode'; - } - - constructor(value, uvNode = null, levelNode = null, biasNode = null) { - super(value); - - this.isTextureNode = true; - - this.uvNode = uvNode; - this.levelNode = levelNode; - this.biasNode = biasNode; - this.compareNode = null; - this.depthNode = null; - this.gradNode = null; - - this.sampler = true; - this.updateMatrix = false; - this.updateType = NodeUpdateType.NONE; - - this.referenceNode = null; - - this._value = value; - this._matrixUniform = null; - - this.setUpdateMatrix(uvNode === null); - } - - set value(value) { - if (this.referenceNode) { - this.referenceNode.value = value; - } else { - this._value = value; - } - } - - get value() { - return this.referenceNode ? this.referenceNode.value : this._value; - } - - getUniformHash(/*builder*/) { - return this.value.uuid; - } - - getNodeType(/*builder*/) { - if (this.value.isDepthTexture === true) return 'float'; - - if (this.value.type === UnsignedIntType) { - return 'uvec4'; - } else if (this.value.type === IntType) { - return 'ivec4'; - } - - return 'vec4'; - } - - getInputType(/*builder*/) { - return 'texture'; - } - - getDefaultUV() { - return uv(this.value.channel); - } - - updateReference(/*state*/) { - return this.value; - } - - getTransformedUV(uvNode) { - if (this._matrixUniform === null) this._matrixUniform = uniform(this.value.matrix); - - return this._matrixUniform.mul(vec3(uvNode, 1)).xy; - } - - setUpdateMatrix(value) { - this.updateMatrix = value; - this.updateType = value ? NodeUpdateType.FRAME : NodeUpdateType.NONE; - - return this; - } - - setupUV(builder, uvNode) { - const texture = this.value; - - if ( - builder.isFlipY() && - (texture.isRenderTargetTexture === true || - texture.isFramebufferTexture === true || - texture.isDepthTexture === true) - ) { - if (this.sampler) { - uvNode = uvNode.flipY(); - } else { - uvNode = uvNode.setY(int(textureSize(this, this.levelNode).y).sub(uvNode.y).sub(1)); - } - } - - return uvNode; - } - - setup(builder) { - const properties = builder.getNodeProperties(this); - properties.referenceNode = this.referenceNode; - - // - - let uvNode = this.uvNode; - - if ((uvNode === null || builder.context.forceUVContext === true) && builder.context.getUV) { - uvNode = builder.context.getUV(this); - } - - if (!uvNode) uvNode = this.getDefaultUV(); - - if (this.updateMatrix === true) { - uvNode = this.getTransformedUV(uvNode); - } - - uvNode = this.setupUV(builder, uvNode); - - // - - let levelNode = this.levelNode; - - if (levelNode === null && builder.context.getTextureLevel) { - levelNode = builder.context.getTextureLevel(this); - } - - // - - properties.uvNode = uvNode; - properties.levelNode = levelNode; - properties.biasNode = this.biasNode; - properties.compareNode = this.compareNode; - properties.gradNode = this.gradNode; - properties.depthNode = this.depthNode; - } - - generateUV(builder, uvNode) { - return uvNode.build(builder, this.sampler === true ? 'vec2' : 'ivec2'); - } - - generateSnippet( - builder, - textureProperty, - uvSnippet, - levelSnippet, - biasSnippet, - depthSnippet, - compareSnippet, - gradSnippet, - ) { - const texture = this.value; - - let snippet; - - if (levelSnippet) { - snippet = builder.generateTextureLevel(texture, textureProperty, uvSnippet, levelSnippet, depthSnippet); - } else if (biasSnippet) { - snippet = builder.generateTextureBias(texture, textureProperty, uvSnippet, biasSnippet, depthSnippet); - } else if (gradSnippet) { - snippet = builder.generateTextureGrad(texture, textureProperty, uvSnippet, gradSnippet, depthSnippet); - } else if (compareSnippet) { - snippet = builder.generateTextureCompare(texture, textureProperty, uvSnippet, compareSnippet, depthSnippet); - } else if (this.sampler === false) { - snippet = builder.generateTextureLoad(texture, textureProperty, uvSnippet, depthSnippet); - } else { - snippet = builder.generateTexture(texture, textureProperty, uvSnippet, depthSnippet); - } - - return snippet; - } - - generate(builder, output) { - const properties = builder.getNodeProperties(this); - - const texture = this.value; - - if (!texture || texture.isTexture !== true) { - throw new Error('TextureNode: Need a three.js texture.'); - } - - const textureProperty = super.generate(builder, 'property'); - - if (output === 'sampler') { - return textureProperty + '_sampler'; - } else if (builder.isReference(output)) { - return textureProperty; - } else { - const nodeData = builder.getDataFromNode(this); - - let propertyName = nodeData.propertyName; - - if (propertyName === undefined) { - const { uvNode, levelNode, biasNode, compareNode, depthNode, gradNode } = properties; - - const uvSnippet = this.generateUV(builder, uvNode); - const levelSnippet = levelNode ? levelNode.build(builder, 'float') : null; - const biasSnippet = biasNode ? biasNode.build(builder, 'float') : null; - const depthSnippet = depthNode ? depthNode.build(builder, 'int') : null; - const compareSnippet = compareNode ? compareNode.build(builder, 'float') : null; - const gradSnippet = gradNode - ? [gradNode[0].build(builder, 'vec2'), gradNode[1].build(builder, 'vec2')] - : null; - - const nodeVar = builder.getVarFromNode(this); - - propertyName = builder.getPropertyName(nodeVar); - - const snippet = this.generateSnippet( - builder, - textureProperty, - uvSnippet, - levelSnippet, - biasSnippet, - depthSnippet, - compareSnippet, - gradSnippet, - ); - - builder.addLineFlowCode(`${propertyName} = ${snippet}`, this); - - nodeData.snippet = snippet; - nodeData.propertyName = propertyName; - } - - let snippet = propertyName; - const nodeType = this.getNodeType(builder); - - if (builder.needsToWorkingColorSpace(texture)) { - snippet = colorSpaceToWorking(expression(snippet, nodeType), texture.colorSpace) - .setup(builder) - .build(builder, nodeType); - } - - return builder.format(snippet, nodeType, output); - } - } - - setSampler(value) { - this.sampler = value; - - return this; - } - - getSampler() { - return this.sampler; - } - - // @TODO: Move to TSL - - uv(uvNode) { - const textureNode = this.clone(); - textureNode.uvNode = nodeObject(uvNode); - textureNode.referenceNode = this.getSelf(); - - return nodeObject(textureNode); - } - - blur(amountNode) { - const textureNode = this.clone(); - textureNode.biasNode = nodeObject(amountNode).mul(maxMipLevel(textureNode)); - textureNode.referenceNode = this.getSelf(); - - return nodeObject(textureNode); - } - - level(levelNode) { - const textureNode = this.clone(); - textureNode.levelNode = nodeObject(levelNode); - textureNode.referenceNode = this.getSelf(); - - return nodeObject(textureNode); - } - - size(levelNode) { - return textureSize(this, levelNode); - } - - bias(biasNode) { - const textureNode = this.clone(); - textureNode.biasNode = nodeObject(biasNode); - textureNode.referenceNode = this.getSelf(); - - return nodeObject(textureNode); - } - - compare(compareNode) { - const textureNode = this.clone(); - textureNode.compareNode = nodeObject(compareNode); - textureNode.referenceNode = this.getSelf(); - - return nodeObject(textureNode); - } - - grad(gradNodeX, gradNodeY) { - const textureNode = this.clone(); - textureNode.gradNode = [nodeObject(gradNodeX), nodeObject(gradNodeY)]; - textureNode.referenceNode = this.getSelf(); - - return nodeObject(textureNode); - } - - depth(depthNode) { - const textureNode = this.clone(); - textureNode.depthNode = nodeObject(depthNode); - textureNode.referenceNode = this.getSelf(); - - return nodeObject(textureNode); - } - - // -- - - serialize(data) { - super.serialize(data); - - data.value = this.value.toJSON(data.meta).uuid; - data.sampler = this.sampler; - data.updateMatrix = this.updateMatrix; - data.updateType = this.updateType; - } - - deserialize(data) { - super.deserialize(data); - - this.value = data.meta.textures[data.value]; - this.sampler = data.sampler; - this.updateMatrix = data.updateMatrix; - this.updateType = data.updateType; - } - - update() { - const texture = this.value; - const matrixUniform = this._matrixUniform; - - if (matrixUniform !== null) matrixUniform.value = texture.matrix; - - if (texture.matrixAutoUpdate === true) { - texture.updateMatrix(); - } - } - - clone() { - const newNode = new this.constructor(this.value, this.uvNode, this.levelNode, this.biasNode); - newNode.sampler = this.sampler; - - return newNode; - } -} - -export default TextureNode; - -export const texture = /*@__PURE__*/ nodeProxy(TextureNode); -export const textureLoad = (...params) => texture(...params).setSampler(false); - -//export const textureLevel = ( value, uv, level ) => texture( value, uv ).level( level ); - -export const sampler = aTexture => (aTexture.isNode === true ? aTexture : texture(aTexture)).convert('sampler'); diff --git a/src-testing/src/nodes/accessors/TextureSizeNode.d.ts b/src-testing/src/nodes/accessors/TextureSizeNode.d.ts deleted file mode 100644 index 0b995fccf..000000000 --- a/src-testing/src/nodes/accessors/TextureSizeNode.d.ts +++ /dev/null @@ -1,18 +0,0 @@ -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -declare class TextureSizeNode extends Node { - readonly isTextureSizeNode: true; - - textureNode: Node; - levelNode: Node | null; - - constructor(textureNode: Node, levelNode?: Node | null); -} - -export default TextureSizeNode; - -export const textureSize: ( - textureNode: NodeRepresentation, - levelNode?: NodeRepresentation | null, -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/UV.d.ts b/src-testing/src/nodes/accessors/UV.d.ts deleted file mode 100644 index aedabbd02..000000000 --- a/src-testing/src/nodes/accessors/UV.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -import AttributeNode from "../core/AttributeNode.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -export const uv: (index?: number) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/UniformArrayNode.d.ts b/src-testing/src/nodes/accessors/UniformArrayNode.d.ts deleted file mode 100644 index 72e539cb4..000000000 --- a/src-testing/src/nodes/accessors/UniformArrayNode.d.ts +++ /dev/null @@ -1,30 +0,0 @@ -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; -import ArrayElementNode from "../utils/ArrayElementNode.js"; -import BufferNode from "./BufferNode.js"; - -declare class UniformArrayElementNode extends ArrayElementNode { - constructor(arrayBuffer: Node, indexNode: Node); -} - -declare class UniformArrayNode extends BufferNode { - array: unknown[]; - elementType: string | null; - - readonly isArrayBufferNode: true; - - constructor(value: unknown[], elementType?: string | null); - - getElementLength(): number; - - element(indexNode: NodeRepresentation): ShaderNodeObject; -} - -export default UniformArrayNode; - -export const uniformArray: (values: unknown[], nodeType?: string | null) => ShaderNodeObject; - -/** - * @deprecated uniforms() has been renamed to uniformArray(). - */ -export const uniforms: (values: unknown[], nodeType?: string | null) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/UserDataNode.d.ts b/src-testing/src/nodes/accessors/UserDataNode.d.ts deleted file mode 100644 index 647c18412..000000000 --- a/src-testing/src/nodes/accessors/UserDataNode.d.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { ShaderNodeObject } from "../tsl/TSLCore.js"; -import ReferenceNode from "./ReferenceNode.js"; - -export type NodeUserData = Record; - -export default class UserDataNode extends ReferenceNode { - userData: NodeUserData | null; - constructor(property: string, inputType: string, userData?: NodeUserData | null); -} - -export const userData: ( - name: string, - inputType: string, - userData?: NodeUserData, -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/VelocityNode.d.ts b/src-testing/src/nodes/accessors/VelocityNode.d.ts deleted file mode 100644 index 32c040c16..000000000 --- a/src-testing/src/nodes/accessors/VelocityNode.d.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Matrix4 } from "../../math/Matrix4.js"; -import TempNode from "../core/TempNode.js"; -import UniformNode from "../core/UniformNode.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -declare class VelocityNode extends TempNode { - projectionMatrix: Matrix4 | null; - - previousModelWorldMatrix: UniformNode; - previousProjectionMatrix: UniformNode; - previousCameraViewMatrix: UniformNode; - - constructor(); - - setProjectionMatrix(projectionMatrix: Matrix4 | null): void; -} - -export default VelocityNode; - -export const velocity: ShaderNodeObject; diff --git a/src-testing/src/nodes/accessors/VertexColorNode.d.ts b/src-testing/src/nodes/accessors/VertexColorNode.d.ts deleted file mode 100644 index b2bb76339..000000000 --- a/src-testing/src/nodes/accessors/VertexColorNode.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -import AttributeNode from "../core/AttributeNode.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -export default class VertexColorNode extends AttributeNode { - readonly isVertexColorNode: true; - - index: number; - - constructor(index?: number); -} - -export const vertexColor: (index?: number) => ShaderNodeObject; diff --git a/src-testing/src/nodes/code/CodeNode.ts b/src-testing/src/nodes/code/CodeNode.ts deleted file mode 100644 index 2f4c60511..000000000 --- a/src-testing/src/nodes/code/CodeNode.ts +++ /dev/null @@ -1,68 +0,0 @@ -import Node from '../core/Node.js'; -import { nodeProxy } from '../tsl/TSLBase.js'; - -class CodeNode extends Node { - static get type() { - return 'CodeNode'; - } - - constructor(code = '', includes = [], language = '') { - super('code'); - - this.isCodeNode = true; - - this.code = code; - this.language = language; - - this.includes = includes; - } - - isGlobal() { - return true; - } - - setIncludes(includes) { - this.includes = includes; - - return this; - } - - getIncludes(/*builder*/) { - return this.includes; - } - - generate(builder) { - const includes = this.getIncludes(builder); - - for (const include of includes) { - include.build(builder); - } - - const nodeCode = builder.getCodeFromNode(this, this.getNodeType(builder)); - nodeCode.code = this.code; - - return nodeCode.code; - } - - serialize(data) { - super.serialize(data); - - data.code = this.code; - data.language = this.language; - } - - deserialize(data) { - super.deserialize(data); - - this.code = data.code; - this.language = data.language; - } -} - -export default CodeNode; - -export const code = /*@__PURE__*/ nodeProxy(CodeNode); - -export const js = (src, includes) => code(src, includes, 'js'); -export const wgsl = (src, includes) => code(src, includes, 'wgsl'); -export const glsl = (src, includes) => code(src, includes, 'glsl'); diff --git a/src-testing/src/nodes/code/ExpressionNode.d.ts b/src-testing/src/nodes/code/ExpressionNode.d.ts deleted file mode 100644 index ce5fc783b..000000000 --- a/src-testing/src/nodes/code/ExpressionNode.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import TempNode from "../core/TempNode.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -export default class ExpressionNode extends TempNode { - snipped: string; /* sic */ - constructor(snipped?: string, nodeType?: string); -} - -export const expression: (snipped?: string, nodeType?: string) => ShaderNodeObject; diff --git a/src-testing/src/nodes/code/FunctionCallNode.d.ts b/src-testing/src/nodes/code/FunctionCallNode.d.ts deleted file mode 100644 index 7bf6d7360..000000000 --- a/src-testing/src/nodes/code/FunctionCallNode.d.ts +++ /dev/null @@ -1,25 +0,0 @@ -import Node from "../core/Node.js"; -import TempNode from "../core/TempNode.js"; -import { ProxiedObject, ShaderNodeObject } from "../tsl/TSLCore.js"; -import FunctionNode, { FunctionNodeArguments } from "./FunctionNode.js"; - -export default class FunctionCallNode

extends TempNode { - functionNode: FunctionNode

; - parameters: { [name: string]: Node }; - - constructor(functionNode?: FunctionNode

, parameters?: P); - - setParameters(parameters: P): this; - getParameters(): P; -} - -export const call:

( - functionNode?: FunctionNode

, - parameters?: ProxiedObject

, -) => ShaderNodeObject>; - -declare module "../tsl/TSLCore.js" { - interface NodeElements { - call: typeof call; - } -} diff --git a/src-testing/src/nodes/code/FunctionNode.ts b/src-testing/src/nodes/code/FunctionNode.ts deleted file mode 100644 index 54d8a5c54..000000000 --- a/src-testing/src/nodes/code/FunctionNode.ts +++ /dev/null @@ -1,87 +0,0 @@ -import CodeNode from './CodeNode.js'; -import { nodeObject } from '../tsl/TSLBase.js'; - -class FunctionNode extends CodeNode { - static get type() { - return 'FunctionNode'; - } - - constructor(code = '', includes = [], language = '') { - super(code, includes, language); - } - - getNodeType(builder) { - return this.getNodeFunction(builder).type; - } - - getInputs(builder) { - return this.getNodeFunction(builder).inputs; - } - - getNodeFunction(builder) { - const nodeData = builder.getDataFromNode(this); - - let nodeFunction = nodeData.nodeFunction; - - if (nodeFunction === undefined) { - nodeFunction = builder.parser.parseFunction(this.code); - - nodeData.nodeFunction = nodeFunction; - } - - return nodeFunction; - } - - generate(builder, output) { - super.generate(builder); - - const nodeFunction = this.getNodeFunction(builder); - - const name = nodeFunction.name; - const type = nodeFunction.type; - - const nodeCode = builder.getCodeFromNode(this, type); - - if (name !== '') { - // use a custom property name - - nodeCode.name = name; - } - - const propertyName = builder.getPropertyName(nodeCode); - - const code = this.getNodeFunction(builder).getCode(propertyName); - - nodeCode.code = code + '\n'; - - if (output === 'property') { - return propertyName; - } else { - return builder.format(`${propertyName}()`, type, output); - } - } -} - -export default FunctionNode; - -const nativeFn = (code, includes = [], language = '') => { - for (let i = 0; i < includes.length; i++) { - const include = includes[i]; - - // TSL Function: glslFn, wgslFn - - if (typeof include === 'function') { - includes[i] = include.functionNode; - } - } - - const functionNode = nodeObject(new FunctionNode(code, includes, language)); - - const fn = (...params) => functionNode.call(...params); - fn.functionNode = functionNode; - - return fn; -}; - -export const glslFn = (code, includes) => nativeFn(code, includes, 'glsl'); -export const wgslFn = (code, includes) => nativeFn(code, includes, 'wgsl'); diff --git a/src-testing/src/nodes/code/ScriptableNode.d.ts b/src-testing/src/nodes/code/ScriptableNode.d.ts deleted file mode 100644 index 7922afe12..000000000 --- a/src-testing/src/nodes/code/ScriptableNode.d.ts +++ /dev/null @@ -1,22 +0,0 @@ -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -declare class Resources extends Map { - get(key: string, callback?: ((...args: TArgs) => void) | null, ...params: TArgs): unknown; -} - -export const global: Resources; - -declare class ScriptableNode extends Node { - codeNode: Node | null; - parameters: Record; - - constructor(codeNode?: Node | null, parameters?: Record); -} - -export default ScriptableNode; - -export const scriptable: ( - codeNode?: NodeRepresentation | null, - parameters?: Record, -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/code/ScriptableValueNode.d.ts b/src-testing/src/nodes/code/ScriptableValueNode.d.ts deleted file mode 100644 index eccec90c6..000000000 --- a/src-testing/src/nodes/code/ScriptableValueNode.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import Node from "../core/Node.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -declare class ScriptableValueNode extends Node { - constructor(value: unknown); -} - -export default ScriptableValueNode; - -export const scriptableValue: (value?: unknown) => ShaderNodeObject; diff --git a/src-testing/src/nodes/core/AssignNode.d.ts b/src-testing/src/nodes/core/AssignNode.d.ts deleted file mode 100644 index a5628e76c..000000000 --- a/src-testing/src/nodes/core/AssignNode.d.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; -import Node from "./Node.js"; -import NodeBuilder from "./NodeBuilder.js"; -import TempNode from "./TempNode.js"; - -export default class AssignNode extends TempNode { - constructor(targetNode: Node, sourceNode: Node); - - needsSplitAssign(builder: NodeBuilder): boolean; -} - -export const assign: (targetNode: NodeRepresentation, sourceNode: NodeRepresentation) => ShaderNodeObject; - -declare module "../tsl/TSLCore.js" { - interface NodeElements { - assign: typeof assign; - } -} diff --git a/src-testing/src/nodes/core/AttributeNode.d.ts b/src-testing/src/nodes/core/AttributeNode.d.ts deleted file mode 100644 index 179f07b74..000000000 --- a/src-testing/src/nodes/core/AttributeNode.d.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; -import Node from "./Node.js"; -import NodeBuilder from "./NodeBuilder.js"; - -export default class AttributeNode extends Node { - constructor(attributeName: string, nodeType?: string | null); - - setAttributeName(attributeName: string): this; - - getAttributeName(builder: NodeBuilder): string; -} - -export const attribute: ( - name: string, - nodeType?: string | null, -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/core/BypassNode.d.ts b/src-testing/src/nodes/core/BypassNode.d.ts deleted file mode 100644 index 5d152654d..000000000 --- a/src-testing/src/nodes/core/BypassNode.d.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; -import Node from "./Node.js"; - -export default class BypassNode extends Node { - isBypassNode: true; - outputNode: Node; - callNode: Node; - - constructor(returnNode: Node, callNode: Node); -} - -export const bypass: (returnNode: NodeRepresentation, callNode: NodeRepresentation) => ShaderNodeObject; - -declare module "../tsl/TSLCore.js" { - interface NodeElements { - bypass: typeof bypass; - } -} diff --git a/src-testing/src/nodes/core/CacheNode.d.ts b/src-testing/src/nodes/core/CacheNode.d.ts deleted file mode 100644 index 4b7f173d1..000000000 --- a/src-testing/src/nodes/core/CacheNode.d.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { ShaderNodeObject } from "../tsl/TSLCore.js"; -import Node from "./Node.js"; -import NodeCache from "./NodeCache.js"; - -export default class CacheNode extends Node { - node: Node; - parent: boolean; - - readonly isCacheNode: true; - - constructor(node: Node, parent?: boolean); -} - -export const cache: (node: Node, cache?: NodeCache) => ShaderNodeObject; - -declare module "../tsl/TSLCore.js" { - interface NodeElements { - cache: typeof cache; - } -} diff --git a/src-testing/src/nodes/core/ConstNode.d.ts b/src-testing/src/nodes/core/ConstNode.d.ts deleted file mode 100644 index f866b0c0c..000000000 --- a/src-testing/src/nodes/core/ConstNode.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import InputNode from "./InputNode.js"; -import NodeBuilder from "./NodeBuilder.js"; - -export default class ConstNode extends InputNode { - isConstNode: true; - constructor(value: Value, nodeType?: string | null); - - generateConst(builder: NodeBuilder): string; -} diff --git a/src-testing/src/nodes/core/ContextNode.ts b/src-testing/src/nodes/core/ContextNode.ts deleted file mode 100644 index 32b8ac0af..000000000 --- a/src-testing/src/nodes/core/ContextNode.ts +++ /dev/null @@ -1,61 +0,0 @@ -import Node from './Node.js'; -import { addMethodChaining, nodeProxy } from '../tsl/TSLCore.js'; - -class ContextNode extends Node { - static get type() { - return 'ContextNode'; - } - - constructor(node, value = {}) { - super(); - - this.isContextNode = true; - - this.node = node; - this.value = value; - } - - getScope() { - return this.node.getScope(); - } - - getNodeType(builder) { - return this.node.getNodeType(builder); - } - - analyze(builder) { - this.node.build(builder); - } - - setup(builder) { - const previousContext = builder.getContext(); - - builder.setContext({ ...builder.context, ...this.value }); - - const node = this.node.build(builder); - - builder.setContext(previousContext); - - return node; - } - - generate(builder, output) { - const previousContext = builder.getContext(); - - builder.setContext({ ...builder.context, ...this.value }); - - const snippet = this.node.build(builder, output); - - builder.setContext(previousContext); - - return snippet; - } -} - -export default ContextNode; - -export const context = /*@__PURE__*/ nodeProxy(ContextNode); -export const label = (node, name) => context(node, { label: name }); - -addMethodChaining('context', context); -addMethodChaining('label', label); diff --git a/src-testing/src/nodes/core/IndexNode.d.ts b/src-testing/src/nodes/core/IndexNode.d.ts deleted file mode 100644 index ebaba50ae..000000000 --- a/src-testing/src/nodes/core/IndexNode.d.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { ShaderNodeObject } from "../tsl/TSLCore.js"; -import Node from "./Node.js"; - -export type IndexNodeScope = - | typeof IndexNode.VERTEX - | typeof IndexNode.INSTANCE - | typeof IndexNode.INVOCATION_LOCAL - | typeof IndexNode.DRAW; - -declare class IndexNode extends Node { - scope: IndexNodeScope; - - readonly isInstanceNode: true; - - constructor(scope: IndexNodeScope); - - static VERTEX: "vertex"; - static INSTANCE: "instance"; - static INVOCATION_LOCAL: "invocationLocal"; - static DRAW: "draw"; -} - -export default IndexNode; - -export const vertexIndex: ShaderNodeObject; -export const instanceIndex: ShaderNodeObject; -export const invocationLocalIndex: ShaderNodeObject; -export const drawIndex: ShaderNodeObject; diff --git a/src-testing/src/nodes/core/InputNode.ts b/src-testing/src/nodes/core/InputNode.ts deleted file mode 100644 index 07af45dc3..000000000 --- a/src-testing/src/nodes/core/InputNode.ts +++ /dev/null @@ -1,67 +0,0 @@ -import Node from './Node.js'; -import { getValueType, getValueFromType, arrayBufferToBase64 } from './NodeUtils.js'; - -class InputNode extends Node { - static get type() { - return 'InputNode'; - } - - constructor(value, nodeType = null) { - super(nodeType); - - this.isInputNode = true; - - this.value = value; - this.precision = null; - } - - getNodeType(/*builder*/) { - if (this.nodeType === null) { - return getValueType(this.value); - } - - return this.nodeType; - } - - getInputType(builder) { - return this.getNodeType(builder); - } - - setPrecision(precision) { - this.precision = precision; - - return this; - } - - serialize(data) { - super.serialize(data); - - data.value = this.value; - - if (this.value && this.value.toArray) data.value = this.value.toArray(); - - data.valueType = getValueType(this.value); - data.nodeType = this.nodeType; - - if (data.valueType === 'ArrayBuffer') data.value = arrayBufferToBase64(data.value); - - data.precision = this.precision; - } - - deserialize(data) { - super.deserialize(data); - - this.nodeType = data.nodeType; - this.value = Array.isArray(data.value) ? getValueFromType(data.valueType, ...data.value) : data.value; - - this.precision = data.precision || null; - - if (this.value && this.value.fromArray) this.value = this.value.fromArray(data.value); - } - - generate(/*builder, output*/) { - console.warn('Abstract function.'); - } -} - -export default InputNode; diff --git a/src-testing/src/nodes/core/LightingModel.d.ts b/src-testing/src/nodes/core/LightingModel.d.ts deleted file mode 100644 index f64dd07db..000000000 --- a/src-testing/src/nodes/core/LightingModel.d.ts +++ /dev/null @@ -1,46 +0,0 @@ -import Node from "./Node.js"; -import NodeBuilder from "./NodeBuilder.js"; -import StackNode from "./StackNode.js"; - -export interface LightingModelReflectedLight { - directDiffuse: Node; - directSpecular: Node; - indirectDiffuse: Node; - indirectSpecular: Node; -} - -export interface LightingModelDirectInput { - lightDirection: Node; - lightColor: Node; - reflectedLight: LightingModelReflectedLight; -} - -export interface LightingModelDirectRectAreaInput { - lightColor: Node; - lightPosition: Node; - halfWidth: Node; - halfHeight: Node; - reflectedLight: LightingModelReflectedLight; - ltc_1: Node; - ltc_2: Node; -} - -export interface LightingModelIndirectInput { - radiance: Node; - irradiance: Node; - iblIrradiance: Node; - ambientOcclusion: Node; - reflectedLight: LightingModelReflectedLight; - backdrop: Node; - backdropAlpha: Node; - outgoingLight: Node; -} - -export default class LightingModel { - start(input: LightingModelIndirectInput, stack: StackNode, builder: NodeBuilder): void; - finish(input: LightingModelIndirectInput, stack: StackNode, builder: NodeBuilder): void; - direct(input: LightingModelDirectInput, stack: StackNode, builder: NodeBuilder): void; - directRectArea(input: LightingModelDirectRectAreaInput, stack: StackNode, builder: NodeBuilder): void; - indirect(input: LightingModelIndirectInput, stack: StackNode, builder: NodeBuilder): void; - ambientOcclusion(input: LightingModelIndirectInput, stack: StackNode, builder: NodeBuilder): void; -} diff --git a/src-testing/src/nodes/core/MRTNode.d.ts b/src-testing/src/nodes/core/MRTNode.d.ts deleted file mode 100644 index ef223da73..000000000 --- a/src-testing/src/nodes/core/MRTNode.d.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { Texture } from "../../textures/Texture.js"; -import { Node } from "../Nodes.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; -import OutputStructNode from "./OutputStructNode.js"; - -export function getTextureIndex(textures: ReadonlyArray, name: string): number; - -declare class MRTNode extends OutputStructNode { - outputNodes: { [name: string]: Node }; - - readonly isMRTNode: true; - - constructor(outputNodes: { [name: string]: Node }); - - has(name: string): boolean; - - get(name: string): Node; - - merge(mrtNode: MRTNode): ShaderNodeObject; -} - -export default MRTNode; - -export const mrt: (outputNodes: { [name: string]: Node }) => ShaderNodeObject; diff --git a/src-testing/src/nodes/core/Node.ts b/src-testing/src/nodes/core/Node.ts deleted file mode 100644 index 2e54fce07..000000000 --- a/src-testing/src/nodes/core/Node.ts +++ /dev/null @@ -1,401 +0,0 @@ -import { NodeUpdateType } from './constants.js'; -import { getNodeChildren, getCacheKey } from './NodeUtils.js'; - -import { EventDispatcher } from '../../core/EventDispatcher.js'; -import { MathUtils } from '../../math/MathUtils.js'; - -let _nodeId = 0; - -class Node extends EventDispatcher { - static get type() { - return 'Node'; - } - - constructor(nodeType = null) { - super(); - - this.nodeType = nodeType; - - this.updateType = NodeUpdateType.NONE; - this.updateBeforeType = NodeUpdateType.NONE; - this.updateAfterType = NodeUpdateType.NONE; - - this.uuid = MathUtils.generateUUID(); - - this.version = 0; - - this._cacheKey = null; - this._cacheKeyVersion = 0; - - this.global = false; - - this.isNode = true; - - Object.defineProperty(this, 'id', { value: _nodeId++ }); - } - - set needsUpdate(value) { - if (value === true) { - this.version++; - } - } - - get type() { - return this.constructor.type; - } - - onUpdate(callback, updateType) { - this.updateType = updateType; - this.update = callback.bind(this.getSelf()); - - return this; - } - - onFrameUpdate(callback) { - return this.onUpdate(callback, NodeUpdateType.FRAME); - } - - onRenderUpdate(callback) { - return this.onUpdate(callback, NodeUpdateType.RENDER); - } - - onObjectUpdate(callback) { - return this.onUpdate(callback, NodeUpdateType.OBJECT); - } - - onReference(callback) { - this.updateReference = callback.bind(this.getSelf()); - - return this; - } - - getSelf() { - // Returns non-node object. - - return this.self || this; - } - - updateReference(/*state*/) { - return this; - } - - isGlobal(/*builder*/) { - return this.global; - } - - *getChildren() { - for (const { childNode } of getNodeChildren(this)) { - yield childNode; - } - } - - dispose() { - this.dispatchEvent({ type: 'dispose' }); - } - - traverse(callback) { - callback(this); - - for (const childNode of this.getChildren()) { - childNode.traverse(callback); - } - } - - getCacheKey(force = false) { - force = force || this.version !== this._cacheKeyVersion; - - if (force === true || this._cacheKey === null) { - this._cacheKey = getCacheKey(this, force); - this._cacheKeyVersion = this.version; - } - - return this._cacheKey; - } - - getScope() { - return this; - } - - getHash(/*builder*/) { - return this.uuid; - } - - getUpdateType() { - return this.updateType; - } - - getUpdateBeforeType() { - return this.updateBeforeType; - } - - getUpdateAfterType() { - return this.updateAfterType; - } - - getElementType(builder) { - const type = this.getNodeType(builder); - const elementType = builder.getElementType(type); - - return elementType; - } - - getNodeType(builder) { - const nodeProperties = builder.getNodeProperties(this); - - if (nodeProperties.outputNode) { - return nodeProperties.outputNode.getNodeType(builder); - } - - return this.nodeType; - } - - getShared(builder) { - const hash = this.getHash(builder); - const nodeFromHash = builder.getNodeFromHash(hash); - - return nodeFromHash || this; - } - - setup(builder) { - const nodeProperties = builder.getNodeProperties(this); - - let index = 0; - - for (const childNode of this.getChildren()) { - nodeProperties['node' + index++] = childNode; - } - - // return a outputNode if exists - return null; - } - - analyze(builder) { - const usageCount = builder.increaseUsage(this); - - if (usageCount === 1) { - // node flow children - - const nodeProperties = builder.getNodeProperties(this); - - for (const childNode of Object.values(nodeProperties)) { - if (childNode && childNode.isNode === true) { - childNode.build(builder); - } - } - } - } - - generate(builder, output) { - const { outputNode } = builder.getNodeProperties(this); - - if (outputNode && outputNode.isNode === true) { - return outputNode.build(builder, output); - } - } - - updateBefore(/*frame*/) { - console.warn('Abstract function.'); - } - - updateAfter(/*frame*/) { - console.warn('Abstract function.'); - } - - update(/*frame*/) { - console.warn('Abstract function.'); - } - - build(builder, output = null) { - const refNode = this.getShared(builder); - - if (this !== refNode) { - return refNode.build(builder, output); - } - - builder.addNode(this); - builder.addChain(this); - - /* Build stages expected results: - - "setup" -> Node - - "analyze" -> null - - "generate" -> String - */ - let result = null; - - const buildStage = builder.getBuildStage(); - - if (buildStage === 'setup') { - this.updateReference(builder); - - const properties = builder.getNodeProperties(this); - - if (properties.initialized !== true) { - const stackNodesBeforeSetup = builder.stack.nodes.length; - - properties.initialized = true; - properties.outputNode = this.setup(builder); - - if (properties.outputNode !== null && builder.stack.nodes.length !== stackNodesBeforeSetup) { - // !! no outputNode !! - //properties.outputNode = builder.stack; - } - - for (const childNode of Object.values(properties)) { - if (childNode && childNode.isNode === true) { - childNode.build(builder); - } - } - } - } else if (buildStage === 'analyze') { - this.analyze(builder); - } else if (buildStage === 'generate') { - const isGenerateOnce = this.generate.length === 1; - - if (isGenerateOnce) { - const type = this.getNodeType(builder); - const nodeData = builder.getDataFromNode(this); - - result = nodeData.snippet; - - if (result === undefined) { - result = this.generate(builder) || ''; - - nodeData.snippet = result; - } else if (nodeData.flowCodes !== undefined && builder.context.nodeBlock !== undefined) { - builder.addFlowCodeHierarchy(this, builder.context.nodeBlock); - } - - result = builder.format(result, type, output); - } else { - result = this.generate(builder, output) || ''; - } - } - - builder.removeChain(this); - builder.addSequentialNode(this); - - return result; - } - - getSerializeChildren() { - return getNodeChildren(this); - } - - serialize(json) { - const nodeChildren = this.getSerializeChildren(); - - const inputNodes = {}; - - for (const { property, index, childNode } of nodeChildren) { - if (index !== undefined) { - if (inputNodes[property] === undefined) { - inputNodes[property] = Number.isInteger(index) ? [] : {}; - } - - inputNodes[property][index] = childNode.toJSON(json.meta).uuid; - } else { - inputNodes[property] = childNode.toJSON(json.meta).uuid; - } - } - - if (Object.keys(inputNodes).length > 0) { - json.inputNodes = inputNodes; - } - } - - deserialize(json) { - if (json.inputNodes !== undefined) { - const nodes = json.meta.nodes; - - for (const property in json.inputNodes) { - if (Array.isArray(json.inputNodes[property])) { - const inputArray = []; - - for (const uuid of json.inputNodes[property]) { - inputArray.push(nodes[uuid]); - } - - this[property] = inputArray; - } else if (typeof json.inputNodes[property] === 'object') { - const inputObject = {}; - - for (const subProperty in json.inputNodes[property]) { - const uuid = json.inputNodes[property][subProperty]; - - inputObject[subProperty] = nodes[uuid]; - } - - this[property] = inputObject; - } else { - const uuid = json.inputNodes[property]; - - this[property] = nodes[uuid]; - } - } - } - } - - toJSON(meta) { - const { uuid, type } = this; - const isRoot = meta === undefined || typeof meta === 'string'; - - if (isRoot) { - meta = { - textures: {}, - images: {}, - nodes: {}, - }; - } - - // serialize - - let data = meta.nodes[uuid]; - - if (data === undefined) { - data = { - uuid, - type, - meta, - metadata: { - version: 4.6, - type: 'Node', - generator: 'Node.toJSON', - }, - }; - - if (isRoot !== true) meta.nodes[data.uuid] = data; - - this.serialize(data); - - delete data.meta; - } - - // TODO: Copied from Object3D.toJSON - - function extractFromCache(cache) { - const values = []; - - for (const key in cache) { - const data = cache[key]; - delete data.metadata; - values.push(data); - } - - return values; - } - - if (isRoot) { - const textures = extractFromCache(meta.textures); - const images = extractFromCache(meta.images); - const nodes = extractFromCache(meta.nodes); - - if (textures.length > 0) data.textures = textures; - if (images.length > 0) data.images = images; - if (nodes.length > 0) data.nodes = nodes; - } - - return data; - } -} - -export default Node; diff --git a/src-testing/src/nodes/core/NodeAttribute.ts b/src-testing/src/nodes/core/NodeAttribute.ts deleted file mode 100644 index 190fe8c51..000000000 --- a/src-testing/src/nodes/core/NodeAttribute.ts +++ /dev/null @@ -1,11 +0,0 @@ -class NodeAttribute { - constructor(name, type, node = null) { - this.isNodeAttribute = true; - - this.name = name; - this.type = type; - this.node = node; - } -} - -export default NodeAttribute; diff --git a/src-testing/src/nodes/core/NodeBuilder.ts b/src-testing/src/nodes/core/NodeBuilder.ts deleted file mode 100644 index 3003d1680..000000000 --- a/src-testing/src/nodes/core/NodeBuilder.ts +++ /dev/null @@ -1,1208 +0,0 @@ -import NodeUniform from './NodeUniform.js'; -import NodeAttribute from './NodeAttribute.js'; -import NodeVarying from './NodeVarying.js'; -import NodeVar from './NodeVar.js'; -import NodeCode from './NodeCode.js'; -import NodeCache from './NodeCache.js'; -import ParameterNode from './ParameterNode.js'; -import FunctionNode from '../code/FunctionNode.js'; -import NodeMaterial from '../../materials/nodes/NodeMaterial.js'; -import { NodeUpdateType, defaultBuildStages, shaderStages } from './constants.js'; - -import { - NumberNodeUniform, - Vector2NodeUniform, - Vector3NodeUniform, - Vector4NodeUniform, - ColorNodeUniform, - Matrix3NodeUniform, - Matrix4NodeUniform, -} from '../../renderers/common/nodes/NodeUniform.js'; - -import { stack } from './StackNode.js'; -import { getCurrentStack, setCurrentStack } from '../tsl/TSLBase.js'; - -import CubeRenderTarget from '../../renderers/common/CubeRenderTarget.js'; -import ChainMap from '../../renderers/common/ChainMap.js'; - -import PMREMGenerator from '../../renderers/common/extras/PMREMGenerator.js'; - -import BindGroup from '../../renderers/common/BindGroup.js'; - -import { REVISION } from '../../constants.js'; -import { RenderTarget } from '../../core/RenderTarget.js'; -import { Color } from '../../math/Color.js'; -import { Vector2 } from '../../math/Vector2.js'; -import { Vector3 } from '../../math/Vector3.js'; -import { Vector4 } from '../../math/Vector4.js'; -import { Float16BufferAttribute } from '../../core/BufferAttribute.js'; -import { - IntType, - UnsignedIntType, - LinearFilter, - LinearMipmapNearestFilter, - NearestMipmapLinearFilter, - LinearMipmapLinearFilter, -} from '../../constants.js'; - -const rendererCache = new WeakMap(); - -const typeFromLength = new Map([ - [2, 'vec2'], - [3, 'vec3'], - [4, 'vec4'], - [9, 'mat3'], - [16, 'mat4'], -]); - -const typeFromArray = new Map([ - [Int8Array, 'int'], - [Int16Array, 'int'], - [Int32Array, 'int'], - [Uint8Array, 'uint'], - [Uint16Array, 'uint'], - [Uint32Array, 'uint'], - [Float32Array, 'float'], -]); - -const toFloat = value => { - if (/e/g.test(value)) { - return String(value).replace(/\+/g, ''); - } else { - value = Number(value); - - return value + (value % 1 ? '' : '.0'); - } -}; - -class NodeBuilder { - constructor(object, renderer, parser) { - this.object = object; - this.material = (object && object.material) || null; - this.geometry = (object && object.geometry) || null; - this.renderer = renderer; - this.parser = parser; - this.scene = null; - this.camera = null; - - this.nodes = []; - this.sequentialNodes = []; - this.updateNodes = []; - this.updateBeforeNodes = []; - this.updateAfterNodes = []; - this.hashNodes = {}; - - this.monitor = null; - - this.lightsNode = null; - this.environmentNode = null; - this.fogNode = null; - - this.clippingContext = null; - - this.vertexShader = null; - this.fragmentShader = null; - this.computeShader = null; - - this.flowNodes = { vertex: [], fragment: [], compute: [] }; - this.flowCode = { vertex: '', fragment: '', compute: '' }; - this.uniforms = { vertex: [], fragment: [], compute: [], index: 0 }; - this.structs = { vertex: [], fragment: [], compute: [], index: 0 }; - this.bindings = { vertex: {}, fragment: {}, compute: {} }; - this.bindingsIndexes = {}; - this.bindGroups = null; - this.attributes = []; - this.bufferAttributes = []; - this.varyings = []; - this.codes = {}; - this.vars = {}; - this.flow = { code: '' }; - this.chaining = []; - this.stack = stack(); - this.stacks = []; - this.tab = '\t'; - - this.currentFunctionNode = null; - - this.context = { - material: this.material, - }; - - this.cache = new NodeCache(); - this.globalCache = this.cache; - - this.flowsData = new WeakMap(); - - this.shaderStage = null; - this.buildStage = null; - - this.useComparisonMethod = false; - } - - getBindGroupsCache() { - let bindGroupsCache = rendererCache.get(this.renderer); - - if (bindGroupsCache === undefined) { - bindGroupsCache = new ChainMap(); - - rendererCache.set(this.renderer, bindGroupsCache); - } - - return bindGroupsCache; - } - - createRenderTarget(width, height, options) { - return new RenderTarget(width, height, options); - } - - createCubeRenderTarget(size, options) { - return new CubeRenderTarget(size, options); - } - - createPMREMGenerator() { - // TODO: Move Materials.js to outside of the Nodes.js in order to remove this function and improve tree-shaking support - - return new PMREMGenerator(this.renderer); - } - - includes(node) { - return this.nodes.includes(node); - } - - _getBindGroup(groupName, bindings) { - const bindGroupsCache = this.getBindGroupsCache(); - - // - - const bindingsArray = []; - - let sharedGroup = true; - - for (const binding of bindings) { - bindingsArray.push(binding); - - sharedGroup = sharedGroup && binding.groupNode.shared !== true; - } - - // - - let bindGroup; - - if (sharedGroup) { - bindGroup = bindGroupsCache.get(bindingsArray); - - if (bindGroup === undefined) { - bindGroup = new BindGroup( - groupName, - bindingsArray, - this.bindingsIndexes[groupName].group, - bindingsArray, - ); - - bindGroupsCache.set(bindingsArray, bindGroup); - } - } else { - bindGroup = new BindGroup(groupName, bindingsArray, this.bindingsIndexes[groupName].group, bindingsArray); - } - - return bindGroup; - } - - getBindGroupArray(groupName, shaderStage) { - const bindings = this.bindings[shaderStage]; - - let bindGroup = bindings[groupName]; - - if (bindGroup === undefined) { - if (this.bindingsIndexes[groupName] === undefined) { - this.bindingsIndexes[groupName] = { binding: 0, group: Object.keys(this.bindingsIndexes).length }; - } - - bindings[groupName] = bindGroup = []; - } - - return bindGroup; - } - - getBindings() { - let bindingsGroups = this.bindGroups; - - if (bindingsGroups === null) { - const groups = {}; - const bindings = this.bindings; - - for (const shaderStage of shaderStages) { - for (const groupName in bindings[shaderStage]) { - const uniforms = bindings[shaderStage][groupName]; - - const groupUniforms = groups[groupName] || (groups[groupName] = []); - groupUniforms.push(...uniforms); - } - } - - bindingsGroups = []; - - for (const groupName in groups) { - const group = groups[groupName]; - - const bindingsGroup = this._getBindGroup(groupName, group); - - bindingsGroups.push(bindingsGroup); - } - - this.bindGroups = bindingsGroups; - } - - return bindingsGroups; - } - - sortBindingGroups() { - const bindingsGroups = this.getBindings(); - - bindingsGroups.sort((a, b) => a.bindings[0].groupNode.order - b.bindings[0].groupNode.order); - - for (let i = 0; i < bindingsGroups.length; i++) { - const bindingGroup = bindingsGroups[i]; - this.bindingsIndexes[bindingGroup.name].group = i; - - bindingGroup.index = i; - } - } - - setHashNode(node, hash) { - this.hashNodes[hash] = node; - } - - addNode(node) { - if (this.nodes.includes(node) === false) { - this.nodes.push(node); - - this.setHashNode(node, node.getHash(this)); - } - } - - addSequentialNode(node) { - if (this.sequentialNodes.includes(node) === false) { - this.sequentialNodes.push(node); - } - } - - buildUpdateNodes() { - for (const node of this.nodes) { - const updateType = node.getUpdateType(); - - if (updateType !== NodeUpdateType.NONE) { - this.updateNodes.push(node.getSelf()); - } - } - - for (const node of this.sequentialNodes) { - const updateBeforeType = node.getUpdateBeforeType(); - const updateAfterType = node.getUpdateAfterType(); - - if (updateBeforeType !== NodeUpdateType.NONE) { - this.updateBeforeNodes.push(node.getSelf()); - } - - if (updateAfterType !== NodeUpdateType.NONE) { - this.updateAfterNodes.push(node.getSelf()); - } - } - } - - get currentNode() { - return this.chaining[this.chaining.length - 1]; - } - - isFilteredTexture(texture) { - return ( - texture.magFilter === LinearFilter || - texture.magFilter === LinearMipmapNearestFilter || - texture.magFilter === NearestMipmapLinearFilter || - texture.magFilter === LinearMipmapLinearFilter || - texture.minFilter === LinearFilter || - texture.minFilter === LinearMipmapNearestFilter || - texture.minFilter === NearestMipmapLinearFilter || - texture.minFilter === LinearMipmapLinearFilter - ); - } - - addChain(node) { - /* - if ( this.chaining.indexOf( node ) !== - 1 ) { - - console.warn( 'Recursive node: ', node ); - - } - */ - - this.chaining.push(node); - } - - removeChain(node) { - const lastChain = this.chaining.pop(); - - if (lastChain !== node) { - throw new Error('NodeBuilder: Invalid node chaining!'); - } - } - - getMethod(method) { - return method; - } - - getNodeFromHash(hash) { - return this.hashNodes[hash]; - } - - addFlow(shaderStage, node) { - this.flowNodes[shaderStage].push(node); - - return node; - } - - setContext(context) { - this.context = context; - } - - getContext() { - return this.context; - } - - getSharedContext() { - const context = { ...this.context }; - - delete context.material; - - return this.context; - } - - setCache(cache) { - this.cache = cache; - } - - getCache() { - return this.cache; - } - - getCacheFromNode(node, parent = true) { - const data = this.getDataFromNode(node); - if (data.cache === undefined) data.cache = new NodeCache(parent ? this.getCache() : null); - - return data.cache; - } - - isAvailable(/*name*/) { - return false; - } - - getVertexIndex() { - console.warn('Abstract function.'); - } - - getInstanceIndex() { - console.warn('Abstract function.'); - } - - getDrawIndex() { - console.warn('Abstract function.'); - } - - getFrontFacing() { - console.warn('Abstract function.'); - } - - getFragCoord() { - console.warn('Abstract function.'); - } - - isFlipY() { - return false; - } - - increaseUsage(node) { - const nodeData = this.getDataFromNode(node); - nodeData.usageCount = nodeData.usageCount === undefined ? 1 : nodeData.usageCount + 1; - - return nodeData.usageCount; - } - - generateTexture(/* texture, textureProperty, uvSnippet */) { - console.warn('Abstract function.'); - } - - generateTextureLod(/* texture, textureProperty, uvSnippet, levelSnippet */) { - console.warn('Abstract function.'); - } - - generateConst(type, value = null) { - if (value === null) { - if (type === 'float' || type === 'int' || type === 'uint') value = 0; - else if (type === 'bool') value = false; - else if (type === 'color') value = new Color(); - else if (type === 'vec2') value = new Vector2(); - else if (type === 'vec3') value = new Vector3(); - else if (type === 'vec4') value = new Vector4(); - } - - if (type === 'float') return toFloat(value); - if (type === 'int') return `${Math.round(value)}`; - if (type === 'uint') return value >= 0 ? `${Math.round(value)}u` : '0u'; - if (type === 'bool') return value ? 'true' : 'false'; - if (type === 'color') - return `${this.getType('vec3')}( ${toFloat(value.r)}, ${toFloat(value.g)}, ${toFloat(value.b)} )`; - - const typeLength = this.getTypeLength(type); - - const componentType = this.getComponentType(type); - - const generateConst = value => this.generateConst(componentType, value); - - if (typeLength === 2) { - return `${this.getType(type)}( ${generateConst(value.x)}, ${generateConst(value.y)} )`; - } else if (typeLength === 3) { - return `${this.getType(type)}( ${generateConst(value.x)}, ${generateConst(value.y)}, ${generateConst(value.z)} )`; - } else if (typeLength === 4) { - return `${this.getType(type)}( ${generateConst(value.x)}, ${generateConst(value.y)}, ${generateConst(value.z)}, ${generateConst(value.w)} )`; - } else if (typeLength > 4 && value && (value.isMatrix3 || value.isMatrix4)) { - return `${this.getType(type)}( ${value.elements.map(generateConst).join(', ')} )`; - } else if (typeLength > 4) { - return `${this.getType(type)}()`; - } - - throw new Error(`NodeBuilder: Type '${type}' not found in generate constant attempt.`); - } - - getType(type) { - if (type === 'color') return 'vec3'; - - return type; - } - - hasGeometryAttribute(name) { - return this.geometry && this.geometry.getAttribute(name) !== undefined; - } - - getAttribute(name, type) { - const attributes = this.attributes; - - // find attribute - - for (const attribute of attributes) { - if (attribute.name === name) { - return attribute; - } - } - - // create a new if no exist - - const attribute = new NodeAttribute(name, type); - - attributes.push(attribute); - - return attribute; - } - - getPropertyName(node /*, shaderStage*/) { - return node.name; - } - - isVector(type) { - return /vec\d/.test(type); - } - - isMatrix(type) { - return /mat\d/.test(type); - } - - isReference(type) { - return ( - type === 'void' || - type === 'property' || - type === 'sampler' || - type === 'texture' || - type === 'cubeTexture' || - type === 'storageTexture' || - type === 'depthTexture' || - type === 'texture3D' - ); - } - - needsToWorkingColorSpace(/*texture*/) { - return false; - } - - getComponentTypeFromTexture(texture) { - const type = texture.type; - - if (texture.isDataTexture) { - if (type === IntType) return 'int'; - if (type === UnsignedIntType) return 'uint'; - } - - return 'float'; - } - - getElementType(type) { - if (type === 'mat2') return 'vec2'; - if (type === 'mat3') return 'vec3'; - if (type === 'mat4') return 'vec4'; - - return this.getComponentType(type); - } - - getComponentType(type) { - type = this.getVectorType(type); - - if (type === 'float' || type === 'bool' || type === 'int' || type === 'uint') return type; - - const componentType = /(b|i|u|)(vec|mat)([2-4])/.exec(type); - - if (componentType === null) return null; - - if (componentType[1] === 'b') return 'bool'; - if (componentType[1] === 'i') return 'int'; - if (componentType[1] === 'u') return 'uint'; - - return 'float'; - } - - getVectorType(type) { - if (type === 'color') return 'vec3'; - if (type === 'texture' || type === 'cubeTexture' || type === 'storageTexture' || type === 'texture3D') - return 'vec4'; - - return type; - } - - getTypeFromLength(length, componentType = 'float') { - if (length === 1) return componentType; - - const baseType = typeFromLength.get(length); - const prefix = componentType === 'float' ? '' : componentType[0]; - - return prefix + baseType; - } - - getTypeFromArray(array) { - return typeFromArray.get(array.constructor); - } - - getTypeFromAttribute(attribute) { - let dataAttribute = attribute; - - if (attribute.isInterleavedBufferAttribute) dataAttribute = attribute.data; - - const array = dataAttribute.array; - const itemSize = attribute.itemSize; - const normalized = attribute.normalized; - - let arrayType; - - if (!(attribute instanceof Float16BufferAttribute) && normalized !== true) { - arrayType = this.getTypeFromArray(array); - } - - return this.getTypeFromLength(itemSize, arrayType); - } - - getTypeLength(type) { - const vecType = this.getVectorType(type); - const vecNum = /vec([2-4])/.exec(vecType); - - if (vecNum !== null) return Number(vecNum[1]); - if (vecType === 'float' || vecType === 'bool' || vecType === 'int' || vecType === 'uint') return 1; - if (/mat2/.test(type) === true) return 4; - if (/mat3/.test(type) === true) return 9; - if (/mat4/.test(type) === true) return 16; - - return 0; - } - - getVectorFromMatrix(type) { - return type.replace('mat', 'vec'); - } - - changeComponentType(type, newComponentType) { - return this.getTypeFromLength(this.getTypeLength(type), newComponentType); - } - - getIntegerType(type) { - const componentType = this.getComponentType(type); - - if (componentType === 'int' || componentType === 'uint') return type; - - return this.changeComponentType(type, 'int'); - } - - addStack() { - this.stack = stack(this.stack); - - this.stacks.push(getCurrentStack() || this.stack); - setCurrentStack(this.stack); - - return this.stack; - } - - removeStack() { - const lastStack = this.stack; - this.stack = lastStack.parent; - - setCurrentStack(this.stacks.pop()); - - return lastStack; - } - - getDataFromNode(node, shaderStage = this.shaderStage, cache = null) { - cache = cache === null ? (node.isGlobal(this) ? this.globalCache : this.cache) : cache; - - let nodeData = cache.getData(node); - - if (nodeData === undefined) { - nodeData = {}; - - cache.setData(node, nodeData); - } - - if (nodeData[shaderStage] === undefined) nodeData[shaderStage] = {}; - - return nodeData[shaderStage]; - } - - getNodeProperties(node, shaderStage = 'any') { - const nodeData = this.getDataFromNode(node, shaderStage); - - return nodeData.properties || (nodeData.properties = { outputNode: null }); - } - - getBufferAttributeFromNode(node, type) { - const nodeData = this.getDataFromNode(node); - - let bufferAttribute = nodeData.bufferAttribute; - - if (bufferAttribute === undefined) { - const index = this.uniforms.index++; - - bufferAttribute = new NodeAttribute('nodeAttribute' + index, type, node); - - this.bufferAttributes.push(bufferAttribute); - - nodeData.bufferAttribute = bufferAttribute; - } - - return bufferAttribute; - } - - getStructTypeFromNode(node, shaderStage = this.shaderStage) { - const nodeData = this.getDataFromNode(node, shaderStage); - - if (nodeData.structType === undefined) { - const index = this.structs.index++; - - node.name = `StructType${index}`; - this.structs[shaderStage].push(node); - - nodeData.structType = node; - } - - return node; - } - - getUniformFromNode(node, type, shaderStage = this.shaderStage, name = null) { - const nodeData = this.getDataFromNode(node, shaderStage, this.globalCache); - - let nodeUniform = nodeData.uniform; - - if (nodeUniform === undefined) { - const index = this.uniforms.index++; - - nodeUniform = new NodeUniform(name || 'nodeUniform' + index, type, node); - - this.uniforms[shaderStage].push(nodeUniform); - - nodeData.uniform = nodeUniform; - } - - return nodeUniform; - } - - getVarFromNode(node, name = null, type = node.getNodeType(this), shaderStage = this.shaderStage) { - const nodeData = this.getDataFromNode(node, shaderStage); - - let nodeVar = nodeData.variable; - - if (nodeVar === undefined) { - const vars = this.vars[shaderStage] || (this.vars[shaderStage] = []); - - if (name === null) name = 'nodeVar' + vars.length; - - nodeVar = new NodeVar(name, type); - - vars.push(nodeVar); - - nodeData.variable = nodeVar; - } - - return nodeVar; - } - - getVaryingFromNode(node, name = null, type = node.getNodeType(this)) { - const nodeData = this.getDataFromNode(node, 'any'); - - let nodeVarying = nodeData.varying; - - if (nodeVarying === undefined) { - const varyings = this.varyings; - const index = varyings.length; - - if (name === null) name = 'nodeVarying' + index; - - nodeVarying = new NodeVarying(name, type); - - varyings.push(nodeVarying); - - nodeData.varying = nodeVarying; - } - - return nodeVarying; - } - - getCodeFromNode(node, type, shaderStage = this.shaderStage) { - const nodeData = this.getDataFromNode(node); - - let nodeCode = nodeData.code; - - if (nodeCode === undefined) { - const codes = this.codes[shaderStage] || (this.codes[shaderStage] = []); - const index = codes.length; - - nodeCode = new NodeCode('nodeCode' + index, type); - - codes.push(nodeCode); - - nodeData.code = nodeCode; - } - - return nodeCode; - } - - addFlowCodeHierarchy(node, nodeBlock) { - const { flowCodes, flowCodeBlock } = this.getDataFromNode(node); - - let needsFlowCode = true; - let nodeBlockHierarchy = nodeBlock; - - while (nodeBlockHierarchy) { - if (flowCodeBlock.get(nodeBlockHierarchy) === true) { - needsFlowCode = false; - break; - } - - nodeBlockHierarchy = this.getDataFromNode(nodeBlockHierarchy).parentNodeBlock; - } - - if (needsFlowCode) { - for (const flowCode of flowCodes) { - this.addLineFlowCode(flowCode); - } - } - } - - addLineFlowCodeBlock(node, code, nodeBlock) { - const nodeData = this.getDataFromNode(node); - const flowCodes = nodeData.flowCodes || (nodeData.flowCodes = []); - const codeBlock = nodeData.flowCodeBlock || (nodeData.flowCodeBlock = new WeakMap()); - - flowCodes.push(code); - codeBlock.set(nodeBlock, true); - } - - addLineFlowCode(code, node = null) { - if (code === '') return this; - - if (node !== null && this.context.nodeBlock) { - this.addLineFlowCodeBlock(node, code, this.context.nodeBlock); - } - - code = this.tab + code; - - if (!/;\s*$/.test(code)) { - code = code + ';\n'; - } - - this.flow.code += code; - - return this; - } - - addFlowCode(code) { - this.flow.code += code; - - return this; - } - - addFlowTab() { - this.tab += '\t'; - - return this; - } - - removeFlowTab() { - this.tab = this.tab.slice(0, -1); - - return this; - } - - getFlowData(node /*, shaderStage*/) { - return this.flowsData.get(node); - } - - flowNode(node) { - const output = node.getNodeType(this); - - const flowData = this.flowChildNode(node, output); - - this.flowsData.set(node, flowData); - - return flowData; - } - - buildFunctionNode(shaderNode) { - const fn = new FunctionNode(); - - const previous = this.currentFunctionNode; - - this.currentFunctionNode = fn; - - fn.code = this.buildFunctionCode(shaderNode); - - this.currentFunctionNode = previous; - - return fn; - } - - flowShaderNode(shaderNode) { - const layout = shaderNode.layout; - - const inputs = { - [Symbol.iterator]() { - let index = 0; - const values = Object.values(this); - return { - next: () => ({ - value: values[index], - done: index++ >= values.length, - }), - }; - }, - }; - - for (const input of layout.inputs) { - inputs[input.name] = new ParameterNode(input.type, input.name); - } - - // - - shaderNode.layout = null; - - const callNode = shaderNode.call(inputs); - const flowData = this.flowStagesNode(callNode, layout.type); - - shaderNode.layout = layout; - - return flowData; - } - - flowStagesNode(node, output = null) { - const previousFlow = this.flow; - const previousVars = this.vars; - const previousCache = this.cache; - const previousBuildStage = this.buildStage; - const previousStack = this.stack; - - const flow = { - code: '', - }; - - this.flow = flow; - this.vars = {}; - this.cache = new NodeCache(); - this.stack = stack(); - - for (const buildStage of defaultBuildStages) { - this.setBuildStage(buildStage); - - flow.result = node.build(this, output); - } - - flow.vars = this.getVars(this.shaderStage); - - this.flow = previousFlow; - this.vars = previousVars; - this.cache = previousCache; - this.stack = previousStack; - - this.setBuildStage(previousBuildStage); - - return flow; - } - - getFunctionOperator() { - return null; - } - - flowChildNode(node, output = null) { - const previousFlow = this.flow; - - const flow = { - code: '', - }; - - this.flow = flow; - - flow.result = node.build(this, output); - - this.flow = previousFlow; - - return flow; - } - - flowNodeFromShaderStage(shaderStage, node, output = null, propertyName = null) { - const previousShaderStage = this.shaderStage; - - this.setShaderStage(shaderStage); - - const flowData = this.flowChildNode(node, output); - - if (propertyName !== null) { - flowData.code += `${this.tab + propertyName} = ${flowData.result};\n`; - } - - this.flowCode[shaderStage] = this.flowCode[shaderStage] + flowData.code; - - this.setShaderStage(previousShaderStage); - - return flowData; - } - - getAttributesArray() { - return this.attributes.concat(this.bufferAttributes); - } - - getAttributes(/*shaderStage*/) { - console.warn('Abstract function.'); - } - - getVaryings(/*shaderStage*/) { - console.warn('Abstract function.'); - } - - getVar(type, name) { - return `${this.getType(type)} ${name}`; - } - - getVars(shaderStage) { - let snippet = ''; - - const vars = this.vars[shaderStage]; - - if (vars !== undefined) { - for (const variable of vars) { - snippet += `${this.getVar(variable.type, variable.name)}; `; - } - } - - return snippet; - } - - getUniforms(/*shaderStage*/) { - console.warn('Abstract function.'); - } - - getCodes(shaderStage) { - const codes = this.codes[shaderStage]; - - let code = ''; - - if (codes !== undefined) { - for (const nodeCode of codes) { - code += nodeCode.code + '\n'; - } - } - - return code; - } - - getHash() { - return this.vertexShader + this.fragmentShader + this.computeShader; - } - - setShaderStage(shaderStage) { - this.shaderStage = shaderStage; - } - - getShaderStage() { - return this.shaderStage; - } - - setBuildStage(buildStage) { - this.buildStage = buildStage; - } - - getBuildStage() { - return this.buildStage; - } - - buildCode() { - console.warn('Abstract function.'); - } - - build() { - const { object, material, renderer } = this; - - if (material !== null) { - let nodeMaterial = renderer.library.fromMaterial(material); - - if (nodeMaterial === null) { - console.error(`NodeMaterial: Material "${material.type}" is not compatible.`); - - nodeMaterial = new NodeMaterial(); - } - - nodeMaterial.build(this); - } else { - this.addFlow('compute', object); - } - - // setup() -> stage 1: create possible new nodes and returns an output reference node - // analyze() -> stage 2: analyze nodes to possible optimization and validation - // generate() -> stage 3: generate shader - - for (const buildStage of defaultBuildStages) { - this.setBuildStage(buildStage); - - if (this.context.vertex && this.context.vertex.isNode) { - this.flowNodeFromShaderStage('vertex', this.context.vertex); - } - - for (const shaderStage of shaderStages) { - this.setShaderStage(shaderStage); - - const flowNodes = this.flowNodes[shaderStage]; - - for (const node of flowNodes) { - if (buildStage === 'generate') { - this.flowNode(node); - } else { - node.build(this); - } - } - } - } - - this.setBuildStage(null); - this.setShaderStage(null); - - // stage 4: build code for a specific output - - this.buildCode(); - this.buildUpdateNodes(); - - return this; - } - - getNodeUniform(uniformNode, type) { - if (type === 'float' || type === 'int' || type === 'uint') return new NumberNodeUniform(uniformNode); - if (type === 'vec2' || type === 'ivec2' || type === 'uvec2') return new Vector2NodeUniform(uniformNode); - if (type === 'vec3' || type === 'ivec3' || type === 'uvec3') return new Vector3NodeUniform(uniformNode); - if (type === 'vec4' || type === 'ivec4' || type === 'uvec4') return new Vector4NodeUniform(uniformNode); - if (type === 'color') return new ColorNodeUniform(uniformNode); - if (type === 'mat3') return new Matrix3NodeUniform(uniformNode); - if (type === 'mat4') return new Matrix4NodeUniform(uniformNode); - - throw new Error(`Uniform "${type}" not declared.`); - } - - createNodeMaterial(type = 'NodeMaterial') { - // @deprecated, r168 - - throw new Error(`THREE.NodeBuilder: createNodeMaterial() was deprecated. Use new ${type}() instead.`); - } - - format(snippet, fromType, toType) { - fromType = this.getVectorType(fromType); - toType = this.getVectorType(toType); - - if (fromType === toType || toType === null || this.isReference(toType)) { - return snippet; - } - - const fromTypeLength = this.getTypeLength(fromType); - const toTypeLength = this.getTypeLength(toType); - - if (fromTypeLength === 16 && toTypeLength === 9) { - return `${this.getType(toType)}(${snippet}[0].xyz, ${snippet}[1].xyz, ${snippet}[2].xyz)`; - } - - if (fromTypeLength === 9 && toTypeLength === 4) { - return `${this.getType(toType)}(${snippet}[0].xy, ${snippet}[1].xy)`; - } - - if (fromTypeLength > 4) { - // fromType is matrix-like - - // @TODO: ignore for now - - return snippet; - } - - if (toTypeLength > 4 || toTypeLength === 0) { - // toType is matrix-like or unknown - - // @TODO: ignore for now - - return snippet; - } - - if (fromTypeLength === toTypeLength) { - return `${this.getType(toType)}( ${snippet} )`; - } - - if (fromTypeLength > toTypeLength) { - return this.format( - `${snippet}.${'xyz'.slice(0, toTypeLength)}`, - this.getTypeFromLength(toTypeLength, this.getComponentType(fromType)), - toType, - ); - } - - if (toTypeLength === 4 && fromTypeLength > 1) { - // toType is vec4-like - - return `${this.getType(toType)}( ${this.format(snippet, fromType, 'vec3')}, 1.0 )`; - } - - if (fromTypeLength === 2) { - // fromType is vec2-like and toType is vec3-like - - return `${this.getType(toType)}( ${this.format(snippet, fromType, 'vec2')}, 0.0 )`; - } - - if (fromTypeLength === 1 && toTypeLength > 1 && fromType !== this.getComponentType(toType)) { - // fromType is float-like - - // convert a number value to vector type, e.g: - // vec3( 1u ) -> vec3( float( 1u ) ) - - snippet = `${this.getType(this.getComponentType(toType))}( ${snippet} )`; - } - - return `${this.getType(toType)}( ${snippet} )`; // fromType is float-like - } - - getSignature() { - return `// Three.js r${REVISION} - Node System\n`; - } -} - -export default NodeBuilder; diff --git a/src-testing/src/nodes/core/NodeCache.ts b/src-testing/src/nodes/core/NodeCache.ts deleted file mode 100644 index ad72d50c5..000000000 --- a/src-testing/src/nodes/core/NodeCache.ts +++ /dev/null @@ -1,26 +0,0 @@ -let id = 0; - -class NodeCache { - constructor(parent = null) { - this.id = id++; - this.nodesData = new WeakMap(); - - this.parent = parent; - } - - getData(node) { - let data = this.nodesData.get(node); - - if (data === undefined && this.parent !== null) { - data = this.parent.getData(node); - } - - return data; - } - - setData(node, data) { - this.nodesData.set(node, data); - } -} - -export default NodeCache; diff --git a/src-testing/src/nodes/core/NodeCode.ts b/src-testing/src/nodes/core/NodeCode.ts deleted file mode 100644 index 2ee509037..000000000 --- a/src-testing/src/nodes/core/NodeCode.ts +++ /dev/null @@ -1,11 +0,0 @@ -class NodeCode { - constructor(name, type, code = '') { - this.name = name; - this.type = type; - this.code = code; - - Object.defineProperty(this, 'isNodeCode', { value: true }); - } -} - -export default NodeCode; diff --git a/src-testing/src/nodes/core/NodeFrame.ts b/src-testing/src/nodes/core/NodeFrame.ts deleted file mode 100644 index ee64620ca..000000000 --- a/src-testing/src/nodes/core/NodeFrame.ts +++ /dev/null @@ -1,127 +0,0 @@ -import { NodeUpdateType } from './constants.js'; - -class NodeFrame { - constructor() { - this.time = 0; - this.deltaTime = 0; - - this.frameId = 0; - this.renderId = 0; - - this.startTime = null; - - this.updateMap = new WeakMap(); - this.updateBeforeMap = new WeakMap(); - this.updateAfterMap = new WeakMap(); - - this.renderer = null; - this.material = null; - this.camera = null; - this.object = null; - this.scene = null; - } - - _getMaps(referenceMap, nodeRef) { - let maps = referenceMap.get(nodeRef); - - if (maps === undefined) { - maps = { - renderMap: new WeakMap(), - frameMap: new WeakMap(), - }; - - referenceMap.set(nodeRef, maps); - } - - return maps; - } - - updateBeforeNode(node) { - const updateType = node.getUpdateBeforeType(); - const reference = node.updateReference(this); - - if (updateType === NodeUpdateType.FRAME) { - const { frameMap } = this._getMaps(this.updateBeforeMap, reference); - - if (frameMap.get(reference) !== this.frameId) { - if (node.updateBefore(this) !== false) { - frameMap.set(reference, this.frameId); - } - } - } else if (updateType === NodeUpdateType.RENDER) { - const { renderMap } = this._getMaps(this.updateBeforeMap, reference); - - if (renderMap.get(reference) !== this.renderId) { - if (node.updateBefore(this) !== false) { - renderMap.set(reference, this.renderId); - } - } - } else if (updateType === NodeUpdateType.OBJECT) { - node.updateBefore(this); - } - } - - updateAfterNode(node) { - const updateType = node.getUpdateAfterType(); - const reference = node.updateReference(this); - - if (updateType === NodeUpdateType.FRAME) { - const { frameMap } = this._getMaps(this.updateAfterMap, reference); - - if (frameMap.get(reference) !== this.frameId) { - if (node.updateAfter(this) !== false) { - frameMap.set(reference, this.frameId); - } - } - } else if (updateType === NodeUpdateType.RENDER) { - const { renderMap } = this._getMaps(this.updateAfterMap, reference); - - if (renderMap.get(reference) !== this.renderId) { - if (node.updateAfter(this) !== false) { - renderMap.set(reference, this.renderId); - } - } - } else if (updateType === NodeUpdateType.OBJECT) { - node.updateAfter(this); - } - } - - updateNode(node) { - const updateType = node.getUpdateType(); - const reference = node.updateReference(this); - - if (updateType === NodeUpdateType.FRAME) { - const { frameMap } = this._getMaps(this.updateMap, reference); - - if (frameMap.get(reference) !== this.frameId) { - if (node.update(this) !== false) { - frameMap.set(reference, this.frameId); - } - } - } else if (updateType === NodeUpdateType.RENDER) { - const { renderMap } = this._getMaps(this.updateMap, reference); - - if (renderMap.get(reference) !== this.renderId) { - if (node.update(this) !== false) { - renderMap.set(reference, this.renderId); - } - } - } else if (updateType === NodeUpdateType.OBJECT) { - node.update(this); - } - } - - update() { - this.frameId++; - - if (this.lastTime === undefined) this.lastTime = performance.now(); - - this.deltaTime = (performance.now() - this.lastTime) / 1000; - - this.lastTime = performance.now(); - - this.time += this.deltaTime; - } -} - -export default NodeFrame; diff --git a/src-testing/src/nodes/core/NodeFunction.ts b/src-testing/src/nodes/core/NodeFunction.ts deleted file mode 100644 index d05afb5e6..000000000 --- a/src-testing/src/nodes/core/NodeFunction.ts +++ /dev/null @@ -1,16 +0,0 @@ -class NodeFunction { - constructor(type, inputs, name = '', precision = '') { - this.type = type; - this.inputs = inputs; - this.name = name; - this.precision = precision; - } - - getCode(/*name = this.name*/) { - console.warn('Abstract function.'); - } -} - -NodeFunction.isNodeFunction = true; - -export default NodeFunction; diff --git a/src-testing/src/nodes/core/NodeFunctionInput.d.ts b/src-testing/src/nodes/core/NodeFunctionInput.d.ts deleted file mode 100644 index a8231d126..000000000 --- a/src-testing/src/nodes/core/NodeFunctionInput.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -export default class NodeFunctionInput { - isNodeFunctionInput: true; - count: null | number; - qualifier: string; - isConst: boolean; - constructor(type: string, name: string, count?: number, qualifier?: string, isConst?: boolean); -} diff --git a/src-testing/src/nodes/core/NodeParser.ts b/src-testing/src/nodes/core/NodeParser.ts deleted file mode 100644 index 9849452f1..000000000 --- a/src-testing/src/nodes/core/NodeParser.ts +++ /dev/null @@ -1,7 +0,0 @@ -class NodeParser { - parseFunction(/*source*/) { - console.warn('Abstract function.'); - } -} - -export default NodeParser; diff --git a/src-testing/src/nodes/core/NodeUniform.ts b/src-testing/src/nodes/core/NodeUniform.ts deleted file mode 100644 index ca43958fc..000000000 --- a/src-testing/src/nodes/core/NodeUniform.ts +++ /dev/null @@ -1,27 +0,0 @@ -class NodeUniform { - constructor(name, type, node) { - this.isNodeUniform = true; - - this.name = name; - this.type = type; - this.node = node.getSelf(); - } - - get value() { - return this.node.value; - } - - set value(val) { - this.node.value = val; - } - - get id() { - return this.node.id; - } - - get groupNode() { - return this.node.groupNode; - } -} - -export default NodeUniform; diff --git a/src-testing/src/nodes/core/NodeUtils.ts b/src-testing/src/nodes/core/NodeUtils.ts deleted file mode 100644 index 7ebac01f9..000000000 --- a/src-testing/src/nodes/core/NodeUtils.ts +++ /dev/null @@ -1,171 +0,0 @@ -import { Color } from '../../math/Color.js'; -import { Matrix3 } from '../../math/Matrix3.js'; -import { Matrix4 } from '../../math/Matrix4.js'; -import { Vector2 } from '../../math/Vector2.js'; -import { Vector3 } from '../../math/Vector3.js'; -import { Vector4 } from '../../math/Vector4.js'; - -// cyrb53 (c) 2018 bryc (github.com/bryc). License: Public domain. Attribution appreciated. -// A fast and simple 64-bit (or 53-bit) string hash function with decent collision resistance. -// Largely inspired by MurmurHash2/3, but with a focus on speed/simplicity. -// See https://stackoverflow.com/questions/7616461/generate-a-hash-from-string-in-javascript/52171480#52171480 -// https://github.com/bryc/code/blob/master/jshash/experimental/cyrb53.js -function cyrb53(value, seed = 0) { - let h1 = 0xdeadbeef ^ seed, - h2 = 0x41c6ce57 ^ seed; - - if (value instanceof Array) { - for (let i = 0, val; i < value.length; i++) { - val = value[i]; - h1 = Math.imul(h1 ^ val, 2654435761); - h2 = Math.imul(h2 ^ val, 1597334677); - } - } else { - for (let i = 0, ch; i < value.length; i++) { - ch = value.charCodeAt(i); - h1 = Math.imul(h1 ^ ch, 2654435761); - h2 = Math.imul(h2 ^ ch, 1597334677); - } - } - - h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507); - h1 ^= Math.imul(h2 ^ (h2 >>> 13), 3266489909); - h2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507); - h2 ^= Math.imul(h1 ^ (h1 >>> 13), 3266489909); - - return 4294967296 * (2097151 & h2) + (h1 >>> 0); -} - -export const hashString = str => cyrb53(str); -export const hashArray = array => cyrb53(array); -export const hash = (...params) => cyrb53(params); - -export function getCacheKey(object, force = false) { - const values = []; - - if (object.isNode === true) { - values.push(object.id); - object = object.getSelf(); - } - - for (const { property, childNode } of getNodeChildren(object)) { - values.push(values, cyrb53(property.slice(0, -4)), childNode.getCacheKey(force)); - } - - return cyrb53(values); -} - -export function* getNodeChildren(node, toJSON = false) { - for (const property in node) { - // Ignore private properties. - if (property.startsWith('_') === true) continue; - - const object = node[property]; - - if (Array.isArray(object) === true) { - for (let i = 0; i < object.length; i++) { - const child = object[i]; - - if (child && (child.isNode === true || (toJSON && typeof child.toJSON === 'function'))) { - yield { property, index: i, childNode: child }; - } - } - } else if (object && object.isNode === true) { - yield { property, childNode: object }; - } else if (typeof object === 'object') { - for (const subProperty in object) { - const child = object[subProperty]; - - if (child && (child.isNode === true || (toJSON && typeof child.toJSON === 'function'))) { - yield { property, index: subProperty, childNode: child }; - } - } - } - } -} - -export function getValueType(value) { - if (value === undefined || value === null) return null; - - const typeOf = typeof value; - - if (value.isNode === true) { - return 'node'; - } else if (typeOf === 'number') { - return 'float'; - } else if (typeOf === 'boolean') { - return 'bool'; - } else if (typeOf === 'string') { - return 'string'; - } else if (typeOf === 'function') { - return 'shader'; - } else if (value.isVector2 === true) { - return 'vec2'; - } else if (value.isVector3 === true) { - return 'vec3'; - } else if (value.isVector4 === true) { - return 'vec4'; - } else if (value.isMatrix3 === true) { - return 'mat3'; - } else if (value.isMatrix4 === true) { - return 'mat4'; - } else if (value.isColor === true) { - return 'color'; - } else if (value instanceof ArrayBuffer) { - return 'ArrayBuffer'; - } - - return null; -} - -export function getValueFromType(type, ...params) { - const last4 = type ? type.slice(-4) : undefined; - - if (params.length === 1) { - // ensure same behaviour as in NodeBuilder.format() - - if (last4 === 'vec2') params = [params[0], params[0]]; - else if (last4 === 'vec3') params = [params[0], params[0], params[0]]; - else if (last4 === 'vec4') params = [params[0], params[0], params[0], params[0]]; - } - - if (type === 'color') { - return new Color(...params); - } else if (last4 === 'vec2') { - return new Vector2(...params); - } else if (last4 === 'vec3') { - return new Vector3(...params); - } else if (last4 === 'vec4') { - return new Vector4(...params); - } else if (last4 === 'mat3') { - return new Matrix3(...params); - } else if (last4 === 'mat4') { - return new Matrix4(...params); - } else if (type === 'bool') { - return params[0] || false; - } else if (type === 'float' || type === 'int' || type === 'uint') { - return params[0] || 0; - } else if (type === 'string') { - return params[0] || ''; - } else if (type === 'ArrayBuffer') { - return base64ToArrayBuffer(params[0]); - } - - return null; -} - -export function arrayBufferToBase64(arrayBuffer) { - let chars = ''; - - const array = new Uint8Array(arrayBuffer); - - for (let i = 0; i < array.length; i++) { - chars += String.fromCharCode(array[i]); - } - - return btoa(chars); -} - -export function base64ToArrayBuffer(base64) { - return Uint8Array.from(atob(base64), c => c.charCodeAt(0)).buffer; -} diff --git a/src-testing/src/nodes/core/NodeVar.ts b/src-testing/src/nodes/core/NodeVar.ts deleted file mode 100644 index e6e935b31..000000000 --- a/src-testing/src/nodes/core/NodeVar.ts +++ /dev/null @@ -1,10 +0,0 @@ -class NodeVar { - constructor(name, type) { - this.isNodeVar = true; - - this.name = name; - this.type = type; - } -} - -export default NodeVar; diff --git a/src-testing/src/nodes/core/NodeVarying.ts b/src-testing/src/nodes/core/NodeVarying.ts deleted file mode 100644 index a14823628..000000000 --- a/src-testing/src/nodes/core/NodeVarying.ts +++ /dev/null @@ -1,13 +0,0 @@ -import NodeVar from './NodeVar.js'; - -class NodeVarying extends NodeVar { - constructor(name, type) { - super(name, type); - - this.needsInterpolation = false; - - this.isNodeVarying = true; - } -} - -export default NodeVarying; diff --git a/src-testing/src/nodes/core/OutputStructNode.d.ts b/src-testing/src/nodes/core/OutputStructNode.d.ts deleted file mode 100644 index 5a7fc6e7b..000000000 --- a/src-testing/src/nodes/core/OutputStructNode.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { ShaderNodeObject } from "../tsl/TSLCore.js"; -import Node from "./Node.js"; - -export default class OutputStructNode extends Node { - members: Node[]; - - readonly isOutputStructNode: true; - - constructor(...members: Node[]); -} - -export const outputStruct: (...members: Node[]) => ShaderNodeObject; diff --git a/src-testing/src/nodes/core/ParameterNode.d.ts b/src-testing/src/nodes/core/ParameterNode.d.ts deleted file mode 100644 index 02629dbf5..000000000 --- a/src-testing/src/nodes/core/ParameterNode.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { ShaderNodeObject } from "../tsl/TSLCore.js"; -import PropertyNode from "./PropertyNode.js"; - -declare class ParameterNode extends PropertyNode { - readonly isParameterNode: true; - - constructor(nodeType: string, name?: string | null); -} - -export default ParameterNode; - -export const parameter: (type: string, name?: string | null) => ShaderNodeObject; diff --git a/src-testing/src/nodes/core/PropertyNode.d.ts b/src-testing/src/nodes/core/PropertyNode.d.ts deleted file mode 100644 index b365d107b..000000000 --- a/src-testing/src/nodes/core/PropertyNode.d.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { ShaderNodeObject } from "../tsl/TSLCore.js"; -import Node from "./Node.js"; - -export default class PropertyNode extends Node { - name: string | null; - varying: boolean; - - readonly isPropertyNode: true; - - constructor(nodeType?: string | null, name?: string | null, varying?: boolean); -} - -export const property: (type?: string | null, name?: string | null) => ShaderNodeObject; -export const varyingProperty: (type?: string | null, name?: string | null) => ShaderNodeObject; - -export const diffuseColor: ShaderNodeObject; -export const emissive: ShaderNodeObject; -export const roughness: ShaderNodeObject; -export const metalness: ShaderNodeObject; -export const clearcoat: ShaderNodeObject; -export const clearcoatRoughness: ShaderNodeObject; -export const sheen: ShaderNodeObject; -export const sheenRoughness: ShaderNodeObject; -export const iridescence: ShaderNodeObject; -export const iridescenceIOR: ShaderNodeObject; -export const iridescenceThickness: ShaderNodeObject; -export const alphaT: ShaderNodeObject; -export const anisotropy: ShaderNodeObject; -export const anisotropyT: ShaderNodeObject; -export const anisotropyB: ShaderNodeObject; -export const specularColor: ShaderNodeObject; -export const specularF90: ShaderNodeObject; -export const shininess: ShaderNodeObject; -export const output: ShaderNodeObject; -export const dashSize: ShaderNodeObject; -export const gapSize: ShaderNodeObject; -export const pointWidth: ShaderNodeObject; -export const ior: ShaderNodeObject; -export const transmission: ShaderNodeObject; -export const thickness: ShaderNodeObject; -export const attenuationDistance: ShaderNodeObject; -export const attenuationColor: ShaderNodeObject; -export const dispersion: ShaderNodeObject; diff --git a/src-testing/src/nodes/core/StackNode.ts b/src-testing/src/nodes/core/StackNode.ts deleted file mode 100644 index 79313afad..000000000 --- a/src-testing/src/nodes/core/StackNode.ts +++ /dev/null @@ -1,89 +0,0 @@ -import Node from './Node.js'; -import { select } from '../math/ConditionalNode.js'; -import { ShaderNode, nodeProxy, getCurrentStack, setCurrentStack } from '../tsl/TSLBase.js'; - -class StackNode extends Node { - static get type() { - return 'StackNode'; - } - - constructor(parent = null) { - super(); - - this.nodes = []; - this.outputNode = null; - - this.parent = parent; - - this._currentCond = null; - - this.isStackNode = true; - } - - getNodeType(builder) { - return this.outputNode ? this.outputNode.getNodeType(builder) : 'void'; - } - - add(node) { - this.nodes.push(node); - - return this; - } - - If(boolNode, method) { - const methodNode = new ShaderNode(method); - this._currentCond = select(boolNode, methodNode); - - return this.add(this._currentCond); - } - - ElseIf(boolNode, method) { - const methodNode = new ShaderNode(method); - const ifNode = select(boolNode, methodNode); - - this._currentCond.elseNode = ifNode; - this._currentCond = ifNode; - - return this; - } - - Else(method) { - this._currentCond.elseNode = new ShaderNode(method); - - return this; - } - - build(builder, ...params) { - const previousStack = getCurrentStack(); - - setCurrentStack(this); - - for (const node of this.nodes) { - node.build(builder, 'void'); - } - - setCurrentStack(previousStack); - - return this.outputNode ? this.outputNode.build(builder, ...params) : super.build(builder, ...params); - } - - // - - else(...params) { - // @deprecated, r168 - - console.warn('TSL.StackNode: .else() has been renamed to .Else().'); - return this.Else(...params); - } - - elseif(...params) { - // @deprecated, r168 - - console.warn('TSL.StackNode: .elseif() has been renamed to .ElseIf().'); - return this.ElseIf(...params); - } -} - -export default StackNode; - -export const stack = /*@__PURE__*/ nodeProxy(StackNode); diff --git a/src-testing/src/nodes/core/StructTypeNode.ts b/src-testing/src/nodes/core/StructTypeNode.ts deleted file mode 100644 index acadb07e1..000000000 --- a/src-testing/src/nodes/core/StructTypeNode.ts +++ /dev/null @@ -1,20 +0,0 @@ -import Node from './Node.js'; - -class StructTypeNode extends Node { - static get type() { - return 'StructTypeNode'; - } - - constructor(types) { - super(); - - this.types = types; - this.isStructTypeNode = true; - } - - getMemberTypes() { - return this.types; - } -} - -export default StructTypeNode; diff --git a/src-testing/src/nodes/core/TempNode.d.ts b/src-testing/src/nodes/core/TempNode.d.ts deleted file mode 100644 index 367f5ade1..000000000 --- a/src-testing/src/nodes/core/TempNode.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import Node from "./Node.js"; -import NodeBuilder from "./NodeBuilder.js"; - -export default class TempNode extends Node { - isTempNode: true; - - constructor(type: string | null); - - hasDependencies(builder: NodeBuilder): boolean; -} diff --git a/src-testing/src/nodes/core/UniformGroup.d.ts b/src-testing/src/nodes/core/UniformGroup.d.ts deleted file mode 100644 index 60339877b..000000000 --- a/src-testing/src/nodes/core/UniformGroup.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -export default class UniformGroup { - name: string; - - readonly isUniformGroup: true; - - constructor(name: string); -} diff --git a/src-testing/src/nodes/core/UniformGroupNode.ts b/src-testing/src/nodes/core/UniformGroupNode.ts deleted file mode 100644 index 829fd3ee8..000000000 --- a/src-testing/src/nodes/core/UniformGroupNode.ts +++ /dev/null @@ -1,47 +0,0 @@ -import Node from './Node.js'; - -class UniformGroupNode extends Node { - static get type() { - return 'UniformGroupNode'; - } - - constructor(name, shared = false, order = 1) { - super('string'); - - this.name = name; - this.version = 0; - - this.shared = shared; - this.order = order; - this.isUniformGroup = true; - } - - set needsUpdate(value) { - if (value === true) this.version++; - } - - serialize(data) { - super.serialize(data); - - data.name = this.name; - data.version = this.version; - data.shared = this.shared; - } - - deserialize(data) { - super.deserialize(data); - - this.name = data.name; - this.version = data.version; - this.shared = data.shared; - } -} - -export default UniformGroupNode; - -export const uniformGroup = name => new UniformGroupNode(name); -export const sharedUniformGroup = (name, order = 0) => new UniformGroupNode(name, true, order); - -export const frameGroup = /*@__PURE__*/ sharedUniformGroup('frame'); -export const renderGroup = /*@__PURE__*/ sharedUniformGroup('render'); -export const objectGroup = /*@__PURE__*/ uniformGroup('object'); diff --git a/src-testing/src/nodes/core/UniformNode.ts b/src-testing/src/nodes/core/UniformNode.ts deleted file mode 100644 index ec9fa9aee..000000000 --- a/src-testing/src/nodes/core/UniformNode.ts +++ /dev/null @@ -1,91 +0,0 @@ -import InputNode from './InputNode.js'; -import { objectGroup } from './UniformGroupNode.js'; -import { nodeObject, getConstNodeType } from '../tsl/TSLCore.js'; - -class UniformNode extends InputNode { - static get type() { - return 'UniformNode'; - } - - constructor(value, nodeType = null) { - super(value, nodeType); - - this.isUniformNode = true; - - this.name = ''; - this.groupNode = objectGroup; - } - - label(name) { - this.name = name; - - return this; - } - - setGroup(group) { - this.groupNode = group; - - return this; - } - - getGroup() { - return this.groupNode; - } - - getUniformHash(builder) { - return this.getHash(builder); - } - - onUpdate(callback, updateType) { - const self = this.getSelf(); - - callback = callback.bind(self); - - return super.onUpdate(frame => { - const value = callback(frame, self); - - if (value !== undefined) { - this.value = value; - } - }, updateType); - } - - generate(builder, output) { - const type = this.getNodeType(builder); - - const hash = this.getUniformHash(builder); - - let sharedNode = builder.getNodeFromHash(hash); - - if (sharedNode === undefined) { - builder.setHashNode(this, hash); - - sharedNode = this; - } - - const sharedNodeType = sharedNode.getInputType(builder); - - const nodeUniform = builder.getUniformFromNode( - sharedNode, - sharedNodeType, - builder.shaderStage, - this.name || builder.context.label, - ); - const propertyName = builder.getPropertyName(nodeUniform); - - if (builder.context.label !== undefined) delete builder.context.label; - - return builder.format(propertyName, type, output); - } -} - -export default UniformNode; - -export const uniform = (arg1, arg2) => { - const nodeType = getConstNodeType(arg2 || arg1); - - // @TODO: get ConstNode from .traverse() in the future - const value = arg1 && arg1.isNode === true ? (arg1.node && arg1.node.value) || arg1.value : arg1; - - return nodeObject(new UniformNode(value, nodeType)); -}; diff --git a/src-testing/src/nodes/core/VarNode.d.ts b/src-testing/src/nodes/core/VarNode.d.ts deleted file mode 100644 index 327df482a..000000000 --- a/src-testing/src/nodes/core/VarNode.d.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; -import Node from "./Node.js"; - -export default class VarNode extends Node { - node: Node; - name: string | null; - - readonly isVarNode: true; - - constructor(node: Node, name?: string | null); -} - -declare module "../tsl/TSLCore.js" { - interface NodeElements { - toVar: (node: NodeRepresentation, name?: string | null) => ShaderNodeObject; - } -} - -/** - * @deprecated Use ".toVar()" instead. - */ -export const temp: (node: NodeRepresentation, name?: string | null) => ShaderNodeObject; - -declare module "../tsl/TSLCore.js" { - interface NodeElements { - /** - * @deprecated Use ".toVar()" instead. - */ - temp: typeof temp; - } -} diff --git a/src-testing/src/nodes/core/VaryingNode.d.ts b/src-testing/src/nodes/core/VaryingNode.d.ts deleted file mode 100644 index f10077ce0..000000000 --- a/src-testing/src/nodes/core/VaryingNode.d.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; -import Node from "./Node.js"; -import NodeBuilder from "./NodeBuilder.js"; -import NodeVarying from "./NodeVarying.js"; - -export default class VaryingNode extends Node { - node: Node; - name: string | null; - - constructor(node: Node, name?: string | null); - - setupVarying(builder: NodeBuilder): NodeVarying; -} - -export const varying: (node: NodeRepresentation, name?: string) => ShaderNodeObject; - -declare module "../tsl/TSLCore.js" { - interface NodeElements { - varying: typeof varying; - } -} diff --git a/src-testing/src/nodes/core/constants.ts b/src-testing/src/nodes/core/constants.ts deleted file mode 100644 index 3b01a9a6d..000000000 --- a/src-testing/src/nodes/core/constants.ts +++ /dev/null @@ -1,28 +0,0 @@ -export const NodeShaderStage = { - VERTEX: 'vertex', - FRAGMENT: 'fragment', -}; - -export const NodeUpdateType = { - NONE: 'none', - FRAME: 'frame', - RENDER: 'render', - OBJECT: 'object', -}; - -export const NodeType = { - BOOLEAN: 'bool', - INTEGER: 'int', - FLOAT: 'float', - VECTOR2: 'vec2', - VECTOR3: 'vec3', - VECTOR4: 'vec4', - MATRIX2: 'mat2', - MATRIX3: 'mat3', - MATRIX4: 'mat4', -}; - -export const defaultShaderStages = ['fragment', 'vertex']; -export const defaultBuildStages = ['setup', 'analyze', 'generate']; -export const shaderStages = [...defaultShaderStages, 'compute']; -export const vectorComponents = ['x', 'y', 'z', 'w']; diff --git a/src-testing/src/nodes/display/BlendMode.d.ts b/src-testing/src/nodes/display/BlendMode.d.ts deleted file mode 100644 index 1f2d23991..000000000 --- a/src-testing/src/nodes/display/BlendMode.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -export const burn: (base: NodeRepresentation, blend: NodeRepresentation) => ShaderNodeObject; - -export const dodge: (base: NodeRepresentation, blend: NodeRepresentation) => ShaderNodeObject; - -export const screen: (base: NodeRepresentation, blend: NodeRepresentation) => ShaderNodeObject; - -export const overlay: (base: NodeRepresentation, blend: NodeRepresentation) => ShaderNodeObject; diff --git a/src-testing/src/nodes/display/BumpMapNode.d.ts b/src-testing/src/nodes/display/BumpMapNode.d.ts deleted file mode 100644 index 726f55685..000000000 --- a/src-testing/src/nodes/display/BumpMapNode.d.ts +++ /dev/null @@ -1,16 +0,0 @@ -import TempNode from "../core/TempNode.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -declare class BumpMapNode extends TempNode { - textureNode: Node; - scaleNode: Node | null; - - constructor(textureNode: Node, scaleNode?: Node | null); -} - -export default BumpMapNode; - -export const bumpMap: ( - textureNode: NodeRepresentation, - scaleNode?: NodeRepresentation | null, -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/display/ColorAdjustment.d.ts b/src-testing/src/nodes/display/ColorAdjustment.d.ts deleted file mode 100644 index 4de024be7..000000000 --- a/src-testing/src/nodes/display/ColorAdjustment.d.ts +++ /dev/null @@ -1,56 +0,0 @@ -import Node from "../core/Node.js"; -import MathNode from "../math/MathNode.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -export const grayscale: (color: NodeRepresentation) => ShaderNodeObject; - -export const saturation: ( - color: NodeRepresentation, - adjustment?: NodeRepresentation, -) => ShaderNodeObject; - -export const vibrance: ( - color: NodeRepresentation, - adjustment?: NodeRepresentation, -) => ShaderNodeObject; - -export const hue: ( - color: NodeRepresentation, - adjustment?: NodeRepresentation, -) => ShaderNodeObject; - -export const luminance: ( - color: NodeRepresentation, - luminanceCoefficients?: NodeRepresentation, -) => ShaderNodeObject; - -export const threshold: (color: NodeRepresentation, thershold: NodeRepresentation) => ShaderNodeObject; - -/** - * Color Decision List (CDL) v1.2 - * - * Compact representation of color grading information, defined by slope, offset, power, and saturation. The CDL should - * be typically be given input in a log space (such as LogC, ACEScc, or AgX Log), and will return output in the same - * space. Output may require clamping >=0. - * - * References: - * - ASC CDL v1.2 - * - https://blender.stackexchange.com/a/55239/43930 - * - https://docs.acescentral.com/specifications/acescc/ - * - * @param color Input (-Infinity < input < +Infinity) - * @param slope Slope (0 ≤ slope < +Infinity) - * @param offset Offset (-Infinity < offset < +Infinity; typically -1 < offset < 1) - * @param power Power (0 < power < +Infinity) - * @param saturation Saturation (0 ≤ saturation < +Infinity; typically 0 ≤ saturation < 4) - * @param luminanceCoefficients Luminance coefficients for saturation term, typically Rec. 709 - * @return Output, -Infinity < output < +Infinity - */ -export const cdl: ( - color: NodeRepresentation, - slope?: NodeRepresentation, - offset?: NodeRepresentation, - power?: NodeRepresentation, - saturation?: NodeRepresentation, - luminanceCoefficients?: NodeRepresentation, -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/display/ColorSpaceFunctions.d.ts b/src-testing/src/nodes/display/ColorSpaceFunctions.d.ts deleted file mode 100644 index a4bd01216..000000000 --- a/src-testing/src/nodes/display/ColorSpaceFunctions.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -export const sRGBTransferEOTF: (color: NodeRepresentation) => ShaderNodeObject; - -export const sRGBTransferOETF: (color: NodeRepresentation) => ShaderNodeObject; diff --git a/src-testing/src/nodes/display/ColorSpaceNode.d.ts b/src-testing/src/nodes/display/ColorSpaceNode.d.ts deleted file mode 100644 index c0de945da..000000000 --- a/src-testing/src/nodes/display/ColorSpaceNode.d.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { LinearSRGBColorSpace, SRGBColorSpace } from "../../constants.js"; -import Node from "../core/Node.js"; -import NodeBuilder from "../core/NodeBuilder.js"; -import TempNode from "../core/TempNode.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -export type WorkingOrOutputColorSpace = "WorkingColorSpace" | "OutputColorSpace"; - -export type ColorSpaceMethod = "LinearTosRGB" | "sRGBToLinear" | "LinearToLinear" | "sRGBTosRGB"; - -export function getColorSpaceMethod( - source: typeof LinearSRGBColorSpace | typeof SRGBColorSpace, - target: typeof LinearSRGBColorSpace | typeof SRGBColorSpace, -): ColorSpaceMethod; - -export default class ColorSpaceNode extends TempNode { - colorNode: Node; - source: string; - target: string; - - constructor( - colorNode: Node, - source: string, - target: string, - ); - - resolveColorSpace(nodeBuilder: NodeBuilder, colorSpace: WorkingOrOutputColorSpace): string; -} - -export const toOutputColorSpace: ( - node: NodeRepresentation, -) => ShaderNodeObject; -export const toWorkingColorSpace: ( - node: NodeRepresentation, -) => ShaderNodeObject; - -export const workingToColorSpace: ( - node: NodeRepresentation, - colorSpace: string, -) => ShaderNodeObject; -export const colorSpaceToWorking: ( - node: NodeRepresentation, - colorSpace: string, -) => ShaderNodeObject; - -export const convertColorSpace: ( - node: NodeRepresentation, - sourceColorSpace: string, - targetColorSpace: string, -) => ShaderNodeObject; - -declare module "../tsl/TSLCore.js" { - interface NodeElements { - toOutputColorSpace: typeof toOutputColorSpace; - toWorkingColorSpace: typeof toWorkingColorSpace; - - workingToColorSpace: typeof workingToColorSpace; - colorSpaceToWorking: typeof colorSpaceToWorking; - } -} diff --git a/src-testing/src/nodes/display/FrontFacingNode.d.ts b/src-testing/src/nodes/display/FrontFacingNode.d.ts deleted file mode 100644 index f550ecacf..000000000 --- a/src-testing/src/nodes/display/FrontFacingNode.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -import Node from "../core/Node.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -declare class FrontFacingNode extends Node { - isFrontFacingNode: true; - constructor(); -} - -export default FrontFacingNode; - -export const frontFacing: ShaderNodeObject; -export const faceDirection: ShaderNodeObject; diff --git a/src-testing/src/nodes/display/NormalMapNode.d.ts b/src-testing/src/nodes/display/NormalMapNode.d.ts deleted file mode 100644 index d06459502..000000000 --- a/src-testing/src/nodes/display/NormalMapNode.d.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { NormalMapTypes } from "../../constants.js"; -import Node from "../core/Node.js"; -import TempNode from "../core/TempNode.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -declare class NormalMapNode extends TempNode { - node: Node; - scaleNode: Node | null; - - normalMapType: NormalMapTypes; - - constructor(node: Node, scaleNode?: Node | null); -} - -export default NormalMapNode; - -export const normalMap: (node: Node, scaleNode?: Node) => ShaderNodeObject; diff --git a/src-testing/src/nodes/display/PassNode.d.ts b/src-testing/src/nodes/display/PassNode.d.ts deleted file mode 100644 index 97bad417f..000000000 --- a/src-testing/src/nodes/display/PassNode.d.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { Camera } from "../../cameras/Camera.js"; -import { RenderTarget, RenderTargetOptions } from "../../core/RenderTarget.js"; -import { Scene } from "../../scenes/Scene.js"; -import { Texture } from "../../textures/Texture.js"; -import TextureNode from "../accessors/TextureNode.js"; -import MRTNode from "../core/MRTNode.js"; -import Node from "../core/Node.js"; -import TempNode from "../core/TempNode.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -declare class PassTextureNode extends TextureNode { - passNode: PassNode; - - constructor(passNode: PassNode, texture: Texture); -} - -declare class PassMultipleTextureNode extends PassTextureNode { - textureName: string; - previousTexture: boolean; - - constructor(passNode: PassNode, textureName: string, previousTexture?: boolean); - - updateTexture(): void; -} - -declare class PassNode extends TempNode { - scope: PassNodeScope; - scene: Scene; - camera: Camera; - - renderTarget: RenderTarget; - - readonly isPassNode: true; - - constructor(scope: PassNodeScope, scene: Scene, camera: Camera, options?: RenderTargetOptions); - - setMRT(mrt: MRTNode | null): this; - - getMRT(): MRTNode | null; - - getTexture(name: string): Texture; - - getPreviousTexture(name: string): Texture; - - toggleTexture(name: string): void; - - getTextureNode(name?: string): ShaderNodeObject; - - getPreviousTextureNode(name?: string): ShaderNodeObject; - - getViewZNode(name?: string): ShaderNodeObject; - - getLinearDepthNode(name?: string): ShaderNodeObject; - - setSize(width: number, height: number): void; - - setPixelRatio(pixelRatio: number): void; - - dispose(): void; - - static COLOR: "color"; - static DEPTH: "depth"; -} - -export type PassNodeScope = typeof PassNode.COLOR | typeof PassNode.DEPTH; - -export default PassNode; - -export const pass: (scene: Scene, camera: Camera, options?: RenderTargetOptions) => ShaderNodeObject; -export const passTexture: (pass: PassNode, texture: Texture) => ShaderNodeObject; -export const depthPass: (scene: Scene, camera: Camera) => ShaderNodeObject; diff --git a/src-testing/src/nodes/display/PosterizeNode.d.ts b/src-testing/src/nodes/display/PosterizeNode.d.ts deleted file mode 100644 index 17eb0fe52..000000000 --- a/src-testing/src/nodes/display/PosterizeNode.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -export default class PosterizeNode extends Node { - sourceNode: Node; - stepsNode: Node; - - constructor(sourceNode: Node, stepsNode: Node); -} - -export const posterize: ( - sourceNode: NodeRepresentation, - stepsNode: NodeRepresentation, -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/display/RenderOutputNode.d.ts b/src-testing/src/nodes/display/RenderOutputNode.d.ts deleted file mode 100644 index b7edad754..000000000 --- a/src-testing/src/nodes/display/RenderOutputNode.d.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { ToneMapping } from "../../constants.js"; -import Node from "../core/Node.js"; -import TempNode from "../core/TempNode.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -declare class RenderOutputNode extends TempNode { - colorNode: Node; - toneMapping: ToneMapping | null; - outputColorSpace: string | null; - - readonly isRenderOutput: true; - - constructor(colorNode: Node, toneMapping?: ToneMapping | null, outputColorSpace?: string | null); -} - -export default RenderOutputNode; - -export const renderOutput: ( - color: NodeRepresentation, - toneMapping?: ToneMapping | null, - outputColorSpace?: string | null, -) => ShaderNodeObject; - -declare module "../tsl/TSLCore.js" { - interface NodeElements { - renderOutput: typeof renderOutput; - } -} diff --git a/src-testing/src/nodes/display/ScreenNode.d.ts b/src-testing/src/nodes/display/ScreenNode.d.ts deleted file mode 100644 index f9ed102fc..000000000 --- a/src-testing/src/nodes/display/ScreenNode.d.ts +++ /dev/null @@ -1,48 +0,0 @@ -import Node from "../core/Node.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -export type ScreenNodeScope = - | typeof ScreenNode.COORDINATE - | typeof ScreenNode.VIEWPORT - | typeof ScreenNode.SIZE - | typeof ScreenNode.UV; - -declare class ScreenNode extends Node { - scope: ScreenNodeScope; - - readonly isViewportNode: true; - - constructor(scope: ScreenNodeScope); - - static COORDINATE: "coordinate"; - static VIEWPORT: "viewport"; - static SIZE: "size"; - static UV: "uv"; -} - -export default ScreenNode; - -// Screen - -export const screenUV: ShaderNodeObject; -export const screenSize: ShaderNodeObject; -export const screenCoordinate: ShaderNodeObject; - -// Viewport - -export const viewport: ShaderNodeObject; -export const viewportSize: ShaderNodeObject; -export const viewportCoordinate: ShaderNodeObject; -export const viewportUV: ShaderNodeObject; - -// Deprecated - -/** - * @deprecated "viewportTopLeft" is deprecated. Use "viewportUV" instead. - */ -export const viewportTopLeft: ShaderNodeObject; - -/** - * @deprecated "viewportBottomLeft" is deprecated. Use "viewportUV.flipY()" instead. - */ -export const viewportBottomLeft: ShaderNodeObject; diff --git a/src-testing/src/nodes/display/ToneMappingFunctions.d.ts b/src-testing/src/nodes/display/ToneMappingFunctions.d.ts deleted file mode 100644 index b972d6b6f..000000000 --- a/src-testing/src/nodes/display/ToneMappingFunctions.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -export const linearToneMapping: (color: NodeRepresentation, exposure: NodeRepresentation) => ShaderNodeObject; - -export const reinhardToneMapping: (color: NodeRepresentation, exposure: NodeRepresentation) => ShaderNodeObject; - -export const cineonToneMapping: (color: NodeRepresentation, exposure: NodeRepresentation) => ShaderNodeObject; - -export const acesFilmicToneMapping: (color: NodeRepresentation, exposure: NodeRepresentation) => ShaderNodeObject; - -export const agxToneMapping: (color: NodeRepresentation, exposure: NodeRepresentation) => ShaderNodeObject; - -export const neutralToneMapping: (color: NodeRepresentation, exposure: NodeRepresentation) => ShaderNodeObject; diff --git a/src-testing/src/nodes/display/ToneMappingNode.d.ts b/src-testing/src/nodes/display/ToneMappingNode.d.ts deleted file mode 100644 index e4fdf9cf6..000000000 --- a/src-testing/src/nodes/display/ToneMappingNode.d.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { ToneMapping } from "../../constants.js"; -import RendererReferenceNode from "../accessors/RendererReferenceNode.js"; -import Node from "../core/Node.js"; -import TempNode from "../core/TempNode.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -declare class ToneMappingNode extends TempNode { - toneMapping: ToneMapping; - exposureNode: Node; - colorNode: Node | null; - - constructor(toneMapping: ToneMapping, exposureNode?: Node, colorNode?: Node | null); -} - -export default ToneMappingNode; - -export const toneMapping: ( - mapping: ToneMapping, - exposure: NodeRepresentation, - color?: NodeRepresentation, -) => ShaderNodeObject; -export const toneMappingExposure: ShaderNodeObject; - -declare module "../tsl/TSLCore.js" { - interface NodeElements { - toneMapping: ( - color: NodeRepresentation, - mapping?: NodeRepresentation, - exposure?: NodeRepresentation, - ) => ShaderNodeObject; - } -} diff --git a/src-testing/src/nodes/display/ToonOutlinePassNode.d.ts b/src-testing/src/nodes/display/ToonOutlinePassNode.d.ts deleted file mode 100644 index fe556b505..000000000 --- a/src-testing/src/nodes/display/ToonOutlinePassNode.d.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { Camera } from "../../cameras/Camera.js"; -import { Color } from "../../math/Color.js"; -import { Scene } from "../../scenes/Scene.js"; -import Node from "../core/Node.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; -import PassNode from "./PassNode.js"; - -declare class ToonOutlinePassNode extends PassNode { - colorNode: Node; - thicknessNode: Node; - alphaNode: Node; - - constructor(scene: Scene, camera: Camera, colorNode: Node, thicknessNode: Node, alphaNode: Node); -} - -export default ToonOutlinePassNode; - -export const toonOutlinePass: ( - scene: Scene, - camera: Camera, - color?: Color, - thickness?: number, - alpha?: number, -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/display/ViewportDepthNode.d.ts b/src-testing/src/nodes/display/ViewportDepthNode.d.ts deleted file mode 100644 index c741caba9..000000000 --- a/src-testing/src/nodes/display/ViewportDepthNode.d.ts +++ /dev/null @@ -1,36 +0,0 @@ -import Node from "../core/Node.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -declare class ViewportDepthNode extends Node { - scope: ViewportDepthNodeScope; - valueNode: Node; - - readonly isViewportDepthNode: true; - - constructor(scope: ViewportDepthNodeScope, valueNode?: Node | null); - - static DEPTH_BASE: "depthBase"; - static DEPTH: "depth"; - static LINEAR_DEPTH: "linearDepth"; -} - -export type ViewportDepthNodeScope = - | typeof ViewportDepthNode.DEPTH_BASE - | typeof ViewportDepthNode.DEPTH - | typeof ViewportDepthNode.LINEAR_DEPTH; - -export default ViewportDepthNode; - -export const viewZToOrthographicDepth: (viewZ: Node, near: Node, far: Node) => Node; - -export const orthographicDepthToViewZ: (depth: Node, near: Node, far: Node) => Node; - -export const viewZToPerspectiveDepth: (viewZ: Node, near: Node, far: Node) => Node; - -export const perspectiveDepthToViewZ: (depth: Node, near: Node, far: Node) => Node; - -export const perspectiveDepthToLogarithmicDepth: (perspectiveW: Node, near: Node, far: Node) => Node; - -export const depth: ShaderNodeObject; -export const linearDepth: (valueNode?: Node | null) => ShaderNodeObject; -export const viewportLinearDepth: ShaderNodeObject; diff --git a/src-testing/src/nodes/display/ViewportDepthTextureNode.d.ts b/src-testing/src/nodes/display/ViewportDepthTextureNode.d.ts deleted file mode 100644 index 7c1102e45..000000000 --- a/src-testing/src/nodes/display/ViewportDepthTextureNode.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; -import ViewportTextureNode from "./ViewportTextureNode.js"; - -declare class ViewportDepthTextureNode extends ViewportTextureNode { - constructor(uvNode?: Node, levelNode?: Node | null); -} - -export default ViewportDepthTextureNode; - -export const viewportDepthTexture: ( - uvNode?: NodeRepresentation, - levelNode?: NodeRepresentation, -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/display/ViewportSharedTextureNode.d.ts b/src-testing/src/nodes/display/ViewportSharedTextureNode.d.ts deleted file mode 100644 index 307bfbde5..000000000 --- a/src-testing/src/nodes/display/ViewportSharedTextureNode.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -import Node from "../core/Node.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; -import ViewportTextureNode from "./ViewportTextureNode.js"; - -declare class ViewportSharedTextureNode extends ViewportTextureNode { - constructor(uvNode?: Node, levelNode?: Node | null); -} - -export default ViewportSharedTextureNode; - -export const viewportSharedTexture: ( - uvNode?: Node, - levelNode?: Node | null, -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/display/ViewportTextureNode.d.ts b/src-testing/src/nodes/display/ViewportTextureNode.d.ts deleted file mode 100644 index ade4ea51e..000000000 --- a/src-testing/src/nodes/display/ViewportTextureNode.d.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { FramebufferTexture } from "../../textures/FramebufferTexture.js"; -import TextureNode from "../accessors/TextureNode.js"; -import { NodeUpdateType } from "../core/constants.js"; -import Node from "../core/Node.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -declare class ViewportTextureNode extends TextureNode { - generateMipmaps: boolean; - - readonly isOutputTextureNode: true; - - updateBeforeType: NodeUpdateType; - - constructor(uvNode?: Node, levelNode?: Node | null, framebufferTexture?: FramebufferTexture | null); -} - -export default ViewportTextureNode; - -export const viewportTexture: ( - uvNode?: Node, - levelNode?: Node | null, - framebufferTexture?: FramebufferTexture | null, -) => ShaderNodeObject; -export const viewportMipTexture: ( - uvNode?: Node, - levelNode?: Node | null, - framebufferTexture?: FramebufferTexture | null, -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/fog/FogExp2Node.d.ts b/src-testing/src/nodes/fog/FogExp2Node.d.ts deleted file mode 100644 index d129d2c72..000000000 --- a/src-testing/src/nodes/fog/FogExp2Node.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -import Node from "../core/Node.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; -import FogNode from "./FogNode.js"; - -declare class FogExp2Node extends FogNode { - isFogExp2Node: true; - densityNode: Node; - - constructor(colorNode: Node, densityNode: Node); -} - -export default FogExp2Node; - -export const densityFog: (colorNode: Node, densityNode: Node) => ShaderNodeObject; diff --git a/src-testing/src/nodes/fog/FogNode.ts b/src-testing/src/nodes/fog/FogNode.ts deleted file mode 100644 index f08efb700..000000000 --- a/src-testing/src/nodes/fog/FogNode.ts +++ /dev/null @@ -1,38 +0,0 @@ -import Node from '../core/Node.js'; -import { positionView } from '../accessors/Position.js'; -import { nodeProxy } from '../tsl/TSLBase.js'; - -class FogNode extends Node { - static get type() { - return 'FogNode'; - } - - constructor(colorNode, factorNode) { - super('float'); - - this.isFogNode = true; - - this.colorNode = colorNode; - this.factorNode = factorNode; - } - - getViewZNode(builder) { - let viewZ; - - const getViewZ = builder.context.getViewZ; - - if (getViewZ !== undefined) { - viewZ = getViewZ(this); - } - - return (viewZ || positionView.z).negate(); - } - - setup() { - return this.factorNode; - } -} - -export default FogNode; - -export const fog = /*@__PURE__*/ nodeProxy(FogNode); diff --git a/src-testing/src/nodes/fog/FogRangeNode.d.ts b/src-testing/src/nodes/fog/FogRangeNode.d.ts deleted file mode 100644 index d0e1c7cf2..000000000 --- a/src-testing/src/nodes/fog/FogRangeNode.d.ts +++ /dev/null @@ -1,19 +0,0 @@ -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; -import FogNode from "./FogNode.js"; - -declare class FogRangeNode extends FogNode { - isFogRangeNode: true; - nearNode: Node | null; - farNode: Node | null; - - constructor(colorNode: Node | null, nearNode: Node | null, farNode: Node | null); -} - -export default FogRangeNode; - -export const rangeFog: ( - colorNode: NodeRepresentation | null, - nearNode: NodeRepresentation | null, - farNode: NodeRepresentation | null, -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/functions/BSDF/BRDF_GGX.d.ts b/src-testing/src/nodes/functions/BSDF/BRDF_GGX.d.ts deleted file mode 100644 index a22bb480a..000000000 --- a/src-testing/src/nodes/functions/BSDF/BRDF_GGX.d.ts +++ /dev/null @@ -1,15 +0,0 @@ -import Node from "../../core/Node.js"; -import OperatorNode from "../../math/OperatorNode.js"; -import { ShaderNodeObject } from "../../tsl/TSLCore.js"; - -declare const BRDF_GGX: (args: { - lightDirection: Node; - f0: Node; - f90: Node; - roughness: Node; - f?: Node; - USE_IRIDESCENCE?: Node; - USE_ANISOTROPY?: Node; -}) => ShaderNodeObject; - -export default BRDF_GGX; diff --git a/src-testing/src/nodes/functions/BSDF/BRDF_Lambert.d.ts b/src-testing/src/nodes/functions/BSDF/BRDF_Lambert.d.ts deleted file mode 100644 index 591fc262d..000000000 --- a/src-testing/src/nodes/functions/BSDF/BRDF_Lambert.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -import Node from "../../core/Node.js"; -import OperatorNode from "../../math/OperatorNode.js"; -import { ShaderNodeObject } from "../../tsl/TSLCore.js"; - -declare const BRDF_Lambert: (args: { diffuseColor: Node }) => ShaderNodeObject; - -export default BRDF_Lambert; diff --git a/src-testing/src/nodes/functions/BSDF/BRDF_Sheen.d.ts b/src-testing/src/nodes/functions/BSDF/BRDF_Sheen.d.ts deleted file mode 100644 index 3e5b218e8..000000000 --- a/src-testing/src/nodes/functions/BSDF/BRDF_Sheen.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -import Node from "../../core/Node.js"; -import OperatorNode from "../../math/OperatorNode.js"; -import { ShaderNodeObject } from "../../tsl/TSLCore.js"; - -declare const BRDF_Sheen: (args: { lightDirection: Node }) => ShaderNodeObject; - -export default BRDF_Sheen; diff --git a/src-testing/src/nodes/functions/BSDF/DFGApprox.d.ts b/src-testing/src/nodes/functions/BSDF/DFGApprox.d.ts deleted file mode 100644 index 010b70ccc..000000000 --- a/src-testing/src/nodes/functions/BSDF/DFGApprox.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -import Node from "../../core/Node.js"; -import OperatorNode from "../../math/OperatorNode.js"; -import { ShaderNodeObject } from "../../tsl/TSLCore.js"; - -// Analytical approximation of the DFG LUT, one half of the -// split-sum approximation used in indirect specular lighting. -// via 'environmentBRDF' from "Physically Based Shading on Mobile" -// https://www.unrealengine.com/blog/physically-based-shading-on-mobile -declare const DFGApprox: (args: { roughness: Node; dotNV: Node }) => ShaderNodeObject; - -export default DFGApprox; diff --git a/src-testing/src/nodes/functions/BSDF/D_GGX.d.ts b/src-testing/src/nodes/functions/BSDF/D_GGX.d.ts deleted file mode 100644 index 71b673c6c..000000000 --- a/src-testing/src/nodes/functions/BSDF/D_GGX.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import Node from "../../core/Node.js"; -import OperatorNode from "../../math/OperatorNode.js"; -import { ShaderNodeObject } from "../../tsl/TSLCore.js"; - -// Microfacet Models for Refraction through Rough Surfaces - equation (33) -// http://graphicrants.blogspot.com/2013/08/specular-brdf-reference.html -// alpha is "roughness squared" in Disney’s reparameterization -declare const D_GGX: (args: { alpha: Node; dotNH: Node }) => ShaderNodeObject; - -export default D_GGX; diff --git a/src-testing/src/nodes/functions/BSDF/D_GGX_Anisotropic.d.ts b/src-testing/src/nodes/functions/BSDF/D_GGX_Anisotropic.d.ts deleted file mode 100644 index e296ea11d..000000000 --- a/src-testing/src/nodes/functions/BSDF/D_GGX_Anisotropic.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import Node from "../../core/Node.js"; -import OperatorNode from "../../math/OperatorNode.js"; -import { ShaderNodeObject } from "../../tsl/TSLCore.js"; - -// https://google.github.io/filament/Filament.md.html#materialsystem/anisotropicmodel/anisotropicspecularbrdf -declare const D_GGX_Anisotropic: ( - args: { alphaT: Node; alphaB: Node; dotNH: Node; dotTH: Node; dotBH: Node }, -) => ShaderNodeObject; - -export default D_GGX_Anisotropic; diff --git a/src-testing/src/nodes/functions/BSDF/F_Schlick.d.ts b/src-testing/src/nodes/functions/BSDF/F_Schlick.d.ts deleted file mode 100644 index 46940e6a3..000000000 --- a/src-testing/src/nodes/functions/BSDF/F_Schlick.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -import Node from "../../core/Node.js"; -import OperatorNode from "../../math/OperatorNode.js"; -import { ShaderNodeObject } from "../../tsl/TSLCore.js"; - -declare const F_Schlick: (args: { f0: Node; f90: Node; dotVH: Node }) => ShaderNodeObject; - -export default F_Schlick; diff --git a/src-testing/src/nodes/functions/BSDF/LTC.d.ts b/src-testing/src/nodes/functions/BSDF/LTC.d.ts deleted file mode 100644 index 4bd6d7f76..000000000 --- a/src-testing/src/nodes/functions/BSDF/LTC.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import Node from "../../core/Node.js"; - -declare const LTC_Uv: (args: { N: Node; V: Node; roughness: Node }) => Node; - -declare const LTC_Evaluate: ( - args: { N: Node; V: Node; P: Node; mInv: Node; p0: Node; p1: Node; p2: Node; p3: Node }, -) => Node; - -export { LTC_Evaluate, LTC_Uv }; diff --git a/src-testing/src/nodes/functions/BSDF/Schlick_to_F0.d.ts b/src-testing/src/nodes/functions/BSDF/Schlick_to_F0.d.ts deleted file mode 100644 index d0554ba2c..000000000 --- a/src-testing/src/nodes/functions/BSDF/Schlick_to_F0.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import Node from "../../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../../tsl/TSLCore.js"; - -declare const Schlick_to_F0: ( - f: NodeRepresentation, - f90: NodeRepresentation, - dotVH: NodeRepresentation, -) => ShaderNodeObject; - -export default Schlick_to_F0; diff --git a/src-testing/src/nodes/functions/BSDF/V_GGX_SmithCorrelated.d.ts b/src-testing/src/nodes/functions/BSDF/V_GGX_SmithCorrelated.d.ts deleted file mode 100644 index b6c1ca80c..000000000 --- a/src-testing/src/nodes/functions/BSDF/V_GGX_SmithCorrelated.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -import Node from "../../core/Node.js"; -import OperatorNode from "../../math/OperatorNode.js"; -import { ShaderNodeObject } from "../../tsl/TSLCore.js"; - -declare const V_GGX_SmithCorrelated: (inputs: { - alpha: Node; - dotNL: Node; - dotNV: Node; -}) => ShaderNodeObject; - -export default V_GGX_SmithCorrelated; diff --git a/src-testing/src/nodes/functions/BSDF/V_GGX_SmithCorrelated_Anisotropic.d.ts b/src-testing/src/nodes/functions/BSDF/V_GGX_SmithCorrelated_Anisotropic.d.ts deleted file mode 100644 index 5150bf6b1..000000000 --- a/src-testing/src/nodes/functions/BSDF/V_GGX_SmithCorrelated_Anisotropic.d.ts +++ /dev/null @@ -1,16 +0,0 @@ -import Node from "../../core/Node.js"; -import MathNode from "../../math/MathNode.js"; -import { ShaderNodeObject } from "../../tsl/TSLCore.js"; - -declare const V_GGX_SmithCorrelated: (inputs: { - alphaT: Node; - alphaB: Node; - dotTV: Node; - dotBV: Node; - dotTL: Node; - dotBL: Node; - dotNV: Node; - dotNL: Node; -}) => ShaderNodeObject; - -export default V_GGX_SmithCorrelated; diff --git a/src-testing/src/nodes/functions/BasicLightingModel.d.ts b/src-testing/src/nodes/functions/BasicLightingModel.d.ts deleted file mode 100644 index a64fafd44..000000000 --- a/src-testing/src/nodes/functions/BasicLightingModel.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -import LightingModel from "../core/LightingModel.js"; - -declare class BasicLightingModel extends LightingModel { - constructor(); -} - -export default BasicLightingModel; diff --git a/src-testing/src/nodes/functions/PhongLightingModel.d.ts b/src-testing/src/nodes/functions/PhongLightingModel.d.ts deleted file mode 100644 index 5df595269..000000000 --- a/src-testing/src/nodes/functions/PhongLightingModel.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -import BasicLightingModel from "./BasicLightingModel.js"; - -export default class PhongLightingModel extends BasicLightingModel { - specular: boolean; - - constructor(specular?: boolean); -} diff --git a/src-testing/src/nodes/functions/PhysicalLightingModel.d.ts b/src-testing/src/nodes/functions/PhysicalLightingModel.d.ts deleted file mode 100644 index bec381051..000000000 --- a/src-testing/src/nodes/functions/PhysicalLightingModel.d.ts +++ /dev/null @@ -1,30 +0,0 @@ -import LightingModel from "../core/LightingModel.js"; -import Node from "../core/Node.js"; - -export default class PhysicalLightingModel extends LightingModel { - clearcoat: boolean; - sheen: boolean; - iridescence: boolean; - anisotropy: boolean; - transmission: boolean; - dispersion: boolean; - - clearcoatRadiance: Node | null; - clearcoatSpecularDirect: Node | null; - clearcoatSpecularIndirect: Node | null; - sheenSpecularDirect: Node | null; - sheenSpecularIndirect: Node | null; - iridescenceFresnel: Node | null; - iridescenceF0: Node | null; - - constructor( - clearcoat?: boolean, - sheen?: boolean, - iridescence?: boolean, - anisotropy?: boolean, - transmission?: boolean, - dispersion?: boolean, - ); - - computeMultiscattering(singleScatter: Node, multiScatter: Node, specularF90: Node): void; -} diff --git a/src-testing/src/nodes/functions/ShadowMaskModel.d.ts b/src-testing/src/nodes/functions/ShadowMaskModel.d.ts deleted file mode 100644 index bcdee8b5c..000000000 --- a/src-testing/src/nodes/functions/ShadowMaskModel.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import LightingModel from "../core/LightingModel.js"; -import VarNode from "../core/VarNode.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -export default class ShadowMaskModel extends LightingModel { - shadowNode: ShaderNodeObject; - - constructor(); -} diff --git a/src-testing/src/nodes/functions/ToonLightingModel.d.ts b/src-testing/src/nodes/functions/ToonLightingModel.d.ts deleted file mode 100644 index d26db3457..000000000 --- a/src-testing/src/nodes/functions/ToonLightingModel.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -import LightingModel from "../core/LightingModel.js"; - -export default class ToonLightingModel extends LightingModel { -} diff --git a/src-testing/src/nodes/functions/material/getGeometryRoughness.d.ts b/src-testing/src/nodes/functions/material/getGeometryRoughness.d.ts deleted file mode 100644 index dd629cee0..000000000 --- a/src-testing/src/nodes/functions/material/getGeometryRoughness.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -import MathNode from "../../math/MathNode.js"; -import { ShaderNodeObject } from "../../tsl/TSLCore.js"; - -declare const getGeometryRoughness: () => ShaderNodeObject; - -export default getGeometryRoughness; diff --git a/src-testing/src/nodes/functions/material/getRoughness.d.ts b/src-testing/src/nodes/functions/material/getRoughness.d.ts deleted file mode 100644 index 7022672b0..000000000 --- a/src-testing/src/nodes/functions/material/getRoughness.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -import Node from "../../core/Node.js"; -import MathNode from "../../math/MathNode.js"; -import { ShaderNodeObject } from "../../tsl/TSLCore.js"; - -declare const getRoughness: (args: { roughness: Node }) => ShaderNodeObject; - -export default getRoughness; diff --git a/src-testing/src/nodes/functions/material/getShIrradianceAt.d.ts b/src-testing/src/nodes/functions/material/getShIrradianceAt.d.ts deleted file mode 100644 index 95c8d03c5..000000000 --- a/src-testing/src/nodes/functions/material/getShIrradianceAt.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -import Node from "../../core/Node.js"; -import { ShaderNodeObject } from "../../tsl/TSLCore.js"; - -declare const getShIrradianceAt: (normal: Node, shCoefficients: Node) => ShaderNodeObject; - -export default getShIrradianceAt; diff --git a/src-testing/src/nodes/geometry/RangeNode.d.ts b/src-testing/src/nodes/geometry/RangeNode.d.ts deleted file mode 100644 index c4c932486..000000000 --- a/src-testing/src/nodes/geometry/RangeNode.d.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Color } from "../../math/Color.js"; -import { Vector2 } from "../../math/Vector2.js"; -import { Vector3 } from "../../math/Vector3.js"; -import { Vector4 } from "../../math/Vector4.js"; -import Node from "../core/Node.js"; -import NodeBuilder from "../core/NodeBuilder.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -export type RangeModeBound = number | Color | Vector2 | Vector3 | Vector4; - -export default class RangeNode extends Node { - min: RangeModeBound; - max: RangeModeBound; - - constructor(min: RangeModeBound, max: RangeModeBound); - getVectorLength(builder: NodeBuilder): number; -} - -export const range: (min: RangeModeBound, max: RangeModeBound) => ShaderNodeObject; diff --git a/src-testing/src/nodes/gpgpu/ComputeNode.ts b/src-testing/src/nodes/gpgpu/ComputeNode.ts deleted file mode 100644 index 30d5be0b3..000000000 --- a/src-testing/src/nodes/gpgpu/ComputeNode.ts +++ /dev/null @@ -1,75 +0,0 @@ -import Node from '../core/Node.js'; -import { NodeUpdateType } from '../core/constants.js'; -import { addMethodChaining, nodeObject } from '../tsl/TSLCore.js'; - -class ComputeNode extends Node { - static get type() { - return 'ComputeNode'; - } - - constructor(computeNode, count, workgroupSize = [64]) { - super('void'); - - this.isComputeNode = true; - - this.computeNode = computeNode; - - this.count = count; - this.workgroupSize = workgroupSize; - this.dispatchCount = 0; - - this.version = 1; - this.updateBeforeType = NodeUpdateType.OBJECT; - - this.onInitFunction = null; - - this.updateDispatchCount(); - } - - dispose() { - this.dispatchEvent({ type: 'dispose' }); - } - - set needsUpdate(value) { - if (value === true) this.version++; - } - - updateDispatchCount() { - const { count, workgroupSize } = this; - - let size = workgroupSize[0]; - - for (let i = 1; i < workgroupSize.length; i++) size *= workgroupSize[i]; - - this.dispatchCount = Math.ceil(count / size); - } - - onInit(callback) { - this.onInitFunction = callback; - - return this; - } - - updateBefore({ renderer }) { - renderer.compute(this); - } - - generate(builder) { - const { shaderStage } = builder; - - if (shaderStage === 'compute') { - const snippet = this.computeNode.build(builder, 'void'); - - if (snippet !== '') { - builder.addLineFlowCode(snippet, this); - } - } - } -} - -export default ComputeNode; - -export const compute = (node, count, workgroupSize) => - nodeObject(new ComputeNode(nodeObject(node), count, workgroupSize)); - -addMethodChaining('compute', compute); diff --git a/src-testing/src/nodes/lighting/AONode.d.ts b/src-testing/src/nodes/lighting/AONode.d.ts deleted file mode 100644 index 998ec5236..000000000 --- a/src-testing/src/nodes/lighting/AONode.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import Node from "../core/Node.js"; -import LightingNode from "./LightingNode.js"; - -export default class AONode extends LightingNode { - aoNode: Node | null; - - constructor(aoNode?: Node | null); -} diff --git a/src-testing/src/nodes/lighting/AmbientLightNode.d.ts b/src-testing/src/nodes/lighting/AmbientLightNode.d.ts deleted file mode 100644 index 3b7cc6fb6..000000000 --- a/src-testing/src/nodes/lighting/AmbientLightNode.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { AmbientLight } from "../../lights/AmbientLight.js"; -import AnalyticLightNode from "./AnalyticLightNode.js"; - -declare class AmbientLightNode extends AnalyticLightNode { - constructor(light?: AmbientLight | null); -} - -export default AmbientLightNode; diff --git a/src-testing/src/nodes/lighting/AnalyticLightNode.d.ts b/src-testing/src/nodes/lighting/AnalyticLightNode.d.ts deleted file mode 100644 index d8cea32ef..000000000 --- a/src-testing/src/nodes/lighting/AnalyticLightNode.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Light } from "../../lights/Light.js"; -import LightingNode from "./LightingNode.js"; - -export default class AnalyticLightNode extends LightingNode { - light: T | null; - - constructor(light?: T | null); -} diff --git a/src-testing/src/nodes/lighting/BasicEnvironmentNode.d.ts b/src-testing/src/nodes/lighting/BasicEnvironmentNode.d.ts deleted file mode 100644 index de244562f..000000000 --- a/src-testing/src/nodes/lighting/BasicEnvironmentNode.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import Node from "../core/Node.js"; -import LightingNode from "./LightingNode.js"; - -declare class BasicEnvironmentNode extends LightingNode { - envNode: Node | null; - - constructor(envNode?: Node | null); -} - -export default BasicEnvironmentNode; diff --git a/src-testing/src/nodes/lighting/BasicLightMapNode.d.ts b/src-testing/src/nodes/lighting/BasicLightMapNode.d.ts deleted file mode 100644 index c759e8857..000000000 --- a/src-testing/src/nodes/lighting/BasicLightMapNode.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import Node from "../core/Node.js"; -import LightingNode from "./LightingNode.js"; - -declare class BasicLightMapNode extends LightingNode { - constructor(lightMapNode?: Node | null); -} - -export default BasicLightMapNode; diff --git a/src-testing/src/nodes/lighting/DirectionalLightNode.d.ts b/src-testing/src/nodes/lighting/DirectionalLightNode.d.ts deleted file mode 100644 index 41908abaf..000000000 --- a/src-testing/src/nodes/lighting/DirectionalLightNode.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { DirectionalLight } from "../../lights/DirectionalLight.js"; -import AnalyticLightNode from "./AnalyticLightNode.js"; - -declare class DirectionalLightNode extends AnalyticLightNode { - constructor(light?: DirectionalLight | null); -} - -export default DirectionalLightNode; diff --git a/src-testing/src/nodes/lighting/EnvironmentNode.ts b/src-testing/src/nodes/lighting/EnvironmentNode.ts deleted file mode 100644 index eab24fba0..000000000 --- a/src-testing/src/nodes/lighting/EnvironmentNode.ts +++ /dev/null @@ -1,114 +0,0 @@ -import LightingNode from './LightingNode.js'; -import { cache } from '../core/CacheNode.js'; -import { roughness, clearcoatRoughness } from '../core/PropertyNode.js'; -import { cameraViewMatrix } from '../accessors/Camera.js'; -import { transformedClearcoatNormalView, transformedNormalView, transformedNormalWorld } from '../accessors/Normal.js'; -import { positionViewDirection } from '../accessors/Position.js'; -import { float } from '../tsl/TSLBase.js'; -import { reference } from '../accessors/ReferenceNode.js'; -import { transformedBentNormalView } from '../accessors/AccessorsUtils.js'; -import { pmremTexture } from '../pmrem/PMREMNode.js'; - -const _envNodeCache = new WeakMap(); - -class EnvironmentNode extends LightingNode { - static get type() { - return 'EnvironmentNode'; - } - - constructor(envNode = null) { - super(); - - this.envNode = envNode; - } - - setup(builder) { - const { material } = builder; - - let envNode = this.envNode; - - if (envNode.isTextureNode || envNode.isMaterialReferenceNode) { - const value = envNode.isTextureNode ? envNode.value : material[envNode.property]; - - let cacheEnvNode = _envNodeCache.get(value); - - if (cacheEnvNode === undefined) { - cacheEnvNode = pmremTexture(value); - - _envNodeCache.set(value, cacheEnvNode); - } - - envNode = cacheEnvNode; - } - - // - - const envMap = material.envMap; - const intensity = envMap - ? reference('envMapIntensity', 'float', builder.material) - : reference('environmentIntensity', 'float', builder.scene); // @TODO: Add materialEnvIntensity in MaterialNode - - const useAnisotropy = material.useAnisotropy === true || material.anisotropy > 0; - const radianceNormalView = useAnisotropy ? transformedBentNormalView : transformedNormalView; - - const radiance = envNode.context(createRadianceContext(roughness, radianceNormalView)).mul(intensity); - const irradiance = envNode.context(createIrradianceContext(transformedNormalWorld)).mul(Math.PI).mul(intensity); - - const isolateRadiance = cache(radiance); - const isolateIrradiance = cache(irradiance); - - // - - builder.context.radiance.addAssign(isolateRadiance); - - builder.context.iblIrradiance.addAssign(isolateIrradiance); - - // - - const clearcoatRadiance = builder.context.lightingModel.clearcoatRadiance; - - if (clearcoatRadiance) { - const clearcoatRadianceContext = envNode - .context(createRadianceContext(clearcoatRoughness, transformedClearcoatNormalView)) - .mul(intensity); - const isolateClearcoatRadiance = cache(clearcoatRadianceContext); - - clearcoatRadiance.addAssign(isolateClearcoatRadiance); - } - } -} - -export default EnvironmentNode; - -const createRadianceContext = (roughnessNode, normalViewNode) => { - let reflectVec = null; - - return { - getUV: () => { - if (reflectVec === null) { - reflectVec = positionViewDirection.negate().reflect(normalViewNode); - - // Mixing the reflection with the normal is more accurate and keeps rough objects from gathering light from behind their tangent plane. - reflectVec = roughnessNode.mul(roughnessNode).mix(reflectVec, normalViewNode).normalize(); - - reflectVec = reflectVec.transformDirection(cameraViewMatrix); - } - - return reflectVec; - }, - getTextureLevel: () => { - return roughnessNode; - }, - }; -}; - -const createIrradianceContext = normalWorldNode => { - return { - getUV: () => { - return normalWorldNode; - }, - getTextureLevel: () => { - return float(1.0); - }, - }; -}; diff --git a/src-testing/src/nodes/lighting/HemisphereLightNode.d.ts b/src-testing/src/nodes/lighting/HemisphereLightNode.d.ts deleted file mode 100644 index 7cf38dd79..000000000 --- a/src-testing/src/nodes/lighting/HemisphereLightNode.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { HemisphereLight } from "../../lights/HemisphereLight.js"; -import Object3DNode from "../accessors/Object3DNode.js"; -import Node from "../core/Node.js"; -import AnalyticLightNode from "./AnalyticLightNode.js"; - -export default class HemisphereLightNode extends AnalyticLightNode { - lightPositionNode: Object3DNode; - lightDirectionNode: Node; - - groundColorNode: Node; - - constructor(light?: HemisphereLight | null); -} diff --git a/src-testing/src/nodes/lighting/IESSpotLightNode.d.ts b/src-testing/src/nodes/lighting/IESSpotLightNode.d.ts deleted file mode 100644 index 5906fe96d..000000000 --- a/src-testing/src/nodes/lighting/IESSpotLightNode.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -import SpotLightNode from "./SpotLightNode.js"; - -declare class IESSpotLightNode extends SpotLightNode {} - -export default IESSpotLightNode; diff --git a/src-testing/src/nodes/lighting/IrradianceNode.d.ts b/src-testing/src/nodes/lighting/IrradianceNode.d.ts deleted file mode 100644 index a59838044..000000000 --- a/src-testing/src/nodes/lighting/IrradianceNode.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import Node from "../core/Node.js"; -import LightingNode from "./LightingNode.js"; - -export default class IrradianceNode extends LightingNode { - node: Node | null; - - constructor(node?: Node | null); -} diff --git a/src-testing/src/nodes/lighting/LightNode.d.ts b/src-testing/src/nodes/lighting/LightNode.d.ts deleted file mode 100644 index de64bdb60..000000000 --- a/src-testing/src/nodes/lighting/LightNode.d.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Light } from "../../lights/Light.js"; -import Node from "../core/Node.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -export type LightNodeScope = typeof LightNode.TARGET_DIRECTION; - -declare class LightNode extends Node { - scope: LightNodeScope; - light: Light; - - constructor(scope?: LightNodeScope, light?: Light | null); - - static TARGET_DIRECTION: "targetDirection"; -} - -export default LightNode; - -export const lightTargetDirection: (light?: Light | null) => ShaderNodeObject; diff --git a/src-testing/src/nodes/lighting/LightProbeNode.d.ts b/src-testing/src/nodes/lighting/LightProbeNode.d.ts deleted file mode 100644 index 3a5b12963..000000000 --- a/src-testing/src/nodes/lighting/LightProbeNode.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { LightProbe } from "../../lights/LightProbe.js"; -import UniformArrayNode from "../accessors/UniformArrayNode.js"; -import AnalyticLightNode from "./AnalyticLightNode.js"; - -declare class LightProbeNode extends AnalyticLightNode { - lightProbe: UniformArrayNode; - - constructor(light?: LightProbe | null); -} - -export default LightProbeNode; diff --git a/src-testing/src/nodes/lighting/LightUtils.d.ts b/src-testing/src/nodes/lighting/LightUtils.d.ts deleted file mode 100644 index 4fd41ea55..000000000 --- a/src-testing/src/nodes/lighting/LightUtils.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import Node from "../core/Node.js"; -import ConditionalNode from "../math/ConditionalNode.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -export const getDistanceAttenuation: (args: { - lightDistance: Node; - cutoffDistance: Node; - decayExponent: Node; -}) => ShaderNodeObject; diff --git a/src-testing/src/nodes/lighting/LightingContextNode.ts b/src-testing/src/nodes/lighting/LightingContextNode.ts deleted file mode 100644 index f9dbf1a82..000000000 --- a/src-testing/src/nodes/lighting/LightingContextNode.ts +++ /dev/null @@ -1,57 +0,0 @@ -import ContextNode from '../core/ContextNode.js'; -import { nodeProxy, float, vec3 } from '../tsl/TSLBase.js'; - -class LightingContextNode extends ContextNode { - static get type() { - return 'LightingContextNode'; - } - - constructor(node, lightingModel = null, backdropNode = null, backdropAlphaNode = null) { - super(node); - - this.lightingModel = lightingModel; - this.backdropNode = backdropNode; - this.backdropAlphaNode = backdropAlphaNode; - - this._value = null; - } - - getContext() { - const { backdropNode, backdropAlphaNode } = this; - - const directDiffuse = vec3().toVar('directDiffuse'), - directSpecular = vec3().toVar('directSpecular'), - indirectDiffuse = vec3().toVar('indirectDiffuse'), - indirectSpecular = vec3().toVar('indirectSpecular'); - - const reflectedLight = { - directDiffuse, - directSpecular, - indirectDiffuse, - indirectSpecular, - }; - - const context = { - radiance: vec3().toVar('radiance'), - irradiance: vec3().toVar('irradiance'), - iblIrradiance: vec3().toVar('iblIrradiance'), - ambientOcclusion: float(1).toVar('ambientOcclusion'), - reflectedLight, - backdrop: backdropNode, - backdropAlpha: backdropAlphaNode, - }; - - return context; - } - - setup(builder) { - this.value = this._value || (this._value = this.getContext()); - this.value.lightingModel = this.lightingModel || builder.context.lightingModel; - - return super.setup(builder); - } -} - -export default LightingContextNode; - -export const lightingContext = /*@__PURE__*/ nodeProxy(LightingContextNode); diff --git a/src-testing/src/nodes/lighting/LightingNode.d.ts b/src-testing/src/nodes/lighting/LightingNode.d.ts deleted file mode 100644 index 3e8dd5424..000000000 --- a/src-testing/src/nodes/lighting/LightingNode.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -import Node from "../core/Node.js"; - -export default abstract class LightingNode extends Node { - readonly isLightingNode: true; - - constructor(); -} diff --git a/src-testing/src/nodes/lighting/LightsNode.ts b/src-testing/src/nodes/lighting/LightsNode.ts deleted file mode 100644 index 1cf0b19ac..000000000 --- a/src-testing/src/nodes/lighting/LightsNode.ts +++ /dev/null @@ -1,200 +0,0 @@ -import Node from '../core/Node.js'; -import { nodeObject, vec3 } from '../tsl/TSLBase.js'; - -const sortLights = lights => { - return lights.sort((a, b) => a.id - b.id); -}; - -const getLightNodeById = (id, lightNodes) => { - for (const lightNode of lightNodes) { - if (lightNode.isAnalyticLightNode && lightNode.light.id === id) { - return lightNode; - } - } - - return null; -}; - -const _lightsNodeRef = /*@__PURE__*/ new WeakMap(); - -class LightsNode extends Node { - static get type() { - return 'LightsNode'; - } - - constructor() { - super('vec3'); - - this.totalDiffuseNode = vec3().toVar('totalDiffuse'); - this.totalSpecularNode = vec3().toVar('totalSpecular'); - - this.outgoingLightNode = vec3().toVar('outgoingLight'); - - this._lights = []; - - this._lightNodes = null; - this._lightNodesHash = null; - - this.global = true; - } - - getHash(builder) { - if (this._lightNodesHash === null) { - if (this._lightNodes === null) this.setupLightsNode(builder); - - const hash = []; - - for (const lightNode of this._lightNodes) { - hash.push(lightNode.getSelf().getHash()); - } - - this._lightNodesHash = 'lights-' + hash.join(','); - } - - return this._lightNodesHash; - } - - analyze(builder) { - const properties = builder.getDataFromNode(this); - - for (const node of properties.nodes) { - node.build(builder); - } - } - - setupLightsNode(builder) { - const lightNodes = []; - - const previousLightNodes = this._lightNodes; - - const lights = sortLights(this._lights); - const nodeLibrary = builder.renderer.library; - - for (const light of lights) { - if (light.isNode) { - lightNodes.push(nodeObject(light)); - } else { - let lightNode = null; - - if (previousLightNodes !== null) { - lightNode = getLightNodeById(light.id, previousLightNodes); // resuse existing light node - } - - if (lightNode === null) { - const lightNodeClass = nodeLibrary.getLightNodeClass(light.constructor); - - if (lightNodeClass === null) { - console.warn(`LightsNode.setupNodeLights: Light node not found for ${light.constructor.name}`); - continue; - } - - let lightNode = null; - - if (!_lightsNodeRef.has(light)) { - lightNode = nodeObject(new lightNodeClass(light)); - _lightsNodeRef.set(light, lightNode); - } else { - lightNode = _lightsNodeRef.get(light); - } - - lightNodes.push(lightNode); - } - } - } - - this._lightNodes = lightNodes; - } - - setupLights(builder, lightNodes) { - for (const lightNode of lightNodes) { - lightNode.build(builder); - } - } - - setup(builder) { - if (this._lightNodes === null) this.setupLightsNode(builder); - - const context = builder.context; - const lightingModel = context.lightingModel; - - let outgoingLightNode = this.outgoingLightNode; - - if (lightingModel) { - const { _lightNodes, totalDiffuseNode, totalSpecularNode } = this; - - context.outgoingLight = outgoingLightNode; - - const stack = builder.addStack(); - - // - - const properties = builder.getDataFromNode(this); - properties.nodes = stack.nodes; - - // - - lightingModel.start(context, stack, builder); - - // lights - - this.setupLights(builder, _lightNodes); - - // - - lightingModel.indirect(context, stack, builder); - - // - - const { backdrop, backdropAlpha } = context; - const { directDiffuse, directSpecular, indirectDiffuse, indirectSpecular } = context.reflectedLight; - - let totalDiffuse = directDiffuse.add(indirectDiffuse); - - if (backdrop !== null) { - if (backdropAlpha !== null) { - totalDiffuse = vec3(backdropAlpha.mix(totalDiffuse, backdrop)); - } else { - totalDiffuse = vec3(backdrop); - } - - context.material.transparent = true; - } - - totalDiffuseNode.assign(totalDiffuse); - totalSpecularNode.assign(directSpecular.add(indirectSpecular)); - - outgoingLightNode.assign(totalDiffuseNode.add(totalSpecularNode)); - - // - - lightingModel.finish(context, stack, builder); - - // - - outgoingLightNode = outgoingLightNode.bypass(builder.removeStack()); - } - - return outgoingLightNode; - } - - setLights(lights) { - this._lights = lights; - - this._lightNodes = null; - this._lightNodesHash = null; - - return this; - } - - getLights() { - return this._lights; - } - - get hasLights() { - return this._lights.length > 0; - } -} - -export default LightsNode; - -export const lights = (lights = []) => nodeObject(new LightsNode()).setLights(lights); diff --git a/src-testing/src/nodes/lighting/PointLightNode.d.ts b/src-testing/src/nodes/lighting/PointLightNode.d.ts deleted file mode 100644 index 6ae10bc08..000000000 --- a/src-testing/src/nodes/lighting/PointLightNode.d.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { PointLight } from "../../lights/PointLight.js"; -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; -import AnalyticLightNode from "./AnalyticLightNode.js"; - -export const directPointLight: ( - color: NodeRepresentation, - lightViewPosition: NodeRepresentation, - cutoffDistance: NodeRepresentation, - decayExponent: NodeRepresentation, -) => ShaderNodeObject; - -declare class PointLightNode extends AnalyticLightNode { - cutoffDistanceNode: Node; - decayExponentNode: Node; - - constructor(light?: PointLight | null); -} - -export default PointLightNode; diff --git a/src-testing/src/nodes/lighting/RectAreaLightNode.d.ts b/src-testing/src/nodes/lighting/RectAreaLightNode.d.ts deleted file mode 100644 index db4d18b82..000000000 --- a/src-testing/src/nodes/lighting/RectAreaLightNode.d.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { RectAreaLight } from "../../lights/RectAreaLight.js"; -import { DataTexture } from "../../textures/DataTexture.js"; -import Node from "../core/Node.js"; -import AnalyticLightNode from "./AnalyticLightNode.js"; - -export interface RectAreaLightTexturesLib { - LTC_HALF_1: DataTexture; - LTC_HALF_2: DataTexture; - - LTC_FLOAT_1: DataTexture; - LTC_FLOAT_2: DataTexture; -} - -export default class RectAreaLightNode extends AnalyticLightNode { - halfHeight: Node; - halfWidth: Node; - - constructor(light?: RectAreaLight | null); - - static setLTC(ltc: RectAreaLightTexturesLib): void; -} diff --git a/src-testing/src/nodes/lighting/ShadowNode.d.ts b/src-testing/src/nodes/lighting/ShadowNode.d.ts deleted file mode 100644 index 1b8d4fa9f..000000000 --- a/src-testing/src/nodes/lighting/ShadowNode.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Light } from "../../lights/Light.js"; -import { LightShadow } from "../../lights/LightShadow.js"; -import Node from "../core/Node.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -declare class ShadowNode extends Node { - constructor(light: Light, shadow: LightShadow); -} - -export default ShadowNode; - -export const shadow: (light: Light, shadow: LightShadow) => ShaderNodeObject; diff --git a/src-testing/src/nodes/lighting/SpotLightNode.d.ts b/src-testing/src/nodes/lighting/SpotLightNode.d.ts deleted file mode 100644 index 0b1ae4b13..000000000 --- a/src-testing/src/nodes/lighting/SpotLightNode.d.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { SpotLight } from "../../lights/SpotLight.js"; -import Node from "../core/Node.js"; -import AnalyticLightNode from "./AnalyticLightNode.js"; - -export default class PointLightNode extends AnalyticLightNode { - directionNode: Node; - - coneCosNode: Node; - penumbraCosNode: Node; - - cutoffDistanceNode: Node; - decayExponentNode: Node; - - constructor(light?: SpotLight | null); -} diff --git a/src-testing/src/nodes/materialx/MaterialXNodes.d.ts b/src-testing/src/nodes/materialx/MaterialXNodes.d.ts deleted file mode 100644 index 8007125a7..000000000 --- a/src-testing/src/nodes/materialx/MaterialXNodes.d.ts +++ /dev/null @@ -1,107 +0,0 @@ -import Node from "../core/Node.js"; -import MathNode from "../math/MathNode.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; -import { mx_hsvtorgb, mx_rgbtohsv } from "./lib/mx_hsv.js"; -import { mx_srgb_texture_to_lin_rec709 } from "./lib/mx_transform_color.js"; - -export function mx_aastep(threshold: NodeRepresentation, value: NodeRepresentation): ShaderNodeObject; - -export function mx_ramplr( - valuel: NodeRepresentation, - valuer: NodeRepresentation, - texcoord?: NodeRepresentation, -): ShaderNodeObject; -export function mx_ramptb( - valuet: NodeRepresentation, - valueb: NodeRepresentation, - texcoord?: NodeRepresentation, -): ShaderNodeObject; - -export function mx_splitlr( - valuel: NodeRepresentation, - valuer: NodeRepresentation, - center: NodeRepresentation, - texcoord?: NodeRepresentation, -): ShaderNodeObject; -export function mx_splittb( - valuet: NodeRepresentation, - valueb: NodeRepresentation, - center: NodeRepresentation, - texcoord?: NodeRepresentation, -): ShaderNodeObject; - -export function mx_transform_uv( - uv_scale?: NodeRepresentation, - uv_offset?: NodeRepresentation, - uv_geo?: NodeRepresentation, -): ShaderNodeObject; - -export function mx_safepower(in1: NodeRepresentation, in2?: NodeRepresentation): ShaderNodeObject; - -export function mx_contrast( - input: NodeRepresentation, - amount?: NodeRepresentation, - pivot?: NodeRepresentation, -): ShaderNodeObject; - -export function mx_noise_float( - texcoord?: NodeRepresentation, - amplitude?: NodeRepresentation, - pivot?: NodeRepresentation, -): ShaderNodeObject; -export function mx_noise_vec3( - texcoord?: NodeRepresentation, - amplitude?: NodeRepresentation, - pivot?: NodeRepresentation, -): ShaderNodeObject; -export function mx_noise_vec4( - texcoord?: NodeRepresentation, - amplitude?: NodeRepresentation, - pivot?: NodeRepresentation, -): ShaderNodeObject; - -export function mx_worley_noise_float( - texcoord?: NodeRepresentation, - jitter?: NodeRepresentation, -): ShaderNodeObject; -export function mx_worley_noise_vec2( - texcoord?: NodeRepresentation, - jitter?: NodeRepresentation, -): ShaderNodeObject; -export function mx_worley_noise_vec3( - texcoord?: NodeRepresentation, - jitter?: NodeRepresentation, -): ShaderNodeObject; - -export function mx_cell_noise_float(texcoord?: NodeRepresentation): ShaderNodeObject; - -export function mx_fractal_noise_float( - position?: NodeRepresentation, - octaves?: NodeRepresentation, - lacunarity?: NodeRepresentation, - diminish?: NodeRepresentation, - amplitude?: NodeRepresentation, -): ShaderNodeObject; -export function mx_fractal_noise_vec2( - position?: NodeRepresentation, - octaves?: NodeRepresentation, - lacunarity?: NodeRepresentation, - diminish?: NodeRepresentation, - amplitude?: NodeRepresentation, -): ShaderNodeObject; -export function mx_fractal_noise_vec3( - position?: NodeRepresentation, - octaves?: NodeRepresentation, - lacunarity?: NodeRepresentation, - diminish?: NodeRepresentation, - amplitude?: NodeRepresentation, -): ShaderNodeObject; -export function mx_fractal_noise_vec4( - position?: NodeRepresentation, - octaves?: NodeRepresentation, - lacunarity?: NodeRepresentation, - diminish?: NodeRepresentation, - amplitude?: NodeRepresentation, -): ShaderNodeObject; - -export { mx_hsvtorgb, mx_rgbtohsv, mx_srgb_texture_to_lin_rec709 }; diff --git a/src-testing/src/nodes/materialx/lib/mx_hsv.d.ts b/src-testing/src/nodes/materialx/lib/mx_hsv.d.ts deleted file mode 100644 index ce11882e9..000000000 --- a/src-testing/src/nodes/materialx/lib/mx_hsv.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -import Node from "../../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../../tsl/TSLCore.js"; - -export const mx_hsvtorgb: (hsv: NodeRepresentation) => ShaderNodeObject; - -export const mx_rgbtohsv: (c_immutable: NodeRepresentation) => ShaderNodeObject; diff --git a/src-testing/src/nodes/materialx/lib/mx_noise.d.ts b/src-testing/src/nodes/materialx/lib/mx_noise.d.ts deleted file mode 100644 index 2e5405f75..000000000 --- a/src-testing/src/nodes/materialx/lib/mx_noise.d.ts +++ /dev/null @@ -1,359 +0,0 @@ -import Node from "../../core/Node.js"; -import VarNode from "../../core/VarNode.js"; -import { NodeRepresentation, ShaderNodeObject } from "../../tsl/TSLCore.js"; - -export const mx_select: ( - b_immutable: NodeRepresentation, - t_immutable: NodeRepresentation, - f_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_negate_if: ( - val_immutable: NodeRepresentation, - b_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_floor: (x_immutable: NodeRepresentation) => ShaderNodeObject; - -export const mx_floorfrac: (x_immutable: NodeRepresentation, i: ShaderNodeObject) => ShaderNodeObject; - -export const mx_bilerp_0: ( - v0_immutable: NodeRepresentation, - v1_immutable: NodeRepresentation, - v2_immutable: NodeRepresentation, - v3_immutable: NodeRepresentation, - s_immutable: NodeRepresentation, - t_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_bilerp_1: ( - v0_immutable: NodeRepresentation, - v1_immutable: NodeRepresentation, - v2_immutable: NodeRepresentation, - v3_immutable: NodeRepresentation, - s_immutable: NodeRepresentation, - t_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_bilerp: ( - v0_immutable: NodeRepresentation, - v1_immutable: NodeRepresentation, - v2_immutable: NodeRepresentation, - v3_immutable: NodeRepresentation, - s_immutable: NodeRepresentation, - t_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_trilerp_0: ( - v0_immutable: NodeRepresentation, - v1_immutable: NodeRepresentation, - v2_immutable: NodeRepresentation, - v3_immutable: NodeRepresentation, - v4_immutable: NodeRepresentation, - v5_immutable: NodeRepresentation, - v6_immutable: NodeRepresentation, - v7_immutable: NodeRepresentation, - s_immutable: NodeRepresentation, - t_immutable: NodeRepresentation, - r_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_trilerp_1: ( - v0_immutable: NodeRepresentation, - v1_immutable: NodeRepresentation, - v2_immutable: NodeRepresentation, - v3_immutable: NodeRepresentation, - v4_immutable: NodeRepresentation, - v5_immutable: NodeRepresentation, - v6_immutable: NodeRepresentation, - v7_immutable: NodeRepresentation, - s_immutable: NodeRepresentation, - t_immutable: NodeRepresentation, - r_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_trilerp: ( - v0_immutable: NodeRepresentation, - v1_immutable: NodeRepresentation, - v2_immutable: NodeRepresentation, - v3_immutable: NodeRepresentation, - v4_immutable: NodeRepresentation, - v5_immutable: NodeRepresentation, - v6_immutable: NodeRepresentation, - v7_immutable: NodeRepresentation, - s_immutable: NodeRepresentation, - t_immutable: NodeRepresentation, - r_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_gradient_float_0: ( - hash_immutable: NodeRepresentation, - x_immutable: NodeRepresentation, - y_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_gradient_float_1: ( - hash_immutable: NodeRepresentation, - x_immutable: NodeRepresentation, - y_immutable: NodeRepresentation, - z_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_gradient_float: ( - hash_immutable: NodeRepresentation, - x_immutable: NodeRepresentation, - y_immutable: NodeRepresentation, - z_immutable?: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_gradient_vec3_0: ( - hash_immutable: NodeRepresentation, - x_immutable: NodeRepresentation, - y_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_gradient_vec3_1: ( - hash_immutable: NodeRepresentation, - x_immutable: NodeRepresentation, - y_immutable: NodeRepresentation, - z_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_gradient_vec3: ( - hash_immutable: NodeRepresentation, - x_immutable: NodeRepresentation, - y_immutable: NodeRepresentation, - z_immutable?: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_gradient_scale2d_0: (v_immutable: NodeRepresentation) => ShaderNodeObject; - -export const mx_gradient_scale3d_0: (v_immutable: NodeRepresentation) => ShaderNodeObject; - -export const mx_gradient_scale2d_1: (v_immutable: NodeRepresentation) => ShaderNodeObject; - -export const mx_gradient_scale2d: (v_immutable: NodeRepresentation) => ShaderNodeObject; - -export const mx_gradient_scale3d_1: (v_immutable: NodeRepresentation) => ShaderNodeObject; - -export const mx_gradient_scale3d: (v_immutable: NodeRepresentation) => ShaderNodeObject; - -export const mx_rotl32: (x_immutable: NodeRepresentation, k_immutable: NodeRepresentation) => ShaderNodeObject; - -export const mx_bjmix: ( - a: ShaderNodeObject, - b: ShaderNodeObject, - c: ShaderNodeObject, -) => ShaderNodeObject; - -export const mx_bjfinal: ( - a_immutable: NodeRepresentation, - b_immutable: NodeRepresentation, - c_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_bits_to_01: (bits_immutable: NodeRepresentation) => ShaderNodeObject; - -export const mx_fade: (t_immutable: NodeRepresentation) => ShaderNodeObject; - -export const mx_hash_int_0: (x_immutable: NodeRepresentation) => ShaderNodeObject; - -export const mx_hash_int_1: ( - x_immutable: NodeRepresentation, - y_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_hash_int_2: ( - x_immutable: NodeRepresentation, - y_immutable: NodeRepresentation, - z_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_hash_int_3: ( - x_immutable: NodeRepresentation, - y_immutable: NodeRepresentation, - z_immutable: NodeRepresentation, - xx_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_hash_int_4: ( - x_immutable: NodeRepresentation, - y_immutable: NodeRepresentation, - z_immutable: NodeRepresentation, - xx_immutable: NodeRepresentation, - yy_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_hash_int: ( - x_immutable: NodeRepresentation, - y_immutable?: NodeRepresentation, - z_immutable?: NodeRepresentation, - xx_immutable?: NodeRepresentation, - yy_immutable?: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_hash_vec3_0: ( - x_immutable: NodeRepresentation, - y_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_hash_vec3_1: ( - x_immutable: NodeRepresentation, - y_immutable: NodeRepresentation, - z_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_hash_vec3: ( - x_immutable: NodeRepresentation, - y_immutable: NodeRepresentation, - z_immutable?: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_perlin_noise_float_0: (p_immutable: NodeRepresentation) => ShaderNodeObject; - -export const mx_perlin_noise_float_1: (p_immutable: NodeRepresentation) => ShaderNodeObject; - -export const mx_perlin_noise_float: (p_immutable: NodeRepresentation) => ShaderNodeObject; - -export const mx_perlin_noise_vec3_0: (p_immutable: NodeRepresentation) => ShaderNodeObject; - -export const mx_perlin_noise_vec3_1: (p_immutable: NodeRepresentation) => ShaderNodeObject; - -export const mx_perlin_noise_vec3: (p_immutable: NodeRepresentation) => ShaderNodeObject; - -export const mx_cell_noise_float_0: (p_immutable: NodeRepresentation) => ShaderNodeObject; - -export const mx_cell_noise_float_1: (p_immutable: NodeRepresentation) => ShaderNodeObject; - -export const mx_cell_noise_float_2: (p_immutable: NodeRepresentation) => ShaderNodeObject; - -export const mx_cell_noise_float_3: (p_immutable: NodeRepresentation) => ShaderNodeObject; - -export const mx_cell_noise_float: (p_immutable: NodeRepresentation) => ShaderNodeObject; - -export const mx_cell_noise_vec3_0: (p_immutable: NodeRepresentation) => ShaderNodeObject; - -export const mx_cell_noise_vec3_1: (p_immutable: NodeRepresentation) => ShaderNodeObject; - -export const mx_cell_noise_vec3_2: (p_immutable: NodeRepresentation) => ShaderNodeObject; - -export const mx_cell_noise_vec3_3: (p_immutable: NodeRepresentation) => ShaderNodeObject; - -export const mx_cell_noise_vec3: (p_immutable: NodeRepresentation) => ShaderNodeObject; - -export const mx_fractal_noise_float: ( - p_immutable: NodeRepresentation, - octaves_immutable: NodeRepresentation, - lacunarity_immutable: NodeRepresentation, - diminish_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_fractal_noise_vec3: ( - p_immutable: NodeRepresentation, - octaves_immutable: NodeRepresentation, - lacunarity_immutable: NodeRepresentation, - diminish_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_fractal_noise_vec2: ( - p_immutable: NodeRepresentation, - octaves_immutable: NodeRepresentation, - lacunarity_immutable: NodeRepresentation, - diminish_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_fractal_noise_vec4: ( - p_immutable: NodeRepresentation, - octaves_immutable: NodeRepresentation, - lacunarity_immutable: NodeRepresentation, - diminish_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_worley_distance_0: ( - p_immutable: NodeRepresentation, - x_immutable: NodeRepresentation, - y_immutable: NodeRepresentation, - z_immutable: NodeRepresentation, - xoff_immutable: NodeRepresentation, - yoff_immutable: NodeRepresentation, - jitter_immutable: NodeRepresentation, - metric_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_worley_distance_1: ( - p_immutable: NodeRepresentation, - x_immutable: NodeRepresentation, - y_immutable: NodeRepresentation, - z_immutable: NodeRepresentation, - xoff_immutable: NodeRepresentation, - yoff_immutable: NodeRepresentation, - zoff_immutable: NodeRepresentation, - jitter_immutable: NodeRepresentation, - metric_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_worley_distance: ( - p_immutable: NodeRepresentation, - x_immutable: NodeRepresentation, - y_immutable: NodeRepresentation, - z_immutable: NodeRepresentation, - xoff_immutable: NodeRepresentation, - yoff_immutable: NodeRepresentation, - zoff_immutable: NodeRepresentation, - jitter_immutable: NodeRepresentation, - metric_immutable?: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_worley_noise_float_0: ( - p_immutable: NodeRepresentation, - jitter_immutable: NodeRepresentation, - metric_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_worley_noise_vec2_0: ( - p_immutable: NodeRepresentation, - jitter_immutable: NodeRepresentation, - metric_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_worley_noise_vec3_0: ( - p_immutable: NodeRepresentation, - jitter_immutable: NodeRepresentation, - metric_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_worley_noise_float_1: ( - p_immutable: NodeRepresentation, - jitter_immutable: NodeRepresentation, - metric_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_worley_noise_float: ( - p_immutable: NodeRepresentation, - jitter_immutable: NodeRepresentation, - metric_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_worley_noise_vec2_1: ( - p_immutable: NodeRepresentation, - jitter_immutable: NodeRepresentation, - metric_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_worley_noise_vec2: ( - p_immutable: NodeRepresentation, - jitter_immutable: NodeRepresentation, - metric_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_worley_noise_vec3_1: ( - p_immutable: NodeRepresentation, - jitter_immutable: NodeRepresentation, - metric_immutable: NodeRepresentation, -) => ShaderNodeObject; - -export const mx_worley_noise_vec3: ( - p_immutable: NodeRepresentation, - jitter_immutable: NodeRepresentation, - metric_immutable: NodeRepresentation, -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/materialx/lib/mx_transform_color.d.ts b/src-testing/src/nodes/materialx/lib/mx_transform_color.d.ts deleted file mode 100644 index 418818d0e..000000000 --- a/src-testing/src/nodes/materialx/lib/mx_transform_color.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -import Node from "../../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../../tsl/TSLCore.js"; - -export const mx_srgb_texture_to_lin_rec709: (color_immutable: NodeRepresentation) => ShaderNodeObject; diff --git a/src-testing/src/nodes/math/ConditionalNode.d.ts b/src-testing/src/nodes/math/ConditionalNode.d.ts deleted file mode 100644 index 5313a9836..000000000 --- a/src-testing/src/nodes/math/ConditionalNode.d.ts +++ /dev/null @@ -1,39 +0,0 @@ -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -declare class ConditionalNode extends Node { - condNode: Node; - ifNode: Node; - elseNode: Node; - - constructor(condNode: Node, ifNode: Node, elseNode: Node); -} - -export default ConditionalNode; - -export const select: ( - condNode: NodeRepresentation, - ifNode: NodeRepresentation, - elseNode: NodeRepresentation, -) => ShaderNodeObject; - -declare module "../tsl/TSLCore.js" { - interface NodeElements { - select: typeof select; - } -} - -/** - * @deprecated cond() has been renamed to select() - */ -export const cond: ( - condNode: NodeRepresentation, - ifNode: NodeRepresentation, - elseNode: NodeRepresentation, -) => ShaderNodeObject; - -declare module "../tsl/TSLCore.js" { - interface NodeElements { - cond: typeof cond; - } -} diff --git a/src-testing/src/nodes/math/Hash.d.ts b/src-testing/src/nodes/math/Hash.d.ts deleted file mode 100644 index df9e81997..000000000 --- a/src-testing/src/nodes/math/Hash.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -export const hash: (seed: NodeRepresentation) => ShaderNodeObject; diff --git a/src-testing/src/nodes/math/MathNode.d.ts b/src-testing/src/nodes/math/MathNode.d.ts deleted file mode 100644 index f65546d75..000000000 --- a/src-testing/src/nodes/math/MathNode.d.ts +++ /dev/null @@ -1,273 +0,0 @@ -import Node from "../core/Node.js"; -import TempNode from "../core/TempNode.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; -import OperatorNode from "./OperatorNode.js"; - -export type MathNodeMethod1 = - | typeof MathNode.RADIANS - | typeof MathNode.DEGREES - | typeof MathNode.EXP - | typeof MathNode.EXP2 - | typeof MathNode.LOG - | typeof MathNode.LOG2 - | typeof MathNode.SQRT - | typeof MathNode.INVERSE_SQRT - | typeof MathNode.FLOOR - | typeof MathNode.CEIL - | typeof MathNode.NORMALIZE - | typeof MathNode.FRACT - | typeof MathNode.SIN - | typeof MathNode.COS - | typeof MathNode.TAN - | typeof MathNode.ASIN - | typeof MathNode.ACOS - | typeof MathNode.ATAN - | typeof MathNode.ABS - | typeof MathNode.SIGN - | typeof MathNode.LENGTH - | typeof MathNode.NEGATE - | typeof MathNode.ONE_MINUS - | typeof MathNode.DFDX - | typeof MathNode.DFDY - | typeof MathNode.ROUND - | typeof MathNode.RECIPROCAL - | typeof MathNode.TRUNC - | typeof MathNode.FWIDTH - | typeof MathNode.BITCAST - | typeof MathNode.TRANSPOSE; - -export type MathNodeMethod2 = - | typeof MathNode.ATAN2 - | typeof MathNode.MIN - | typeof MathNode.MAX - | typeof MathNode.MOD - | typeof MathNode.STEP - | typeof MathNode.REFLECT - | typeof MathNode.DISTANCE - | typeof MathNode.DOT - | typeof MathNode.CROSS - | typeof MathNode.POW - | typeof MathNode.TRANSFORM_DIRECTION; - -export type MathNodeMethod3 = - | typeof MathNode.MIX - | typeof MathNode.CLAMP - | typeof MathNode.REFRACT - | typeof MathNode.SMOOTHSTEP - | typeof MathNode.FACEFORWARD; - -export type MathNodeMethod = MathNodeMethod1 | MathNodeMethod2 | MathNodeMethod3; - -export default class MathNode extends TempNode { - // 1 input - - static ALL: "all"; - static ANY: "any"; - static EQUALS: "equals"; - - static RADIANS: "radians"; - static DEGREES: "degrees"; - static EXP: "exp"; - static EXP2: "exp2"; - static LOG: "log"; - static LOG2: "log2"; - static SQRT: "sqrt"; - static INVERSE_SQRT: "inversesqrt"; - static FLOOR: "floor"; - static CEIL: "ceil"; - static NORMALIZE: "normalize"; - static FRACT: "fract"; - static SIN: "sin"; - static COS: "cos"; - static TAN: "tan"; - static ASIN: "asin"; - static ACOS: "acos"; - static ATAN: "atan"; - static ABS: "abs"; - static SIGN: "sign"; - static LENGTH: "length"; - static NEGATE: "negate"; - static ONE_MINUS: "oneMinus"; - static DFDX: "dFdx"; - static DFDY: "dFdy"; - static ROUND: "round"; - static RECIPROCAL: "reciprocal"; - static TRUNC: "trunc"; - static FWIDTH: "fwidth"; - static BITCAST: "bitcast"; - static TRANSPOSE: "transpose"; - - // 2 inputs - - static ATAN2: "atan2"; - static MIN: "min"; - static MAX: "max"; - static MOD: "mod"; - static STEP: "step"; - static REFLECT: "reflect"; - static DISTANCE: "distance"; - static DOT: "dot"; - static CROSS: "cross"; - static POW: "pow"; - static TRANSFORM_DIRECTION: "transformDirection"; - - // 3 inputs - - static MIX: "mix"; - static CLAMP: "clamp"; - static REFRACT: "refract"; - static SMOOTHSTEP: "smoothstep"; - static FACEFORWARD: "faceforward"; - - method: MathNodeMethod; - aNode: Node; - bNode: Node | null; - cNode: Node | null; - - constructor(method: MathNodeMethod1, aNode: Node); - constructor(method: MathNodeMethod2, aNode: Node, bNode: Node); - constructor(method: MathNodeMethod3, aNode: Node, bNode: Node, cNode: Node); -} - -export const EPSILON: ShaderNodeObject; -export const INFINITY: ShaderNodeObject; -export const PI: ShaderNodeObject; -export const PI2: ShaderNodeObject; - -type Unary = (a: NodeRepresentation) => ShaderNodeObject; - -export const all: Unary; -export const any: Unary; -export const equals: Unary; - -export const radians: Unary; -export const degrees: Unary; -export const exp: Unary; -export const exp2: Unary; -export const log: Unary; -export const log2: Unary; -export const sqrt: Unary; -export const inverseSqrt: Unary; -export const floor: Unary; -export const ceil: Unary; -export const normalize: Unary; -export const fract: Unary; -export const sin: Unary; -export const cos: Unary; -export const tan: Unary; -export const asin: Unary; -export const acos: Unary; -export const atan: Unary; -export const abs: Unary; -export const sign: Unary; -export const length: Unary; -export const negate: Unary; -export const oneMinus: Unary; -export const dFdx: Unary; -export const dFdy: Unary; -export const round: Unary; -export const reciprocal: Unary; -export const trunc: Unary; -export const fwidth: Unary; -export const bitcast: Unary; -export const transpose: Unary; - -type Binary = (a: NodeRepresentation, b: NodeRepresentation) => ShaderNodeObject; - -export const atan2: Binary; -export const min: Binary; -export const max: Binary; -export const mod: Binary; -export const step: Binary; -export const reflect: Binary; -export const distance: Binary; -export const difference: Binary; -export const dot: Binary; -export const cross: Binary; -export const pow: Binary; -export const pow2: Binary; -export const pow3: Binary; -export const pow4: Binary; -export const transformDirection: Binary; - -type Ternary = (a: NodeRepresentation, b: NodeRepresentation, c: NodeRepresentation) => ShaderNodeObject; - -export const cbrt: Unary; -export const lengthSq: Unary; -export const mix: Ternary; -export const clamp: ( - a: NodeRepresentation, - b?: NodeRepresentation, - c?: NodeRepresentation, -) => ShaderNodeObject; -export const saturate: Unary; -export const refract: Ternary; -export const smoothstep: Ternary; -export const faceForward: Ternary; - -export const rand: (uv: NodeRepresentation) => ShaderNodeObject; - -export const mixElement: Ternary; -export const smoothstepElement: Ternary; - -declare module "../tsl/TSLCore.js" { - interface NodeElements { - all: typeof all; - any: typeof any; - equals: typeof equals; - radians: typeof radians; - degrees: typeof degrees; - exp: typeof exp; - exp2: typeof exp2; - log: typeof log; - log2: typeof log2; - sqrt: typeof sqrt; - inverseSqrt: typeof inverseSqrt; - floor: typeof floor; - ceil: typeof ceil; - normalize: typeof normalize; - fract: typeof fract; - sin: typeof sin; - cos: typeof cos; - tan: typeof tan; - asin: typeof asin; - acos: typeof acos; - atan: typeof atan; - abs: typeof abs; - sign: typeof sign; - length: typeof length; - lengthSq: typeof lengthSq; - negate: typeof negate; - oneMinus: typeof oneMinus; - dFdx: typeof dFdx; - dFdy: typeof dFdy; - round: typeof round; - reciprocal: typeof reciprocal; - trunc: typeof trunc; - fwidth: typeof fwidth; - atan2: typeof atan2; - min: typeof min; - max: typeof max; - mod: typeof mod; - step: typeof step; - reflect: typeof reflect; - distance: typeof distance; - dot: typeof dot; - cross: typeof cross; - pow: typeof pow; - pow2: typeof pow2; - pow3: typeof pow3; - pow4: typeof pow4; - transformDirection: typeof transformDirection; - mix: typeof mixElement; - clamp: typeof clamp; - refract: typeof refract; - smoothstep: typeof smoothstepElement; - faceForward: typeof faceForward; - difference: typeof difference; - saturate: typeof saturate; - cbrt: typeof cbrt; - transpose: typeof transpose; - rand: typeof rand; - } -} diff --git a/src-testing/src/nodes/math/MathUtils.d.ts b/src-testing/src/nodes/math/MathUtils.d.ts deleted file mode 100644 index 572d9eef5..000000000 --- a/src-testing/src/nodes/math/MathUtils.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { Binary, Ternary } from "./MathNode.js"; - -export const parabola: Binary; -export const gain: Binary; -export const pcurve: Ternary; -export const sinc: Binary; diff --git a/src-testing/src/nodes/math/OperatorNode.d.ts b/src-testing/src/nodes/math/OperatorNode.d.ts deleted file mode 100644 index 77157ea73..000000000 --- a/src-testing/src/nodes/math/OperatorNode.d.ts +++ /dev/null @@ -1,97 +0,0 @@ -import Node from "../core/Node.js"; -import TempNode from "../core/TempNode.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -export type OperatorNodeOp = - | "%" - | "&" - | "|" - | "^" - | ">>" - | "<<" - | "==" - | "&&" - | "||" - | "^^" - | "<" - | ">" - | "<=" - | ">=" - | "+" - | "-" - | "*" - | "/"; - -export default class OperatorNode extends TempNode { - aNode: Node; - bNode: Node; - op: OperatorNodeOp; - - constructor(op: OperatorNodeOp, ...params: [Node, Node, ...Node[]]); -} - -type Operator = ( - a: NodeRepresentation, - b: NodeRepresentation, - ...others: NodeRepresentation[] -) => ShaderNodeObject; - -export const add: Operator; -export const sub: Operator; -export const mul: Operator; -export const div: Operator; -export const modInt: Operator; -export const equal: Operator; -export const lessThan: Operator; -export const greaterThan: Operator; -export const lessThanEqual: Operator; -export const greaterThanEqual: Operator; -export const and: Operator; -export const or: Operator; -export const not: (a: NodeRepresentation) => ShaderNodeObject; -export const xor: Operator; -export const bitAnd: Operator; -export const bitNot: (a: NodeRepresentation) => ShaderNodeObject; -export const bitOr: Operator; -export const bitXor: Operator; -export const shiftLeft: Operator; -export const shiftRight: Operator; - -declare module "../tsl/TSLCore.js" { - interface NodeElements { - add: typeof add; - sub: typeof sub; - mul: typeof mul; - div: typeof div; - modInt: typeof modInt; - equal: typeof equal; - lessThan: typeof lessThan; - greaterThan: typeof greaterThan; - lessThanEqual: typeof lessThanEqual; - greaterThanEqual: typeof greaterThanEqual; - and: typeof and; - or: typeof or; - not: typeof not; - xor: typeof xor; - bitAnd: typeof bitAnd; - bitNot: typeof bitNot; - bitOr: typeof bitOr; - bitXor: typeof bitXor; - shiftLeft: typeof shiftLeft; - shiftRight: typeof shiftRight; - } -} - -/** - * @deprecated .remainder() has been renamed to .modInt(). - */ -export const remainder: Operator; - -declare module "../tsl/TSLCore.js" { - interface NodeElements { - /** - * @deprecated .remainder() has been renamed to .modInt(). - */ - remainder: typeof remainder; - } -} diff --git a/src-testing/src/nodes/math/TriNoise3D.d.ts b/src-testing/src/nodes/math/TriNoise3D.d.ts deleted file mode 100644 index f5220dbe6..000000000 --- a/src-testing/src/nodes/math/TriNoise3D.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -export const tri: (x: NodeRepresentation) => ShaderNodeObject; - -export const tri3: (p: NodeRepresentation) => ShaderNodeObject; - -export const triNoise3D: ( - p_immutable: NodeRepresentation, - spd: NodeRepresentation, - time: NodeRepresentation, -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/parsers/GLSLNodeFunction.d.ts b/src-testing/src/nodes/parsers/GLSLNodeFunction.d.ts deleted file mode 100644 index ec2396423..000000000 --- a/src-testing/src/nodes/parsers/GLSLNodeFunction.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import NodeFunction from "../core/NodeFunction.js"; - -declare class GLSLNodeFunction extends NodeFunction { - constructor(source: string); - - getCode(name?: string): string; -} - -export default GLSLNodeFunction; diff --git a/src-testing/src/nodes/parsers/GLSLNodeParser.d.ts b/src-testing/src/nodes/parsers/GLSLNodeParser.d.ts deleted file mode 100644 index f6b663d4b..000000000 --- a/src-testing/src/nodes/parsers/GLSLNodeParser.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import NodeParser from "../core/NodeParser.js"; -import GLSLNodeFunction from "./GLSLNodeFunction.js"; - -declare class GLSLNodeParser extends NodeParser { - parseFunction(source: string): GLSLNodeFunction; -} - -export default GLSLNodeParser; diff --git a/src-testing/src/nodes/pmrem/PMREMNode.d.ts b/src-testing/src/nodes/pmrem/PMREMNode.d.ts deleted file mode 100644 index 2a957c8e6..000000000 --- a/src-testing/src/nodes/pmrem/PMREMNode.d.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Texture } from "../../textures/Texture.js"; -import Node from "../core/Node.js"; -import TempNode from "../core/TempNode.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -declare class PMREMNode extends TempNode { - uvNode: Node | null; - levelNode: Node | null; - - constructor(value: Texture, uvNode?: Node | null, levelNode?: Node | null); - - set value(value: Texture); - get value(): Texture; -} - -export default PMREMNode; - -export const pmremTexture: ( - value: Texture, - uvNode?: NodeRepresentation, - levelNode?: NodeRepresentation, -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/pmrem/PMREMUtils.d.ts b/src-testing/src/nodes/pmrem/PMREMUtils.d.ts deleted file mode 100644 index 947e7fe25..000000000 --- a/src-testing/src/nodes/pmrem/PMREMUtils.d.ts +++ /dev/null @@ -1,28 +0,0 @@ -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -export const getDirection: (uv_immutable: NodeRepresentation, face: NodeRepresentation) => ShaderNodeObject; - -export const textureCubeUV: ( - envMap: NodeRepresentation, - sampleDir_immutable: NodeRepresentation, - roughness_immutable: NodeRepresentation, - CUBEUV_TEXEL_WIDTH: NodeRepresentation, - CUBEUV_TEXEL_HEIGHT: NodeRepresentation, - CUBEUV_MAX_MIP: NodeRepresentation, -) => ShaderNodeObject; - -export const blur: ( - n: NodeRepresentation, - latitudinal: NodeRepresentation, - poleAxis: NodeRepresentation, - outputDirection: NodeRepresentation, - weights: NodeRepresentation, - samples: NodeRepresentation, - dTheta: NodeRepresentation, - mipInt: NodeRepresentation, - envMap: NodeRepresentation, - CUBEUV_TEXEL_WIDTH: NodeRepresentation, - CUBEUV_TEXEL_HEIGHT: NodeRepresentation, - CUBEUV_MAX_MIP: NodeRepresentation, -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/procedural/Checker.d.ts b/src-testing/src/nodes/procedural/Checker.d.ts deleted file mode 100644 index af7cce3a7..000000000 --- a/src-testing/src/nodes/procedural/Checker.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -export const checker: (coord?: NodeRepresentation) => ShaderNodeObject; diff --git a/src-testing/src/nodes/tsl/TSLBase.d.ts b/src-testing/src/nodes/tsl/TSLBase.d.ts deleted file mode 100644 index 297b9a483..000000000 --- a/src-testing/src/nodes/tsl/TSLBase.d.ts +++ /dev/null @@ -1,21 +0,0 @@ -export * from "../accessors/BufferAttributeNode.js"; -export * from "../code/ExpressionNode.js"; -export * from "../code/FunctionCallNode.js"; -export * from "../core/AssignNode.js"; -export * from "../core/BypassNode.js"; -export * from "../core/CacheNode.js"; -export * from "../core/ContextNode.js"; -export * from "../core/PropertyNode.js"; -export * from "../core/UniformNode.js"; -export * from "../core/VarNode.js"; -export * from "../core/VaryingNode.js"; -export * from "../display/ColorSpaceNode.js"; -export * from "../display/RenderOutputNode.js"; -export * from "../display/ToneMappingNode.js"; -export * from "../gpgpu/ComputeNode.js"; -export * from "../math/ConditionalNode.js"; -export * from "../math/MathNode.js"; -export * from "../math/OperatorNode.js"; -export * from "../utils/Discard.js"; -export * from "../utils/RemapNode.js"; -export * from "./TSLCore.js"; diff --git a/src-testing/src/nodes/tsl/TSLCore.ts b/src-testing/src/nodes/tsl/TSLCore.ts deleted file mode 100644 index 4ac059f08..000000000 --- a/src-testing/src/nodes/tsl/TSLCore.ts +++ /dev/null @@ -1,533 +0,0 @@ -import Node from '../core/Node.js'; -import ArrayElementNode from '../utils/ArrayElementNode.js'; -import ConvertNode from '../utils/ConvertNode.js'; -import JoinNode from '../utils/JoinNode.js'; -import SplitNode from '../utils/SplitNode.js'; -import SetNode from '../utils/SetNode.js'; -import FlipNode from '../utils/FlipNode.js'; -import ConstNode from '../core/ConstNode.js'; -import { getValueFromType, getValueType } from '../core/NodeUtils.js'; - -// - -let currentStack = null; - -const NodeElements = new Map(); - -export function addMethodChaining(name, nodeElement) { - if (NodeElements.has(name)) { - console.warn(`Redefinition of method chaining ${name}`); - return; - } - - if (typeof nodeElement !== 'function') throw new Error(`Node element ${name} is not a function`); - - NodeElements.set(name, nodeElement); -} - -const parseSwizzle = props => props.replace(/r|s/g, 'x').replace(/g|t/g, 'y').replace(/b|p/g, 'z').replace(/a|q/g, 'w'); -const parseSwizzleAndSort = props => parseSwizzle(props).split('').sort().join(''); - -const shaderNodeHandler = { - setup(NodeClosure, params) { - const inputs = params.shift(); - - return NodeClosure(nodeObjects(inputs), ...params); - }, - - get(node, prop, nodeObj) { - if (typeof prop === 'string' && node[prop] === undefined) { - if (node.isStackNode !== true && prop === 'assign') { - return (...params) => { - currentStack.assign(nodeObj, ...params); - - return nodeObj; - }; - } else if (NodeElements.has(prop)) { - const nodeElement = NodeElements.get(prop); - - return node.isStackNode - ? (...params) => nodeObj.add(nodeElement(...params)) - : (...params) => nodeElement(nodeObj, ...params); - } else if (prop === 'self') { - return node; - } else if (prop.endsWith('Assign') && NodeElements.has(prop.slice(0, prop.length - 'Assign'.length))) { - const nodeElement = NodeElements.get(prop.slice(0, prop.length - 'Assign'.length)); - - return node.isStackNode - ? (...params) => nodeObj.assign(params[0], nodeElement(...params)) - : (...params) => nodeObj.assign(nodeElement(nodeObj, ...params)); - } else if (/^[xyzwrgbastpq]{1,4}$/.test(prop) === true) { - // accessing properties ( swizzle ) - - prop = parseSwizzle(prop); - - return nodeObject(new SplitNode(nodeObj, prop)); - } else if (/^set[XYZWRGBASTPQ]{1,4}$/.test(prop) === true) { - // set properties ( swizzle ) and sort to xyzw sequence - - prop = parseSwizzleAndSort(prop.slice(3).toLowerCase()); - - return value => nodeObject(new SetNode(node, prop, value)); - } else if (/^flip[XYZWRGBASTPQ]{1,4}$/.test(prop) === true) { - // set properties ( swizzle ) and sort to xyzw sequence - - prop = parseSwizzleAndSort(prop.slice(4).toLowerCase()); - - return () => nodeObject(new FlipNode(nodeObject(node), prop)); - } else if (prop === 'width' || prop === 'height' || prop === 'depth') { - // accessing property - - if (prop === 'width') prop = 'x'; - else if (prop === 'height') prop = 'y'; - else if (prop === 'depth') prop = 'z'; - - return nodeObject(new SplitNode(node, prop)); - } else if (/^\d+$/.test(prop) === true) { - // accessing array - - return nodeObject(new ArrayElementNode(nodeObj, new ConstNode(Number(prop), 'uint'))); - } - } - - return Reflect.get(node, prop, nodeObj); - }, - - set(node, prop, value, nodeObj) { - if (typeof prop === 'string' && node[prop] === undefined) { - // setting properties - - if ( - /^[xyzwrgbastpq]{1,4}$/.test(prop) === true || - prop === 'width' || - prop === 'height' || - prop === 'depth' || - /^\d+$/.test(prop) === true - ) { - nodeObj[prop].assign(value); - - return true; - } - } - - return Reflect.set(node, prop, value, nodeObj); - }, -}; - -const nodeObjectsCacheMap = new WeakMap(); -const nodeBuilderFunctionsCacheMap = new WeakMap(); - -const ShaderNodeObject = function (obj, altType = null) { - const type = getValueType(obj); - - if (type === 'node') { - let nodeObject = nodeObjectsCacheMap.get(obj); - - if (nodeObject === undefined) { - nodeObject = new Proxy(obj, shaderNodeHandler); - - nodeObjectsCacheMap.set(obj, nodeObject); - nodeObjectsCacheMap.set(nodeObject, nodeObject); - } - - return nodeObject; - } else if ( - (altType === null && (type === 'float' || type === 'boolean')) || - (type && type !== 'shader' && type !== 'string') - ) { - return nodeObject(getConstNode(obj, altType)); - } else if (type === 'shader') { - return Fn(obj); - } - - return obj; -}; - -const ShaderNodeObjects = function (objects, altType = null) { - for (const name in objects) { - objects[name] = nodeObject(objects[name], altType); - } - - return objects; -}; - -const ShaderNodeArray = function (array, altType = null) { - const len = array.length; - - for (let i = 0; i < len; i++) { - array[i] = nodeObject(array[i], altType); - } - - return array; -}; - -const ShaderNodeProxy = function (NodeClass, scope = null, factor = null, settings = null) { - const assignNode = node => nodeObject(settings !== null ? Object.assign(node, settings) : node); - - if (scope === null) { - return (...params) => { - return assignNode(new NodeClass(...nodeArray(params))); - }; - } else if (factor !== null) { - factor = nodeObject(factor); - - return (...params) => { - return assignNode(new NodeClass(scope, ...nodeArray(params), factor)); - }; - } else { - return (...params) => { - return assignNode(new NodeClass(scope, ...nodeArray(params))); - }; - } -}; - -const ShaderNodeImmutable = function (NodeClass, ...params) { - return nodeObject(new NodeClass(...nodeArray(params))); -}; - -class ShaderCallNodeInternal extends Node { - constructor(shaderNode, inputNodes) { - super(); - - this.shaderNode = shaderNode; - this.inputNodes = inputNodes; - } - - getNodeType(builder) { - return this.shaderNode.nodeType || this.getOutputNode(builder).getNodeType(builder); - } - - call(builder) { - const { shaderNode, inputNodes } = this; - - const properties = builder.getNodeProperties(shaderNode); - if (properties.onceOutput) return properties.onceOutput; - - // - - let result = null; - - if (shaderNode.layout) { - let functionNodesCacheMap = nodeBuilderFunctionsCacheMap.get(builder.constructor); - - if (functionNodesCacheMap === undefined) { - functionNodesCacheMap = new WeakMap(); - - nodeBuilderFunctionsCacheMap.set(builder.constructor, functionNodesCacheMap); - } - - let functionNode = functionNodesCacheMap.get(shaderNode); - - if (functionNode === undefined) { - functionNode = nodeObject(builder.buildFunctionNode(shaderNode)); - - functionNodesCacheMap.set(shaderNode, functionNode); - } - - if (builder.currentFunctionNode !== null) { - builder.currentFunctionNode.includes.push(functionNode); - } - - result = nodeObject(functionNode.call(inputNodes)); - } else { - const jsFunc = shaderNode.jsFunc; - const outputNode = inputNodes !== null ? jsFunc(inputNodes, builder) : jsFunc(builder); - - result = nodeObject(outputNode); - } - - if (shaderNode.once) { - properties.onceOutput = result; - } - - return result; - } - - getOutputNode(builder) { - const properties = builder.getNodeProperties(this); - - if (properties.outputNode === null) { - properties.outputNode = this.setupOutput(builder); - } - - return properties.outputNode; - } - - setup(builder) { - return this.getOutputNode(builder); - } - - setupOutput(builder) { - builder.addStack(); - - builder.stack.outputNode = this.call(builder); - - return builder.removeStack(); - } - - generate(builder, output) { - const outputNode = this.getOutputNode(builder); - - return outputNode.build(builder, output); - } -} - -class ShaderNodeInternal extends Node { - constructor(jsFunc, nodeType) { - super(nodeType); - - this.jsFunc = jsFunc; - this.layout = null; - - this.global = true; - - this.once = false; - } - - setLayout(layout) { - this.layout = layout; - - return this; - } - - call(inputs = null) { - nodeObjects(inputs); - - return nodeObject(new ShaderCallNodeInternal(this, inputs)); - } - - setup() { - return this.call(); - } -} - -const bools = [false, true]; -const uints = [0, 1, 2, 3]; -const ints = [-1, -2]; -const floats = [ - 0.5, - 1.5, - 1 / 3, - 1e-6, - 1e6, - Math.PI, - Math.PI * 2, - 1 / Math.PI, - 2 / Math.PI, - 1 / (Math.PI * 2), - Math.PI / 2, -]; - -const boolsCacheMap = new Map(); -for (const bool of bools) boolsCacheMap.set(bool, new ConstNode(bool)); - -const uintsCacheMap = new Map(); -for (const uint of uints) uintsCacheMap.set(uint, new ConstNode(uint, 'uint')); - -const intsCacheMap = new Map([...uintsCacheMap].map(el => new ConstNode(el.value, 'int'))); -for (const int of ints) intsCacheMap.set(int, new ConstNode(int, 'int')); - -const floatsCacheMap = new Map([...intsCacheMap].map(el => new ConstNode(el.value))); -for (const float of floats) floatsCacheMap.set(float, new ConstNode(float)); -for (const float of floats) floatsCacheMap.set(-float, new ConstNode(-float)); - -const cacheMaps = { bool: boolsCacheMap, uint: uintsCacheMap, ints: intsCacheMap, float: floatsCacheMap }; - -const constNodesCacheMap = new Map([...boolsCacheMap, ...floatsCacheMap]); - -const getConstNode = (value, type) => { - if (constNodesCacheMap.has(value)) { - return constNodesCacheMap.get(value); - } else if (value.isNode === true) { - return value; - } else { - return new ConstNode(value, type); - } -}; - -const safeGetNodeType = node => { - try { - return node.getNodeType(); - } catch (_) { - return undefined; - } -}; - -const ConvertType = function (type, cacheMap = null) { - return (...params) => { - if ( - params.length === 0 || - (!['bool', 'float', 'int', 'uint'].includes(type) && params.every(param => typeof param !== 'object')) - ) { - params = [getValueFromType(type, ...params)]; - } - - if (params.length === 1 && cacheMap !== null && cacheMap.has(params[0])) { - return nodeObject(cacheMap.get(params[0])); - } - - if (params.length === 1) { - const node = getConstNode(params[0], type); - if (safeGetNodeType(node) === type) return nodeObject(node); - return nodeObject(new ConvertNode(node, type)); - } - - const nodes = params.map(param => getConstNode(param)); - return nodeObject(new JoinNode(nodes, type)); - }; -}; - -// exports - -export const defined = v => (typeof v === 'object' && v !== null ? v.value : v); // TODO: remove boolean conversion and defined function - -// utils - -export const getConstNodeType = value => - value !== undefined && value !== null - ? value.nodeType || value.convertTo || (typeof value === 'string' ? value : null) - : null; - -// shader node base - -export function ShaderNode(jsFunc, nodeType) { - return new Proxy(new ShaderNodeInternal(jsFunc, nodeType), shaderNodeHandler); -} - -export const nodeObject = (val, altType = null) => /* new */ ShaderNodeObject(val, altType); -export const nodeObjects = (val, altType = null) => new ShaderNodeObjects(val, altType); -export const nodeArray = (val, altType = null) => new ShaderNodeArray(val, altType); -export const nodeProxy = (...params) => new ShaderNodeProxy(...params); -export const nodeImmutable = (...params) => new ShaderNodeImmutable(...params); - -export const Fn = (jsFunc, nodeType) => { - const shaderNode = new ShaderNode(jsFunc, nodeType); - - const fn = (...params) => { - let inputs; - - nodeObjects(params); - - if (params[0] && params[0].isNode) { - inputs = [...params]; - } else { - inputs = params[0]; - } - - return shaderNode.call(inputs); - }; - - fn.shaderNode = shaderNode; - - fn.setLayout = layout => { - shaderNode.setLayout(layout); - - return fn; - }; - - fn.once = () => { - shaderNode.once = true; - - return fn; - }; - - return fn; -}; - -export const tslFn = (...params) => { - // @deprecated, r168 - - console.warn('TSL.ShaderNode: tslFn() has been renamed to Fn().'); - return Fn(...params); -}; - -// - -addMethodChaining('toGlobal', node => { - node.global = true; - - return node; -}); - -// - -export const setCurrentStack = stack => { - if (currentStack === stack) { - //throw new Error( 'Stack already defined.' ); - } - - currentStack = stack; -}; - -export const getCurrentStack = () => currentStack; - -export const If = (...params) => currentStack.If(...params); - -export function append(node) { - if (currentStack) currentStack.add(node); - - return node; -} - -addMethodChaining('append', append); - -// types - -export const color = new ConvertType('color'); - -export const float = new ConvertType('float', cacheMaps.float); -export const int = new ConvertType('int', cacheMaps.ints); -export const uint = new ConvertType('uint', cacheMaps.uint); -export const bool = new ConvertType('bool', cacheMaps.bool); - -export const vec2 = new ConvertType('vec2'); -export const ivec2 = new ConvertType('ivec2'); -export const uvec2 = new ConvertType('uvec2'); -export const bvec2 = new ConvertType('bvec2'); - -export const vec3 = new ConvertType('vec3'); -export const ivec3 = new ConvertType('ivec3'); -export const uvec3 = new ConvertType('uvec3'); -export const bvec3 = new ConvertType('bvec3'); - -export const vec4 = new ConvertType('vec4'); -export const ivec4 = new ConvertType('ivec4'); -export const uvec4 = new ConvertType('uvec4'); -export const bvec4 = new ConvertType('bvec4'); - -export const mat2 = new ConvertType('mat2'); -export const mat3 = new ConvertType('mat3'); -export const mat4 = new ConvertType('mat4'); - -export const string = (value = '') => nodeObject(new ConstNode(value, 'string')); -export const arrayBuffer = value => nodeObject(new ConstNode(value, 'ArrayBuffer')); - -addMethodChaining('toColor', color); -addMethodChaining('toFloat', float); -addMethodChaining('toInt', int); -addMethodChaining('toUint', uint); -addMethodChaining('toBool', bool); -addMethodChaining('toVec2', vec2); -addMethodChaining('toIVec2', ivec2); -addMethodChaining('toUVec2', uvec2); -addMethodChaining('toBVec2', bvec2); -addMethodChaining('toVec3', vec3); -addMethodChaining('toIVec3', ivec3); -addMethodChaining('toUVec3', uvec3); -addMethodChaining('toBVec3', bvec3); -addMethodChaining('toVec4', vec4); -addMethodChaining('toIVec4', ivec4); -addMethodChaining('toUVec4', uvec4); -addMethodChaining('toBVec4', bvec4); -addMethodChaining('toMat2', mat2); -addMethodChaining('toMat3', mat3); -addMethodChaining('toMat4', mat4); - -// basic nodes - -export const element = /*@__PURE__*/ nodeProxy(ArrayElementNode); -export const convert = (node, types) => nodeObject(new ConvertNode(nodeObject(node), types)); -export const split = (node, channels) => nodeObject(new SplitNode(nodeObject(node), channels)); - -addMethodChaining('element', element); -addMethodChaining('convert', convert); diff --git a/src-testing/src/nodes/utils/ArrayElementNode.d.ts b/src-testing/src/nodes/utils/ArrayElementNode.d.ts deleted file mode 100644 index 650f04047..000000000 --- a/src-testing/src/nodes/utils/ArrayElementNode.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import Node from "../core/Node.js"; -import { TempNode } from "../Nodes.js"; - -export default class ArrayElementNode extends TempNode { - node: Node; - indexNode: Node; - - constructor(node: Node, indexNode: Node); -} diff --git a/src-testing/src/nodes/utils/ConvertNode.d.ts b/src-testing/src/nodes/utils/ConvertNode.d.ts deleted file mode 100644 index 7972df608..000000000 --- a/src-testing/src/nodes/utils/ConvertNode.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -import Node from "../core/Node.js"; - -export default class ConvertNode extends Node { - node: Node; - convertTo: string; - constructor(node: Node, convertTo: string); -} diff --git a/src-testing/src/nodes/utils/CubeMapNode.d.ts b/src-testing/src/nodes/utils/CubeMapNode.d.ts deleted file mode 100644 index 6a5c47371..000000000 --- a/src-testing/src/nodes/utils/CubeMapNode.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -import Node from "../core/Node.js"; -import TempNode from "../core/TempNode.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -declare class CubeMapNode extends TempNode { - envNode: Node; - - constructor(envNode: Node); -} - -export default CubeMapNode; - -export const cubeMapNode: (envNode: NodeRepresentation) => ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/Discard.d.ts b/src-testing/src/nodes/utils/Discard.d.ts deleted file mode 100644 index 819c009b1..000000000 --- a/src-testing/src/nodes/utils/Discard.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -export const Discard: (conditional?: NodeRepresentation) => ShaderNodeObject; -export const Return: () => ShaderNodeObject; - -declare module "../tsl/TSLCore.js" { - interface NodeElements { - discard: typeof Discard; - } -} diff --git a/src-testing/src/nodes/utils/EquirectUVNode.d.ts b/src-testing/src/nodes/utils/EquirectUVNode.d.ts deleted file mode 100644 index 4e85dc40e..000000000 --- a/src-testing/src/nodes/utils/EquirectUVNode.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Node, TempNode } from "../Nodes.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -export default class EquirectUVNode extends TempNode { - constructor(dirNode?: ShaderNodeObject); -} - -export const equirectUV: ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/FunctionOverloadingNode.d.ts b/src-testing/src/nodes/utils/FunctionOverloadingNode.d.ts deleted file mode 100644 index d7c3febb4..000000000 --- a/src-testing/src/nodes/utils/FunctionOverloadingNode.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -import Node from "../core/Node.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -declare class FunctionOverloadingNode extends Node { - functionNodes: Node[]; - parameterNodes: Node[]; - - constructor(functionNodes?: Node[], ...parameterNodes: Node[]); -} - -export default FunctionOverloadingNode; - -export const overloadingFn: (functionNodes: Node[]) => (...params: Node[]) => ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/JoinNode.d.ts b/src-testing/src/nodes/utils/JoinNode.d.ts deleted file mode 100644 index 7f456bafa..000000000 --- a/src-testing/src/nodes/utils/JoinNode.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import Node from "../core/Node.js"; -import { TempNode } from "../Nodes.js"; - -/** - * This node constructs given type from elements, like vec3(a,b,c) - */ -export default class JoinNode extends TempNode { - nodes: Node[]; - constructor(nodes: Node[]); -} diff --git a/src-testing/src/nodes/utils/LoopNode.d.ts b/src-testing/src/nodes/utils/LoopNode.d.ts deleted file mode 100644 index d59518588..000000000 --- a/src-testing/src/nodes/utils/LoopNode.d.ts +++ /dev/null @@ -1,22 +0,0 @@ -import Node from "../core/Node.js"; -import NodeBuilder from "../core/NodeBuilder.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -declare class LoopNode extends Node { - params: unknown[]; - - constructor(params?: unknown[]); - - getProperties(builder: NodeBuilder): unknown; -} - -export default LoopNode; - -export const Loop: (...params: unknown[]) => ShaderNodeObject; -export const Continue: () => ShaderNodeObject; -export const Break: () => ShaderNodeObject; - -/** - * @deprecated loop() has been renamed to Loop() - */ -export const loop: (...params: unknown[]) => ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/MatcapUVNode.d.ts b/src-testing/src/nodes/utils/MatcapUVNode.d.ts deleted file mode 100644 index 7f56667b3..000000000 --- a/src-testing/src/nodes/utils/MatcapUVNode.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import TempNode from "../core/TempNode.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -export default class MatcapUVNode extends TempNode { - constructor(); -} - -export const matcapUV: ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/MaxMipLevelNode.d.ts b/src-testing/src/nodes/utils/MaxMipLevelNode.d.ts deleted file mode 100644 index 455cb77a5..000000000 --- a/src-testing/src/nodes/utils/MaxMipLevelNode.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Texture } from "../../textures/Texture.js"; -import TextureNode from "../accessors/TextureNode.js"; -import UniformNode from "../core/UniformNode.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -export default class MaxMipLevelNode extends UniformNode<0> { - constructor(textureNode: TextureNode); - - get textureNode(): TextureNode; - - get texture(): Texture; -} - -export const maxMipLevel: (texture: Texture) => ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/Oscillators.d.ts b/src-testing/src/nodes/utils/Oscillators.d.ts deleted file mode 100644 index b1a196d43..000000000 --- a/src-testing/src/nodes/utils/Oscillators.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -export const oscSine: (timeNode?: NodeRepresentation) => ShaderNodeObject; -export const oscSquare: (timeNode?: NodeRepresentation) => ShaderNodeObject; -export const oscTriangle: (timeNode?: NodeRepresentation) => ShaderNodeObject; -export const oscSawtooth: (timeNode?: NodeRepresentation) => ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/Packing.d.ts b/src-testing/src/nodes/utils/Packing.d.ts deleted file mode 100644 index 61d0d039e..000000000 --- a/src-testing/src/nodes/utils/Packing.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -export const directionToColor: (node: NodeRepresentation) => ShaderNodeObject; -export const colorToDirection: (node: NodeRepresentation) => ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/PostProcessingUtils.d.ts b/src-testing/src/nodes/utils/PostProcessingUtils.d.ts deleted file mode 100644 index 0406e4d77..000000000 --- a/src-testing/src/nodes/utils/PostProcessingUtils.d.ts +++ /dev/null @@ -1,45 +0,0 @@ -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -/** - * Computes a position in view space based on a fragment's screen position expressed as uv coordinates, the fragments - * depth value and the camera's inverse projection matrix. - * - * @param {vec2} screenPosition - The fragment's screen position expressed as uv coordinates. - * @param {float} depth - The fragment's depth value. - * @param {mat4} projectionMatrixInverse - The camera's inverse projection matrix. - * @return {vec3} The fragments position in view space. - */ -export const getViewPosition: ( - screenPosition: NodeRepresentation, - depth: NodeRepresentation, - projectionMatrixInverse: NodeRepresentation, -) => ShaderNodeObject; - -/** - * Computes a screen position expressed as uv coordinates based on a fragment's position in view space and the camera's - * projection matrix - * - * @param {vec3} viewPosition - The fragments position in view space. - * @param {mat4} projectionMatrix - The camera's projection matrix. - * @return {vec2} The fragment's screen position expressed as uv coordinates. - */ -export const getScreenPosition: ( - viewPosition: NodeRepresentation, - projectionMatrix: NodeRepresentation, -) => ShaderNodeObject; - -/** - * Computes a normal vector based on depth data. Can be used as a fallback when no normal render target is available or - * if flat surface normals are required. - * - * @param {vec2} uv - The texture coordinate. - * @param {DepthTexture} depthTexture - The depth texture. - * @param {mat4} projectionMatrixInverse - The camera's inverse projection matrix. - * @return {vec3} The computed normal vector. - */ -export const getNormalFromDepth: ( - uv: NodeRepresentation, - depthTexture: NodeRepresentation, - projectionMatrixInverse: NodeRepresentation, -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/RTTNode.d.ts b/src-testing/src/nodes/utils/RTTNode.d.ts deleted file mode 100644 index 9f0d3e46e..000000000 --- a/src-testing/src/nodes/utils/RTTNode.d.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { TextureDataType } from "../../constants.js"; -import { RenderTarget } from "../../core/RenderTarget.js"; -import TextureNode from "../accessors/TextureNode.js"; -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -export interface RTTNodeOptions { - type: TextureDataType; -} - -declare class RTTNode extends TextureNode { - node: Node; - width: number | null; - height: number | null; - - renderTarget: RenderTarget | null; - - textureNeedsUpdate: boolean; - autoUpdate: boolean; - - pixelRatio?: number; - - constructor(node: Node, width?: number | null, height?: number | null, options?: RTTNodeOptions); - - get autoSize(): boolean; - - setSize(width: number | null, height: number | null): void; - - setPixelRatio(pixelRatio: number): void; -} - -export default RTTNode; - -export const rtt: ( - node: NodeRepresentation, - width?: number | null, - height?: number | null, - options?: RTTNodeOptions, -) => ShaderNodeObject; -export const convertToTexture: ( - node: Node, - width?: number | null, - height?: number | null, - options?: RTTNodeOptions, -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/ReflectorNode.d.ts b/src-testing/src/nodes/utils/ReflectorNode.d.ts deleted file mode 100644 index 54cd9abfc..000000000 --- a/src-testing/src/nodes/utils/ReflectorNode.d.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { Camera } from "../../cameras/Camera.js"; -import { Object3D } from "../../core/Object3D.js"; -import { RenderTarget } from "../../core/RenderTarget.js"; -import TextureNode from "../accessors/TextureNode.js"; -import Node from "../core/Node.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -export interface ReflectorNodeParameters { - target?: Object3D | undefined; - resolution?: number | undefined; - generateMipmaps?: boolean | undefined; - bounces?: boolean | undefined; -} - -declare class ReflectorNode extends TextureNode { - constructor(parameters?: ReflectorNodeParameters); - - get reflector(): ReflectorBaseNode; - - get target(): Object3D; - - getDepthNode(): ShaderNodeObject; -} - -declare class ReflectorBaseNode extends Node { - textureNode: TextureNode; - - target: Object3D; - resolution: number; - generateMipmaps: boolean; - bounces: boolean; - - virtualCameras: WeakMap; - renderTargets: WeakMap; - - constructor(textureNode: TextureNode, parameters?: ReflectorNodeParameters); - - getVirtualCamera(camera: Camera): Camera; - - getRenderTarget(camera: Camera): RenderTarget; -} - -export const reflector: (parameters?: ReflectorNodeParameters) => ShaderNodeObject; - -export default ReflectorNode; diff --git a/src-testing/src/nodes/utils/RemapNode.d.ts b/src-testing/src/nodes/utils/RemapNode.d.ts deleted file mode 100644 index e50456d0a..000000000 --- a/src-testing/src/nodes/utils/RemapNode.d.ts +++ /dev/null @@ -1,36 +0,0 @@ -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -export default class RemapNode extends Node { - node: Node; - inLowNode: Node; - inHighNode: Node; - outLowNode: Node; - outHighNode: Node; - - doClamp: boolean; - - constructor(node: Node, inLowNode: Node, inHighNode: Node, outLowNode?: Node, outHighNode?: Node); -} - -export const remap: ( - node: Node, - inLowNode: NodeRepresentation, - inHighNode: NodeRepresentation, - outLowNode?: NodeRepresentation, - outHighNode?: NodeRepresentation, -) => ShaderNodeObject; -export const remapClamp: ( - node: Node, - inLowNode: NodeRepresentation, - inHighNode: NodeRepresentation, - outLowNode?: NodeRepresentation, - outHighNode?: NodeRepresentation, -) => ShaderNodeObject; - -declare module "../tsl/TSLCore.js" { - interface NodeElements { - remap: typeof remap; - remapClamp: typeof remapClamp; - } -} diff --git a/src-testing/src/nodes/utils/RotateNode.d.ts b/src-testing/src/nodes/utils/RotateNode.d.ts deleted file mode 100644 index 8f6df796a..000000000 --- a/src-testing/src/nodes/utils/RotateNode.d.ts +++ /dev/null @@ -1,15 +0,0 @@ -import Node from "../core/Node.js"; -import TempNode from "../core/TempNode.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -export default class RotateNode extends TempNode { - positionNode: Node; - rotationNode: Node; - - constructor(positionNode: Node, rotationNode: Node); -} - -export const rotate: ( - positionNode: NodeRepresentation, - rotationNode: NodeRepresentation, -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/SetNode.d.ts b/src-testing/src/nodes/utils/SetNode.d.ts deleted file mode 100644 index 7124d46c3..000000000 --- a/src-testing/src/nodes/utils/SetNode.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -import TempNode from "../core/TempNode.js"; - -declare class SetNode extends TempNode { - sourceNode: Node; - components: string[]; - targetNode: Node; - - constructor(sourceNode: Node, components: string[], targetNode: Node); -} - -export default SetNode; diff --git a/src-testing/src/nodes/utils/SplitNode.d.ts b/src-testing/src/nodes/utils/SplitNode.d.ts deleted file mode 100644 index f3aa50f41..000000000 --- a/src-testing/src/nodes/utils/SplitNode.d.ts +++ /dev/null @@ -1,15 +0,0 @@ -import Node from "../core/Node.js"; -import { SwizzleOption } from "../tsl/TSLCore.js"; - -/** swizzle node */ -export default class SplitNode extends Node { - node: Node; - components: string; - - /** - * @param node the input node - * @param components swizzle like string, default = "x" - */ - constructor(node: Node, components?: SwizzleOption); - getVectorLength(): number; -} diff --git a/src-testing/src/nodes/utils/SpriteSheetUVNode.d.ts b/src-testing/src/nodes/utils/SpriteSheetUVNode.d.ts deleted file mode 100644 index 9e191a390..000000000 --- a/src-testing/src/nodes/utils/SpriteSheetUVNode.d.ts +++ /dev/null @@ -1,16 +0,0 @@ -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -export default class SpriteSheetUVNode extends Node { - countNode: Node; - uvNode: Node; - frameNode: Node; - - constructor(countNode: Node, uvNode?: Node, frameNode?: Node); -} - -export const spritesheetUV: ( - countNode: NodeRepresentation, - uvNode?: NodeRepresentation, - frameNode?: NodeRepresentation, -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/SpriteUtils.d.ts b/src-testing/src/nodes/utils/SpriteUtils.d.ts deleted file mode 100644 index 85884df7b..000000000 --- a/src-testing/src/nodes/utils/SpriteUtils.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -export const billboarding: ( - args?: { position?: NodeRepresentation | null; horizontal?: boolean; vertical?: boolean }, -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/StorageArrayElementNode.d.ts b/src-testing/src/nodes/utils/StorageArrayElementNode.d.ts deleted file mode 100644 index 53ff9a79a..000000000 --- a/src-testing/src/nodes/utils/StorageArrayElementNode.d.ts +++ /dev/null @@ -1,19 +0,0 @@ -import StorageBufferNode from "../accessors/StorageBufferNode.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; -import ArrayElementNode from "./ArrayElementNode.js"; - -export default class StorageArrayElementNode extends ArrayElementNode { - node: StorageBufferNode; - - readonly isStorageArrayElementNode: true; - - constructor(storageBufferNode: StorageBufferNode, indexNode: Node); - - get storageBufferNode(): StorageBufferNode; - set storageBufferNode(value: StorageBufferNode); -} - -export const storageElement: ( - storageBufferNode: NodeRepresentation, - indexNode: NodeRepresentation, -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/Timer.d.ts b/src-testing/src/nodes/utils/Timer.d.ts deleted file mode 100644 index ffad3ed7f..000000000 --- a/src-testing/src/nodes/utils/Timer.d.ts +++ /dev/null @@ -1,21 +0,0 @@ -import Node from "../core/Node.js"; -import { ShaderNodeObject } from "../tsl/TSLCore.js"; - -export const time: ShaderNodeObject; -export const deltaTime: ShaderNodeObject; -export const frameId: ShaderNodeObject; - -/** - * @deprecated Use "time" instead. - */ -export const timerLocal: (timeScale?: number) => ShaderNodeObject; - -/** - * @deprecated Use "time" instead. - */ -export const timerGlobal: (timeScale?: number) => ShaderNodeObject; - -/** - * @deprecated Use "deltaTime" instead. - */ -export const timerDelta: (timeScale?: number) => ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/TriplanarTexturesNode.d.ts b/src-testing/src/nodes/utils/TriplanarTexturesNode.d.ts deleted file mode 100644 index 1f2875c26..000000000 --- a/src-testing/src/nodes/utils/TriplanarTexturesNode.d.ts +++ /dev/null @@ -1,36 +0,0 @@ -import TextureNode from "../accessors/TextureNode.js"; -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -export default class TriplanarTexturesNode extends Node { - textureXNode: TextureNode; - textureYNode: TextureNode | null; - textureZNode: TextureNode | null; - - scaleNode: ShaderNodeObject; - - positionNode: ShaderNodeObject; - normalNode: ShaderNodeObject; - - constructor( - textureXNode: Node, - textureYNode?: TextureNode | null, - textureZNode?: TextureNode | null, - scaleNode?: ShaderNodeObject, - positionNode?: ShaderNodeObject, - normalNode?: ShaderNodeObject, - ); -} - -export const triplanarTextures: ( - textureXNode: NodeRepresentation, - textureYNode?: NodeRepresentation, - textureZNode?: NodeRepresentation, - scaleNode?: NodeRepresentation, - positionNode?: NodeRepresentation, - normalNode?: NodeRepresentation, -) => ShaderNodeObject; -export const triplanarTexture: ( - texture: NodeRepresentation, - ...params: NodeRepresentation[] -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/UVUtils.d.ts b/src-testing/src/nodes/utils/UVUtils.d.ts deleted file mode 100644 index d375e1e11..000000000 --- a/src-testing/src/nodes/utils/UVUtils.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -import OperatorNode from "../math/OperatorNode.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -export const rotateUV: ( - uv: NodeRepresentation, - rotation: NodeRepresentation, - center?: NodeRepresentation, -) => ShaderNodeObject; - -export const spherizeUV: ( - uv: NodeRepresentation, - strength: NodeRepresentation, - center?: NodeRepresentation, -) => ShaderNodeObject; diff --git a/src-testing/src/nodes/utils/ViewportUtils.d.ts b/src-testing/src/nodes/utils/ViewportUtils.d.ts deleted file mode 100644 index e77e7f350..000000000 --- a/src-testing/src/nodes/utils/ViewportUtils.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -import Node from "../core/Node.js"; -import { NodeRepresentation, ShaderNodeObject } from "../tsl/TSLCore.js"; - -export const viewportSafeUV: (uv?: NodeRepresentation | null) => ShaderNodeObject; diff --git a/src-testing/src/objects/BatchedMesh.d.ts b/src-testing/src/objects/BatchedMesh.d.ts deleted file mode 100644 index 84044f00b..000000000 --- a/src-testing/src/objects/BatchedMesh.d.ts +++ /dev/null @@ -1,275 +0,0 @@ -import { Camera } from "../cameras/Camera.js"; -import { BufferGeometry } from "../core/BufferGeometry.js"; -import { Material } from "../materials/Material.js"; -import { Box3 } from "../math/Box3.js"; -import { Color } from "../math/Color.js"; -import { Matrix4 } from "../math/Matrix4.js"; -import { Sphere } from "../math/Sphere.js"; -import { Mesh } from "./Mesh.js"; - -export interface BatchedMeshGeometryRange { - vertexStart: number; - vertexCount: number; - reservedVertexCount: number; - indexStart: number; - indexCount: number; - reservedIndexCount: number; - start: number; - count: number; -} - -/** - * A special version of {@link Mesh} with multi draw batch rendering support. Use {@link BatchedMesh} if you have to - * render a large number of objects with the same material but with different world transformations. The usage of - * {@link BatchedMesh} will help you to reduce the number of draw calls and thus improve the overall rendering - * performance in your application. - * - * If the {@link https://developer.mozilla.org/en-US/docs/Web/API/WEBGL_multi_draw WEBGL_multi_draw extension} is not - * supported then a less performant fallback is used. - * - * @example - * const box = new THREE.BoxGeometry( 1, 1, 1 ); - * const sphere = new THREE.SphereGeometry( 1, 12, 12 ); - * const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } ); - * - * // initialize and add geometries into the batched mesh - * const batchedMesh = new BatchedMesh( 10, 5000, 10000, material ); - * const boxGeometryId = batchedMesh.addGeometry( box ); - * const sphereGeometryId = batchedMesh.addGeometry( sphere ); - * - * // create instances of those geometries - * const boxInstancedId1 = batchedMesh.addInstance( boxGeometryId ); - * const boxInstancedId2 = batchedMesh.addInstance( boxGeometryId ); - * - * const sphereInstancedId1 = batchedMesh.addInstance( sphereGeometryId ); - * const sphereInstancedId2 = batchedMesh.addInstance( sphereGeometryId ); - * - * // position the geometries - * batchedMesh.setMatrixAt( boxInstancedId1, boxMatrix1 ); - * batchedMesh.setMatrixAt( boxInstancedId2, boxMatrix2 ); - * - * batchedMesh.setMatrixAt( sphereInstancedId1, sphereMatrix1 ); - * batchedMesh.setMatrixAt( sphereInstancedId2, sphereMatrix2 ); - * - * scene.add( batchedMesh ); - * - * @also Example: {@link https://threejs.org/examples/#webgl_mesh_batch WebGL / mesh / batch} - */ -declare class BatchedMesh extends Mesh { - /** - * This bounding box encloses all instances of the {@link BatchedMesh}. Can be calculated with - * {@link .computeBoundingBox()}. - * @default null - */ - boundingBox: Box3 | null; - - /** - * This bounding sphere encloses all instances of the {@link BatchedMesh}. Can be calculated with - * {@link .computeBoundingSphere()}. - * @default null - */ - boundingSphere: Sphere | null; - - customSort: ((this: this, list: Array<{ start: number; count: number; z: number }>, camera: Camera) => void) | null; - - /** - * If true then the individual objects within the {@link BatchedMesh} are frustum culled. - * @default true - */ - perObjectFrustumCulled: boolean; - - /** - * If true then the individual objects within the {@link BatchedMesh} are sorted to improve overdraw-related - * artifacts. If the material is marked as "transparent" objects are rendered back to front and if not then they are - * rendered front to back. - * @default true - */ - sortObjects: boolean; - - /** - * The maximum number of individual geometries that can be stored in the {@link BatchedMesh}. Read only. - */ - get maxInstanceCount(): number; - - get instanceCount(): number; - - get unusedVertexCount(): number; - - get unusedIndexCount(): number; - - /** - * Read-only flag to check if a given object is of type {@link BatchedMesh}. - */ - readonly isBatchedMesh: true; - - /** - * @param maxInstanceCount the max number of individual geometries planned to be added. - * @param maxVertexCount the max number of vertices to be used by all geometries. - * @param maxIndexCount the max number of indices to be used by all geometries. - * @param material an instance of {@link Material}. Default is a new {@link MeshBasicMaterial}. - */ - constructor(maxInstanceCount: number, maxVertexCount: number, maxIndexCount?: number, material?: Material); - - /** - * Computes the bounding box, updating {@link .boundingBox} attribute. - * Bounding boxes aren't computed by default. They need to be explicitly computed, otherwise they are `null`. - */ - computeBoundingBox(): void; - - /** - * Computes the bounding sphere, updating {@link .boundingSphere} attribute. - * Bounding spheres aren't computed by default. They need to be explicitly computed, otherwise they are `null`. - */ - computeBoundingSphere(): void; - - /** - * Frees the GPU-related resources allocated by this instance. Call this method whenever this instance is no longer - * used in your app. - */ - dispose(): this; - - /** - * Takes a sort a function that is run before render. The function takes a list of instances to sort and a camera. - * The objects in the list include a "z" field to perform a depth-ordered sort with. - */ - setCustomSort( - sortFunction: - | ((this: this, list: Array<{ start: number; count: number; z: number }>, camera: Camera) => void) - | null, - ): this; - - /** - * Get the color of the defined geometry. - * @param instanceId The id of an instance to get the color of. - * @param target The target object to copy the color in to. - */ - getColorAt(instanceId: number, target: Color): void; - - /** - * Get the local transformation matrix of the defined instance. - * @param instanceId The id of an instance to get the matrix of. - * @param target This 4x4 matrix will be set to the local transformation matrix of the defined instance. - */ - getMatrixAt(instanceId: number, target: Matrix4): Matrix4; - - /** - * Get whether the given instance is marked as "visible" or not. - * @param instanceId The id of an instance to get the visibility state of. - */ - getVisibleAt(instanceId: number): boolean; - - /** - * Get the range representing the subset of triangles related to the attached geometry, indicating the starting - * offset and count, or `null` if invalid. - * - * Return an object of the form: { start: Integer, count: Integer } - * @param geometryId The id of the geometry to get the range of. - * @param target Optional target object to copy the range in to. - */ - getGeometryRangeAt( - geometryId: number, - target?: BatchedMeshGeometryRange, - ): BatchedMeshGeometryRange | null; - - /** - * Get the geometryIndex of the defined instance. - * @param instanceId The id of an instance to get the geometryIndex of. - */ - getGeometryIdAt(instanceId: number): number; - - /** - * Sets the given color to the defined geometry instance. - * @param instanceId The id of the instance to set the color of. - * @param color The color to set the instance to. - */ - setColorAt(instanceId: number, color: Color): void; - - /** - * Sets the given local transformation matrix to the defined instance. - * @param instanceId The id of an instance to set the matrix of. - * @param matrix A 4x4 matrix representing the local transformation of a single instance. - */ - setMatrixAt(instanceId: number, matrix: Matrix4): this; - - /** - * Sets the visibility of the instance at the given index. - * @param instanceId The id of the instance to set the visibility of. - * @param visible A boolean value indicating the visibility state. - */ - setVisibleAt(instanceId: number, visible: boolean): this; - - /** - * Sets the geometryIndex of the instance at the given index. - * @param instanceId The id of the instance to set the geometryIndex of. - * @param geometryId The geometryIndex to be use by the instance. - */ - setGeometryIdAt(instanceId: number, geometryId: number): this; - - /** - * Adds the given geometry to the {@link BatchedMesh} and returns the associated index referring to it. - * @param geometry The geometry to add into the {@link BatchedMesh}. - * @param reservedVertexRange Optional parameter specifying the amount of vertex buffer space to reserve for the - * added geometry. This is necessary if it is planned to set a new geometry at this index at a later time that is - * larger than the original geometry. Defaults to the length of the given geometry vertex buffer. - * @param reservedIndexRange Optional parameter specifying the amount of index buffer space to reserve for the added - * geometry. This is necessary if it is planned to set a new geometry at this index at a later time that is larger - * than the original geometry. Defaults to the length of the given geometry index buffer. - */ - addGeometry(geometry: BufferGeometry, reservedVertexRange?: number, reservedIndexRange?: number): number; - - /** - * Adds a new instance to the {@link BatchedMesh} using the geometry of the given geometryId and returns a new id - * referring to the new instance to be used by other functions. - * @param geometryId The id of a previously added geometry via "addGeometry" to add into the {@link BatchedMesh} to - * render. - */ - addInstance(geometryId: number): number; - - /** - * @param geometryId The id of a geometry to remove from the [name] that was previously added via "addGeometry". Any - * instances referencing this geometry will also be removed as a side effect. - */ - deleteGeometry(geometryId: number): this; - - /** - * Removes an existing instance from the BatchedMesh using the given instanceId. - * @param instanceId The id of an instance to remove from the BatchedMesh that was previously added via - * "addInstance". - */ - deleteInstance(instanceId: number): this; - - /** - * Replaces the geometry at `geometryId` with the provided geometry. Throws an error if there is not enough space - * reserved for geometry. Calling this will change all instances that are rendering that geometry. - * @param geometryId Which geometry id to replace with this geometry. - * @param geometry The geometry to substitute at the given geometry id. - */ - setGeometryAt(geometryId: number, geometry: BufferGeometry): number; - - /** - * Repacks the sub geometries in [name] to remove any unused space remaining from previously deleted geometry, - * freeing up space to add new geometry. - */ - optimize(): this; - - /** - * Resizes the available space in BatchedMesh's vertex and index buffer attributes to the provided sizes. If the - * provided arguments shrink the geometry buffers but there is not enough unused space at the end of the geometry - * attributes then an error is thrown. - * @param maxVertexCount the max number of vertices to be used by all unique geometries to resize to. - * @param maxIndexCount the max number of indices to be used by all unique geometries to resize to. - */ - setGeometrySize(maxVertexCount: number, maxIndexCount: number): void; - - /** - * Resizes the necessary buffers to support the provided number of instances. If the provided arguments shrink the - * number of instances but there are not enough unused ids at the end of the list then an error is thrown. - * @param maxInstanceCount the max number of individual instances that can be added and rendered by the BatchedMesh. - */ - setInstanceCount(maxInstanceCount: number): void; - - getBoundingBoxAt(geometryId: number, target: Box3): Box3 | null; - getBoundingSphereAt(geometryId: number, target: Sphere): Sphere | null; -} - -export { BatchedMesh }; diff --git a/src-testing/src/objects/Bone.d.ts b/src-testing/src/objects/Bone.d.ts deleted file mode 100644 index 3400ea1b6..000000000 --- a/src-testing/src/objects/Bone.d.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { Object3D, Object3DEventMap } from "../core/Object3D.js"; - -/** - * A {@link Bone} which is part of a {@link THREE.Skeleton | Skeleton} - * @remarks - * The skeleton in turn is used by the {@link THREE.SkinnedMesh | SkinnedMesh} - * Bones are almost identical to a blank {@link THREE.Object3D | Object3D}. - * @example - * ```typescript - * const root = new THREE.Bone(); - * const child = new THREE.Bone(); - * root.add(child); - * child.position.y = 5; - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/objects/Bone | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/objects/Bone.js | Source} - */ -export class Bone extends Object3D { - /** - * Creates a new {@link Bone}. - */ - constructor(); - - /** - * Read-only flag to check if a given object is of type {@link Bone}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isBone: true; - - /** - * @override - * @defaultValue `Bone` - */ - override readonly type: string | "Bone"; -} diff --git a/src-testing/src/objects/Group.d.ts b/src-testing/src/objects/Group.d.ts deleted file mode 100644 index 4b882d2e9..000000000 --- a/src-testing/src/objects/Group.d.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { Object3D, Object3DEventMap } from "../core/Object3D.js"; - -/** - * Its purpose is to make working with groups of objects syntactically clearer. - * @remarks This is almost identical to an {@link Object3D | Object3D} - * @example - * ```typescript - * const geometry = new THREE.BoxGeometry(1, 1, 1); - * const material = new THREE.MeshBasicMaterial({ - * color: 0x00ff00 - * }); - * const cubeA = new THREE.Mesh(geometry, material); - * cubeA.position.set(100, 100, 0); - * const cubeB = new THREE.Mesh(geometry, material); - * cubeB.position.set(-100, -100, 0); - * //create a {@link Group} and add the two cubes - * //These cubes can now be rotated / scaled etc as a {@link Group} * const {@link Group} = new THREE.Group(); - * group.add(cubeA); - * group.add(cubeB); - * scene.add(group); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/objects/Group | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/objects/Group.js | Source} - */ -export class Group extends Object3D { - /** - * Creates a new {@link Group}. - */ - constructor(); - - /** - * Read-only flag to check if a given object is of type {@link Group}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isGroup: true; -} diff --git a/src-testing/src/objects/InstancedMesh.d.ts b/src-testing/src/objects/InstancedMesh.d.ts deleted file mode 100644 index b239afb7a..000000000 --- a/src-testing/src/objects/InstancedMesh.d.ts +++ /dev/null @@ -1,179 +0,0 @@ -import { BufferAttributeJSON } from "./../core/BufferAttribute.js"; -import { BufferGeometry } from "../core/BufferGeometry.js"; -import { InstancedBufferAttribute } from "../core/InstancedBufferAttribute.js"; -import { JSONMeta, Object3DEventMap } from "../core/Object3D.js"; -import { Material } from "../materials/Material.js"; -import { Box3 } from "../math/Box3.js"; -import { Color } from "../math/Color.js"; -import { Matrix4 } from "../math/Matrix4.js"; -import { Sphere } from "../math/Sphere.js"; -import { DataTexture } from "../textures/DataTexture.js"; -import { Mesh, MeshJSONObject } from "./Mesh.js"; - -export interface InstancedMeshJSONObject extends MeshJSONObject { - count: number; - instanceMatrix: BufferAttributeJSON; - instanceColor?: BufferAttributeJSON; -} - -export interface InstancedMeshJSON extends MeshJSONObject { - object: InstancedMeshJSONObject; -} - -export interface InstancedMeshEventMap extends Object3DEventMap { - dispose: {}; -} - -/** - * A special version of {@link THREE.Mesh | Mesh} with instanced rendering support - * @remarks - * Use {@link InstancedMesh} if you have to render a large number of objects with the same geometry and material(s) but with different world transformations - * @remarks - * The usage of {@link InstancedMesh} will help you to reduce the number of draw calls and thus improve the overall rendering performance in your application. - * @see Example: {@link https://threejs.org/examples/#webgl_instancing_dynamic | WebGL / instancing / dynamic} - * @see Example: {@link https://threejs.org/examples/#webgl_instancing_performance | WebGL / instancing / performance} - * @see Example: {@link https://threejs.org/examples/#webgl_instancing_scatter | WebGL / instancing / scatter} - * @see Example: {@link https://threejs.org/examples/#webgl_instancing_raycast | WebGL / instancing / raycast} - * @see {@link https://threejs.org/docs/index.html#api/en/objects/InstancedMesh | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/objects/InstancedMesh.js | Source} - */ -export class InstancedMesh< - TGeometry extends BufferGeometry = BufferGeometry, - TMaterial extends Material | Material[] = Material | Material[], - TEventMap extends InstancedMeshEventMap = InstancedMeshEventMap, -> extends Mesh { - /** - * Create a new instance of {@link InstancedMesh} - * @param geometry An instance of {@link BufferGeometry}. - * @param material A single or an array of {@link Material}. Default is a new {@link MeshBasicMaterial}. - * @param count The **maximum** number of instances of this Mesh. Expects a `Integer` - */ - constructor(geometry: TGeometry | undefined, material: TMaterial | undefined, count: number); - - /** - * Read-only flag to check if a given object is of type {@link InstancedMesh}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isInstancedMesh: true; - - /** - * This bounding box encloses all instances of the {@link InstancedMesh},, which can be calculated with {@link computeBoundingBox | .computeBoundingBox()}. - * @remarks Bounding boxes aren't computed by default. They need to be explicitly computed, otherwise they are `null`. - * @defaultValue `null` - */ - boundingBox: Box3 | null; - - /** - * This bounding sphere encloses all instances of the {@link InstancedMesh}, which can be calculated with {@link computeBoundingSphere | .computeBoundingSphere()}. - * @remarks bounding spheres aren't computed by default. They need to be explicitly computed, otherwise they are `null`. - * @defaultValue `null` - */ - boundingSphere: Sphere | null; - - /** - * The number of instances. - * @remarks - * The `count` value passed into the {@link InstancedMesh | constructor} represents the **maximum** number of instances of this mesh. - * You can change the number of instances at runtime to an integer value in the range `[0, count]`. - * @remarks If you need more instances than the original `count` value, you have to create a new InstancedMesh. - * @remarks Expects a `Integer` - */ - count: number; - - /** - * Represents the colors of all instances. - * You have to set {@link InstancedBufferAttribute.needsUpdate | .instanceColor.needsUpdate()} flag to `true` if you modify instanced data via {@link setColorAt | .setColorAt()}. - * @defaultValue `null` - */ - instanceColor: InstancedBufferAttribute | null; - - /** - * Represents the local transformation of all instances. - * You have to set {@link InstancedBufferAttribute.needsUpdate | .instanceMatrix.needsUpdate()} flag to `true` if you modify instanced data via {@link setMatrixAt | .setMatrixAt()}. - */ - instanceMatrix: InstancedBufferAttribute; - - /** - * Represents the morph target weights of all instances. You have to set its {@link .needsUpdate} flag to true if - * you modify instanced data via {@link .setMorphAt}. - */ - morphTexture: DataTexture | null; - - /** - * Computes the bounding box of the instanced mesh, and updates the {@link .boundingBox} attribute. The bounding box - * is not computed by the engine; it must be computed by your app. You may need to recompute the bounding box if an - * instance is transformed via {@link .setMatrixAt()}. - */ - computeBoundingBox(): void; - - /** - * Computes the bounding sphere of the instanced mesh, and updates the {@link .boundingSphere} attribute. The engine - * automatically computes the bounding sphere when it is needed, e.g., for ray casting or view frustum culling. You - * may need to recompute the bounding sphere if an instance is transformed via [page:.setMatrixAt](). - */ - computeBoundingSphere(): void; - - /** - * Get the color of the defined instance. - * @param index The index of an instance. Values have to be in the range `[0, count]`. Expects a `Integer` - * @param color This color object will be set to the color of the defined instance. - */ - getColorAt(index: number, color: Color): void; - - /** - * Sets the given color to the defined instance - * @remarks - * Make sure you set {@link InstancedBufferAttribute.needsUpdate | .instanceColor.needsUpdate()} to `true` after updating all the colors. - * @param index The index of an instance. Values have to be in the range `[0, count]`. Expects a `Integer` - * @param color The color of a single instance. - */ - setColorAt(index: number, color: Color): void; - - /** - * Get the local transformation matrix of the defined instance. - * @param index The index of an instance Values have to be in the range `[0, count]`. Expects a `Integer` - * @param matrix This 4x4 matrix will be set to the local transformation matrix of the defined instance. - */ - getMatrixAt(index: number, matrix: Matrix4): void; - - /** - * Get the morph target weights of the defined instance. - * @param index The index of an instance. Values have to be in the range [0, count]. - * @param mesh The {@link .morphTargetInfluences} property of this mesh will be filled with the morph target weights of the defined instance. - */ - getMorphAt(index: number, mesh: Mesh): void; - - /** - * Sets the given local transformation matrix to the defined instance. - * @remarks - * Make sure you set {@link InstancedBufferAttribute.needsUpdate | .instanceMatrix.needsUpdate()} flag to `true` after updating all the matrices. - * @param index The index of an instance. Values have to be in the range `[0, count]`. Expects a `Integer` - * @param matrix A 4x4 matrix representing the local transformation of a single instance. - */ - setMatrixAt(index: number, matrix: Matrix4): void; - - /** - * Sets the morph target weights to the defined instance. Make sure you set {@link .morphTexture}{@link .needsUpdate} - * to true after updating all the influences. - * @param index The index of an instance. Values have to be in the range [0, count]. - * @param mesh A mesh with {@link .morphTargetInfluences} property containing the morph target weights of a single instance. - */ - setMorphAt(index: number, mesh: Mesh): void; - - /** - * No effect in {@link InstancedMesh}. - * @ignore - * @hidden - */ - override updateMorphTargets(): void; - - /** - * Frees the GPU-related resources allocated by this instance - * @remarks - * Call this method whenever this instance is no longer used in your app. - */ - dispose(): this; - - toJSON(meta?: JSONMeta): InstancedMeshJSON; -} diff --git a/src-testing/src/objects/LOD.d.ts b/src-testing/src/objects/LOD.d.ts deleted file mode 100644 index 2440b8503..000000000 --- a/src-testing/src/objects/LOD.d.ts +++ /dev/null @@ -1,111 +0,0 @@ -import { Camera } from "../cameras/Camera.js"; -import { JSONMeta, Object3D, Object3DEventMap, Object3DJSON, Object3DJSONObject } from "../core/Object3D.js"; - -export interface LODJSONObject extends Object3DJSONObject { - autoUpdate?: boolean; - - levels: Array<{ - object: string; - distance: number; - hysteresis: number; - }>; -} - -export interface LODJSON extends Object3DJSON { - object: LODJSONObject; -} - -/** - * Every level is associated with an object, and rendering can be switched between them at the distances specified - * @remarks - * Typically you would create, say, three meshes, one for far away (low detail), one for mid range (medium detail) and one for close up (high detail). - * @example - * ```typescript - * const {@link LOD} = new THREE.LOD(); - * //Create spheres with 3 levels of detail and create new {@link LOD} levels for them - * for (let i = 0; i & lt; 3; i++) { - * const geometry = new THREE.IcosahedronGeometry(10, 3 - i) - * const mesh = new THREE.Mesh(geometry, material); - * lod.addLevel(mesh, i * 75); - * } - * scene.add(lod); - * ``` - * @see Example: {@link https://threejs.org/examples/#webgl_lod | webgl / {@link LOD} } - * @see {@link https://threejs.org/docs/index.html#api/en/objects/LOD | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/objects/LOD.js | Source} - */ -export class LOD extends Object3D { - /** - * Creates a new {@link LOD}. - */ - constructor(); - - /** - * Read-only flag to check if a given object is of type {@link LOD}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isLOD: true; - - /** - * @override - * @defaultValue `LOD` - */ - override readonly type: string | "LOD"; - - /** - * An array of level objects - */ - levels: Array<{ - /** The Object3D to display at this level. */ - object: Object3D; - /** The distance at which to display this level of detail. Expects a `Float`. */ - distance: number; - /** Threshold used to avoid flickering at LOD boundaries, as a fraction of distance. Expects a `Float`. */ - hysteresis: number; - }>; - - /** - * Whether the {@link LOD} object is updated automatically by the renderer per frame or not. - * If set to `false`, you have to call {@link update | .update()} in the render loop by yourself. - * @defaultValue `true` - */ - autoUpdate: boolean; - - /** - * Adds a mesh that will display at a certain distance and greater. Typically the further away the distance, the lower the detail on the mesh. - * - * @param object The Object3D to display at this level. - * @param distance The distance at which to display this level of detail. Expects a `Float`. Default `0.0`. - * @param hysteresis Threshold used to avoid flickering at LOD boundaries, as a fraction of distance. Expects a `Float`. Default `0.0`. - */ - addLevel(object: Object3D, distance?: number, hysteresis?: number): this; - - /** - * Removes an existing level, based on the distance from the camera. Returns `true` when the level has been removed. - * Otherwise `false`. - * @param distance Distance of the level to delete. - */ - removeLabel(distance: number): boolean; - - /** - * Get the currently active {@link LOD} level - * @remarks - * As index of the levels array. - */ - getCurrentLevel(): number; - - /** - * Get a reference to the first {@link THREE.Object3D | Object3D} (mesh) that is greater than {@link distance}. - * @param distance Expects a `Float` - */ - getObjectForDistance(distance: number): Object3D | null; - - /** - * Set the visibility of each {@link levels | level}'s {@link THREE.Object3D | object} based on distance from the {@link THREE.Camera | camera}. - * @param camera - */ - update(camera: Camera): void; - - toJSON(meta?: JSONMeta): LODJSON; -} diff --git a/src-testing/src/objects/Line.d.ts b/src-testing/src/objects/Line.d.ts deleted file mode 100644 index 2d76dec69..000000000 --- a/src-testing/src/objects/Line.d.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { BufferGeometry } from "../core/BufferGeometry.js"; -import { Object3D, Object3DEventMap } from "../core/Object3D.js"; -import { Material } from "../materials/Material.js"; - -/** - * A continuous line. - * @remarks - * This is nearly the same as {@link THREE.LineSegments | LineSegments}, - * the only difference is that it is rendered using {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/drawElements | gl.LINE_STRIP} - * instead of {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/drawElements | gl.LINES} - * @example - * ```typescript - * const material = new THREE.LineBasicMaterial({ - * color: 0x0000ff - * }); - * const points = []; - * points.push(new THREE.Vector3(-10, 0, 0)); - * points.push(new THREE.Vector3(0, 10, 0)); - * points.push(new THREE.Vector3(10, 0, 0)); - * const geometry = new THREE.BufferGeometry().setFromPoints(points); - * const {@link Line} = new THREE.Line(geometry, material); - * scene.add(line); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/objects/Line | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/objects/Line.js | Source} - */ -export class Line< - TGeometry extends BufferGeometry = BufferGeometry, - TMaterial extends Material | Material[] = Material | Material[], - TEventMap extends Object3DEventMap = Object3DEventMap, -> extends Object3D { - /** - * Create a new instance of {@link Line} - * @param geometry Vertices representing the {@link Line} segment(s). Default {@link THREE.BufferGeometry | `new THREE.BufferGeometry()`}. - * @param material Material for the line. Default {@link THREE.LineBasicMaterial | `new THREE.LineBasicMaterial()`}. - */ - constructor(geometry?: TGeometry, material?: TMaterial); - - /** - * Read-only flag to check if a given object is of type {@link Line}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isLine: true; - - /** - * @override - * @defaultValue `Line` - */ - override readonly type: string | "Line"; - - /** - * Vertices representing the {@link Line} segment(s). - */ - geometry: TGeometry; - - /** - * Material for the line. - */ - material: TMaterial; - - /** - * An array of weights typically from `0-1` that specify how much of the morph is applied. - * @defaultValue `undefined`, but reset to a blank array by {@link updateMorphTargets | .updateMorphTargets()}. - */ - morphTargetInfluences?: number[] | undefined; - - /** - * A dictionary of morphTargets based on the `morphTarget.name` property. - * @defaultValue `undefined`, but reset to a blank array by {@link updateMorphTargets | .updateMorphTargets()}. - */ - morphTargetDictionary?: { [key: string]: number } | undefined; - - /** - * Computes an array of distance values which are necessary for {@link THREE.LineDashedMaterial | LineDashedMaterial} - * @remarks - * For each vertex in the geometry, the method calculates the cumulative length from the current point to the very beginning of the line. - */ - computeLineDistances(): this; - - /** - * Updates the morphTargets to have no influence on the object - * @remarks - * Resets the {@link morphTargetInfluences | .morphTargetInfluences} and {@link morphTargetDictionary | .morphTargetDictionary} properties. - */ - updateMorphTargets(): void; -} diff --git a/src-testing/src/objects/LineLoop.d.ts b/src-testing/src/objects/LineLoop.d.ts deleted file mode 100644 index 0a070a838..000000000 --- a/src-testing/src/objects/LineLoop.d.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { BufferGeometry } from "../core/BufferGeometry.js"; -import { Object3DEventMap } from "../core/Object3D.js"; -import { Material } from "../materials/Material.js"; -import { Line } from "./Line.js"; - -/** - * A continuous line that connects back to the start. - * @remarks - * This is nearly the same as {@link THREE.Line | Line}, - * the only difference is that it is rendered using {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/drawElements | gl.LINE_LOOP} - * instead of {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/drawElements | gl.LINE_STRIP}, - * which draws a straight line to the next vertex, and connects the last vertex back to the first. - * @see {@link https://threejs.org/docs/index.html#api/en/objects/LineLoop | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/objects/LineLoop.js | Source} - */ -export class LineLoop< - TGeometry extends BufferGeometry = BufferGeometry, - TMaterial extends Material | Material[] = Material | Material[], - TEventMap extends Object3DEventMap = Object3DEventMap, -> extends Line { - /** - * Create a new instance of {@link LineLoop} - * @param geometry List of vertices representing points on the line loop. Default {@link THREE.BufferGeometry | `new THREE.BufferGeometry()`}. - * @param material Material for the line. Default {@link THREE.LineBasicMaterial | `new THREE.LineBasicMaterial()`}. - */ - constructor(geometry?: TGeometry, material?: TMaterial); - - /** - * Read-only flag to check if a given object is of type {@link LineLoop}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isLineLoop: true; - - /** - * @override - * @defaultValue `LineLoop` - */ - override readonly type: string | "LineLoop"; -} diff --git a/src-testing/src/objects/LineSegments.d.ts b/src-testing/src/objects/LineSegments.d.ts deleted file mode 100644 index 9a8199bdc..000000000 --- a/src-testing/src/objects/LineSegments.d.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { BufferGeometry } from "../core/BufferGeometry.js"; -import { Object3DEventMap } from "../core/Object3D.js"; -import { Material } from "../materials/Material.js"; -import { Line } from "./Line.js"; - -/** - * A series of lines drawn between pairs of vertices. - * @remarks - * This is nearly the same as {@link THREE.Line | Line}, - * the only difference is that it is rendered using {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/drawElements | gl.LINES} - * instead of {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/drawElements | gl.LINE_STRIP}. - * @see {@link https://threejs.org/docs/index.html#api/en/objects/LineSegments | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/objects/LineSegments.js | Source} - */ -export class LineSegments< - TGeometry extends BufferGeometry = BufferGeometry, - TMaterial extends Material | Material[] = Material | Material[], - TEventMap extends Object3DEventMap = Object3DEventMap, -> extends Line { - /** - * Create a new instance of {@link LineSegments} - * @param geometry Pair(s) of vertices representing each line segment(s). Default {@link THREE.BufferGeometry | `new THREE.BufferGeometry()`}. - * @param material Material for the line. Default {@link THREE.LineBasicMaterial | `new THREE.LineBasicMaterial()`}. - */ - constructor(geometry?: TGeometry, material?: TMaterial); - - /** - * Read-only flag to check if a given object is of type {@link LineSegments}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isLineSegments: true; - - /** - * A Read-only _string_ to check if `this` object type. - * @remarks Sub-classes will update this value. - * @override - * @defaultValue `LineSegments` - */ - override readonly type: string | "LineSegments"; -} diff --git a/src-testing/src/objects/Mesh.d.ts b/src-testing/src/objects/Mesh.d.ts deleted file mode 100644 index 38dad1c73..000000000 --- a/src-testing/src/objects/Mesh.d.ts +++ /dev/null @@ -1,94 +0,0 @@ -import { BufferGeometry } from "../core/BufferGeometry.js"; -import { JSONMeta, Object3D, Object3DEventMap, Object3DJSON, Object3DJSONObject } from "../core/Object3D.js"; -import { Material } from "../materials/Material.js"; -import { Vector3 } from "../math/Vector3.js"; - -export interface MeshJSONObject extends Object3DJSONObject { - geometry: string; -} - -export interface MeshJSON extends Object3DJSON { - object: MeshJSONObject; -} - -/** - * Class representing triangular {@link https://en.wikipedia.org/wiki/Polygon_mesh | polygon mesh} based objects. - * @remarks - * Also serves as a base for other classes such as {@link THREE.SkinnedMesh | SkinnedMesh}, {@link THREE.InstancedMesh | InstancedMesh}. - * @example - * ```typescript - * const geometry = new THREE.BoxGeometry(1, 1, 1); - * const material = new THREE.MeshBasicMaterial({ - * color: 0xffff00 - * }); - * const {@link Mesh} = new THREE.Mesh(geometry, material); - * scene.add(mesh); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/objects/Mesh | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/objects/Mesh.js | Source} - */ -export class Mesh< - TGeometry extends BufferGeometry = BufferGeometry, - TMaterial extends Material | Material[] = Material | Material[], - TEventMap extends Object3DEventMap = Object3DEventMap, -> extends Object3D { - /** - * Create a new instance of {@link Mesh} - * @param geometry An instance of {@link THREE.BufferGeometry | BufferGeometry}. Default {@link THREE.BufferGeometry | `new THREE.BufferGeometry()`}. - * @param material A single or an array of {@link THREE.Material | Material}. Default {@link THREE.MeshBasicMaterial | `new THREE.MeshBasicMaterial()`}. - */ - constructor(geometry?: TGeometry, material?: TMaterial); - - /** - * Read-only flag to check if a given object is of type {@link Mesh}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isMesh: true; - - /** - * @override - * @defaultValue `Mesh` - */ - override readonly type: string | "Mesh"; - - /** - * An instance of {@link THREE.BufferGeometry | BufferGeometry} (or derived classes), defining the object's structure. - * @defaultValue {@link THREE.BufferGeometry | `new THREE.BufferGeometry()`}. - */ - geometry: TGeometry; - - /** - * An instance of material derived from the {@link THREE.Material | Material} base class or an array of materials, defining the object's appearance. - * @defaultValue {@link THREE.MeshBasicMaterial | `new THREE.MeshBasicMaterial()`}. - */ - material: TMaterial; - - /** - * An array of weights typically from `0-1` that specify how much of the morph is applied. - * @defaultValue `undefined`, _but reset to a blank array by {@link updateMorphTargets | .updateMorphTargets()}._ - */ - morphTargetInfluences?: number[] | undefined; - - /** - * A dictionary of morphTargets based on the `morphTarget.name` property. - * @defaultValue `undefined`, _but rebuilt by {@link updateMorphTargets | .updateMorphTargets()}._ - */ - morphTargetDictionary?: { [key: string]: number } | undefined; - - /** - * Updates the morphTargets to have no influence on the object - * @remarks Resets the {@link morphTargetInfluences} and {@link morphTargetDictionary} properties. - */ - updateMorphTargets(): void; - - /** - * Get the local-space position of the vertex at the given index, - * taking into account the current animation state of both morph targets and skinning. - * @param index Expects a `Integer` - * @param target - */ - getVertexPosition(index: number, target: Vector3): Vector3; - - toJSON(meta?: JSONMeta): MeshJSON; -} diff --git a/src-testing/src/objects/Points.d.ts b/src-testing/src/objects/Points.d.ts deleted file mode 100644 index 3cba2c74b..000000000 --- a/src-testing/src/objects/Points.d.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { BufferGeometry, NormalOrGLBufferAttributes } from "../core/BufferGeometry.js"; -import { Object3D, Object3DEventMap } from "../core/Object3D.js"; -import { Material } from "../materials/Material.js"; - -/** - * A class for displaying {@link Points} - * @remarks - * The {@link Points} are rendered by the {@link THREE.WebGLRenderer | WebGLRenderer} using {@link https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/drawElements | gl.POINTS}. - * @see {@link https://threejs.org/docs/index.html#api/en/objects/Points | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/objects/Points.js | Source} - */ -export class Points< - TGeometry extends BufferGeometry = BufferGeometry, - TMaterial extends Material | Material[] = Material | Material[], - TEventMap extends Object3DEventMap = Object3DEventMap, -> extends Object3D { - /** - * Create a new instance of {@link Points} - * @param geometry An instance of {@link THREE.BufferGeometry | BufferGeometry}. Default {@link THREE.BufferGeometry | `new THREE.BufferGeometry()`}. - * @param material A single or an array of {@link THREE.Material | Material}. Default {@link THREE.PointsMaterial | `new THREE.PointsMaterial()`}. - */ - constructor(geometry?: TGeometry, material?: TMaterial); - - /** - * Read-only flag to check if a given object is of type {@link Points}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isPoints: true; - - /** - * @override - * @defaultValue `Points` - */ - override readonly type: string | "Points"; - - /** - * An array of weights typically from `0-1` that specify how much of the morph is applied. - * @defaultValue `undefined`, _but reset to a blank array by {@link updateMorphTargets | .updateMorphTargets()}._ - */ - morphTargetInfluences?: number[] | undefined; - - /** - * A dictionary of morphTargets based on the `morphTarget.name` property. - * @defaultValue `undefined`, _but rebuilt by {@link updateMorphTargets | .updateMorphTargets()}._ - */ - morphTargetDictionary?: { [key: string]: number } | undefined; - - /** - * An instance of {@link THREE.BufferGeometry | BufferGeometry} (or derived classes), defining the object's structure. - * @remarks each vertex designates the position of a particle in the system. - */ - geometry: TGeometry; - - /** - * An instance of {@link THREE.Material | Material}, defining the object's appearance. - * @defaultValue {@link THREE.PointsMaterial | `new THREE.PointsMaterial()`}, _with randomised colour_. - */ - material: TMaterial; - - /** - * Updates the morphTargets to have no influence on the object - * @remarks Resets the {@link morphTargetInfluences} and {@link morphTargetDictionary} properties. - */ - updateMorphTargets(): void; -} diff --git a/src-testing/src/objects/Skeleton.d.ts b/src-testing/src/objects/Skeleton.d.ts deleted file mode 100644 index aaeb3198b..000000000 --- a/src-testing/src/objects/Skeleton.d.ts +++ /dev/null @@ -1,120 +0,0 @@ -import { Matrix4, Matrix4Tuple } from "../math/Matrix4.js"; -import { DataTexture } from "../textures/DataTexture.js"; -import { Bone } from "./Bone.js"; - -export interface SkeletonJSON { - metadata: { version: number; type: string; generator: string }; - bones: string[]; - boneInverses: Matrix4Tuple[]; - uuid: string; -} - -/** - * Use an array of {@link Bone | bones} to create a {@link Skeleton} that can be used by a {@link THREE.SkinnedMesh | SkinnedMesh}. - * @example - * ```typescript - * // Create a simple "arm" - * const bones = []; - * const shoulder = new THREE.Bone(); - * const elbow = new THREE.Bone(); - * const hand = new THREE.Bone(); - * shoulder.add(elbow); - * elbow.add(hand); - * bones.push(shoulder); - * bones.push(elbow); - * bones.push(hand); - * shoulder.position.y = -5; - * elbow.position.y = 0; - * hand.position.y = 5; - * const armSkeleton = new THREE.Skeleton(bones); - * See the[page: SkinnedMesh] page - * for an example of usage with standard[page: BufferGeometry]. - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/objects/Skeleton | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/objects/Skeleton.js | Source} - */ -export class Skeleton { - /** - * Creates a new Skeleton. - * @param bones The array of {@link THREE.Bone | bones}. Default `[]`. - * @param boneInverses An array of {@link THREE.Matrix4 | Matrix4s}. Default `[]`. - */ - constructor(bones?: Bone[], boneInverses?: Matrix4[]); - - /** - * {@link http://en.wikipedia.org/wiki/Universally_unique_identifier | UUID} of this object instance. - * @remarks This gets automatically assigned and shouldn't be edited. - */ - uuid: string; - - /** - * The array of {@link THREE.Bone | Bones}. - * @remarks Note this is a copy of the original array, not a reference, so you can modify the original array without effecting this one. - */ - bones: Bone[]; - - /** - * An array of {@link Matrix4 | Matrix4s} that represent the inverse of the {@link THREE.Matrix4 | matrixWorld} of the individual bones. - */ - boneInverses: Matrix4[]; - - /** - * The array buffer holding the bone data when using a vertex texture. - */ - boneMatrices: Float32Array; - - /** - * The {@link THREE.DataTexture | DataTexture} holding the bone data when using a vertex texture. - */ - boneTexture: null | DataTexture; - - frame: number; - - init(): void; - - /** - * Generates the {@link boneInverses} array if not provided in the constructor. - */ - calculateInverses(): void; - - /** - * Computes an instance of {@link THREE.DataTexture | DataTexture} in order to pass the bone data more efficiently to the shader - * @remarks - * The texture is assigned to {@link boneTexture}. - */ - computeBoneTexture(): this; - - /** - * Returns the skeleton to the base pose. - */ - pose(): void; - - /** - * Updates the {@link boneMatrices} and {@link boneTexture} after changing the bones - * @remarks - * This is called automatically by the {@link THREE.WebGLRenderer | WebGLRenderer} if the {@link Skeleton} is used with a {@link THREE.SkinnedMesh | SkinnedMesh}. - */ - update(): void; - - /** - * Returns a clone of this {@link Skeleton} object. - */ - clone(): Skeleton; - - /** - * Searches through the skeleton's bone array and returns the first with a matching name. - * @param name String to match to the Bone's {@link THREE.Bone.name | .name} property. - */ - getBoneByName(name: string): undefined | Bone; - - /** - * Frees the GPU-related resources allocated by this instance - * @remarks - * Call this method whenever this instance is no longer used in your app. - */ - dispose(): void; - - toJSON(): SkeletonJSON; - - fromJSON(json: SkeletonJSON, bones: Record): void; -} diff --git a/src-testing/src/objects/SkinnedMesh.d.ts b/src-testing/src/objects/SkinnedMesh.d.ts deleted file mode 100644 index 35149c5d1..000000000 --- a/src-testing/src/objects/SkinnedMesh.d.ts +++ /dev/null @@ -1,160 +0,0 @@ -import { BindMode } from "../constants.js"; -import { BufferGeometry } from "../core/BufferGeometry.js"; -import { JSONMeta, Object3DEventMap } from "../core/Object3D.js"; -import { Material } from "../materials/Material.js"; -import { Box3 } from "../math/Box3.js"; -import { Matrix4, Matrix4Tuple } from "../math/Matrix4.js"; -import { Sphere } from "../math/Sphere.js"; -import { Vector3 } from "../math/Vector3.js"; -import { Mesh, MeshJSON, MeshJSONObject } from "./Mesh.js"; -import { Skeleton } from "./Skeleton.js"; - -export interface SkinnedMeshJSONObject extends MeshJSONObject { - bindMode: BindMode; - bindMatrix: Matrix4Tuple; - skeleton?: string; -} - -export interface SkinnedMeshJSON extends MeshJSON { - object: SkinnedMeshJSONObject; -} - -/** - * A mesh that has a {@link THREE.Skeleton | Skeleton} with {@link Bone | bones} that can then be used to animate the vertices of the geometry. - * @example - * ```typescript - * const geometry = new THREE.CylinderGeometry(5, 5, 5, 5, 15, 5, 30); - * // create the skin indices and skin weights manually - * // (typically a loader would read this data from a 3D model for you) - * const position = geometry.attributes.position; - * const vertex = new THREE.Vector3(); - * const skinIndices = []; - * const skinWeights = []; - * for (let i = 0; i & lt; position.count; i++) { - * vertex.fromBufferAttribute(position, i); - * // compute skinIndex and skinWeight based on some configuration data - * const y = (vertex.y + sizing.halfHeight); - * const skinIndex = Math.floor(y / sizing.segmentHeight); - * const skinWeight = (y % sizing.segmentHeight) / sizing.segmentHeight; - * skinIndices.push(skinIndex, skinIndex + 1, 0, 0); - * skinWeights.push(1 - skinWeight, skinWeight, 0, 0); - * } - * geometry.setAttribute('skinIndex', new THREE.Uint16BufferAttribute(skinIndices, 4)); - * geometry.setAttribute('skinWeight', new THREE.Float32BufferAttribute(skinWeights, 4)); - * // create skinned mesh and skeleton - * const mesh = new THREE.SkinnedMesh(geometry, material); - * const skeleton = new THREE.Skeleton(bones); - * // see example from THREE.Skeleton - * const rootBone = skeleton.bones[0]; - * mesh.add(rootBone); - * // bind the skeleton to the mesh - * mesh.bind(skeleton); - * // move the bones and manipulate the model - * skeleton.bones[0].rotation.x = -0.1; - * skeleton.bones[1].rotation.x = 0.2; - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/objects/SkinnedMesh | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/objects/SkinnedMesh.js | Source} - */ -export class SkinnedMesh< - TGeometry extends BufferGeometry = BufferGeometry, - TMaterial extends Material | Material[] = Material | Material[], - TEventMap extends Object3DEventMap = Object3DEventMap, -> extends Mesh { - /** - * Create a new instance of {@link SkinnedMesh} - * @param geometry An instance of {@link THREE.BufferGeometry | BufferGeometry}. Default {@link THREE.BufferGeometry | `new THREE.BufferGeometry()`}. - * @param material A single or an array of {@link THREE.Material | Material}. Default {@link THREE.MeshBasicMaterial | `new THREE.MeshBasicMaterial()`}. - */ - constructor(geometry?: TGeometry, material?: TMaterial, useVertexTexture?: boolean); - - /** - * Read-only flag to check if a given object is of type {@link SkinnedMesh}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isSkinnedMesh: true; - - /** - * @override - * @defaultValue `SkinnedMesh` - */ - override readonly type: string | "SkinnedMesh"; - - /** - * Either {@link AttachedBindMode} or {@link DetachedBindMode}. {@link AttachedBindMode} means the skinned mesh - * shares the same world space as the skeleton. This is not true when using {@link DetachedBindMode} which is useful - * when sharing a skeleton across multiple skinned meshes. - * @defaultValue `AttachedBindMode` - */ - bindMode: BindMode; - - /** - * The base matrix that is used for the bound bone transforms. - */ - bindMatrix: Matrix4; - /** - * The base matrix that is used for resetting the bound bone transforms. - */ - bindMatrixInverse: Matrix4; - - /** - * The bounding box of the SkinnedMesh. Can be calculated with {@link computeBoundingBox | .computeBoundingBox()}. - * @default `null` - */ - boundingBox: Box3; - - /** - * The bounding box of the SkinnedMesh. Can be calculated with {@link computeBoundingSphere | .computeBoundingSphere()}. - * @default `null` - */ - boundingSphere: Sphere; - - /** - * {@link THREE.Skeleton | Skeleton} representing the bone hierarchy of the skinned mesh. - */ - skeleton: Skeleton; - - /** - * Bind a skeleton to the skinned mesh - * @remarks - * The bindMatrix gets saved to .bindMatrix property and the .bindMatrixInverse gets calculated. - * @param skeleton {@link THREE.Skeleton | Skeleton} created from a {@link Bone | Bones} tree. - * @param bindMatrix {@link THREE.Matrix4 | Matrix4} that represents the base transform of the skeleton. - */ - bind(skeleton: Skeleton, bindMatrix?: Matrix4): void; - - /** - * Computes the bounding box of the skinned mesh, and updates the {@link .boundingBox} attribute. The bounding box - * is not computed by the engine; it must be computed by your app. If the skinned mesh is animated, the bounding box - * should be recomputed per frame. - */ - computeBoundingBox(): void; - - /** - * Computes the bounding sphere of the skinned mesh, and updates the {@link .boundingSphere} attribute. The bounding - * sphere is automatically computed by the engine when it is needed, e.g., for ray casting and view frustum culling. - * If the skinned mesh is animated, the bounding sphere should be recomputed per frame. - */ - computeBoundingSphere(): void; - - /** - * This method sets the skinned mesh in the rest pose (resets the pose). - */ - pose(): void; - - /** - * Normalizes the skin weights. - */ - normalizeSkinWeights(): void; - - /** - * Applies the bone transform associated with the given index to the given position vector - * @remarks Returns the updated vector. - * @param index Expects a `Integer` - * @param vector - */ - applyBoneTransform(index: number, vector: Vector3): Vector3; - - toJSON(meta?: JSONMeta): SkinnedMeshJSON; -} diff --git a/src-testing/src/objects/Sprite.d.ts b/src-testing/src/objects/Sprite.d.ts deleted file mode 100644 index 427b8b414..000000000 --- a/src-testing/src/objects/Sprite.d.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { BufferGeometry } from "../core/BufferGeometry.js"; -import { Object3D, Object3DEventMap } from "../core/Object3D.js"; -import { SpriteMaterial } from "../materials/Materials.js"; -import { Vector2 } from "../math/Vector2.js"; - -/** - * A {@link Sprite} is a plane that always faces towards the camera, generally with a partially transparent texture applied. - * @remarks Sprites do not cast shadows, setting `castShadow = true` will have no effect. - * @example - * ```typescript - * const map = new THREE.TextureLoader().load('sprite.png'); - * const material = new THREE.SpriteMaterial({ - * map: map - * }); - * const {@link Sprite} = new THREE.Sprite(material); - * scene.add(sprite); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/objects/Sprite | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/objects/Sprite.js | Source} - */ -export class Sprite extends Object3D { - /** - * Creates a new Sprite. - * @param material An instance of {@link THREE.SpriteMaterial | SpriteMaterial}. Default {@link THREE.SpriteMaterial | `new SpriteMaterial()`}, _with white color_. - */ - constructor(material?: SpriteMaterial); - - /** - * Read-only flag to check if a given object is of type {@link Sprite}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isSprite: true; - - /** - * @override - * @defaultValue `Sprite` - */ - override readonly type: string | "Sprite"; - - /** - * Whether the object gets rendered into shadow map. - * No effect in {@link Sprite}. - * @ignore - * @hidden - * @defaultValue `false` - */ - override castShadow: false; - - geometry: BufferGeometry; - - /** - * An instance of {@link THREE.SpriteMaterial | SpriteMaterial}, defining the object's appearance. - * @defaultValue {@link THREE.SpriteMaterial | `new SpriteMaterial()`}, _with white color_. - */ - material: SpriteMaterial; - - /** - * The sprite's anchor point, and the point around which the {@link Sprite} rotates. - * A value of (0.5, 0.5) corresponds to the midpoint of the sprite. - * A value of (0, 0) corresponds to the lower left corner of the sprite. - * @defaultValue {@link THREE.Vector2 | `new Vector2(0.5, 0.5)`}. - */ - center: Vector2; -} diff --git a/src-testing/src/renderers/WebGL3DRenderTarget.d.ts b/src-testing/src/renderers/WebGL3DRenderTarget.d.ts deleted file mode 100644 index 420caa97e..000000000 --- a/src-testing/src/renderers/WebGL3DRenderTarget.d.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { RenderTargetOptions } from "../core/RenderTarget.js"; -import { Data3DTexture } from "../textures/Data3DTexture.js"; -import { WebGLRenderTarget } from "./WebGLRenderTarget.js"; - -/** - * Represents a three-dimensional render target. - */ -export class WebGL3DRenderTarget extends WebGLRenderTarget { - /** - * Creates a new WebGL3DRenderTarget. - * - * @param width the width of the render target, in pixels. Default is `1`. - * @param height the height of the render target, in pixels. Default is `1`. - * @param depth the depth of the render target. Default is `1`. - * @param options optional object that holds texture parameters for an auto-generated target texture and - * depthBuffer/stencilBuffer booleans. See {@link WebGLRenderTarget} for details. - */ - constructor(width?: number, height?: number, depth?: number, options?: RenderTargetOptions); - - textures: Data3DTexture[]; - - /** - * The texture property is overwritten with an instance of {@link Data3DTexture}. - */ - get texture(): Data3DTexture; - set texture(value: Data3DTexture); - - readonly isWebGL3DRenderTarget: true; -} diff --git a/src-testing/src/renderers/WebGLArrayRenderTarget.d.ts b/src-testing/src/renderers/WebGLArrayRenderTarget.d.ts deleted file mode 100644 index 1ac617889..000000000 --- a/src-testing/src/renderers/WebGLArrayRenderTarget.d.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { RenderTargetOptions } from "../core/RenderTarget.js"; -import { DataArrayTexture } from "../textures/DataArrayTexture.js"; -import { WebGLRenderTarget } from "./WebGLRenderTarget.js"; - -/** - * This type of render target represents an array of textures. - */ -export class WebGLArrayRenderTarget extends WebGLRenderTarget { - /** - * Creates a new WebGLArrayRenderTarget. - * - * @param width the width of the render target, in pixels. Default is `1`. - * @param height the height of the render target, in pixels. Default is `1`. - * @param depth the depth/layer count of the render target. Default is `1`. - * @param options optional object that holds texture parameters for an auto-generated target texture and - * depthBuffer/stencilBuffer booleans. See {@link WebGLRenderTarget} for details. - */ - constructor(width?: number, height?: number, depth?: number, options?: RenderTargetOptions); - - textures: DataArrayTexture[]; - - /** - * The texture property is overwritten with an instance of {@link DataArrayTexture}. - */ - get texture(): DataArrayTexture; - set texture(value: DataArrayTexture); - - readonly isWebGLArrayRenderTarget: true; -} diff --git a/src-testing/src/renderers/WebGLCubeRenderTarget.d.ts b/src-testing/src/renderers/WebGLCubeRenderTarget.d.ts deleted file mode 100644 index c390adb67..000000000 --- a/src-testing/src/renderers/WebGLCubeRenderTarget.d.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { RenderTargetOptions } from "../core/RenderTarget.js"; -import { CubeTexture } from "../textures/CubeTexture.js"; -import { Texture } from "../textures/Texture.js"; -import { WebGLRenderer } from "./WebGLRenderer.js"; -import { WebGLRenderTarget } from "./WebGLRenderTarget.js"; - -export class WebGLCubeRenderTarget extends WebGLRenderTarget { - constructor(size?: number, options?: RenderTargetOptions); - - textures: CubeTexture[]; - - get texture(): CubeTexture; - set texture(value: CubeTexture); - - fromEquirectangularTexture(renderer: WebGLRenderer, texture: Texture): this; - - clear(renderer: WebGLRenderer, color: boolean, depth: boolean, stencil: boolean): void; -} diff --git a/src-testing/src/renderers/WebGLRenderTarget.d.ts b/src-testing/src/renderers/WebGLRenderTarget.d.ts deleted file mode 100644 index fdff12e78..000000000 --- a/src-testing/src/renderers/WebGLRenderTarget.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { RenderTarget, RenderTargetOptions } from "../core/RenderTarget.js"; -import { Texture } from "../textures/Texture.js"; - -export class WebGLRenderTarget extends RenderTarget { - constructor(width?: number, height?: number, options?: RenderTargetOptions); - - readonly isWebGLRenderTarget: true; -} diff --git a/src-testing/src/renderers/WebGLRenderer.d.ts b/src-testing/src/renderers/WebGLRenderer.d.ts deleted file mode 100644 index 963fd850a..000000000 --- a/src-testing/src/renderers/WebGLRenderer.d.ts +++ /dev/null @@ -1,558 +0,0 @@ -import { Camera } from "../cameras/Camera.js"; -import { CullFace, ShadowMapType, ToneMapping, WebGLCoordinateSystem } from "../constants.js"; -import { TypedArray } from "../core/BufferAttribute.js"; -import { BufferGeometry } from "../core/BufferGeometry.js"; -import { Object3D } from "../core/Object3D.js"; -import { Material } from "../materials/Material.js"; -import { Box2 } from "../math/Box2.js"; -import { Box3 } from "../math/Box3.js"; -import { Color, ColorRepresentation } from "../math/Color.js"; -import { Plane } from "../math/Plane.js"; -import { Vector2 } from "../math/Vector2.js"; -import { Vector3 } from "../math/Vector3.js"; -import { Vector4 } from "../math/Vector4.js"; -import { Scene } from "../scenes/Scene.js"; -import { Data3DTexture } from "../textures/Data3DTexture.js"; -import { DataArrayTexture } from "../textures/DataArrayTexture.js"; -import { OffscreenCanvas, Texture } from "../textures/Texture.js"; -import { WebGLCapabilities, WebGLCapabilitiesParameters } from "./webgl/WebGLCapabilities.js"; -import { WebGLExtensions } from "./webgl/WebGLExtensions.js"; -import { WebGLInfo } from "./webgl/WebGLInfo.js"; -import { WebGLProgram } from "./webgl/WebGLProgram.js"; -import { WebGLProperties } from "./webgl/WebGLProperties.js"; -import { WebGLRenderLists } from "./webgl/WebGLRenderLists.js"; -import { WebGLShadowMap } from "./webgl/WebGLShadowMap.js"; -import { WebGLState } from "./webgl/WebGLState.js"; -import { WebGLRenderTarget } from "./WebGLRenderTarget.js"; -import { WebXRManager } from "./webxr/WebXRManager.js"; - -export interface Renderer { - domElement: HTMLCanvasElement; - - render(scene: Object3D, camera: Camera): void; - setSize(width: number, height: number, updateStyle?: boolean): void; -} - -export interface WebGLRendererParameters extends WebGLCapabilitiesParameters { - /** - * A Canvas where the renderer draws its output. - */ - canvas?: HTMLCanvasElement | OffscreenCanvas | undefined; - - /** - * A WebGL Rendering Context. - * (https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext) - * Default is null - */ - context?: WebGLRenderingContext | undefined; - - /** - * default is false. - */ - alpha?: boolean | undefined; - - /** - * default is true. - */ - premultipliedAlpha?: boolean | undefined; - - /** - * default is false. - */ - antialias?: boolean | undefined; - - /** - * default is false. - */ - stencil?: boolean | undefined; - - /** - * default is false. - */ - preserveDrawingBuffer?: boolean | undefined; - - /** - * Can be "high-performance", "low-power" or "default" - */ - powerPreference?: WebGLPowerPreference | undefined; - - /** - * default is true. - */ - depth?: boolean | undefined; - - /** - * default is false. - */ - failIfMajorPerformanceCaveat?: boolean | undefined; -} - -export interface WebGLDebug { - /** - * Enables error checking and reporting when shader programs are being compiled. - */ - checkShaderErrors: boolean; - - /** - * A callback function that can be used for custom error reporting. The callback receives the WebGL context, an - * instance of WebGLProgram as well two instances of WebGLShader representing the vertex and fragment shader. - * Assigning a custom function disables the default error reporting. - * @default `null` - */ - onShaderError: - | (( - gl: WebGLRenderingContext, - program: WebGLProgram, - glVertexShader: WebGLShader, - glFragmentShader: WebGLShader, - ) => void) - | null; -} - -/** - * The WebGL renderer displays your beautifully crafted scenes using WebGL, if your device supports it. - * This renderer has way better performance than CanvasRenderer. - * - * see {@link https://github.com/mrdoob/three.js/blob/master/src/renderers/WebGLRenderer.js|src/renderers/WebGLRenderer.js} - */ -export class WebGLRenderer implements Renderer { - /** - * parameters is an optional object with properties defining the renderer's behavior. - * The constructor also accepts no parameters at all. - * In all cases, it will assume sane defaults when parameters are missing. - */ - constructor(parameters?: WebGLRendererParameters); - - /** - * A Canvas where the renderer draws its output. - * This is automatically created by the renderer in the constructor (if not provided already); you just need to add it to your page. - * @default document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' ) - */ - domElement: HTMLCanvasElement; - - /** - * Defines whether the renderer should automatically clear its output before rendering. - * @default true - */ - autoClear: boolean; - - /** - * If autoClear is true, defines whether the renderer should clear the color buffer. Default is true. - * @default true - */ - autoClearColor: boolean; - - /** - * If autoClear is true, defines whether the renderer should clear the depth buffer. Default is true. - * @default true - */ - autoClearDepth: boolean; - - /** - * If autoClear is true, defines whether the renderer should clear the stencil buffer. Default is true. - * @default true - */ - autoClearStencil: boolean; - - /** - * Debug configurations. - * @default { checkShaderErrors: true } - */ - debug: WebGLDebug; - - /** - * Defines whether the renderer should sort objects. Default is true. - * @default true - */ - sortObjects: boolean; - - /** - * @default [] - */ - clippingPlanes: Plane[]; - - /** - * @default false - */ - localClippingEnabled: boolean; - - extensions: WebGLExtensions; - - /** - * Color space used for output to HTMLCanvasElement. Supported values are - * {@link SRGBColorSpace} and {@link LinearSRGBColorSpace}. - * @default THREE.SRGBColorSpace. - */ - get outputColorSpace(): string; - set outputColorSpace(colorSpace: string); - - get coordinateSystem(): typeof WebGLCoordinateSystem; - - /** - * @default THREE.NoToneMapping - */ - toneMapping: ToneMapping; - - /** - * @default 1 - */ - toneMappingExposure: number; - - info: WebGLInfo; - - shadowMap: WebGLShadowMap; - - pixelRatio: number; - - capabilities: WebGLCapabilities; - properties: WebGLProperties; - renderLists: WebGLRenderLists; - state: WebGLState; - - xr: WebXRManager; - - /** - * Return the WebGL context. - */ - getContext(): WebGLRenderingContext | WebGL2RenderingContext; - getContextAttributes(): any; - forceContextLoss(): void; - forceContextRestore(): void; - - /** - * @deprecated Use {@link WebGLCapabilities#getMaxAnisotropy .capabilities.getMaxAnisotropy()} instead. - */ - getMaxAnisotropy(): number; - - /** - * @deprecated Use {@link WebGLCapabilities#precision .capabilities.precision} instead. - */ - getPrecision(): string; - - getPixelRatio(): number; - setPixelRatio(value: number): void; - - getDrawingBufferSize(target: Vector2): Vector2; - setDrawingBufferSize(width: number, height: number, pixelRatio: number): void; - - getSize(target: Vector2): Vector2; - - /** - * Resizes the output canvas to (width, height), and also sets the viewport to fit that size, starting in (0, 0). - */ - setSize(width: number, height: number, updateStyle?: boolean): void; - - getCurrentViewport(target: Vector4): Vector4; - - /** - * Copies the viewport into target. - */ - getViewport(target: Vector4): Vector4; - - /** - * Sets the viewport to render from (x, y) to (x + width, y + height). - * (x, y) is the lower-left corner of the region. - */ - setViewport(x: Vector4 | number, y?: number, width?: number, height?: number): void; - - /** - * Copies the scissor area into target. - */ - getScissor(target: Vector4): Vector4; - - /** - * Sets the scissor area from (x, y) to (x + width, y + height). - */ - setScissor(x: Vector4 | number, y?: number, width?: number, height?: number): void; - - /** - * Returns true if scissor test is enabled; returns false otherwise. - */ - getScissorTest(): boolean; - - /** - * Enable the scissor test. When this is enabled, only the pixels within the defined scissor area will be affected by further renderer actions. - */ - setScissorTest(enable: boolean): void; - - /** - * Sets the custom opaque sort function for the WebGLRenderLists. Pass null to use the default painterSortStable function. - */ - setOpaqueSort(method: (a: any, b: any) => number): void; - - /** - * Sets the custom transparent sort function for the WebGLRenderLists. Pass null to use the default reversePainterSortStable function. - */ - setTransparentSort(method: (a: any, b: any) => number): void; - - /** - * Returns a THREE.Color instance with the current clear color. - */ - getClearColor(target: Color): Color; - - /** - * Sets the clear color, using color for the color and alpha for the opacity. - */ - setClearColor(color: ColorRepresentation, alpha?: number): void; - - /** - * Returns a float with the current clear alpha. Ranges from 0 to 1. - */ - getClearAlpha(): number; - - setClearAlpha(alpha: number): void; - - /** - * Tells the renderer to clear its color, depth or stencil drawing buffer(s). - * Arguments default to true - */ - clear(color?: boolean, depth?: boolean, stencil?: boolean): void; - - clearColor(): void; - clearDepth(): void; - clearStencil(): void; - clearTarget(renderTarget: WebGLRenderTarget, color: boolean, depth: boolean, stencil: boolean): void; - - /** - * @deprecated Use {@link WebGLState#reset .state.reset()} instead. - */ - resetGLState(): void; - dispose(): void; - - renderBufferDirect( - camera: Camera, - scene: Scene, - geometry: BufferGeometry, - material: Material, - object: Object3D, - geometryGroup: any, - ): void; - - /** - * A build in function that can be used instead of requestAnimationFrame. For WebXR projects this function must be used. - * @param callback The function will be called every available frame. If `null` is passed it will stop any already ongoing animation. - */ - setAnimationLoop(callback: XRFrameRequestCallback | null): void; - - /** - * @deprecated Use {@link WebGLRenderer#setAnimationLoop .setAnimationLoop()} instead. - */ - animate(callback: () => void): void; - - /** - * Compiles all materials in the scene with the camera. This is useful to precompile shaders before the first - * rendering. If you want to add a 3D object to an existing scene, use the third optional parameter for applying the - * target scene. - * Note that the (target) scene's lighting should be configured before calling this method. - */ - compile: (scene: Object3D, camera: Camera, targetScene?: Scene | null) => Set; - - /** - * Asynchronous version of {@link compile}(). The method returns a Promise that resolves when the given scene can be - * rendered without unnecessary stalling due to shader compilation. - * This method makes use of the KHR_parallel_shader_compile WebGL extension. - */ - compileAsync: (scene: Object3D, camera: Camera, targetScene?: Scene | null) => Promise; - - /** - * Render a scene or an object using a camera. - * The render is done to a previously specified {@link WebGLRenderTarget#renderTarget .renderTarget} set by calling - * {@link WebGLRenderer#setRenderTarget .setRenderTarget} or to the canvas as usual. - * - * By default render buffers are cleared before rendering but you can prevent this by setting the property - * {@link WebGLRenderer#autoClear autoClear} to false. If you want to prevent only certain buffers being cleared - * you can set either the {@link WebGLRenderer#autoClearColor autoClearColor}, - * {@link WebGLRenderer#autoClearStencil autoClearStencil} or {@link WebGLRenderer#autoClearDepth autoClearDepth} - * properties to false. To forcibly clear one ore more buffers call {@link WebGLRenderer#clear .clear}. - */ - render(scene: Object3D, camera: Camera): void; - - /** - * Returns the current active cube face. - */ - getActiveCubeFace(): number; - - /** - * Returns the current active mipmap level. - */ - getActiveMipmapLevel(): number; - - /** - * Returns the current render target. If no render target is set, null is returned. - */ - getRenderTarget(): WebGLRenderTarget | null; - - /** - * @deprecated Use {@link WebGLRenderer#getRenderTarget .getRenderTarget()} instead. - */ - getCurrentRenderTarget(): WebGLRenderTarget | null; - - /** - * Sets the active render target. - * - * @param renderTarget The {@link WebGLRenderTarget renderTarget} that needs to be activated. When `null` is given, the canvas is set as the active render target instead. - * @param activeCubeFace Specifies the active cube side (PX 0, NX 1, PY 2, NY 3, PZ 4, NZ 5) of {@link WebGLCubeRenderTarget}. - * @param activeMipmapLevel Specifies the active mipmap level. - */ - setRenderTarget( - renderTarget: WebGLRenderTarget | WebGLRenderTarget | null, - activeCubeFace?: number, - activeMipmapLevel?: number, - ): void; - - readRenderTargetPixels( - renderTarget: WebGLRenderTarget | WebGLRenderTarget, - x: number, - y: number, - width: number, - height: number, - buffer: TypedArray, - activeCubeFaceIndex?: number, - ): void; - - readRenderTargetPixelsAsync( - renderTarget: WebGLRenderTarget | WebGLRenderTarget, - x: number, - y: number, - width: number, - height: number, - buffer: TypedArray, - activeCubeFaceIndex?: number, - ): Promise; - - /** - * Copies a region of the currently bound framebuffer into the selected mipmap level of the selected texture. - * This region is defined by the size of the destination texture's mip level, offset by the input position. - * - * @param texture Specifies the destination texture. - * @param position Specifies the pixel offset from which to copy out of the framebuffer. - * @param level Specifies the destination mipmap level of the texture. - */ - copyFramebufferToTexture(texture: Texture, position?: Vector2 | null, level?: number): void; - - /** - * Copies the pixels of a texture in the bounds `srcRegion` in the destination texture starting from the given - * position. The `depthTexture` and `texture` property of render targets are supported as well. - * - * When using render target textures as `srcTexture` and `dstTexture`, you must make sure both render targets are - * intitialized e.g. via {@link .initRenderTarget}(). - * - * @param srcTexture Specifies the source texture. - * @param dstTexture Specifies the destination texture. - * @param srcRegion Specifies the bounds - * @param dstPosition Specifies the pixel offset into the dstTexture where the copy will occur. - * @param level Specifies the destination mipmap level of the texture. - */ - copyTextureToTexture( - srcTexture: Texture, - dstTexture: Texture, - srcRegion?: Box2 | null, - dstPosition?: Vector2 | null, - level?: number, - ): void; - - /** - * Copies the pixels of a texture in the bounds `srcRegion` in the destination texture starting from the given - * position. The `depthTexture` and `texture` property of 3D render targets are supported as well. - * - * When using render target textures as `srcTexture` and `dstTexture`, you must make sure both render targets are - * intitialized e.g. via {@link .initRenderTarget}(). - * - * @param srcTexture Specifies the source texture. - * @param dstTexture Specifies the destination texture. - * @param srcRegion Specifies the bounds - * @param dstPosition Specifies the pixel offset into the dstTexture where the copy will occur. - * @param level Specifies the destination mipmap level of the texture. - */ - copyTextureToTexture3D( - srcTexture: Texture, - dstTexture: Data3DTexture | DataArrayTexture, - srcRegion?: Box3 | null, - dstPosition?: Vector3 | null, - level?: number, - ): void; - - /** - * Initializes the given WebGLRenderTarget memory. Useful for initializing a render target so data can be copied - * into it using {@link WebGLRenderer.copyTextureToTexture} before it has been rendered to. - * @param target - */ - initRenderTarget(target: WebGLRenderTarget): void; - - /** - * Initializes the given texture. Can be used to preload a texture rather than waiting until first render (which can cause noticeable lags due to decode and GPU upload overhead). - * - * @param texture The texture to Initialize. - */ - initTexture(texture: Texture): void; - - /** - * Can be used to reset the internal WebGL state. - */ - resetState(): void; - - /** - * @deprecated Use {@link WebGLRenderer#xr .xr} instead. - */ - vr: boolean; - - /** - * @deprecated Use {@link WebGLShadowMap#enabled .shadowMap.enabled} instead. - */ - shadowMapEnabled: boolean; - - /** - * @deprecated Use {@link WebGLShadowMap#type .shadowMap.type} instead. - */ - shadowMapType: ShadowMapType; - - /** - * @deprecated Use {@link WebGLShadowMap#cullFace .shadowMap.cullFace} instead. - */ - shadowMapCullFace: CullFace; - - /** - * @deprecated Use {@link WebGLExtensions#get .extensions.get( 'OES_texture_float' )} instead. - */ - supportsFloatTextures(): any; - - /** - * @deprecated Use {@link WebGLExtensions#get .extensions.get( 'OES_texture_half_float' )} instead. - */ - supportsHalfFloatTextures(): any; - - /** - * @deprecated Use {@link WebGLExtensions#get .extensions.get( 'OES_standard_derivatives' )} instead. - */ - supportsStandardDerivatives(): any; - - /** - * @deprecated Use {@link WebGLExtensions#get .extensions.get( 'WEBGL_compressed_texture_s3tc' )} instead. - */ - supportsCompressedTextureS3TC(): any; - - /** - * @deprecated Use {@link WebGLExtensions#get .extensions.get( 'WEBGL_compressed_texture_pvrtc' )} instead. - */ - supportsCompressedTexturePVRTC(): any; - - /** - * @deprecated Use {@link WebGLExtensions#get .extensions.get( 'EXT_blend_minmax' )} instead. - */ - supportsBlendMinMax(): any; - - /** - * @deprecated Use {@link WebGLCapabilities#vertexTextures .capabilities.vertexTextures} instead. - */ - supportsVertexTextures(): any; - - /** - * @deprecated Use {@link WebGLExtensions#get .extensions.get( 'ANGLE_instanced_arrays' )} instead. - */ - supportsInstancedArrays(): any; - - /** - * @deprecated Use {@link WebGLRenderer#setScissorTest .setScissorTest()} instead. - */ - enableScissorTest(boolean: any): any; -} diff --git a/src-testing/src/renderers/common/Animation.ts b/src-testing/src/renderers/common/Animation.ts deleted file mode 100644 index 0b00319a1..000000000 --- a/src-testing/src/renderers/common/Animation.ts +++ /dev/null @@ -1,38 +0,0 @@ -class Animation { - constructor(nodes, info) { - this.nodes = nodes; - this.info = info; - - this.animationLoop = null; - this.requestId = null; - - this._init(); - } - - _init() { - const update = (time, frame) => { - this.requestId = self.requestAnimationFrame(update); - - if (this.info.autoReset === true) this.info.reset(); - - this.nodes.nodeFrame.update(); - - this.info.frame = this.nodes.nodeFrame.frameId; - - if (this.animationLoop !== null) this.animationLoop(time, frame); - }; - - update(); - } - - dispose() { - self.cancelAnimationFrame(this.requestId); - this.requestId = null; - } - - setAnimationLoop(callback) { - this.animationLoop = callback; - } -} - -export default Animation; diff --git a/src-testing/src/renderers/common/Attributes.ts b/src-testing/src/renderers/common/Attributes.ts deleted file mode 100644 index 4631d528b..000000000 --- a/src-testing/src/renderers/common/Attributes.ts +++ /dev/null @@ -1,56 +0,0 @@ -import DataMap from './DataMap.js'; -import { AttributeType } from './Constants.js'; - -import { DynamicDrawUsage } from '../../constants.js'; - -class Attributes extends DataMap { - constructor(backend) { - super(); - - this.backend = backend; - } - - delete(attribute) { - const attributeData = super.delete(attribute); - - if (attributeData !== undefined) { - this.backend.destroyAttribute(attribute); - } - - return attributeData; - } - - update(attribute, type) { - const data = this.get(attribute); - - if (data.version === undefined) { - if (type === AttributeType.VERTEX) { - this.backend.createAttribute(attribute); - } else if (type === AttributeType.INDEX) { - this.backend.createIndexAttribute(attribute); - } else if (type === AttributeType.STORAGE) { - this.backend.createStorageAttribute(attribute); - } else if (type === AttributeType.INDIRECT) { - this.backend.createIndirectStorageAttribute(attribute); - } - - data.version = this._getBufferAttribute(attribute).version; - } else { - const bufferAttribute = this._getBufferAttribute(attribute); - - if (data.version < bufferAttribute.version || bufferAttribute.usage === DynamicDrawUsage) { - this.backend.updateAttribute(attribute); - - data.version = bufferAttribute.version; - } - } - } - - _getBufferAttribute(attribute) { - if (attribute.isInterleavedBufferAttribute) attribute = attribute.data; - - return attribute; - } -} - -export default Attributes; diff --git a/src-testing/src/renderers/common/Backend.ts b/src-testing/src/renderers/common/Backend.ts deleted file mode 100644 index edd4fcf9c..000000000 --- a/src-testing/src/renderers/common/Backend.ts +++ /dev/null @@ -1,170 +0,0 @@ -let vector2 = null; -let vector4 = null; -let color4 = null; - -import Color4 from './Color4.js'; -import { Vector2 } from '../../math/Vector2.js'; -import { Vector4 } from '../../math/Vector4.js'; -import { createCanvasElement } from '../../utils.js'; -import { REVISION } from '../../constants.js'; - -class Backend { - constructor(parameters = {}) { - this.parameters = Object.assign({}, parameters); - this.data = new WeakMap(); - this.renderer = null; - this.domElement = null; - } - - async init(renderer) { - this.renderer = renderer; - } - - // render context - - begin(/*renderContext*/) {} - - finish(/*renderContext*/) {} - - // render object - - draw(/*renderObject, info*/) {} - - // program - - createProgram(/*program*/) {} - - destroyProgram(/*program*/) {} - - // bindings - - createBindings(/*bingGroup, bindings*/) {} - - updateBindings(/*bingGroup, bindings*/) {} - - // pipeline - - createRenderPipeline(/*renderObject*/) {} - - createComputePipeline(/*computeNode, pipeline*/) {} - - destroyPipeline(/*pipeline*/) {} - - // cache key - - needsRenderUpdate(/*renderObject*/) {} // return Boolean ( fast test ) - - getRenderCacheKey(/*renderObject*/) {} // return String - - // node builder - - createNodeBuilder(/*renderObject*/) {} // return NodeBuilder (ADD IT) - - // textures - - createSampler(/*texture*/) {} - - createDefaultTexture(/*texture*/) {} - - createTexture(/*texture*/) {} - - copyTextureToBuffer(/*texture, x, y, width, height*/) {} - - // attributes - - createAttribute(/*attribute*/) {} - - createIndexAttribute(/*attribute*/) {} - - updateAttribute(/*attribute*/) {} - - destroyAttribute(/*attribute*/) {} - - // canvas - - getContext() {} - - updateSize() {} - - // utils - - resolveTimestampAsync(/*renderContext, type*/) {} - - hasFeatureAsync(/*name*/) {} // return Boolean - - hasFeature(/*name*/) {} // return Boolean - - getInstanceCount(renderObject) { - const { object, geometry } = renderObject; - - return geometry.isInstancedBufferGeometry ? geometry.instanceCount : object.count > 1 ? object.count : 1; - } - - getDrawingBufferSize() { - vector2 = vector2 || new Vector2(); - - return this.renderer.getDrawingBufferSize(vector2); - } - - getScissor() { - vector4 = vector4 || new Vector4(); - - return this.renderer.getScissor(vector4); - } - - setScissorTest(/*boolean*/) {} - - getClearColor() { - const renderer = this.renderer; - - color4 = color4 || new Color4(); - - renderer.getClearColor(color4); - - color4.getRGB(color4, this.renderer.currentColorSpace); - - return color4; - } - - getDomElement() { - let domElement = this.domElement; - - if (domElement === null) { - domElement = this.parameters.canvas !== undefined ? this.parameters.canvas : createCanvasElement(); - - // OffscreenCanvas does not have setAttribute, see #22811 - if ('setAttribute' in domElement) domElement.setAttribute('data-engine', `three.js r${REVISION} webgpu`); - - this.domElement = domElement; - } - - return domElement; - } - - // resource properties - - set(object, value) { - this.data.set(object, value); - } - - get(object) { - let map = this.data.get(object); - - if (map === undefined) { - map = {}; - this.data.set(object, map); - } - - return map; - } - - has(object) { - return this.data.has(object); - } - - delete(object) { - this.data.delete(object); - } -} - -export default Backend; diff --git a/src-testing/src/renderers/common/Background.ts b/src-testing/src/renderers/common/Background.ts deleted file mode 100644 index b56dd3724..000000000 --- a/src-testing/src/renderers/common/Background.ts +++ /dev/null @@ -1,133 +0,0 @@ -import DataMap from './DataMap.js'; -import Color4 from './Color4.js'; -import { - vec4, - context, - normalWorld, - backgroundBlurriness, - backgroundIntensity, - modelViewProjection, -} from '../../nodes/TSL.js'; -import NodeMaterial from '../../materials/nodes/NodeMaterial.js'; - -import { Mesh } from '../../objects/Mesh.js'; -import { SphereGeometry } from '../../geometries/SphereGeometry.js'; -import { BackSide, LinearSRGBColorSpace } from '../../constants.js'; - -const _clearColor = /*@__PURE__*/ new Color4(); - -class Background extends DataMap { - constructor(renderer, nodes) { - super(); - - this.renderer = renderer; - this.nodes = nodes; - } - - update(scene, renderList, renderContext) { - const renderer = this.renderer; - const background = this.nodes.getBackgroundNode(scene) || scene.background; - - let forceClear = false; - - if (background === null) { - // no background settings, use clear color configuration from the renderer - - renderer._clearColor.getRGB(_clearColor, LinearSRGBColorSpace); - _clearColor.a = renderer._clearColor.a; - } else if (background.isColor === true) { - // background is an opaque color - - background.getRGB(_clearColor, LinearSRGBColorSpace); - _clearColor.a = 1; - - forceClear = true; - } else if (background.isNode === true) { - const sceneData = this.get(scene); - const backgroundNode = background; - - _clearColor.copy(renderer._clearColor); - - let backgroundMesh = sceneData.backgroundMesh; - - if (backgroundMesh === undefined) { - const backgroundMeshNode = context(vec4(backgroundNode).mul(backgroundIntensity), { - // @TODO: Add Texture2D support using node context - getUV: () => normalWorld, - getTextureLevel: () => backgroundBlurriness, - }); - - let viewProj = modelViewProjection(); - viewProj = viewProj.setZ(viewProj.w); - - const nodeMaterial = new NodeMaterial(); - nodeMaterial.name = 'Background.material'; - nodeMaterial.side = BackSide; - nodeMaterial.depthTest = false; - nodeMaterial.depthWrite = false; - nodeMaterial.fog = false; - nodeMaterial.lights = false; - nodeMaterial.vertexNode = viewProj; - nodeMaterial.colorNode = backgroundMeshNode; - - sceneData.backgroundMeshNode = backgroundMeshNode; - sceneData.backgroundMesh = backgroundMesh = new Mesh(new SphereGeometry(1, 32, 32), nodeMaterial); - backgroundMesh.frustumCulled = false; - backgroundMesh.name = 'Background.mesh'; - - backgroundMesh.onBeforeRender = function (renderer, scene, camera) { - this.matrixWorld.copyPosition(camera.matrixWorld); - }; - } - - const backgroundCacheKey = backgroundNode.getCacheKey(); - - if (sceneData.backgroundCacheKey !== backgroundCacheKey) { - sceneData.backgroundMeshNode.node = vec4(backgroundNode).mul(backgroundIntensity); - sceneData.backgroundMeshNode.needsUpdate = true; - - backgroundMesh.material.needsUpdate = true; - - sceneData.backgroundCacheKey = backgroundCacheKey; - } - - renderList.unshift(backgroundMesh, backgroundMesh.geometry, backgroundMesh.material, 0, 0, null); - } else { - console.error('THREE.Renderer: Unsupported background configuration.', background); - } - - // - - if (renderer.autoClear === true || forceClear === true) { - const clearColorValue = renderContext.clearColorValue; - - clearColorValue.r = _clearColor.r; - clearColorValue.g = _clearColor.g; - clearColorValue.b = _clearColor.b; - clearColorValue.a = _clearColor.a; - - // premultiply alpha - - if (renderer.backend.isWebGLBackend === true || renderer.alpha === true) { - clearColorValue.r *= clearColorValue.a; - clearColorValue.g *= clearColorValue.a; - clearColorValue.b *= clearColorValue.a; - } - - // - - renderContext.depthClearValue = renderer._clearDepth; - renderContext.stencilClearValue = renderer._clearStencil; - - renderContext.clearColor = renderer.autoClearColor === true; - renderContext.clearDepth = renderer.autoClearDepth === true; - renderContext.clearStencil = renderer.autoClearStencil === true; - } else { - renderContext.clearColor = false; - renderContext.clearDepth = false; - renderContext.clearStencil = false; - } - } -} - -export default Background; diff --git a/src-testing/src/renderers/common/BindGroup.ts b/src-testing/src/renderers/common/BindGroup.ts deleted file mode 100644 index ae78d4787..000000000 --- a/src-testing/src/renderers/common/BindGroup.ts +++ /dev/null @@ -1,14 +0,0 @@ -let _id = 0; - -class BindGroup { - constructor(name = '', bindings = [], index = 0, bindingsReference = []) { - this.name = name; - this.bindings = bindings; - this.index = index; - this.bindingsReference = bindingsReference; - - this.id = _id++; - } -} - -export default BindGroup; diff --git a/src-testing/src/renderers/common/Binding.ts b/src-testing/src/renderers/common/Binding.ts deleted file mode 100644 index a12f3563b..000000000 --- a/src-testing/src/renderers/common/Binding.ts +++ /dev/null @@ -1,17 +0,0 @@ -class Binding { - constructor(name = '') { - this.name = name; - - this.visibility = 0; - } - - setVisibility(visibility) { - this.visibility |= visibility; - } - - clone() { - return Object.assign(new this.constructor(), this); - } -} - -export default Binding; diff --git a/src-testing/src/renderers/common/Bindings.ts b/src-testing/src/renderers/common/Bindings.ts deleted file mode 100644 index 1414c94fb..000000000 --- a/src-testing/src/renderers/common/Bindings.ts +++ /dev/null @@ -1,160 +0,0 @@ -import DataMap from './DataMap.js'; -import { AttributeType } from './Constants.js'; - -class Bindings extends DataMap { - constructor(backend, nodes, textures, attributes, pipelines, info) { - super(); - - this.backend = backend; - this.textures = textures; - this.pipelines = pipelines; - this.attributes = attributes; - this.nodes = nodes; - this.info = info; - - this.pipelines.bindings = this; // assign bindings to pipelines - } - - getForRender(renderObject) { - const bindings = renderObject.getBindings(); - - for (const bindGroup of bindings) { - const groupData = this.get(bindGroup); - - if (groupData.bindGroup === undefined) { - // each object defines an array of bindings (ubos, textures, samplers etc.) - - this._init(bindGroup); - - this.backend.createBindings(bindGroup, bindings); - - groupData.bindGroup = bindGroup; - } - } - - return bindings; - } - - getForCompute(computeNode) { - const bindings = this.nodes.getForCompute(computeNode).bindings; - - for (const bindGroup of bindings) { - const groupData = this.get(bindGroup); - - if (groupData.bindGroup === undefined) { - this._init(bindGroup); - - this.backend.createBindings(bindGroup, bindings); - - groupData.bindGroup = bindGroup; - } - } - - return bindings; - } - - updateForCompute(computeNode) { - this._updateBindings(this.getForCompute(computeNode)); - } - - updateForRender(renderObject) { - this._updateBindings(this.getForRender(renderObject)); - } - - _updateBindings(bindings) { - for (const bindGroup of bindings) { - this._update(bindGroup, bindings); - } - } - - _init(bindGroup) { - for (const binding of bindGroup.bindings) { - if (binding.isSampledTexture) { - this.textures.updateTexture(binding.texture); - } else if (binding.isStorageBuffer) { - const attribute = binding.attribute; - const attributeType = attribute.isIndirectStorageBufferAttribute - ? AttributeType.INDIRECT - : AttributeType.STORAGE; - - this.attributes.update(attribute, attributeType); - } - } - } - - _update(bindGroup, bindings) { - const { backend } = this; - - let needsBindingsUpdate = false; - - // iterate over all bindings and check if buffer updates or a new binding group is required - - for (const binding of bindGroup.bindings) { - if (binding.isNodeUniformsGroup) { - const updated = this.nodes.updateGroup(binding); - - if (!updated) continue; - } - - if (binding.isUniformBuffer) { - const updated = binding.update(); - - if (updated) { - backend.updateBinding(binding); - } - } else if (binding.isSampler) { - binding.update(); - } else if (binding.isSampledTexture) { - if (binding.needsBindingsUpdate(this.textures.get(binding.texture).generation)) - needsBindingsUpdate = true; - - const updated = binding.update(); - - const texture = binding.texture; - - if (updated) { - this.textures.updateTexture(texture); - } - - const textureData = backend.get(texture); - - if ( - backend.isWebGPUBackend === true && - textureData.texture === undefined && - textureData.externalTexture === undefined - ) { - // TODO: Remove this once we found why updated === false isn't bound to a texture in the WebGPU backend - console.error( - 'Bindings._update: binding should be available:', - binding, - updated, - texture, - binding.textureNode.value, - needsBindingsUpdate, - ); - - this.textures.updateTexture(texture); - needsBindingsUpdate = true; - } - - if (texture.isStorageTexture === true) { - const textureData = this.get(texture); - - if (binding.store === true) { - textureData.needsMipmap = true; - } else if (this.textures.needsMipmaps(texture) && textureData.needsMipmap === true) { - this.backend.generateMipmaps(texture); - - textureData.needsMipmap = false; - } - } - } - } - - if (needsBindingsUpdate === true) { - this.backend.updateBindings(bindGroup, bindings); - } - } -} - -export default Bindings; diff --git a/src-testing/src/renderers/common/Buffer.ts b/src-testing/src/renderers/common/Buffer.ts deleted file mode 100644 index 17013c6dc..000000000 --- a/src-testing/src/renderers/common/Buffer.ts +++ /dev/null @@ -1,28 +0,0 @@ -import Binding from './Binding.js'; -import { getFloatLength } from './BufferUtils.js'; - -class Buffer extends Binding { - constructor(name, buffer = null) { - super(name); - - this.isBuffer = true; - - this.bytesPerElement = Float32Array.BYTES_PER_ELEMENT; - - this._buffer = buffer; - } - - get byteLength() { - return getFloatLength(this._buffer.byteLength); - } - - get buffer() { - return this._buffer; - } - - update() { - return true; - } -} - -export default Buffer; diff --git a/src-testing/src/renderers/common/BufferUtils.ts b/src-testing/src/renderers/common/BufferUtils.ts deleted file mode 100644 index 99ddcb48b..000000000 --- a/src-testing/src/renderers/common/BufferUtils.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { GPU_CHUNK_BYTES } from './Constants.js'; - -function getFloatLength(floatLength) { - // ensure chunk size alignment (STD140 layout) - - return floatLength + ((GPU_CHUNK_BYTES - (floatLength % GPU_CHUNK_BYTES)) % GPU_CHUNK_BYTES); -} - -function getVectorLength(count, vectorLength = 4) { - const strideLength = getStrideLength(vectorLength); - - const floatLength = strideLength * count; - - return getFloatLength(floatLength); -} - -function getStrideLength(vectorLength) { - const strideLength = 4; - - return vectorLength + ((strideLength - (vectorLength % strideLength)) % strideLength); -} - -export { getFloatLength, getVectorLength, getStrideLength }; diff --git a/src-testing/src/renderers/common/BundleGroup.ts b/src-testing/src/renderers/common/BundleGroup.ts deleted file mode 100644 index 1dd8e0a2c..000000000 --- a/src-testing/src/renderers/common/BundleGroup.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Group } from '../../objects/Group.js'; - -class BundleGroup extends Group { - constructor() { - super(); - - this.isBundleGroup = true; - - this.type = 'BundleGroup'; - - this.static = true; - this.version = 0; - } - - set needsUpdate(value) { - if (value === true) this.version++; - } -} - -export default BundleGroup; diff --git a/src-testing/src/renderers/common/ChainMap.ts b/src-testing/src/renderers/common/ChainMap.ts deleted file mode 100644 index b17e7080f..000000000 --- a/src-testing/src/renderers/common/ChainMap.ts +++ /dev/null @@ -1,43 +0,0 @@ -export default class ChainMap { - constructor() { - this.weakMap = new WeakMap(); - } - - get(keys) { - let map = this.weakMap; - - for (let i = 0; i < keys.length; i++) { - map = map.get(keys[i]); - - if (map === undefined) return undefined; - } - - return map.get(keys[keys.length - 1]); - } - - set(keys, value) { - let map = this.weakMap; - - for (let i = 0; i < keys.length; i++) { - const key = keys[i]; - - if (map.has(key) === false) map.set(key, new WeakMap()); - - map = map.get(key); - } - - return map.set(keys[keys.length - 1], value); - } - - delete(keys) { - let map = this.weakMap; - - for (let i = 0; i < keys.length; i++) { - map = map.get(keys[i]); - - if (map === undefined) return false; - } - - return map.delete(keys[keys.length - 1]); - } -} diff --git a/src-testing/src/renderers/common/ClippingContext.ts b/src-testing/src/renderers/common/ClippingContext.ts deleted file mode 100644 index c5659721a..000000000 --- a/src-testing/src/renderers/common/ClippingContext.ts +++ /dev/null @@ -1,136 +0,0 @@ -import { Matrix3 } from '../../math/Matrix3.js'; -import { Plane } from '../../math/Plane.js'; -import { Vector4 } from '../../math/Vector4.js'; -import { hash } from '../../nodes/core/NodeUtils.js'; - -const _plane = /*@__PURE__*/ new Plane(); - -class ClippingContext { - constructor() { - this.version = 0; - - this.globalClippingCount = 0; - - this.localClippingCount = 0; - this.localClippingEnabled = false; - this.localClipIntersection = false; - - this.planes = []; - - this.parentVersion = 0; - this.viewNormalMatrix = new Matrix3(); - this.cacheKey = 0; - } - - projectPlanes(source, offset) { - const l = source.length; - const planes = this.planes; - - for (let i = 0; i < l; i++) { - _plane.copy(source[i]).applyMatrix4(this.viewMatrix, this.viewNormalMatrix); - - const v = planes[offset + i]; - const normal = _plane.normal; - - v.x = -normal.x; - v.y = -normal.y; - v.z = -normal.z; - v.w = _plane.constant; - } - } - - updateGlobal(renderer, camera) { - const rendererClippingPlanes = renderer.clippingPlanes; - this.viewMatrix = camera.matrixWorldInverse; - - this.viewNormalMatrix.getNormalMatrix(this.viewMatrix); - - let update = false; - - if (Array.isArray(rendererClippingPlanes) && rendererClippingPlanes.length !== 0) { - const l = rendererClippingPlanes.length; - - if (l !== this.globalClippingCount) { - const planes = []; - - for (let i = 0; i < l; i++) { - planes.push(new Vector4()); - } - - this.globalClippingCount = l; - this.planes = planes; - - update = true; - } - - this.projectPlanes(rendererClippingPlanes, 0); - } else if (this.globalClippingCount !== 0) { - this.globalClippingCount = 0; - this.planes = []; - update = true; - } - - if (renderer.localClippingEnabled !== this.localClippingEnabled) { - this.localClippingEnabled = renderer.localClippingEnabled; - update = true; - } - - if (update) { - this.version++; - this.cacheKey = hash(this.globalClippingCount, this.localClippingEnabled === true ? 1 : 0); - } - } - - update(parent, material) { - let update = false; - - if (this !== parent && parent.version !== this.parentVersion) { - this.globalClippingCount = material.isShadowNodeMaterial ? 0 : parent.globalClippingCount; - this.localClippingEnabled = parent.localClippingEnabled; - this.planes = Array.from(parent.planes); - this.parentVersion = parent.version; - this.viewMatrix = parent.viewMatrix; - this.viewNormalMatrix = parent.viewNormalMatrix; - - update = true; - } - - if (this.localClippingEnabled) { - const localClippingPlanes = material.clippingPlanes; - - if (Array.isArray(localClippingPlanes) && localClippingPlanes.length !== 0) { - const l = localClippingPlanes.length; - const planes = this.planes; - const offset = this.globalClippingCount; - - if (update || l !== this.localClippingCount) { - planes.length = offset + l; - - for (let i = 0; i < l; i++) { - planes[offset + i] = new Vector4(); - } - - this.localClippingCount = l; - update = true; - } - - this.projectPlanes(localClippingPlanes, offset); - } else if (this.localClippingCount !== 0) { - this.localClippingCount = 0; - update = true; - } - - if (this.localClipIntersection !== material.clipIntersection) { - this.localClipIntersection = material.clipIntersection; - update = true; - } - } - - if (update) { - this.version += parent.version; - this.cacheKey = hash(parent.cacheKey, this.localClippingCount, this.localClipIntersection === true ? 1 : 0); - } - } -} - -export default ClippingContext; diff --git a/src-testing/src/renderers/common/Color4.ts b/src-testing/src/renderers/common/Color4.ts deleted file mode 100644 index 77caa31e0..000000000 --- a/src-testing/src/renderers/common/Color4.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { Color } from '../../math/Color.js'; - -class Color4 extends Color { - constructor(r, g, b, a = 1) { - super(r, g, b); - - this.a = a; - } - - set(r, g, b, a = 1) { - this.a = a; - - return super.set(r, g, b); - } - - copy(color) { - if (color.a !== undefined) this.a = color.a; - - return super.copy(color); - } - - clone() { - return new this.constructor(this.r, this.g, this.b, this.a); - } -} - -export default Color4; diff --git a/src-testing/src/renderers/common/ComputePipeline.ts b/src-testing/src/renderers/common/ComputePipeline.ts deleted file mode 100644 index 0fd3ca531..000000000 --- a/src-testing/src/renderers/common/ComputePipeline.ts +++ /dev/null @@ -1,13 +0,0 @@ -import Pipeline from './Pipeline.js'; - -class ComputePipeline extends Pipeline { - constructor(cacheKey, computeProgram) { - super(cacheKey); - - this.computeProgram = computeProgram; - - this.isComputePipeline = true; - } -} - -export default ComputePipeline; diff --git a/src-testing/src/renderers/common/Constants.ts b/src-testing/src/renderers/common/Constants.ts deleted file mode 100644 index c2dfad4c4..000000000 --- a/src-testing/src/renderers/common/Constants.ts +++ /dev/null @@ -1,15 +0,0 @@ -export const AttributeType = { - VERTEX: 1, - INDEX: 2, - STORAGE: 3, - INDIRECT: 4, -}; - -// size of a chunk in bytes (STD140 layout) - -export const GPU_CHUNK_BYTES = 16; - -// @TODO: Move to src/constants.js - -export const BlendColorFactor = 211; -export const OneMinusBlendColorFactor = 212; diff --git a/src-testing/src/renderers/common/CubeRenderTarget.ts b/src-testing/src/renderers/common/CubeRenderTarget.ts deleted file mode 100644 index 00c0fd8c4..000000000 --- a/src-testing/src/renderers/common/CubeRenderTarget.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { equirectUV } from '../../nodes/utils/EquirectUVNode.js'; -import { texture as TSL_Texture } from '../../nodes/accessors/TextureNode.js'; -import { positionWorldDirection } from '../../nodes/accessors/Position.js'; -import NodeMaterial from '../../materials/nodes/NodeMaterial.js'; - -import { WebGLCubeRenderTarget } from '../../renderers/WebGLCubeRenderTarget.js'; -import { Scene } from '../../scenes/Scene.js'; -import { CubeCamera } from '../../cameras/CubeCamera.js'; -import { BoxGeometry } from '../../geometries/BoxGeometry.js'; -import { Mesh } from '../../objects/Mesh.js'; -import { BackSide, NoBlending, LinearFilter, LinearMipmapLinearFilter } from '../../constants.js'; - -// @TODO: Consider rename WebGLCubeRenderTarget to just CubeRenderTarget - -class CubeRenderTarget extends WebGLCubeRenderTarget { - constructor(size = 1, options = {}) { - super(size, options); - - this.isCubeRenderTarget = true; - } - - fromEquirectangularTexture(renderer, texture) { - const currentMinFilter = texture.minFilter; - const currentGenerateMipmaps = texture.generateMipmaps; - - texture.generateMipmaps = true; - - this.texture.type = texture.type; - this.texture.colorSpace = texture.colorSpace; - - this.texture.generateMipmaps = texture.generateMipmaps; - this.texture.minFilter = texture.minFilter; - this.texture.magFilter = texture.magFilter; - - const geometry = new BoxGeometry(5, 5, 5); - - const uvNode = equirectUV(positionWorldDirection); - - const material = new NodeMaterial(); - material.colorNode = TSL_Texture(texture, uvNode, 0); - material.side = BackSide; - material.blending = NoBlending; - - const mesh = new Mesh(geometry, material); - - const scene = new Scene(); - scene.add(mesh); - - // Avoid blurred poles - if (texture.minFilter === LinearMipmapLinearFilter) texture.minFilter = LinearFilter; - - const camera = new CubeCamera(1, 10, this); - - const currentMRT = renderer.getMRT(); - renderer.setMRT(null); - - camera.update(renderer, scene); - - renderer.setMRT(currentMRT); - - texture.minFilter = currentMinFilter; - texture.currentGenerateMipmaps = currentGenerateMipmaps; - - mesh.geometry.dispose(); - mesh.material.dispose(); - - return this; - } -} - -export default CubeRenderTarget; diff --git a/src-testing/src/renderers/common/DataMap.ts b/src-testing/src/renderers/common/DataMap.ts deleted file mode 100644 index 006bc2950..000000000 --- a/src-testing/src/renderers/common/DataMap.ts +++ /dev/null @@ -1,38 +0,0 @@ -class DataMap { - constructor() { - this.data = new WeakMap(); - } - - get(object) { - let map = this.data.get(object); - - if (map === undefined) { - map = {}; - this.data.set(object, map); - } - - return map; - } - - delete(object) { - let map; - - if (this.data.has(object)) { - map = this.data.get(object); - - this.data.delete(object); - } - - return map; - } - - has(object) { - return this.data.has(object); - } - - dispose() { - this.data = new WeakMap(); - } -} - -export default DataMap; diff --git a/src-testing/src/renderers/common/Geometries.ts b/src-testing/src/renderers/common/Geometries.ts deleted file mode 100644 index 14c52f6f6..000000000 --- a/src-testing/src/renderers/common/Geometries.ts +++ /dev/null @@ -1,199 +0,0 @@ -import DataMap from './DataMap.js'; -import { AttributeType } from './Constants.js'; - -import { Uint16BufferAttribute, Uint32BufferAttribute } from '../../core/BufferAttribute.js'; - -function arrayNeedsUint32(array) { - // assumes larger values usually on last - - for (let i = array.length - 1; i >= 0; --i) { - if (array[i] >= 65535) return true; // account for PRIMITIVE_RESTART_FIXED_INDEX, #24565 - } - - return false; -} - -function getWireframeVersion(geometry) { - return geometry.index !== null ? geometry.index.version : geometry.attributes.position.version; -} - -function getWireframeIndex(geometry) { - const indices = []; - - const geometryIndex = geometry.index; - const geometryPosition = geometry.attributes.position; - - if (geometryIndex !== null) { - const array = geometryIndex.array; - - for (let i = 0, l = array.length; i < l; i += 3) { - const a = array[i + 0]; - const b = array[i + 1]; - const c = array[i + 2]; - - indices.push(a, b, b, c, c, a); - } - } else { - const array = geometryPosition.array; - - for (let i = 0, l = array.length / 3 - 1; i < l; i += 3) { - const a = i + 0; - const b = i + 1; - const c = i + 2; - - indices.push(a, b, b, c, c, a); - } - } - - const attribute = new (arrayNeedsUint32(indices) ? Uint32BufferAttribute : Uint16BufferAttribute)(indices, 1); - attribute.version = getWireframeVersion(geometry); - - return attribute; -} - -class Geometries extends DataMap { - constructor(attributes, info) { - super(); - - this.attributes = attributes; - this.info = info; - - this.wireframes = new WeakMap(); - - this.attributeCall = new WeakMap(); - } - - has(renderObject) { - const geometry = renderObject.geometry; - - return super.has(geometry) && this.get(geometry).initialized === true; - } - - updateForRender(renderObject) { - if (this.has(renderObject) === false) this.initGeometry(renderObject); - - this.updateAttributes(renderObject); - } - - initGeometry(renderObject) { - const geometry = renderObject.geometry; - const geometryData = this.get(geometry); - - geometryData.initialized = true; - - this.info.memory.geometries++; - - const onDispose = () => { - this.info.memory.geometries--; - - const index = geometry.index; - const geometryAttributes = renderObject.getAttributes(); - - if (index !== null) { - this.attributes.delete(index); - } - - for (const geometryAttribute of geometryAttributes) { - this.attributes.delete(geometryAttribute); - } - - const wireframeAttribute = this.wireframes.get(geometry); - - if (wireframeAttribute !== undefined) { - this.attributes.delete(wireframeAttribute); - } - - geometry.removeEventListener('dispose', onDispose); - }; - - geometry.addEventListener('dispose', onDispose); - } - - updateAttributes(renderObject) { - // attributes - - const attributes = renderObject.getAttributes(); - - for (const attribute of attributes) { - if (attribute.isStorageBufferAttribute || attribute.isStorageInstancedBufferAttribute) { - this.updateAttribute(attribute, AttributeType.STORAGE); - } else { - this.updateAttribute(attribute, AttributeType.VERTEX); - } - } - - // indexes - - const index = this.getIndex(renderObject); - - if (index !== null) { - this.updateAttribute(index, AttributeType.INDEX); - } - - // indirect - - const indirect = renderObject.geometry.indirect; - - if (indirect !== null) { - this.updateAttribute(indirect, AttributeType.INDIRECT); - } - } - - updateAttribute(attribute, type) { - const callId = this.info.render.calls; - - if (!attribute.isInterleavedBufferAttribute) { - if (this.attributeCall.get(attribute) !== callId) { - this.attributes.update(attribute, type); - - this.attributeCall.set(attribute, callId); - } - } else { - if (this.attributeCall.get(attribute) === undefined) { - this.attributes.update(attribute, type); - - this.attributeCall.set(attribute, callId); - } else if (this.attributeCall.get(attribute.data) !== callId) { - this.attributes.update(attribute, type); - - this.attributeCall.set(attribute.data, callId); - - this.attributeCall.set(attribute, callId); - } - } - } - - getIndirect(renderObject) { - return renderObject.geometry.indirect; - } - - getIndex(renderObject) { - const { geometry, material } = renderObject; - - let index = geometry.index; - - if (material.wireframe === true) { - const wireframes = this.wireframes; - - let wireframeAttribute = wireframes.get(geometry); - - if (wireframeAttribute === undefined) { - wireframeAttribute = getWireframeIndex(geometry); - - wireframes.set(geometry, wireframeAttribute); - } else if (wireframeAttribute.version !== getWireframeVersion(geometry)) { - this.attributes.delete(wireframeAttribute); - - wireframeAttribute = getWireframeIndex(geometry); - - wireframes.set(geometry, wireframeAttribute); - } - - index = wireframeAttribute; - } - - return index; - } -} - -export default Geometries; diff --git a/src-testing/src/renderers/common/IndirectStorageBufferAttribute.d.ts b/src-testing/src/renderers/common/IndirectStorageBufferAttribute.d.ts deleted file mode 100644 index 925294395..000000000 --- a/src-testing/src/renderers/common/IndirectStorageBufferAttribute.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { TypedArray } from "../../core/BufferAttribute.js"; -import StorageBufferAttribute from "./StorageBufferAttribute.js"; - -declare class IndirectStorageBufferAttribute extends StorageBufferAttribute { - readonly isIndirectStorageBufferAttribute: true; - - constructor(array: TypedArray, itemSize: number); -} - -export default IndirectStorageBufferAttribute; diff --git a/src-testing/src/renderers/common/Info.ts b/src-testing/src/renderers/common/Info.ts deleted file mode 100644 index 4ede75de7..000000000 --- a/src-testing/src/renderers/common/Info.ts +++ /dev/null @@ -1,95 +0,0 @@ -class Info { - constructor() { - this.autoReset = true; - - this.frame = 0; - this.calls = 0; - - this.render = { - calls: 0, - frameCalls: 0, - drawCalls: 0, - triangles: 0, - points: 0, - lines: 0, - timestamp: 0, - previousFrameCalls: 0, - timestampCalls: 0, - }; - - this.compute = { - calls: 0, - frameCalls: 0, - timestamp: 0, - previousFrameCalls: 0, - timestampCalls: 0, - }; - - this.memory = { - geometries: 0, - textures: 0, - }; - } - - update(object, count, instanceCount) { - this.render.drawCalls++; - - if (object.isMesh || object.isSprite) { - this.render.triangles += instanceCount * (count / 3); - } else if (object.isPoints) { - this.render.points += instanceCount * count; - } else if (object.isLineSegments) { - this.render.lines += instanceCount * (count / 2); - } else if (object.isLine) { - this.render.lines += instanceCount * (count - 1); - } else { - console.error('THREE.WebGPUInfo: Unknown object type.'); - } - } - - updateTimestamp(type, time) { - if (this[type].timestampCalls === 0) { - this[type].timestamp = 0; - } - - this[type].timestamp += time; - - this[type].timestampCalls++; - - if (this[type].timestampCalls >= this[type].previousFrameCalls) { - this[type].timestampCalls = 0; - } - } - - reset() { - const previousRenderFrameCalls = this.render.frameCalls; - this.render.previousFrameCalls = previousRenderFrameCalls; - - const previousComputeFrameCalls = this.compute.frameCalls; - this.compute.previousFrameCalls = previousComputeFrameCalls; - - this.render.drawCalls = 0; - this.render.frameCalls = 0; - this.compute.frameCalls = 0; - - this.render.triangles = 0; - this.render.points = 0; - this.render.lines = 0; - } - - dispose() { - this.reset(); - - this.calls = 0; - - this.render.calls = 0; - this.compute.calls = 0; - - this.render.timestamp = 0; - this.compute.timestamp = 0; - this.memory.geometries = 0; - this.memory.textures = 0; - } -} - -export default Info; diff --git a/src-testing/src/renderers/common/Lighting.d.ts b/src-testing/src/renderers/common/Lighting.d.ts deleted file mode 100644 index 72842e6e7..000000000 --- a/src-testing/src/renderers/common/Lighting.d.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Camera } from "../../cameras/Camera.js"; -import { Object3D } from "../../core/Object3D.js"; -import { Light } from "../../lights/Light.js"; -import LightsNode from "../../nodes/lighting/LightsNode.js"; -import ChainMap from "./ChainMap.js"; - -declare class Lighting extends ChainMap<[Object3D, Camera], LightsNode> { - constructor(); - - createNode(lights?: Light[]): LightsNode; - - getNode(scene: Object3D, camera: Camera): LightsNode; -} - -export default Lighting; diff --git a/src-testing/src/renderers/common/Pipeline.ts b/src-testing/src/renderers/common/Pipeline.ts deleted file mode 100644 index 16017455a..000000000 --- a/src-testing/src/renderers/common/Pipeline.ts +++ /dev/null @@ -1,9 +0,0 @@ -class Pipeline { - constructor(cacheKey) { - this.cacheKey = cacheKey; - - this.usedTimes = 0; - } -} - -export default Pipeline; diff --git a/src-testing/src/renderers/common/Pipelines.ts b/src-testing/src/renderers/common/Pipelines.ts deleted file mode 100644 index 68c8f223c..000000000 --- a/src-testing/src/renderers/common/Pipelines.ts +++ /dev/null @@ -1,270 +0,0 @@ -import DataMap from './DataMap.js'; -import RenderPipeline from './RenderPipeline.js'; -import ComputePipeline from './ComputePipeline.js'; -import ProgrammableStage from './ProgrammableStage.js'; - -class Pipelines extends DataMap { - constructor(backend, nodes) { - super(); - - this.backend = backend; - this.nodes = nodes; - - this.bindings = null; // set by the bindings - - this.caches = new Map(); - this.programs = { - vertex: new Map(), - fragment: new Map(), - compute: new Map(), - }; - } - - getForCompute(computeNode, bindings) { - const { backend } = this; - - const data = this.get(computeNode); - - if (this._needsComputeUpdate(computeNode)) { - const previousPipeline = data.pipeline; - - if (previousPipeline) { - previousPipeline.usedTimes--; - previousPipeline.computeProgram.usedTimes--; - } - - // get shader - - const nodeBuilderState = this.nodes.getForCompute(computeNode); - - // programmable stage - - let stageCompute = this.programs.compute.get(nodeBuilderState.computeShader); - - if (stageCompute === undefined) { - if (previousPipeline && previousPipeline.computeProgram.usedTimes === 0) - this._releaseProgram(previousPipeline.computeProgram); - - stageCompute = new ProgrammableStage( - nodeBuilderState.computeShader, - 'compute', - nodeBuilderState.transforms, - nodeBuilderState.nodeAttributes, - ); - this.programs.compute.set(nodeBuilderState.computeShader, stageCompute); - - backend.createProgram(stageCompute); - } - - // determine compute pipeline - - const cacheKey = this._getComputeCacheKey(computeNode, stageCompute); - - let pipeline = this.caches.get(cacheKey); - - if (pipeline === undefined) { - if (previousPipeline && previousPipeline.usedTimes === 0) this._releasePipeline(previousPipeline); - - pipeline = this._getComputePipeline(computeNode, stageCompute, cacheKey, bindings); - } - - // keep track of all used times - - pipeline.usedTimes++; - stageCompute.usedTimes++; - - // - - data.version = computeNode.version; - data.pipeline = pipeline; - } - - return data.pipeline; - } - - getForRender(renderObject, promises = null) { - const { backend } = this; - - const data = this.get(renderObject); - - if (this._needsRenderUpdate(renderObject)) { - const previousPipeline = data.pipeline; - - if (previousPipeline) { - previousPipeline.usedTimes--; - previousPipeline.vertexProgram.usedTimes--; - previousPipeline.fragmentProgram.usedTimes--; - } - - // get shader - - const nodeBuilderState = renderObject.getNodeBuilderState(); - - // programmable stages - - let stageVertex = this.programs.vertex.get(nodeBuilderState.vertexShader); - - if (stageVertex === undefined) { - if (previousPipeline && previousPipeline.vertexProgram.usedTimes === 0) - this._releaseProgram(previousPipeline.vertexProgram); - - stageVertex = new ProgrammableStage(nodeBuilderState.vertexShader, 'vertex'); - this.programs.vertex.set(nodeBuilderState.vertexShader, stageVertex); - - backend.createProgram(stageVertex); - } - - let stageFragment = this.programs.fragment.get(nodeBuilderState.fragmentShader); - - if (stageFragment === undefined) { - if (previousPipeline && previousPipeline.fragmentProgram.usedTimes === 0) - this._releaseProgram(previousPipeline.fragmentProgram); - - stageFragment = new ProgrammableStage(nodeBuilderState.fragmentShader, 'fragment'); - this.programs.fragment.set(nodeBuilderState.fragmentShader, stageFragment); - - backend.createProgram(stageFragment); - } - - // determine render pipeline - - const cacheKey = this._getRenderCacheKey(renderObject, stageVertex, stageFragment); - - let pipeline = this.caches.get(cacheKey); - - if (pipeline === undefined) { - if (previousPipeline && previousPipeline.usedTimes === 0) this._releasePipeline(previousPipeline); - - pipeline = this._getRenderPipeline(renderObject, stageVertex, stageFragment, cacheKey, promises); - } else { - renderObject.pipeline = pipeline; - } - - // keep track of all used times - - pipeline.usedTimes++; - stageVertex.usedTimes++; - stageFragment.usedTimes++; - - // - - data.pipeline = pipeline; - } - - return data.pipeline; - } - - delete(object) { - const pipeline = this.get(object).pipeline; - - if (pipeline) { - // pipeline - - pipeline.usedTimes--; - - if (pipeline.usedTimes === 0) this._releasePipeline(pipeline); - - // programs - - if (pipeline.isComputePipeline) { - pipeline.computeProgram.usedTimes--; - - if (pipeline.computeProgram.usedTimes === 0) this._releaseProgram(pipeline.computeProgram); - } else { - pipeline.fragmentProgram.usedTimes--; - pipeline.vertexProgram.usedTimes--; - - if (pipeline.vertexProgram.usedTimes === 0) this._releaseProgram(pipeline.vertexProgram); - if (pipeline.fragmentProgram.usedTimes === 0) this._releaseProgram(pipeline.fragmentProgram); - } - } - - return super.delete(object); - } - - dispose() { - super.dispose(); - - this.caches = new Map(); - this.programs = { - vertex: new Map(), - fragment: new Map(), - compute: new Map(), - }; - } - - updateForRender(renderObject) { - this.getForRender(renderObject); - } - - _getComputePipeline(computeNode, stageCompute, cacheKey, bindings) { - // check for existing pipeline - - cacheKey = cacheKey || this._getComputeCacheKey(computeNode, stageCompute); - - let pipeline = this.caches.get(cacheKey); - - if (pipeline === undefined) { - pipeline = new ComputePipeline(cacheKey, stageCompute); - - this.caches.set(cacheKey, pipeline); - - this.backend.createComputePipeline(pipeline, bindings); - } - - return pipeline; - } - - _getRenderPipeline(renderObject, stageVertex, stageFragment, cacheKey, promises) { - // check for existing pipeline - - cacheKey = cacheKey || this._getRenderCacheKey(renderObject, stageVertex, stageFragment); - - let pipeline = this.caches.get(cacheKey); - - if (pipeline === undefined) { - pipeline = new RenderPipeline(cacheKey, stageVertex, stageFragment); - - this.caches.set(cacheKey, pipeline); - - renderObject.pipeline = pipeline; - - this.backend.createRenderPipeline(renderObject, promises); - } - - return pipeline; - } - - _getComputeCacheKey(computeNode, stageCompute) { - return computeNode.id + ',' + stageCompute.id; - } - - _getRenderCacheKey(renderObject, stageVertex, stageFragment) { - return stageVertex.id + ',' + stageFragment.id + ',' + this.backend.getRenderCacheKey(renderObject); - } - - _releasePipeline(pipeline) { - this.caches.delete(pipeline.cacheKey); - } - - _releaseProgram(program) { - const code = program.code; - const stage = program.stage; - - this.programs[stage].delete(code); - } - - _needsComputeUpdate(computeNode) { - const data = this.get(computeNode); - - return data.pipeline === undefined || data.version !== computeNode.version; - } - - _needsRenderUpdate(renderObject) { - const data = this.get(renderObject); - - return data.pipeline === undefined || this.backend.needsRenderUpdate(renderObject); - } -} - -export default Pipelines; diff --git a/src-testing/src/renderers/common/PostProcessing.d.ts b/src-testing/src/renderers/common/PostProcessing.d.ts deleted file mode 100644 index fdd4e5bdc..000000000 --- a/src-testing/src/renderers/common/PostProcessing.d.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { Node } from "../../nodes/Nodes.js"; -import Renderer from "./Renderer.js"; - -declare class PostProcessing { - renderer: Renderer; - outputNode: Node; - - outputColorTransform: boolean; - - needsUpdate: boolean; - - constructor(renderer: Renderer, outputNode?: Node); - - render(): void; - - update(): void; - - renderAsync(): Promise; -} - -export default PostProcessing; diff --git a/src-testing/src/renderers/common/PostProcessingUtils.d.ts b/src-testing/src/renderers/common/PostProcessingUtils.d.ts deleted file mode 100644 index 2ef80556c..000000000 --- a/src-testing/src/renderers/common/PostProcessingUtils.d.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { Camera } from "../../cameras/Camera.js"; -import { ToneMapping } from "../../constants.js"; -import { BufferGeometry, GeometryGroup } from "../../core/BufferGeometry.js"; -import { Object3D } from "../../core/Object3D.js"; -import { RenderTarget } from "../../core/RenderTarget.js"; -import { Material } from "../../materials/Material.js"; -import { Color } from "../../math/Color.js"; -import MRTNode from "../../nodes/core/MRTNode.js"; -import LightsNode from "../../nodes/lighting/LightsNode.js"; -import { Scene } from "../../scenes/Scene.js"; -import { CubeTexture } from "../../textures/CubeTexture.js"; -import { Texture } from "../../textures/Texture.js"; -import Color4 from "./Color4.js"; -import Renderer from "./Renderer.js"; - -// renderer state - -export interface RendererState { - toneMapping: ToneMapping; - toneMappingExposure: number; - outputColorSpace: string; - renderTarget: RenderTarget | null; - activeCubeFace: number; - activeMipmapLevel: number; - renderObjectFunction: - | (( - object: Object3D, - scene: Scene, - camera: Camera, - geometry: BufferGeometry, - material: Material, - group: GeometryGroup, - lightsNode: LightsNode, - ) => void) - | null; - pixelRatio: number; - mrt: MRTNode | null; - clearColor: Color4; - clearAlpha: number; - autoClear: boolean; - scissorTest: boolean; -} - -export function saveRendererState(renderer: Renderer, state?: RendererState): RendererState; - -export function resetRendererState(renderer: Renderer, state?: RendererState): RendererState; - -export function restoreRendererState(renderer: Renderer, state: RendererState): void; - -// renderer and scene state - -export interface RendererAndSceneState extends RendererState { - background: Color | Texture | CubeTexture | null; - backgroundNode: Node | null | undefined; - overrideMaterial: Material | null; -} - -export function saveRendererAndSceneState( - renderer: RendererState, - scene: Scene, - state?: RendererAndSceneState, -): RendererAndSceneState; - -export function resetRendererAndSceneState(renderer: Renderer, state?: RendererAndSceneState): RendererAndSceneState; - -export function restoreRendererAndSceneState(renderer: Renderer, state: RendererAndSceneState): void; diff --git a/src-testing/src/renderers/common/ProgrammableStage.ts b/src-testing/src/renderers/common/ProgrammableStage.ts deleted file mode 100644 index a684e4443..000000000 --- a/src-testing/src/renderers/common/ProgrammableStage.ts +++ /dev/null @@ -1,16 +0,0 @@ -let _id = 0; - -class ProgrammableStage { - constructor(code, type, transforms = null, attributes = null) { - this.id = _id++; - - this.code = code; - this.stage = type; - this.transforms = transforms; - this.attributes = attributes; - - this.usedTimes = 0; - } -} - -export default ProgrammableStage; diff --git a/src-testing/src/renderers/common/QuadMesh.d.ts b/src-testing/src/renderers/common/QuadMesh.d.ts deleted file mode 100644 index ee2bb93ba..000000000 --- a/src-testing/src/renderers/common/QuadMesh.d.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { OrthographicCamera } from "../../cameras/OrthographicCamera.js"; -import { Material } from "../../materials/Material.js"; -import { Mesh } from "../../objects/Mesh.js"; -import Renderer from "./Renderer.js"; - -export default class QuadMesh extends Mesh { - camera: OrthographicCamera; - - readonly isQuadMesh: true; - - constructor(material?: Material | null); - - renderAsync(renderer: Renderer): Promise; - - render(renderer: Renderer): void; -} diff --git a/src-testing/src/renderers/common/RenderBundle.ts b/src-testing/src/renderers/common/RenderBundle.ts deleted file mode 100644 index e59e49378..000000000 --- a/src-testing/src/renderers/common/RenderBundle.ts +++ /dev/null @@ -1,12 +0,0 @@ -class RenderBundle { - constructor(scene, camera) { - this.scene = scene; - this.camera = camera; - } - - clone() { - return Object.assign(new this.constructor(), this); - } -} - -export default RenderBundle; diff --git a/src-testing/src/renderers/common/RenderBundles.ts b/src-testing/src/renderers/common/RenderBundles.ts deleted file mode 100644 index 291403652..000000000 --- a/src-testing/src/renderers/common/RenderBundles.ts +++ /dev/null @@ -1,28 +0,0 @@ -import ChainMap from './ChainMap.js'; -import RenderBundle from './RenderBundle.js'; - -class RenderBundles { - constructor() { - this.lists = new ChainMap(); - } - - get(scene, camera) { - const lists = this.lists; - const keys = [scene, camera]; - - let list = lists.get(keys); - - if (list === undefined) { - list = new RenderBundle(scene, camera); - lists.set(keys, list); - } - - return list; - } - - dispose() { - this.lists = new ChainMap(); - } -} - -export default RenderBundles; diff --git a/src-testing/src/renderers/common/RenderContext.ts b/src-testing/src/renderers/common/RenderContext.ts deleted file mode 100644 index 9b5ee3a28..000000000 --- a/src-testing/src/renderers/common/RenderContext.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { Vector4 } from '../../math/Vector4.js'; -import { hashArray } from '../../nodes/core/NodeUtils.js'; - -let id = 0; - -class RenderContext { - constructor() { - this.id = id++; - - this.color = true; - this.clearColor = true; - this.clearColorValue = { r: 0, g: 0, b: 0, a: 1 }; - - this.depth = true; - this.clearDepth = true; - this.clearDepthValue = 1; - - this.stencil = false; - this.clearStencil = true; - this.clearStencilValue = 1; - - this.viewport = false; - this.viewportValue = new Vector4(); - - this.scissor = false; - this.scissorValue = new Vector4(); - - this.textures = null; - this.depthTexture = null; - this.activeCubeFace = 0; - this.sampleCount = 1; - - this.width = 0; - this.height = 0; - - this.isRenderContext = true; - } - - getCacheKey() { - return getCacheKey(this); - } -} - -export function getCacheKey(renderContext) { - const { textures, activeCubeFace } = renderContext; - - const values = [activeCubeFace]; - - for (const texture of textures) { - values.push(texture.id); - } - - return hashArray(values); -} - -export default RenderContext; diff --git a/src-testing/src/renderers/common/RenderContexts.ts b/src-testing/src/renderers/common/RenderContexts.ts deleted file mode 100644 index e77308c1d..000000000 --- a/src-testing/src/renderers/common/RenderContexts.ts +++ /dev/null @@ -1,47 +0,0 @@ -import ChainMap from './ChainMap.js'; -import RenderContext from './RenderContext.js'; - -class RenderContexts { - constructor() { - this.chainMaps = {}; - } - - get(scene, camera, renderTarget = null) { - const chainKey = [scene, camera]; - - let attachmentState; - - if (renderTarget === null) { - attachmentState = 'default'; - } else { - const format = renderTarget.texture.format; - const count = renderTarget.textures.length; - - attachmentState = `${count}:${format}:${renderTarget.samples}:${renderTarget.depthBuffer}:${renderTarget.stencilBuffer}`; - } - - const chainMap = this.getChainMap(attachmentState); - - let renderState = chainMap.get(chainKey); - - if (renderState === undefined) { - renderState = new RenderContext(); - - chainMap.set(chainKey, renderState); - } - - if (renderTarget !== null) renderState.sampleCount = renderTarget.samples === 0 ? 1 : renderTarget.samples; - - return renderState; - } - - getChainMap(attachmentState) { - return this.chainMaps[attachmentState] || (this.chainMaps[attachmentState] = new ChainMap()); - } - - dispose() { - this.chainMaps = {}; - } -} - -export default RenderContexts; diff --git a/src-testing/src/renderers/common/RenderList.ts b/src-testing/src/renderers/common/RenderList.ts deleted file mode 100644 index 63d236dd0..000000000 --- a/src-testing/src/renderers/common/RenderList.ts +++ /dev/null @@ -1,142 +0,0 @@ -function painterSortStable(a, b) { - if (a.groupOrder !== b.groupOrder) { - return a.groupOrder - b.groupOrder; - } else if (a.renderOrder !== b.renderOrder) { - return a.renderOrder - b.renderOrder; - } else if (a.material.id !== b.material.id) { - return a.material.id - b.material.id; - } else if (a.z !== b.z) { - return a.z - b.z; - } else { - return a.id - b.id; - } -} - -function reversePainterSortStable(a, b) { - if (a.groupOrder !== b.groupOrder) { - return a.groupOrder - b.groupOrder; - } else if (a.renderOrder !== b.renderOrder) { - return a.renderOrder - b.renderOrder; - } else if (a.z !== b.z) { - return b.z - a.z; - } else { - return a.id - b.id; - } -} - -class RenderList { - constructor(lighting, scene, camera) { - this.renderItems = []; - this.renderItemsIndex = 0; - - this.opaque = []; - this.transparent = []; - this.bundles = []; - - this.lightsNode = lighting.getNode(scene, camera); - this.lightsArray = []; - - this.scene = scene; - this.camera = camera; - - this.occlusionQueryCount = 0; - } - - begin() { - this.renderItemsIndex = 0; - - this.opaque.length = 0; - this.transparent.length = 0; - this.bundles.length = 0; - - this.lightsArray.length = 0; - - this.occlusionQueryCount = 0; - - return this; - } - - getNextRenderItem(object, geometry, material, groupOrder, z, group) { - let renderItem = this.renderItems[this.renderItemsIndex]; - - if (renderItem === undefined) { - renderItem = { - id: object.id, - object: object, - geometry: geometry, - material: material, - groupOrder: groupOrder, - renderOrder: object.renderOrder, - z: z, - group: group, - }; - - this.renderItems[this.renderItemsIndex] = renderItem; - } else { - renderItem.id = object.id; - renderItem.object = object; - renderItem.geometry = geometry; - renderItem.material = material; - renderItem.groupOrder = groupOrder; - renderItem.renderOrder = object.renderOrder; - renderItem.z = z; - renderItem.group = group; - } - - this.renderItemsIndex++; - - return renderItem; - } - - push(object, geometry, material, groupOrder, z, group) { - const renderItem = this.getNextRenderItem(object, geometry, material, groupOrder, z, group); - - if (object.occlusionTest === true) this.occlusionQueryCount++; - - (material.transparent === true || material.transmission > 0 ? this.transparent : this.opaque).push(renderItem); - } - - unshift(object, geometry, material, groupOrder, z, group) { - const renderItem = this.getNextRenderItem(object, geometry, material, groupOrder, z, group); - - (material.transparent === true ? this.transparent : this.opaque).unshift(renderItem); - } - - pushBundle(group) { - this.bundles.push(group); - } - - pushLight(light) { - this.lightsArray.push(light); - } - - sort(customOpaqueSort, customTransparentSort) { - if (this.opaque.length > 1) this.opaque.sort(customOpaqueSort || painterSortStable); - if (this.transparent.length > 1) this.transparent.sort(customTransparentSort || reversePainterSortStable); - } - - finish() { - // update lights - - this.lightsNode.setLights(this.lightsArray); - - // Clear references from inactive renderItems in the list - - for (let i = this.renderItemsIndex, il = this.renderItems.length; i < il; i++) { - const renderItem = this.renderItems[i]; - - if (renderItem.id === null) break; - - renderItem.id = null; - renderItem.object = null; - renderItem.geometry = null; - renderItem.material = null; - renderItem.groupOrder = null; - renderItem.renderOrder = null; - renderItem.z = null; - renderItem.group = null; - } - } -} - -export default RenderList; diff --git a/src-testing/src/renderers/common/RenderLists.ts b/src-testing/src/renderers/common/RenderLists.ts deleted file mode 100644 index 0486f7933..000000000 --- a/src-testing/src/renderers/common/RenderLists.ts +++ /dev/null @@ -1,30 +0,0 @@ -import ChainMap from './ChainMap.js'; -import RenderList from './RenderList.js'; - -class RenderLists { - constructor(lighting) { - this.lighting = lighting; - - this.lists = new ChainMap(); - } - - get(scene, camera) { - const lists = this.lists; - const keys = [scene, camera]; - - let list = lists.get(keys); - - if (list === undefined) { - list = new RenderList(this.lighting, scene, camera); - lists.set(keys, list); - } - - return list; - } - - dispose() { - this.lists = new ChainMap(); - } -} - -export default RenderLists; diff --git a/src-testing/src/renderers/common/RenderObject.ts b/src-testing/src/renderers/common/RenderObject.ts deleted file mode 100644 index e46d3871f..000000000 --- a/src-testing/src/renderers/common/RenderObject.ts +++ /dev/null @@ -1,350 +0,0 @@ -import { hashString } from '../../nodes/core/NodeUtils.js'; -import ClippingContext from './ClippingContext.js'; - -let _id = 0; - -function getKeys(obj) { - const keys = Object.keys(obj); - - let proto = Object.getPrototypeOf(obj); - - while (proto) { - const descriptors = Object.getOwnPropertyDescriptors(proto); - - for (const key in descriptors) { - if (descriptors[key] !== undefined) { - const descriptor = descriptors[key]; - - if (descriptor && typeof descriptor.get === 'function') { - keys.push(key); - } - } - } - - proto = Object.getPrototypeOf(proto); - } - - return keys; -} - -export default class RenderObject { - constructor(nodes, geometries, renderer, object, material, scene, camera, lightsNode, renderContext) { - this._nodes = nodes; - this._geometries = geometries; - - this.id = _id++; - - this.renderer = renderer; - this.object = object; - this.material = material; - this.scene = scene; - this.camera = camera; - this.lightsNode = lightsNode; - this.context = renderContext; - - this.geometry = object.geometry; - this.version = material.version; - - this.drawRange = null; - - this.attributes = null; - this.pipeline = null; - this.vertexBuffers = null; - this.drawParams = null; - - this.bundle = null; - - this.updateClipping(renderContext.clippingContext); - - this.clippingContextVersion = this.clippingContext.version; - - this.initialNodesCacheKey = this.getDynamicCacheKey(); - this.initialCacheKey = this.getCacheKey(); - - this._nodeBuilderState = null; - this._bindings = null; - this._monitor = null; - - this.onDispose = null; - - this.isRenderObject = true; - - this.onMaterialDispose = () => { - this.dispose(); - }; - - this.material.addEventListener('dispose', this.onMaterialDispose); - } - - updateClipping(parent) { - const material = this.material; - - let clippingContext = this.clippingContext; - - if (Array.isArray(material.clippingPlanes)) { - if (clippingContext === parent || !clippingContext) { - clippingContext = new ClippingContext(); - this.clippingContext = clippingContext; - } - - clippingContext.update(parent, material); - } else if (this.clippingContext !== parent) { - this.clippingContext = parent; - } - } - - get clippingNeedsUpdate() { - if (this.clippingContext.version === this.clippingContextVersion) return false; - - this.clippingContextVersion = this.clippingContext.version; - - return true; - } - - getNodeBuilderState() { - return this._nodeBuilderState || (this._nodeBuilderState = this._nodes.getForRender(this)); - } - - getMonitor() { - return this._monitor || (this._monitor = this.getNodeBuilderState().monitor); - } - - getBindings() { - return this._bindings || (this._bindings = this.getNodeBuilderState().createBindings()); - } - - getIndex() { - return this._geometries.getIndex(this); - } - - getIndirect() { - return this._geometries.getIndirect(this); - } - - getChainArray() { - return [this.object, this.material, this.context, this.lightsNode]; - } - - getAttributes() { - if (this.attributes !== null) return this.attributes; - - const nodeAttributes = this.getNodeBuilderState().nodeAttributes; - const geometry = this.geometry; - - const attributes = []; - const vertexBuffers = new Set(); - - for (const nodeAttribute of nodeAttributes) { - const attribute = - nodeAttribute.node && nodeAttribute.node.attribute - ? nodeAttribute.node.attribute - : geometry.getAttribute(nodeAttribute.name); - - if (attribute === undefined) continue; - - attributes.push(attribute); - - const bufferAttribute = attribute.isInterleavedBufferAttribute ? attribute.data : attribute; - vertexBuffers.add(bufferAttribute); - } - - this.attributes = attributes; - this.vertexBuffers = Array.from(vertexBuffers.values()); - - return attributes; - } - - getVertexBuffers() { - if (this.vertexBuffers === null) this.getAttributes(); - - return this.vertexBuffers; - } - - getDrawParameters() { - const { object, material, geometry, group, drawRange } = this; - - const drawParams = - this.drawParams || - (this.drawParams = { - vertexCount: 0, - firstVertex: 0, - instanceCount: 0, - firstInstance: 0, - }); - - const index = this.getIndex(); - const hasIndex = index !== null; - const instanceCount = geometry.isInstancedBufferGeometry - ? geometry.instanceCount - : object.count > 1 - ? object.count - : 1; - - if (instanceCount === 0) return null; - - drawParams.instanceCount = instanceCount; - - if (object.isBatchedMesh === true) return drawParams; - - let rangeFactor = 1; - - if ( - material.wireframe === true && - !object.isPoints && - !object.isLineSegments && - !object.isLine && - !object.isLineLoop - ) { - rangeFactor = 2; - } - - let firstVertex = drawRange.start * rangeFactor; - let lastVertex = (drawRange.start + drawRange.count) * rangeFactor; - - if (group !== null) { - firstVertex = Math.max(firstVertex, group.start * rangeFactor); - lastVertex = Math.min(lastVertex, (group.start + group.count) * rangeFactor); - } - - const position = geometry.attributes.position; - let itemCount = Infinity; - - if (hasIndex) { - itemCount = index.count; - } else if (position !== undefined && position !== null) { - itemCount = position.count; - } - - firstVertex = Math.max(firstVertex, 0); - lastVertex = Math.min(lastVertex, itemCount); - - const count = lastVertex - firstVertex; - - if (count < 0 || count === Infinity) return null; - - drawParams.vertexCount = count; - drawParams.firstVertex = firstVertex; - - return drawParams; - } - - getGeometryCacheKey() { - const { geometry } = this; - - let cacheKey = ''; - - for (const name of Object.keys(geometry.attributes).sort()) { - const attribute = geometry.attributes[name]; - - cacheKey += name + ','; - - if (attribute.data) cacheKey += attribute.data.stride + ','; - if (attribute.offset) cacheKey += attribute.offset + ','; - if (attribute.itemSize) cacheKey += attribute.itemSize + ','; - if (attribute.normalized) cacheKey += 'n,'; - } - - if (geometry.index) { - cacheKey += 'index,'; - } - - return cacheKey; - } - - getMaterialCacheKey() { - const { object, material } = this; - - let cacheKey = material.customProgramCacheKey(); - - for (const property of getKeys(material)) { - if (/^(is[A-Z]|_)|^(visible|version|uuid|name|opacity|userData)$/.test(property)) continue; - - const value = material[property]; - - let valueKey; - - if (value !== null) { - // some material values require a formatting - - const type = typeof value; - - if (type === 'number') { - valueKey = value !== 0 ? '1' : '0'; // Convert to on/off, important for clearcoat, transmission, etc - } else if (type === 'object') { - valueKey = '{'; - - if (value.isTexture) { - valueKey += value.mapping; - } - - valueKey += '}'; - } else { - valueKey = String(value); - } - } else { - valueKey = String(value); - } - - cacheKey += /*property + ':' +*/ valueKey + ','; - } - - cacheKey += this.clippingContext.cacheKey + ','; - - if (object.geometry) { - cacheKey += this.getGeometryCacheKey(); - } - - if (object.skeleton) { - cacheKey += object.skeleton.bones.length + ','; - } - - if (object.morphTargetInfluences) { - cacheKey += object.morphTargetInfluences.length + ','; - } - - if (object.isBatchedMesh) { - cacheKey += object._matricesTexture.uuid + ','; - - if (object._colorsTexture !== null) { - cacheKey += object._colorsTexture.uuid + ','; - } - } - - if (object.count > 1) { - // TODO: https://github.com/mrdoob/three.js/pull/29066#issuecomment-2269400850 - - cacheKey += object.uuid + ','; - } - - return hashString(cacheKey); - } - - get needsUpdate() { - return ( - /*this.object.static !== true &&*/ this.initialNodesCacheKey !== this.getDynamicCacheKey() || - this.clippingNeedsUpdate - ); - } - - getDynamicCacheKey() { - // Environment Nodes Cache Key - - let cacheKey = this._nodes.getCacheKey(this.scene, this.lightsNode); - - if (this.object.receiveShadow) { - cacheKey += 1; - } - - return cacheKey; - } - - getCacheKey() { - return this.getMaterialCacheKey() + this.getDynamicCacheKey(); - } - - dispose() { - this.material.removeEventListener('dispose', this.onMaterialDispose); - - this.onDispose(); - } -} diff --git a/src-testing/src/renderers/common/RenderObjects.ts b/src-testing/src/renderers/common/RenderObjects.ts deleted file mode 100644 index 6bd06dd5e..000000000 --- a/src-testing/src/renderers/common/RenderObjects.ts +++ /dev/null @@ -1,107 +0,0 @@ -import ChainMap from './ChainMap.js'; -import RenderObject from './RenderObject.js'; - -const chainArray = []; - -class RenderObjects { - constructor(renderer, nodes, geometries, pipelines, bindings, info) { - this.renderer = renderer; - this.nodes = nodes; - this.geometries = geometries; - this.pipelines = pipelines; - this.bindings = bindings; - this.info = info; - - this.chainMaps = {}; - } - - get(object, material, scene, camera, lightsNode, renderContext, passId) { - const chainMap = this.getChainMap(passId); - - // reuse chainArray - chainArray[0] = object; - chainArray[1] = material; - chainArray[2] = renderContext; - chainArray[3] = lightsNode; - - let renderObject = chainMap.get(chainArray); - - if (renderObject === undefined) { - renderObject = this.createRenderObject( - this.nodes, - this.geometries, - this.renderer, - object, - material, - scene, - camera, - lightsNode, - renderContext, - passId, - ); - - chainMap.set(chainArray, renderObject); - } else { - renderObject.updateClipping(renderContext.clippingContext); - - if (renderObject.version !== material.version || renderObject.needsUpdate) { - if (renderObject.initialCacheKey !== renderObject.getCacheKey()) { - renderObject.dispose(); - - renderObject = this.get(object, material, scene, camera, lightsNode, renderContext, passId); - } else { - renderObject.version = material.version; - } - } - } - - return renderObject; - } - - getChainMap(passId = 'default') { - return this.chainMaps[passId] || (this.chainMaps[passId] = new ChainMap()); - } - - dispose() { - this.chainMaps = {}; - } - - createRenderObject( - nodes, - geometries, - renderer, - object, - material, - scene, - camera, - lightsNode, - renderContext, - passId, - ) { - const chainMap = this.getChainMap(passId); - - const renderObject = new RenderObject( - nodes, - geometries, - renderer, - object, - material, - scene, - camera, - lightsNode, - renderContext, - ); - - renderObject.onDispose = () => { - this.pipelines.delete(renderObject); - this.bindings.delete(renderObject); - this.nodes.delete(renderObject); - - chainMap.delete(renderObject.getChainArray()); - }; - - return renderObject; - } -} - -export default RenderObjects; diff --git a/src-testing/src/renderers/common/RenderPipeline.ts b/src-testing/src/renderers/common/RenderPipeline.ts deleted file mode 100644 index 0ec34b043..000000000 --- a/src-testing/src/renderers/common/RenderPipeline.ts +++ /dev/null @@ -1,12 +0,0 @@ -import Pipeline from './Pipeline.js'; - -class RenderPipeline extends Pipeline { - constructor(cacheKey, vertexProgram, fragmentProgram) { - super(cacheKey); - - this.vertexProgram = vertexProgram; - this.fragmentProgram = fragmentProgram; - } -} - -export default RenderPipeline; diff --git a/src-testing/src/renderers/common/Renderer.ts b/src-testing/src/renderers/common/Renderer.ts deleted file mode 100644 index 533684051..000000000 --- a/src-testing/src/renderers/common/Renderer.ts +++ /dev/null @@ -1,1425 +0,0 @@ -import Animation from './Animation.js'; -import RenderObjects from './RenderObjects.js'; -import Attributes from './Attributes.js'; -import Geometries from './Geometries.js'; -import Info from './Info.js'; -import Pipelines from './Pipelines.js'; -import Bindings from './Bindings.js'; -import RenderLists from './RenderLists.js'; -import RenderContexts from './RenderContexts.js'; -import Textures from './Textures.js'; -import Background from './Background.js'; -import Nodes from './nodes/Nodes.js'; -import Color4 from './Color4.js'; -import ClippingContext from './ClippingContext.js'; -import QuadMesh from './QuadMesh.js'; -import RenderBundles from './RenderBundles.js'; -import NodeLibrary from './nodes/NodeLibrary.js'; -import Lighting from './Lighting.js'; - -import NodeMaterial from '../../materials/nodes/NodeMaterial.js'; - -import { Scene } from '../../scenes/Scene.js'; -import { Frustum } from '../../math/Frustum.js'; -import { Matrix4 } from '../../math/Matrix4.js'; -import { Vector2 } from '../../math/Vector2.js'; -import { Vector4 } from '../../math/Vector4.js'; -import { RenderTarget } from '../../core/RenderTarget.js'; -import { - DoubleSide, - BackSide, - FrontSide, - SRGBColorSpace, - NoToneMapping, - LinearFilter, - LinearSRGBColorSpace, - HalfFloatType, - RGBAFormat, - PCFShadowMap, -} from '../../constants.js'; - -const _scene = /*@__PURE__*/ new Scene(); -const _drawingBufferSize = /*@__PURE__*/ new Vector2(); -const _screen = /*@__PURE__*/ new Vector4(); -const _frustum = /*@__PURE__*/ new Frustum(); -const _projScreenMatrix = /*@__PURE__*/ new Matrix4(); -const _vector4 = /*@__PURE__*/ new Vector4(); - -class Renderer { - constructor(backend, parameters = {}) { - this.isRenderer = true; - - // - - const { - logarithmicDepthBuffer = false, - alpha = true, - depth = true, - stencil = false, - antialias = false, - samples = 0, - getFallback = null, - } = parameters; - - // public - this.domElement = backend.getDomElement(); - - this.backend = backend; - - this.samples = samples || antialias === true ? 4 : 0; - - this.autoClear = true; - this.autoClearColor = true; - this.autoClearDepth = true; - this.autoClearStencil = true; - - this.alpha = alpha; - - this.logarithmicDepthBuffer = logarithmicDepthBuffer; - - this.outputColorSpace = SRGBColorSpace; - - this.toneMapping = NoToneMapping; - this.toneMappingExposure = 1.0; - - this.sortObjects = true; - - this.depth = depth; - this.stencil = stencil; - - this.clippingPlanes = []; - - this.info = new Info(); - - this.nodes = { - modelViewMatrix: null, - modelNormalViewMatrix: null, - }; - - this.library = new NodeLibrary(); - this.lighting = new Lighting(); - - // internals - - this._getFallback = getFallback; - - this._pixelRatio = 1; - this._width = this.domElement.width; - this._height = this.domElement.height; - - this._viewport = new Vector4(0, 0, this._width, this._height); - this._scissor = new Vector4(0, 0, this._width, this._height); - this._scissorTest = false; - - this._attributes = null; - this._geometries = null; - this._nodes = null; - this._animation = null; - this._bindings = null; - this._objects = null; - this._pipelines = null; - this._bundles = null; - this._renderLists = null; - this._renderContexts = null; - this._textures = null; - this._background = null; - - this._quad = new QuadMesh(new NodeMaterial()); - this._quad.material.type = 'Renderer_output'; - - this._currentRenderContext = null; - - this._opaqueSort = null; - this._transparentSort = null; - - this._frameBufferTarget = null; - - const alphaClear = this.alpha === true ? 0 : 1; - - this._clearColor = new Color4(0, 0, 0, alphaClear); - this._clearDepth = 1; - this._clearStencil = 0; - - this._renderTarget = null; - this._activeCubeFace = 0; - this._activeMipmapLevel = 0; - - this._mrt = null; - - this._renderObjectFunction = null; - this._currentRenderObjectFunction = null; - this._currentRenderBundle = null; - - this._handleObjectFunction = this._renderObjectDirect; - - this._initialized = false; - this._initPromise = null; - - this._compilationPromises = null; - - this.transparent = true; - this.opaque = true; - - this.shadowMap = { - enabled: false, - type: PCFShadowMap, - }; - - this.xr = { - enabled: false, - }; - - this.debug = { - checkShaderErrors: true, - onShaderError: null, - getShaderAsync: async (scene, camera, object) => { - await this.compileAsync(scene, camera); - - const renderList = this._renderLists.get(scene, camera); - const renderContext = this._renderContexts.get(scene, camera, this._renderTarget); - - const material = scene.overrideMaterial || object.material; - - const renderObject = this._objects.get( - object, - material, - scene, - camera, - renderList.lightsNode, - renderContext, - ); - - const { fragmentShader, vertexShader } = renderObject.getNodeBuilderState(); - - return { fragmentShader, vertexShader }; - }, - }; - } - - async init() { - if (this._initialized) { - throw new Error('Renderer: Backend has already been initialized.'); - } - - if (this._initPromise !== null) { - return this._initPromise; - } - - this._initPromise = new Promise(async (resolve, reject) => { - let backend = this.backend; - - try { - await backend.init(this); - } catch (error) { - if (this._getFallback !== null) { - // try the fallback - - try { - this.backend = backend = this._getFallback(error); - await backend.init(this); - } catch (error) { - reject(error); - return; - } - } else { - reject(error); - return; - } - } - - this._nodes = new Nodes(this, backend); - this._animation = new Animation(this._nodes, this.info); - this._attributes = new Attributes(backend); - this._background = new Background(this, this._nodes); - this._geometries = new Geometries(this._attributes, this.info); - this._textures = new Textures(this, backend, this.info); - this._pipelines = new Pipelines(backend, this._nodes); - this._bindings = new Bindings( - backend, - this._nodes, - this._textures, - this._attributes, - this._pipelines, - this.info, - ); - this._objects = new RenderObjects( - this, - this._nodes, - this._geometries, - this._pipelines, - this._bindings, - this.info, - ); - this._renderLists = new RenderLists(this.lighting); - this._bundles = new RenderBundles(); - this._renderContexts = new RenderContexts(); - - // - - this._initialized = true; - - resolve(); - }); - - return this._initPromise; - } - - get coordinateSystem() { - return this.backend.coordinateSystem; - } - - async compileAsync(scene, camera, targetScene = null) { - if (this._initialized === false) await this.init(); - - // preserve render tree - - const nodeFrame = this._nodes.nodeFrame; - - const previousRenderId = nodeFrame.renderId; - const previousRenderContext = this._currentRenderContext; - const previousRenderObjectFunction = this._currentRenderObjectFunction; - const previousCompilationPromises = this._compilationPromises; - - // - - const sceneRef = scene.isScene === true ? scene : _scene; - - if (targetScene === null) targetScene = scene; - - const renderTarget = this._renderTarget; - const renderContext = this._renderContexts.get(targetScene, camera, renderTarget); - const activeMipmapLevel = this._activeMipmapLevel; - - const compilationPromises = []; - - this._currentRenderContext = renderContext; - this._currentRenderObjectFunction = this.renderObject; - - this._handleObjectFunction = this._createObjectPipeline; - - this._compilationPromises = compilationPromises; - - nodeFrame.renderId++; - - // - - nodeFrame.update(); - - // - - renderContext.depth = this.depth; - renderContext.stencil = this.stencil; - - if (!renderContext.clippingContext) renderContext.clippingContext = new ClippingContext(); - renderContext.clippingContext.updateGlobal(this, camera); - - // - - sceneRef.onBeforeRender(this, scene, camera, renderTarget); - - // - - const renderList = this._renderLists.get(scene, camera); - renderList.begin(); - - this._projectObject(scene, camera, 0, renderList); - - // include lights from target scene - if (targetScene !== scene) { - targetScene.traverseVisible(function (object) { - if (object.isLight && object.layers.test(camera.layers)) { - renderList.pushLight(object); - } - }); - } - - renderList.finish(); - - // - - if (renderTarget !== null) { - this._textures.updateRenderTarget(renderTarget, activeMipmapLevel); - - const renderTargetData = this._textures.get(renderTarget); - - renderContext.textures = renderTargetData.textures; - renderContext.depthTexture = renderTargetData.depthTexture; - } else { - renderContext.textures = null; - renderContext.depthTexture = null; - } - - // - - this._nodes.updateScene(sceneRef); - - // - - this._background.update(sceneRef, renderList, renderContext); - - // process render lists - - const opaqueObjects = renderList.opaque; - const transparentObjects = renderList.transparent; - const lightsNode = renderList.lightsNode; - - if (this.opaque === true && opaqueObjects.length > 0) - this._renderObjects(opaqueObjects, camera, sceneRef, lightsNode); - if (this.transparent === true && transparentObjects.length > 0) - this._renderObjects(transparentObjects, camera, sceneRef, lightsNode); - - // restore render tree - - nodeFrame.renderId = previousRenderId; - - this._currentRenderContext = previousRenderContext; - this._currentRenderObjectFunction = previousRenderObjectFunction; - this._compilationPromises = previousCompilationPromises; - - this._handleObjectFunction = this._renderObjectDirect; - - // wait for all promises setup by backends awaiting compilation/linking/pipeline creation to complete - - await Promise.all(compilationPromises); - } - - async renderAsync(scene, camera) { - if (this._initialized === false) await this.init(); - - const renderContext = this._renderScene(scene, camera); - - await this.backend.resolveTimestampAsync(renderContext, 'render'); - } - - async waitForGPU() { - await this.backend.waitForGPU(); - } - - setMRT(mrt) { - this._mrt = mrt; - - return this; - } - - getMRT() { - return this._mrt; - } - - _renderBundle(bundle, sceneRef, lightsNode) { - const { bundleGroup, camera, renderList } = bundle; - - const renderContext = this._currentRenderContext; - - // - - const renderBundle = this._bundles.get(bundleGroup, camera); - const renderBundleData = this.backend.get(renderBundle); - - if (renderBundleData.renderContexts === undefined) renderBundleData.renderContexts = new Set(); - - // - - const needsUpdate = bundleGroup.version !== renderBundleData.version; - const renderBundleNeedsUpdate = renderBundleData.renderContexts.has(renderContext) === false || needsUpdate; - - renderBundleData.renderContexts.add(renderContext); - - if (renderBundleNeedsUpdate) { - this.backend.beginBundle(renderContext); - - if (renderBundleData.renderObjects === undefined || needsUpdate) { - renderBundleData.renderObjects = []; - } - - this._currentRenderBundle = renderBundle; - - const opaqueObjects = renderList.opaque; - - if (opaqueObjects.length > 0) this._renderObjects(opaqueObjects, camera, sceneRef, lightsNode); - - this._currentRenderBundle = null; - - // - - this.backend.finishBundle(renderContext, renderBundle); - - renderBundleData.version = bundleGroup.version; - } else { - const { renderObjects } = renderBundleData; - - for (let i = 0, l = renderObjects.length; i < l; i++) { - const renderObject = renderObjects[i]; - - if (this._nodes.needsRefresh(renderObject)) { - this._nodes.updateBefore(renderObject); - - this._nodes.updateForRender(renderObject); - this._bindings.updateForRender(renderObject); - - this._nodes.updateAfter(renderObject); - } - } - } - - this.backend.addBundle(renderContext, renderBundle); - } - - render(scene, camera) { - if (this._initialized === false) { - console.warn( - 'THREE.Renderer: .render() called before the backend is initialized. Try using .renderAsync() instead.', - ); - - return this.renderAsync(scene, camera); - } - - this._renderScene(scene, camera); - } - - _getFrameBufferTarget() { - const { currentToneMapping, currentColorSpace } = this; - - const useToneMapping = currentToneMapping !== NoToneMapping; - const useColorSpace = currentColorSpace !== LinearSRGBColorSpace; - - if (useToneMapping === false && useColorSpace === false) return null; - - const { width, height } = this.getDrawingBufferSize(_drawingBufferSize); - const { depth, stencil } = this; - - let frameBufferTarget = this._frameBufferTarget; - - if (frameBufferTarget === null) { - frameBufferTarget = new RenderTarget(width, height, { - depthBuffer: depth, - stencilBuffer: stencil, - type: HalfFloatType, // FloatType - format: RGBAFormat, - colorSpace: LinearSRGBColorSpace, - generateMipmaps: false, - minFilter: LinearFilter, - magFilter: LinearFilter, - samples: this.samples, - }); - - frameBufferTarget.isPostProcessingRenderTarget = true; - - this._frameBufferTarget = frameBufferTarget; - } - - frameBufferTarget.depthBuffer = depth; - frameBufferTarget.stencilBuffer = stencil; - frameBufferTarget.setSize(width, height); - frameBufferTarget.viewport.copy(this._viewport); - frameBufferTarget.scissor.copy(this._scissor); - frameBufferTarget.viewport.multiplyScalar(this._pixelRatio); - frameBufferTarget.scissor.multiplyScalar(this._pixelRatio); - frameBufferTarget.scissorTest = this._scissorTest; - - return frameBufferTarget; - } - - _renderScene(scene, camera, useFrameBufferTarget = true) { - const frameBufferTarget = useFrameBufferTarget ? this._getFrameBufferTarget() : null; - - // preserve render tree - - const nodeFrame = this._nodes.nodeFrame; - - const previousRenderId = nodeFrame.renderId; - const previousRenderContext = this._currentRenderContext; - const previousRenderObjectFunction = this._currentRenderObjectFunction; - - // - - const sceneRef = scene.isScene === true ? scene : _scene; - - const outputRenderTarget = this._renderTarget; - - const activeCubeFace = this._activeCubeFace; - const activeMipmapLevel = this._activeMipmapLevel; - - // - - let renderTarget; - - if (frameBufferTarget !== null) { - renderTarget = frameBufferTarget; - - this.setRenderTarget(renderTarget); - } else { - renderTarget = outputRenderTarget; - } - - // - - const renderContext = this._renderContexts.get(scene, camera, renderTarget); - - this._currentRenderContext = renderContext; - this._currentRenderObjectFunction = this._renderObjectFunction || this.renderObject; - - // - - this.info.calls++; - this.info.render.calls++; - this.info.render.frameCalls++; - - nodeFrame.renderId = this.info.calls; - - // - - const coordinateSystem = this.coordinateSystem; - - if (camera.coordinateSystem !== coordinateSystem) { - camera.coordinateSystem = coordinateSystem; - - camera.updateProjectionMatrix(); - } - - // - - if (scene.matrixWorldAutoUpdate === true) scene.updateMatrixWorld(); - - if (camera.parent === null && camera.matrixWorldAutoUpdate === true) camera.updateMatrixWorld(); - - // - - let viewport = this._viewport; - let scissor = this._scissor; - let pixelRatio = this._pixelRatio; - - if (renderTarget !== null) { - viewport = renderTarget.viewport; - scissor = renderTarget.scissor; - pixelRatio = 1; - } - - this.getDrawingBufferSize(_drawingBufferSize); - - _screen.set(0, 0, _drawingBufferSize.width, _drawingBufferSize.height); - - const minDepth = viewport.minDepth === undefined ? 0 : viewport.minDepth; - const maxDepth = viewport.maxDepth === undefined ? 1 : viewport.maxDepth; - - renderContext.viewportValue.copy(viewport).multiplyScalar(pixelRatio).floor(); - renderContext.viewportValue.width >>= activeMipmapLevel; - renderContext.viewportValue.height >>= activeMipmapLevel; - renderContext.viewportValue.minDepth = minDepth; - renderContext.viewportValue.maxDepth = maxDepth; - renderContext.viewport = renderContext.viewportValue.equals(_screen) === false; - - renderContext.scissorValue.copy(scissor).multiplyScalar(pixelRatio).floor(); - renderContext.scissor = this._scissorTest && renderContext.scissorValue.equals(_screen) === false; - renderContext.scissorValue.width >>= activeMipmapLevel; - renderContext.scissorValue.height >>= activeMipmapLevel; - - if (!renderContext.clippingContext) renderContext.clippingContext = new ClippingContext(); - renderContext.clippingContext.updateGlobal(this, camera); - - // - - sceneRef.onBeforeRender(this, scene, camera, renderTarget); - - // - - _projScreenMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse); - _frustum.setFromProjectionMatrix(_projScreenMatrix, coordinateSystem); - - const renderList = this._renderLists.get(scene, camera); - renderList.begin(); - - this._projectObject(scene, camera, 0, renderList); - - renderList.finish(); - - if (this.sortObjects === true) { - renderList.sort(this._opaqueSort, this._transparentSort); - } - - // - - if (renderTarget !== null) { - this._textures.updateRenderTarget(renderTarget, activeMipmapLevel); - - const renderTargetData = this._textures.get(renderTarget); - - renderContext.textures = renderTargetData.textures; - renderContext.depthTexture = renderTargetData.depthTexture; - renderContext.width = renderTargetData.width; - renderContext.height = renderTargetData.height; - renderContext.renderTarget = renderTarget; - renderContext.depth = renderTarget.depthBuffer; - renderContext.stencil = renderTarget.stencilBuffer; - } else { - renderContext.textures = null; - renderContext.depthTexture = null; - renderContext.width = this.domElement.width; - renderContext.height = this.domElement.height; - renderContext.depth = this.depth; - renderContext.stencil = this.stencil; - } - - renderContext.width >>= activeMipmapLevel; - renderContext.height >>= activeMipmapLevel; - renderContext.activeCubeFace = activeCubeFace; - renderContext.activeMipmapLevel = activeMipmapLevel; - renderContext.occlusionQueryCount = renderList.occlusionQueryCount; - - // - - this._nodes.updateScene(sceneRef); - - // - - this._background.update(sceneRef, renderList, renderContext); - - // - - this.backend.beginRender(renderContext); - - // process render lists - - const { bundles, lightsNode, transparent: transparentObjects, opaque: opaqueObjects } = renderList; - - if (bundles.length > 0) this._renderBundles(bundles, sceneRef, lightsNode); - if (this.opaque === true && opaqueObjects.length > 0) - this._renderObjects(opaqueObjects, camera, sceneRef, lightsNode); - if (this.transparent === true && transparentObjects.length > 0) - this._renderObjects(transparentObjects, camera, sceneRef, lightsNode); - - // finish render pass - - this.backend.finishRender(renderContext); - - // restore render tree - - nodeFrame.renderId = previousRenderId; - - this._currentRenderContext = previousRenderContext; - this._currentRenderObjectFunction = previousRenderObjectFunction; - - // - - if (frameBufferTarget !== null) { - this.setRenderTarget(outputRenderTarget, activeCubeFace, activeMipmapLevel); - - const quad = this._quad; - - if (this._nodes.hasOutputChange(renderTarget.texture)) { - quad.material.fragmentNode = this._nodes.getOutputNode(renderTarget.texture); - quad.material.needsUpdate = true; - } - - this._renderScene(quad, quad.camera, false); - } - - // - - sceneRef.onAfterRender(this, scene, camera, renderTarget); - - // - - return renderContext; - } - - getMaxAnisotropy() { - return this.backend.getMaxAnisotropy(); - } - - getActiveCubeFace() { - return this._activeCubeFace; - } - - getActiveMipmapLevel() { - return this._activeMipmapLevel; - } - - async setAnimationLoop(callback) { - if (this._initialized === false) await this.init(); - - this._animation.setAnimationLoop(callback); - } - - async getArrayBufferAsync(attribute) { - return await this.backend.getArrayBufferAsync(attribute); - } - - getContext() { - return this.backend.getContext(); - } - - getPixelRatio() { - return this._pixelRatio; - } - - getDrawingBufferSize(target) { - return target.set(this._width * this._pixelRatio, this._height * this._pixelRatio).floor(); - } - - getSize(target) { - return target.set(this._width, this._height); - } - - setPixelRatio(value = 1) { - if (this._pixelRatio === value) return; - - this._pixelRatio = value; - - this.setSize(this._width, this._height, false); - } - - setDrawingBufferSize(width, height, pixelRatio) { - this._width = width; - this._height = height; - - this._pixelRatio = pixelRatio; - - this.domElement.width = Math.floor(width * pixelRatio); - this.domElement.height = Math.floor(height * pixelRatio); - - this.setViewport(0, 0, width, height); - - if (this._initialized) this.backend.updateSize(); - } - - setSize(width, height, updateStyle = true) { - this._width = width; - this._height = height; - - this.domElement.width = Math.floor(width * this._pixelRatio); - this.domElement.height = Math.floor(height * this._pixelRatio); - - if (updateStyle === true) { - this.domElement.style.width = width + 'px'; - this.domElement.style.height = height + 'px'; - } - - this.setViewport(0, 0, width, height); - - if (this._initialized) this.backend.updateSize(); - } - - setOpaqueSort(method) { - this._opaqueSort = method; - } - - setTransparentSort(method) { - this._transparentSort = method; - } - - getScissor(target) { - const scissor = this._scissor; - - target.x = scissor.x; - target.y = scissor.y; - target.width = scissor.width; - target.height = scissor.height; - - return target; - } - - setScissor(x, y, width, height) { - const scissor = this._scissor; - - if (x.isVector4) { - scissor.copy(x); - } else { - scissor.set(x, y, width, height); - } - } - - getScissorTest() { - return this._scissorTest; - } - - setScissorTest(boolean) { - this._scissorTest = boolean; - - this.backend.setScissorTest(boolean); - } - - getViewport(target) { - return target.copy(this._viewport); - } - - setViewport(x, y, width, height, minDepth = 0, maxDepth = 1) { - const viewport = this._viewport; - - if (x.isVector4) { - viewport.copy(x); - } else { - viewport.set(x, y, width, height); - } - - viewport.minDepth = minDepth; - viewport.maxDepth = maxDepth; - } - - getClearColor(target) { - return target.copy(this._clearColor); - } - - setClearColor(color, alpha = 1) { - this._clearColor.set(color); - this._clearColor.a = alpha; - } - - getClearAlpha() { - return this._clearColor.a; - } - - setClearAlpha(alpha) { - this._clearColor.a = alpha; - } - - getClearDepth() { - return this._clearDepth; - } - - setClearDepth(depth) { - this._clearDepth = depth; - } - - getClearStencil() { - return this._clearStencil; - } - - setClearStencil(stencil) { - this._clearStencil = stencil; - } - - isOccluded(object) { - const renderContext = this._currentRenderContext; - - return renderContext && this.backend.isOccluded(renderContext, object); - } - - clear(color = true, depth = true, stencil = true) { - if (this._initialized === false) { - console.warn( - 'THREE.Renderer: .clear() called before the backend is initialized. Try using .clearAsync() instead.', - ); - - return this.clearAsync(color, depth, stencil); - } - - const renderTarget = this._renderTarget || this._getFrameBufferTarget(); - - let renderTargetData = null; - - if (renderTarget !== null) { - this._textures.updateRenderTarget(renderTarget); - - renderTargetData = this._textures.get(renderTarget); - } - - this.backend.clear(color, depth, stencil, renderTargetData); - - if (renderTarget !== null && this._renderTarget === null) { - // If a color space transform or tone mapping is required, - // the clear operation clears the intermediate renderTarget texture, but does not update the screen canvas. - - const quad = this._quad; - - if (this._nodes.hasOutputChange(renderTarget.texture)) { - quad.material.fragmentNode = this._nodes.getOutputNode(renderTarget.texture); - quad.material.needsUpdate = true; - } - - this._renderScene(quad, quad.camera, false); - } - } - - clearColor() { - return this.clear(true, false, false); - } - - clearDepth() { - return this.clear(false, true, false); - } - - clearStencil() { - return this.clear(false, false, true); - } - - async clearAsync(color = true, depth = true, stencil = true) { - if (this._initialized === false) await this.init(); - - this.clear(color, depth, stencil); - } - - clearColorAsync() { - return this.clearAsync(true, false, false); - } - - clearDepthAsync() { - return this.clearAsync(false, true, false); - } - - clearStencilAsync() { - return this.clearAsync(false, false, true); - } - - get currentToneMapping() { - return this._renderTarget !== null ? NoToneMapping : this.toneMapping; - } - - get currentColorSpace() { - return this._renderTarget !== null ? LinearSRGBColorSpace : this.outputColorSpace; - } - - dispose() { - this.info.dispose(); - - this._animation.dispose(); - this._objects.dispose(); - this._pipelines.dispose(); - this._nodes.dispose(); - this._bindings.dispose(); - this._renderLists.dispose(); - this._renderContexts.dispose(); - this._textures.dispose(); - - this.setRenderTarget(null); - this.setAnimationLoop(null); - } - - setRenderTarget(renderTarget, activeCubeFace = 0, activeMipmapLevel = 0) { - this._renderTarget = renderTarget; - this._activeCubeFace = activeCubeFace; - this._activeMipmapLevel = activeMipmapLevel; - } - - getRenderTarget() { - return this._renderTarget; - } - - setRenderObjectFunction(renderObjectFunction) { - this._renderObjectFunction = renderObjectFunction; - } - - getRenderObjectFunction() { - return this._renderObjectFunction; - } - - compute(computeNodes) { - if (this._initialized === false) { - console.warn( - 'THREE.Renderer: .compute() called before the backend is initialized. Try using .computeAsync() instead.', - ); - - return this.computeAsync(computeNodes); - } - - // - - const nodeFrame = this._nodes.nodeFrame; - - const previousRenderId = nodeFrame.renderId; - - // - - this.info.calls++; - this.info.compute.calls++; - this.info.compute.frameCalls++; - - nodeFrame.renderId = this.info.calls; - - // - - const backend = this.backend; - const pipelines = this._pipelines; - const bindings = this._bindings; - const nodes = this._nodes; - - const computeList = Array.isArray(computeNodes) ? computeNodes : [computeNodes]; - - if (computeList[0] === undefined || computeList[0].isComputeNode !== true) { - throw new Error('THREE.Renderer: .compute() expects a ComputeNode.'); - } - - backend.beginCompute(computeNodes); - - for (const computeNode of computeList) { - // onInit - - if (pipelines.has(computeNode) === false) { - const dispose = () => { - computeNode.removeEventListener('dispose', dispose); - - pipelines.delete(computeNode); - bindings.delete(computeNode); - nodes.delete(computeNode); - }; - - computeNode.addEventListener('dispose', dispose); - - // - - const onInitFn = computeNode.onInitFunction; - - if (onInitFn !== null) { - onInitFn.call(computeNode, { renderer: this }); - } - } - - nodes.updateForCompute(computeNode); - bindings.updateForCompute(computeNode); - - const computeBindings = bindings.getForCompute(computeNode); - const computePipeline = pipelines.getForCompute(computeNode, computeBindings); - - backend.compute(computeNodes, computeNode, computeBindings, computePipeline); - } - - backend.finishCompute(computeNodes); - - // - - nodeFrame.renderId = previousRenderId; - } - - async computeAsync(computeNodes) { - if (this._initialized === false) await this.init(); - - this.compute(computeNodes); - - await this.backend.resolveTimestampAsync(computeNodes, 'compute'); - } - - async hasFeatureAsync(name) { - if (this._initialized === false) await this.init(); - - return this.backend.hasFeature(name); - } - - hasFeature(name) { - if (this._initialized === false) { - console.warn( - 'THREE.Renderer: .hasFeature() called before the backend is initialized. Try using .hasFeatureAsync() instead.', - ); - - return false; - } - - return this.backend.hasFeature(name); - } - - copyFramebufferToTexture(framebufferTexture, rectangle = null) { - const renderContext = this._currentRenderContext; - - this._textures.updateTexture(framebufferTexture); - - rectangle = - rectangle === null - ? _vector4.set(0, 0, framebufferTexture.image.width, framebufferTexture.image.height) - : rectangle; - - this.backend.copyFramebufferToTexture(framebufferTexture, renderContext, rectangle); - } - - copyTextureToTexture(srcTexture, dstTexture, srcRegion = null, dstPosition = null, level = 0) { - this._textures.updateTexture(srcTexture); - this._textures.updateTexture(dstTexture); - - this.backend.copyTextureToTexture(srcTexture, dstTexture, srcRegion, dstPosition, level); - } - - readRenderTargetPixelsAsync(renderTarget, x, y, width, height, index = 0, faceIndex = 0) { - return this.backend.copyTextureToBuffer(renderTarget.textures[index], x, y, width, height, faceIndex); - } - - _projectObject(object, camera, groupOrder, renderList) { - if (object.visible === false) return; - - const visible = object.layers.test(camera.layers); - - if (visible) { - if (object.isGroup) { - groupOrder = object.renderOrder; - } else if (object.isLOD) { - if (object.autoUpdate === true) object.update(camera); - } else if (object.isLight) { - renderList.pushLight(object); - } else if (object.isSprite) { - if (!object.frustumCulled || _frustum.intersectsSprite(object)) { - if (this.sortObjects === true) { - _vector4.setFromMatrixPosition(object.matrixWorld).applyMatrix4(_projScreenMatrix); - } - - const { geometry, material } = object; - - if (material.visible) { - renderList.push(object, geometry, material, groupOrder, _vector4.z, null); - } - } - } else if (object.isLineLoop) { - console.error( - 'THREE.Renderer: Objects of type THREE.LineLoop are not supported. Please use THREE.Line or THREE.LineSegments.', - ); - } else if (object.isMesh || object.isLine || object.isPoints) { - if (!object.frustumCulled || _frustum.intersectsObject(object)) { - const { geometry, material } = object; - - if (this.sortObjects === true) { - if (geometry.boundingSphere === null) geometry.computeBoundingSphere(); - - _vector4 - .copy(geometry.boundingSphere.center) - .applyMatrix4(object.matrixWorld) - .applyMatrix4(_projScreenMatrix); - } - - if (Array.isArray(material)) { - const groups = geometry.groups; - - for (let i = 0, l = groups.length; i < l; i++) { - const group = groups[i]; - const groupMaterial = material[group.materialIndex]; - - if (groupMaterial && groupMaterial.visible) { - renderList.push(object, geometry, groupMaterial, groupOrder, _vector4.z, group); - } - } - } else if (material.visible) { - renderList.push(object, geometry, material, groupOrder, _vector4.z, null); - } - } - } - } - - if (object.isBundleGroup === true && this.backend.beginBundle !== undefined) { - const baseRenderList = renderList; - - // replace render list - renderList = this._renderLists.get(object, camera); - - renderList.begin(); - - baseRenderList.pushBundle({ - bundleGroup: object, - camera, - renderList, - }); - - renderList.finish(); - } - - const children = object.children; - - for (let i = 0, l = children.length; i < l; i++) { - this._projectObject(children[i], camera, groupOrder, renderList); - } - } - - _renderBundles(bundles, sceneRef, lightsNode) { - for (const bundle of bundles) { - this._renderBundle(bundle, sceneRef, lightsNode); - } - } - - _renderObjects(renderList, camera, scene, lightsNode) { - // process renderable objects - - for (let i = 0, il = renderList.length; i < il; i++) { - const renderItem = renderList[i]; - - // @TODO: Add support for multiple materials per object. This will require to extract - // the material from the renderItem object and pass it with its group data to renderObject(). - - const { object, geometry, material, group } = renderItem; - - if (camera.isArrayCamera) { - const cameras = camera.cameras; - - for (let j = 0, jl = cameras.length; j < jl; j++) { - const camera2 = cameras[j]; - - if (object.layers.test(camera2.layers)) { - const vp = camera2.viewport; - const minDepth = vp.minDepth === undefined ? 0 : vp.minDepth; - const maxDepth = vp.maxDepth === undefined ? 1 : vp.maxDepth; - - const viewportValue = this._currentRenderContext.viewportValue; - viewportValue.copy(vp).multiplyScalar(this._pixelRatio).floor(); - viewportValue.minDepth = minDepth; - viewportValue.maxDepth = maxDepth; - - this.backend.updateViewport(this._currentRenderContext); - - this._currentRenderObjectFunction( - object, - scene, - camera2, - geometry, - material, - group, - lightsNode, - ); - } - } - } else { - this._currentRenderObjectFunction(object, scene, camera, geometry, material, group, lightsNode); - } - } - } - - renderObject(object, scene, camera, geometry, material, group, lightsNode) { - let overridePositionNode; - let overrideFragmentNode; - let overrideDepthNode; - - // - - object.onBeforeRender(this, scene, camera, geometry, material, group); - - // - - if (scene.overrideMaterial !== null) { - const overrideMaterial = scene.overrideMaterial; - - if (material.positionNode && material.positionNode.isNode) { - overridePositionNode = overrideMaterial.positionNode; - overrideMaterial.positionNode = material.positionNode; - } - - if (overrideMaterial.isShadowNodeMaterial) { - overrideMaterial.side = material.shadowSide === null ? material.side : material.shadowSide; - - if (material.depthNode && material.depthNode.isNode) { - overrideDepthNode = overrideMaterial.depthNode; - overrideMaterial.depthNode = material.depthNode; - } - - if (material.shadowNode && material.shadowNode.isNode) { - overrideFragmentNode = overrideMaterial.fragmentNode; - overrideMaterial.fragmentNode = material.shadowNode; - } - - if (this.localClippingEnabled) { - if (material.clipShadows) { - if (overrideMaterial.clippingPlanes !== material.clippingPlanes) { - overrideMaterial.clippingPlanes = material.clippingPlanes; - overrideMaterial.needsUpdate = true; - } - - if (overrideMaterial.clipIntersection !== material.clipIntersection) { - overrideMaterial.clipIntersection = material.clipIntersection; - } - } else if (Array.isArray(overrideMaterial.clippingPlanes)) { - overrideMaterial.clippingPlanes = null; - overrideMaterial.needsUpdate = true; - } - } - } - - material = overrideMaterial; - } - - // - - if (material.transparent === true && material.side === DoubleSide && material.forceSinglePass === false) { - material.side = BackSide; - this._handleObjectFunction(object, material, scene, camera, lightsNode, group, 'backSide'); // create backSide pass id - - material.side = FrontSide; - this._handleObjectFunction(object, material, scene, camera, lightsNode, group); // use default pass id - - material.side = DoubleSide; - } else { - this._handleObjectFunction(object, material, scene, camera, lightsNode, group); - } - - // - - if (overridePositionNode !== undefined) { - scene.overrideMaterial.positionNode = overridePositionNode; - } - - if (overrideDepthNode !== undefined) { - scene.overrideMaterial.depthNode = overrideDepthNode; - } - - if (overrideFragmentNode !== undefined) { - scene.overrideMaterial.fragmentNode = overrideFragmentNode; - } - - // - - object.onAfterRender(this, scene, camera, geometry, material, group); - } - - _renderObjectDirect(object, material, scene, camera, lightsNode, group, passId) { - const renderObject = this._objects.get( - object, - material, - scene, - camera, - lightsNode, - this._currentRenderContext, - passId, - ); - renderObject.drawRange = object.geometry.drawRange; - renderObject.group = group; - - // - - const needsRefresh = this._nodes.needsRefresh(renderObject); - - if (needsRefresh) { - this._nodes.updateBefore(renderObject); - - this._geometries.updateForRender(renderObject); - - this._nodes.updateForRender(renderObject); - this._bindings.updateForRender(renderObject); - } - - this._pipelines.updateForRender(renderObject); - - // - - if (this._currentRenderBundle !== null) { - const renderBundleData = this.backend.get(this._currentRenderBundle); - - renderBundleData.renderObjects.push(renderObject); - - renderObject.bundle = this._currentRenderBundle.scene; - } - - this.backend.draw(renderObject, this.info); - - if (needsRefresh) this._nodes.updateAfter(renderObject); - } - - _createObjectPipeline(object, material, scene, camera, lightsNode, passId) { - const renderObject = this._objects.get( - object, - material, - scene, - camera, - lightsNode, - this._currentRenderContext, - passId, - ); - - // - - this._nodes.updateBefore(renderObject); - - this._geometries.updateForRender(renderObject); - - this._nodes.updateForRender(renderObject); - this._bindings.updateForRender(renderObject); - - this._pipelines.getForRender(renderObject, this._compilationPromises); - - this._nodes.updateAfter(renderObject); - } - - get compile() { - return this.compileAsync; - } -} - -export default Renderer; diff --git a/src-testing/src/renderers/common/SampledTexture.ts b/src-testing/src/renderers/common/SampledTexture.ts deleted file mode 100644 index 841e6a85b..000000000 --- a/src-testing/src/renderers/common/SampledTexture.ts +++ /dev/null @@ -1,68 +0,0 @@ -import Binding from './Binding.js'; - -let _id = 0; - -class SampledTexture extends Binding { - constructor(name, texture) { - super(name); - - this.id = _id++; - - this.texture = texture; - this.version = texture ? texture.version : 0; - this.store = false; - this.generation = null; - - this.isSampledTexture = true; - } - - needsBindingsUpdate(generation) { - const { texture } = this; - - if (generation !== this.generation) { - this.generation = generation; - - return true; - } - - return texture.isVideoTexture; - } - - update() { - const { texture, version } = this; - - if (version !== texture.version) { - this.version = texture.version; - - return true; - } - - return false; - } -} - -class SampledArrayTexture extends SampledTexture { - constructor(name, texture) { - super(name, texture); - - this.isSampledArrayTexture = true; - } -} - -class Sampled3DTexture extends SampledTexture { - constructor(name, texture) { - super(name, texture); - - this.isSampled3DTexture = true; - } -} - -class SampledCubeTexture extends SampledTexture { - constructor(name, texture) { - super(name, texture); - - this.isSampledCubeTexture = true; - } -} - -export { SampledTexture, SampledArrayTexture, Sampled3DTexture, SampledCubeTexture }; diff --git a/src-testing/src/renderers/common/Sampler.ts b/src-testing/src/renderers/common/Sampler.ts deleted file mode 100644 index 8cd20d04a..000000000 --- a/src-testing/src/renderers/common/Sampler.ts +++ /dev/null @@ -1,14 +0,0 @@ -import Binding from './Binding.js'; - -class Sampler extends Binding { - constructor(name, texture) { - super(name); - - this.texture = texture; - this.version = texture ? texture.version : 0; - - this.isSampler = true; - } -} - -export default Sampler; diff --git a/src-testing/src/renderers/common/StorageBuffer.ts b/src-testing/src/renderers/common/StorageBuffer.ts deleted file mode 100644 index ef5d3e464..000000000 --- a/src-testing/src/renderers/common/StorageBuffer.ts +++ /dev/null @@ -1,13 +0,0 @@ -import Buffer from './Buffer.js'; - -class StorageBuffer extends Buffer { - constructor(name, attribute) { - super(name, attribute ? attribute.array : null); - - this.attribute = attribute; - - this.isStorageBuffer = true; - } -} - -export default StorageBuffer; diff --git a/src-testing/src/renderers/common/StorageBufferAttribute.d.ts b/src-testing/src/renderers/common/StorageBufferAttribute.d.ts deleted file mode 100644 index 2a864f54a..000000000 --- a/src-testing/src/renderers/common/StorageBufferAttribute.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { BufferAttribute, TypedArray } from "../../core/BufferAttribute.js"; - -export default class StorageBufferAttribute extends BufferAttribute { - readonly isStorageBufferAttribute: true; - - constructor(array: TypedArray, itemSize: number); -} diff --git a/src-testing/src/renderers/common/StorageInstancedBufferAttribute.d.ts b/src-testing/src/renderers/common/StorageInstancedBufferAttribute.d.ts deleted file mode 100644 index 3f01891e8..000000000 --- a/src-testing/src/renderers/common/StorageInstancedBufferAttribute.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { TypedArray } from "../../core/BufferAttribute.js"; -import { InstancedBufferAttribute } from "../../core/InstancedBufferAttribute.js"; - -export default class StorageInstancedBufferAttribute extends InstancedBufferAttribute { - readonly isStorageInstancedBufferAttribute: true; - - constructor(array: TypedArray | number, itemSize: number); -} diff --git a/src-testing/src/renderers/common/StorageTexture.d.ts b/src-testing/src/renderers/common/StorageTexture.d.ts deleted file mode 100644 index 435ef9ba3..000000000 --- a/src-testing/src/renderers/common/StorageTexture.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { Texture } from "../../textures/Texture.js"; - -export default class StorageTexture extends Texture { - constructor(width?: number, height?: number); -} diff --git a/src-testing/src/renderers/common/Textures.ts b/src-testing/src/renderers/common/Textures.ts deleted file mode 100644 index 8d35f664f..000000000 --- a/src-testing/src/renderers/common/Textures.ts +++ /dev/null @@ -1,294 +0,0 @@ -import DataMap from './DataMap.js'; - -import { Vector3 } from '../../math/Vector3.js'; -import { DepthTexture } from '../../textures/DepthTexture.js'; -import { - DepthStencilFormat, - DepthFormat, - UnsignedIntType, - UnsignedInt248Type, - EquirectangularReflectionMapping, - EquirectangularRefractionMapping, - CubeReflectionMapping, - CubeRefractionMapping, - UnsignedByteType, -} from '../../constants.js'; - -const _size = /*@__PURE__*/ new Vector3(); - -class Textures extends DataMap { - constructor(renderer, backend, info) { - super(); - - this.renderer = renderer; - this.backend = backend; - this.info = info; - } - - updateRenderTarget(renderTarget, activeMipmapLevel = 0) { - const renderTargetData = this.get(renderTarget); - - const sampleCount = renderTarget.samples === 0 ? 1 : renderTarget.samples; - const depthTextureMips = renderTargetData.depthTextureMips || (renderTargetData.depthTextureMips = {}); - - const textures = renderTarget.textures; - - const size = this.getSize(textures[0]); - - const mipWidth = size.width >> activeMipmapLevel; - const mipHeight = size.height >> activeMipmapLevel; - - let depthTexture = renderTarget.depthTexture || depthTextureMips[activeMipmapLevel]; - const useDepthTexture = renderTarget.depthBuffer === true || renderTarget.stencilBuffer === true; - - let textureNeedsUpdate = false; - - if (depthTexture === undefined && useDepthTexture) { - depthTexture = new DepthTexture(); - depthTexture.format = renderTarget.stencilBuffer ? DepthStencilFormat : DepthFormat; - depthTexture.type = renderTarget.stencilBuffer ? UnsignedInt248Type : UnsignedIntType; // FloatType - depthTexture.image.width = mipWidth; - depthTexture.image.height = mipHeight; - - depthTextureMips[activeMipmapLevel] = depthTexture; - } - - if (renderTargetData.width !== size.width || size.height !== renderTargetData.height) { - textureNeedsUpdate = true; - - if (depthTexture) { - depthTexture.needsUpdate = true; - depthTexture.image.width = mipWidth; - depthTexture.image.height = mipHeight; - } - } - - renderTargetData.width = size.width; - renderTargetData.height = size.height; - renderTargetData.textures = textures; - renderTargetData.depthTexture = depthTexture || null; - renderTargetData.depth = renderTarget.depthBuffer; - renderTargetData.stencil = renderTarget.stencilBuffer; - renderTargetData.renderTarget = renderTarget; - - if (renderTargetData.sampleCount !== sampleCount) { - textureNeedsUpdate = true; - - if (depthTexture) { - depthTexture.needsUpdate = true; - } - - renderTargetData.sampleCount = sampleCount; - } - - // - - const options = { sampleCount }; - - for (let i = 0; i < textures.length; i++) { - const texture = textures[i]; - - if (textureNeedsUpdate) texture.needsUpdate = true; - - this.updateTexture(texture, options); - } - - if (depthTexture) { - this.updateTexture(depthTexture, options); - } - - // dispose handler - - if (renderTargetData.initialized !== true) { - renderTargetData.initialized = true; - - // dispose - - const onDispose = () => { - renderTarget.removeEventListener('dispose', onDispose); - - for (let i = 0; i < textures.length; i++) { - this._destroyTexture(textures[i]); - } - - if (depthTexture) { - this._destroyTexture(depthTexture); - } - - this.delete(renderTarget); - }; - - renderTarget.addEventListener('dispose', onDispose); - } - } - - updateTexture(texture, options = {}) { - const textureData = this.get(texture); - if (textureData.initialized === true && textureData.version === texture.version) return; - - const isRenderTarget = texture.isRenderTargetTexture || texture.isDepthTexture || texture.isFramebufferTexture; - const backend = this.backend; - - if (isRenderTarget && textureData.initialized === true) { - // it's an update - - backend.destroySampler(texture); - backend.destroyTexture(texture); - } - - // - - if (texture.isFramebufferTexture) { - const renderer = this.renderer; - const renderTarget = renderer.getRenderTarget(); - - if (renderTarget) { - texture.type = renderTarget.texture.type; - } else { - texture.type = UnsignedByteType; - } - } - - // - - const { width, height, depth } = this.getSize(texture); - - options.width = width; - options.height = height; - options.depth = depth; - options.needsMipmaps = this.needsMipmaps(texture); - options.levels = options.needsMipmaps ? this.getMipLevels(texture, width, height) : 1; - - // - - if (isRenderTarget || texture.isStorageTexture === true) { - backend.createSampler(texture); - backend.createTexture(texture, options); - - textureData.generation = texture.version; - } else { - const needsCreate = textureData.initialized !== true; - - if (needsCreate) backend.createSampler(texture); - - if (texture.version > 0) { - const image = texture.image; - - if (image === undefined) { - console.warn('THREE.Renderer: Texture marked for update but image is undefined.'); - } else if (image.complete === false) { - console.warn('THREE.Renderer: Texture marked for update but image is incomplete.'); - } else { - if (texture.images) { - const images = []; - - for (const image of texture.images) { - images.push(image); - } - - options.images = images; - } else { - options.image = image; - } - - if (textureData.isDefaultTexture === undefined || textureData.isDefaultTexture === true) { - backend.createTexture(texture, options); - - textureData.isDefaultTexture = false; - textureData.generation = texture.version; - } - - if (texture.source.dataReady === true) backend.updateTexture(texture, options); - - if (options.needsMipmaps && texture.mipmaps.length === 0) backend.generateMipmaps(texture); - } - } else { - // async update - - backend.createDefaultTexture(texture); - - textureData.isDefaultTexture = true; - textureData.generation = texture.version; - } - } - - // dispose handler - - if (textureData.initialized !== true) { - textureData.initialized = true; - textureData.generation = texture.version; - - // - - this.info.memory.textures++; - - // dispose - - const onDispose = () => { - texture.removeEventListener('dispose', onDispose); - - this._destroyTexture(texture); - - this.info.memory.textures--; - }; - - texture.addEventListener('dispose', onDispose); - } - - // - - textureData.version = texture.version; - } - - getSize(texture, target = _size) { - let image = texture.images ? texture.images[0] : texture.image; - - if (image) { - if (image.image !== undefined) image = image.image; - - target.width = image.width; - target.height = image.height; - target.depth = texture.isCubeTexture ? 6 : image.depth || 1; - } else { - target.width = target.height = target.depth = 1; - } - - return target; - } - - getMipLevels(texture, width, height) { - let mipLevelCount; - - if (texture.isCompressedTexture) { - mipLevelCount = texture.mipmaps.length; - } else { - mipLevelCount = Math.floor(Math.log2(Math.max(width, height))) + 1; - } - - return mipLevelCount; - } - - needsMipmaps(texture) { - return this.isEnvironmentTexture(texture) || texture.isCompressedTexture === true || texture.generateMipmaps; - } - - isEnvironmentTexture(texture) { - const mapping = texture.mapping; - - return ( - mapping === EquirectangularReflectionMapping || - mapping === EquirectangularRefractionMapping || - mapping === CubeReflectionMapping || - mapping === CubeRefractionMapping - ); - } - - _destroyTexture(texture) { - this.backend.destroySampler(texture); - this.backend.destroyTexture(texture); - - this.delete(texture); - } -} - -export default Textures; diff --git a/src-testing/src/renderers/common/Uniform.ts b/src-testing/src/renderers/common/Uniform.ts deleted file mode 100644 index 80c131494..000000000 --- a/src-testing/src/renderers/common/Uniform.ts +++ /dev/null @@ -1,105 +0,0 @@ -import { Color } from '../../math/Color.js'; -import { Matrix3 } from '../../math/Matrix3.js'; -import { Matrix4 } from '../../math/Matrix4.js'; -import { Vector2 } from '../../math/Vector2.js'; -import { Vector3 } from '../../math/Vector3.js'; -import { Vector4 } from '../../math/Vector4.js'; - -class Uniform { - constructor(name, value) { - this.name = name; - this.value = value; - - this.boundary = 0; // used to build the uniform buffer according to the STD140 layout - this.itemSize = 0; - - this.offset = 0; // this property is set by WebGPUUniformsGroup and marks the start position in the uniform buffer - } - - setValue(value) { - this.value = value; - } - - getValue() { - return this.value; - } -} - -class NumberUniform extends Uniform { - constructor(name, value = 0) { - super(name, value); - - this.isNumberUniform = true; - - this.boundary = 4; - this.itemSize = 1; - } -} - -class Vector2Uniform extends Uniform { - constructor(name, value = new Vector2()) { - super(name, value); - - this.isVector2Uniform = true; - - this.boundary = 8; - this.itemSize = 2; - } -} - -class Vector3Uniform extends Uniform { - constructor(name, value = new Vector3()) { - super(name, value); - - this.isVector3Uniform = true; - - this.boundary = 16; - this.itemSize = 3; - } -} - -class Vector4Uniform extends Uniform { - constructor(name, value = new Vector4()) { - super(name, value); - - this.isVector4Uniform = true; - - this.boundary = 16; - this.itemSize = 4; - } -} - -class ColorUniform extends Uniform { - constructor(name, value = new Color()) { - super(name, value); - - this.isColorUniform = true; - - this.boundary = 16; - this.itemSize = 3; - } -} - -class Matrix3Uniform extends Uniform { - constructor(name, value = new Matrix3()) { - super(name, value); - - this.isMatrix3Uniform = true; - - this.boundary = 48; - this.itemSize = 12; - } -} - -class Matrix4Uniform extends Uniform { - constructor(name, value = new Matrix4()) { - super(name, value); - - this.isMatrix4Uniform = true; - - this.boundary = 64; - this.itemSize = 16; - } -} - -export { NumberUniform, Vector2Uniform, Vector3Uniform, Vector4Uniform, ColorUniform, Matrix3Uniform, Matrix4Uniform }; diff --git a/src-testing/src/renderers/common/UniformBuffer.ts b/src-testing/src/renderers/common/UniformBuffer.ts deleted file mode 100644 index 28aac0d7e..000000000 --- a/src-testing/src/renderers/common/UniformBuffer.ts +++ /dev/null @@ -1,11 +0,0 @@ -import Buffer from './Buffer.js'; - -class UniformBuffer extends Buffer { - constructor(name, buffer = null) { - super(name, buffer); - - this.isUniformBuffer = true; - } -} - -export default UniformBuffer; diff --git a/src-testing/src/renderers/common/UniformsGroup.ts b/src-testing/src/renderers/common/UniformsGroup.ts deleted file mode 100644 index e2b62671a..000000000 --- a/src-testing/src/renderers/common/UniformsGroup.ts +++ /dev/null @@ -1,277 +0,0 @@ -import UniformBuffer from './UniformBuffer.js'; -import { GPU_CHUNK_BYTES } from './Constants.js'; - -class UniformsGroup extends UniformBuffer { - constructor(name) { - super(name); - - this.isUniformsGroup = true; - - this._values = null; - - // the order of uniforms in this array must match the order of uniforms in the shader - - this.uniforms = []; - } - - addUniform(uniform) { - this.uniforms.push(uniform); - - return this; - } - - removeUniform(uniform) { - const index = this.uniforms.indexOf(uniform); - - if (index !== -1) { - this.uniforms.splice(index, 1); - } - - return this; - } - - get values() { - if (this._values === null) { - this._values = Array.from(this.buffer); - } - - return this._values; - } - - get buffer() { - let buffer = this._buffer; - - if (buffer === null) { - const byteLength = this.byteLength; - - buffer = new Float32Array(new ArrayBuffer(byteLength)); - - this._buffer = buffer; - } - - return buffer; - } - - get byteLength() { - let offset = 0; // global buffer offset in bytes - - for (let i = 0, l = this.uniforms.length; i < l; i++) { - const uniform = this.uniforms[i]; - - const { boundary, itemSize } = uniform; - - // offset within a single chunk in bytes - - const chunkOffset = offset % GPU_CHUNK_BYTES; - const remainingSizeInChunk = GPU_CHUNK_BYTES - chunkOffset; - - // conformance tests - - if (chunkOffset !== 0 && remainingSizeInChunk - boundary < 0) { - // check for chunk overflow - - offset += GPU_CHUNK_BYTES - chunkOffset; - } else if (chunkOffset % boundary !== 0) { - // check for correct alignment - - offset += chunkOffset % boundary; - } - - uniform.offset = offset / this.bytesPerElement; - - offset += itemSize * this.bytesPerElement; - } - - return Math.ceil(offset / GPU_CHUNK_BYTES) * GPU_CHUNK_BYTES; - } - - update() { - let updated = false; - - for (const uniform of this.uniforms) { - if (this.updateByType(uniform) === true) { - updated = true; - } - } - - return updated; - } - - updateByType(uniform) { - if (uniform.isNumberUniform) return this.updateNumber(uniform); - if (uniform.isVector2Uniform) return this.updateVector2(uniform); - if (uniform.isVector3Uniform) return this.updateVector3(uniform); - if (uniform.isVector4Uniform) return this.updateVector4(uniform); - if (uniform.isColorUniform) return this.updateColor(uniform); - if (uniform.isMatrix3Uniform) return this.updateMatrix3(uniform); - if (uniform.isMatrix4Uniform) return this.updateMatrix4(uniform); - - console.error('THREE.WebGPUUniformsGroup: Unsupported uniform type.', uniform); - } - - updateNumber(uniform) { - let updated = false; - - const a = this.values; - const v = uniform.getValue(); - const offset = uniform.offset; - - if (a[offset] !== v) { - const b = this.buffer; - - b[offset] = a[offset] = v; - updated = true; - } - - return updated; - } - - updateVector2(uniform) { - let updated = false; - - const a = this.values; - const v = uniform.getValue(); - const offset = uniform.offset; - - if (a[offset + 0] !== v.x || a[offset + 1] !== v.y) { - const b = this.buffer; - - b[offset + 0] = a[offset + 0] = v.x; - b[offset + 1] = a[offset + 1] = v.y; - - updated = true; - } - - return updated; - } - - updateVector3(uniform) { - let updated = false; - - const a = this.values; - const v = uniform.getValue(); - const offset = uniform.offset; - - if (a[offset + 0] !== v.x || a[offset + 1] !== v.y || a[offset + 2] !== v.z) { - const b = this.buffer; - - b[offset + 0] = a[offset + 0] = v.x; - b[offset + 1] = a[offset + 1] = v.y; - b[offset + 2] = a[offset + 2] = v.z; - - updated = true; - } - - return updated; - } - - updateVector4(uniform) { - let updated = false; - - const a = this.values; - const v = uniform.getValue(); - const offset = uniform.offset; - - if (a[offset + 0] !== v.x || a[offset + 1] !== v.y || a[offset + 2] !== v.z || a[offset + 4] !== v.w) { - const b = this.buffer; - - b[offset + 0] = a[offset + 0] = v.x; - b[offset + 1] = a[offset + 1] = v.y; - b[offset + 2] = a[offset + 2] = v.z; - b[offset + 3] = a[offset + 3] = v.w; - - updated = true; - } - - return updated; - } - - updateColor(uniform) { - let updated = false; - - const a = this.values; - const c = uniform.getValue(); - const offset = uniform.offset; - - if (a[offset + 0] !== c.r || a[offset + 1] !== c.g || a[offset + 2] !== c.b) { - const b = this.buffer; - - b[offset + 0] = a[offset + 0] = c.r; - b[offset + 1] = a[offset + 1] = c.g; - b[offset + 2] = a[offset + 2] = c.b; - - updated = true; - } - - return updated; - } - - updateMatrix3(uniform) { - let updated = false; - - const a = this.values; - const e = uniform.getValue().elements; - const offset = uniform.offset; - - if ( - a[offset + 0] !== e[0] || - a[offset + 1] !== e[1] || - a[offset + 2] !== e[2] || - a[offset + 4] !== e[3] || - a[offset + 5] !== e[4] || - a[offset + 6] !== e[5] || - a[offset + 8] !== e[6] || - a[offset + 9] !== e[7] || - a[offset + 10] !== e[8] - ) { - const b = this.buffer; - - b[offset + 0] = a[offset + 0] = e[0]; - b[offset + 1] = a[offset + 1] = e[1]; - b[offset + 2] = a[offset + 2] = e[2]; - b[offset + 4] = a[offset + 4] = e[3]; - b[offset + 5] = a[offset + 5] = e[4]; - b[offset + 6] = a[offset + 6] = e[5]; - b[offset + 8] = a[offset + 8] = e[6]; - b[offset + 9] = a[offset + 9] = e[7]; - b[offset + 10] = a[offset + 10] = e[8]; - - updated = true; - } - - return updated; - } - - updateMatrix4(uniform) { - let updated = false; - - const a = this.values; - const e = uniform.getValue().elements; - const offset = uniform.offset; - - if (arraysEqual(a, e, offset) === false) { - const b = this.buffer; - b.set(e, offset); - setArray(a, e, offset); - updated = true; - } - - return updated; - } -} - -function setArray(a, b, offset) { - for (let i = 0, l = b.length; i < l; i++) { - a[offset + i] = b[i]; - } -} - -function arraysEqual(a, b, offset) { - for (let i = 0, l = b.length; i < l; i++) { - if (a[offset + i] !== b[i]) return false; - } - - return true; -} - -export default UniformsGroup; diff --git a/src-testing/src/renderers/common/extras/PMREMGenerator.ts b/src-testing/src/renderers/common/extras/PMREMGenerator.ts deleted file mode 100644 index b317f950c..000000000 --- a/src-testing/src/renderers/common/extras/PMREMGenerator.ts +++ /dev/null @@ -1,657 +0,0 @@ -import NodeMaterial from '../../../materials/nodes/NodeMaterial.js'; -import { getDirection, blur } from '../../../nodes/pmrem/PMREMUtils.js'; -import { equirectUV } from '../../../nodes/utils/EquirectUVNode.js'; -import { uniform } from '../../../nodes/core/UniformNode.js'; -import { uniformArray } from '../../../nodes/accessors/UniformArrayNode.js'; -import { texture } from '../../../nodes/accessors/TextureNode.js'; -import { cubeTexture } from '../../../nodes/accessors/CubeTextureNode.js'; -import { float, vec3 } from '../../../nodes/tsl/TSLBase.js'; -import { uv } from '../../../nodes/accessors/UV.js'; -import { attribute } from '../../../nodes/core/AttributeNode.js'; - -import { OrthographicCamera } from '../../../cameras/OrthographicCamera.js'; -import { Color } from '../../../math/Color.js'; -import { Vector3 } from '../../../math/Vector3.js'; -import { BufferGeometry } from '../../../core/BufferGeometry.js'; -import { BufferAttribute } from '../../../core/BufferAttribute.js'; -import { RenderTarget } from '../../../core/RenderTarget.js'; -import { Mesh } from '../../../objects/Mesh.js'; -import { PerspectiveCamera } from '../../../cameras/PerspectiveCamera.js'; -import { MeshBasicMaterial } from '../../../materials/MeshBasicMaterial.js'; -import { BoxGeometry } from '../../../geometries/BoxGeometry.js'; -import { - CubeReflectionMapping, - CubeRefractionMapping, - CubeUVReflectionMapping, - LinearFilter, - NoBlending, - RGBAFormat, - HalfFloatType, - BackSide, - LinearSRGBColorSpace, -} from '../../../constants.js'; - -const LOD_MIN = 4; - -// The standard deviations (radians) associated with the extra mips. These are -// chosen to approximate a Trowbridge-Reitz distribution function times the -// geometric shadowing function. These sigma values squared must match the -// variance #defines in cube_uv_reflection_fragment.glsl.js. -const EXTRA_LOD_SIGMA = [0.125, 0.215, 0.35, 0.446, 0.526, 0.582]; - -// The maximum length of the blur for loop. Smaller sigmas will use fewer -// samples and exit early, but not recompile the shader. -const MAX_SAMPLES = 20; - -const _flatCamera = /*@__PURE__*/ new OrthographicCamera(-1, 1, 1, -1, 0, 1); -const _cubeCamera = /*@__PURE__*/ new PerspectiveCamera(90, 1); -const _clearColor = /*@__PURE__*/ new Color(); -let _oldTarget = null; -let _oldActiveCubeFace = 0; -let _oldActiveMipmapLevel = 0; - -// Golden Ratio -const PHI = (1 + Math.sqrt(5)) / 2; -const INV_PHI = 1 / PHI; - -// Vertices of a dodecahedron (except the opposites, which represent the -// same axis), used as axis directions evenly spread on a sphere. -const _axisDirections = [ - /*@__PURE__*/ new Vector3(-PHI, INV_PHI, 0), - /*@__PURE__*/ new Vector3(PHI, INV_PHI, 0), - /*@__PURE__*/ new Vector3(-INV_PHI, 0, PHI), - /*@__PURE__*/ new Vector3(INV_PHI, 0, PHI), - /*@__PURE__*/ new Vector3(0, PHI, -INV_PHI), - /*@__PURE__*/ new Vector3(0, PHI, INV_PHI), - /*@__PURE__*/ new Vector3(-1, 1, -1), - /*@__PURE__*/ new Vector3(1, 1, -1), - /*@__PURE__*/ new Vector3(-1, 1, 1), - /*@__PURE__*/ new Vector3(1, 1, 1), -]; - -// - -// WebGPU Face indices -const _faceLib = [3, 1, 5, 0, 4, 2]; - -const direction = getDirection(uv(), attribute('faceIndex')).normalize(); -const outputDirection = vec3(direction.x, direction.y.negate(), direction.z); - -/** - * This class generates a Prefiltered, Mipmapped Radiance Environment Map - * (PMREM) from a cubeMap environment texture. This allows different levels of - * blur to be quickly accessed based on material roughness. It is packed into a - * special CubeUV format that allows us to perform custom interpolation so that - * we can support nonlinear formats such as RGBE. Unlike a traditional mipmap - * chain, it only goes down to the LOD_MIN level (above), and then creates extra - * even more filtered 'mips' at the same LOD_MIN resolution, associated with - * higher roughness levels. In this way we maintain resolution to smoothly - * interpolate diffuse lighting while limiting sampling computation. - * - * Paper: Fast, Accurate Image-Based Lighting - * https://drive.google.com/file/d/15y8r_UpKlU9SvV4ILb0C3qCPecS8pvLz/view - */ - -class PMREMGenerator { - constructor(renderer) { - this._renderer = renderer; - this._pingPongRenderTarget = null; - - this._lodMax = 0; - this._cubeSize = 0; - this._lodPlanes = []; - this._sizeLods = []; - this._sigmas = []; - this._lodMeshes = []; - - this._blurMaterial = null; - this._cubemapMaterial = null; - this._equirectMaterial = null; - this._backgroundBox = null; - } - - /** - * Generates a PMREM from a supplied Scene, which can be faster than using an - * image if networking bandwidth is low. Optional sigma specifies a blur radius - * in radians to be applied to the scene before PMREM generation. Optional near - * and far planes ensure the scene is rendered in its entirety (the cubeCamera - * is placed at the origin). - */ - fromScene(scene, sigma = 0, near = 0.1, far = 100) { - _oldTarget = this._renderer.getRenderTarget(); - _oldActiveCubeFace = this._renderer.getActiveCubeFace(); - _oldActiveMipmapLevel = this._renderer.getActiveMipmapLevel(); - - this._setSize(256); - - const cubeUVRenderTarget = this._allocateTargets(); - cubeUVRenderTarget.depthBuffer = true; - - this._sceneToCubeUV(scene, near, far, cubeUVRenderTarget); - - if (sigma > 0) { - this._blur(cubeUVRenderTarget, 0, 0, sigma); - } - - this._applyPMREM(cubeUVRenderTarget); - - this._cleanup(cubeUVRenderTarget); - - return cubeUVRenderTarget; - } - - /** - * Generates a PMREM from an equirectangular texture, which can be either LDR - * or HDR. The ideal input image size is 1k (1024 x 512), - * as this matches best with the 256 x 256 cubemap output. - */ - fromEquirectangular(equirectangular, renderTarget = null) { - return this._fromTexture(equirectangular, renderTarget); - } - - /** - * Generates a PMREM from an cubemap texture, which can be either LDR - * or HDR. The ideal input cube size is 256 x 256, - * as this matches best with the 256 x 256 cubemap output. - */ - fromCubemap(cubemap, renderTarget = null) { - return this._fromTexture(cubemap, renderTarget); - } - - /** - * Pre-compiles the cubemap shader. You can get faster start-up by invoking this method during - * your texture's network fetch for increased concurrency. - */ - async compileCubemapShader() { - if (this._cubemapMaterial === null) { - this._cubemapMaterial = _getCubemapMaterial(); - await this._compileMaterial(this._cubemapMaterial); - } - } - - /** - * Pre-compiles the equirectangular shader. You can get faster start-up by invoking this method during - * your texture's network fetch for increased concurrency. - */ - async compileEquirectangularShader() { - if (this._equirectMaterial === null) { - this._equirectMaterial = _getEquirectMaterial(); - await this._compileMaterial(this._equirectMaterial); - } - } - - /** - * Disposes of the PMREMGenerator's internal memory. Note that PMREMGenerator is a static class, - * so you should not need more than one PMREMGenerator object. If you do, calling dispose() on - * one of them will cause any others to also become unusable. - */ - dispose() { - this._dispose(); - - if (this._cubemapMaterial !== null) this._cubemapMaterial.dispose(); - if (this._equirectMaterial !== null) this._equirectMaterial.dispose(); - if (this._backgroundBox !== null) { - this._backgroundBox.geometry.dispose(); - this._backgroundBox.material.dispose(); - } - } - - // private interface - - _setSize(cubeSize) { - this._lodMax = Math.floor(Math.log2(cubeSize)); - this._cubeSize = Math.pow(2, this._lodMax); - } - - _dispose() { - if (this._blurMaterial !== null) this._blurMaterial.dispose(); - - if (this._pingPongRenderTarget !== null) this._pingPongRenderTarget.dispose(); - - for (let i = 0; i < this._lodPlanes.length; i++) { - this._lodPlanes[i].dispose(); - } - } - - _cleanup(outputTarget) { - this._renderer.setRenderTarget(_oldTarget, _oldActiveCubeFace, _oldActiveMipmapLevel); - outputTarget.scissorTest = false; - _setViewport(outputTarget, 0, 0, outputTarget.width, outputTarget.height); - } - - _fromTexture(texture, renderTarget) { - if (texture.mapping === CubeReflectionMapping || texture.mapping === CubeRefractionMapping) { - this._setSize(texture.image.length === 0 ? 16 : texture.image[0].width || texture.image[0].image.width); - } else { - // Equirectangular - - this._setSize(texture.image.width / 4); - } - - _oldTarget = this._renderer.getRenderTarget(); - _oldActiveCubeFace = this._renderer.getActiveCubeFace(); - _oldActiveMipmapLevel = this._renderer.getActiveMipmapLevel(); - - const cubeUVRenderTarget = renderTarget || this._allocateTargets(); - this._textureToCubeUV(texture, cubeUVRenderTarget); - this._applyPMREM(cubeUVRenderTarget); - this._cleanup(cubeUVRenderTarget); - - return cubeUVRenderTarget; - } - - _allocateTargets() { - const width = 3 * Math.max(this._cubeSize, 16 * 7); - const height = 4 * this._cubeSize; - - const params = { - magFilter: LinearFilter, - minFilter: LinearFilter, - generateMipmaps: false, - type: HalfFloatType, - format: RGBAFormat, - colorSpace: LinearSRGBColorSpace, - //depthBuffer: false - }; - - const cubeUVRenderTarget = _createRenderTarget(width, height, params); - - if ( - this._pingPongRenderTarget === null || - this._pingPongRenderTarget.width !== width || - this._pingPongRenderTarget.height !== height - ) { - if (this._pingPongRenderTarget !== null) { - this._dispose(); - } - - this._pingPongRenderTarget = _createRenderTarget(width, height, params); - - const { _lodMax } = this; - ({ - sizeLods: this._sizeLods, - lodPlanes: this._lodPlanes, - sigmas: this._sigmas, - lodMeshes: this._lodMeshes, - } = _createPlanes(_lodMax)); - - this._blurMaterial = _getBlurShader(_lodMax, width, height); - } - - return cubeUVRenderTarget; - } - - async _compileMaterial(material) { - const tmpMesh = new Mesh(this._lodPlanes[0], material); - await this._renderer.compile(tmpMesh, _flatCamera); - } - - _sceneToCubeUV(scene, near, far, cubeUVRenderTarget) { - const cubeCamera = _cubeCamera; - cubeCamera.near = near; - cubeCamera.far = far; - - // px, py, pz, nx, ny, nz - const upSign = [-1, 1, -1, -1, -1, -1]; - const forwardSign = [1, 1, 1, -1, -1, -1]; - - const renderer = this._renderer; - - const originalAutoClear = renderer.autoClear; - - renderer.getClearColor(_clearColor); - - renderer.autoClear = false; - - let backgroundBox = this._backgroundBox; - - if (backgroundBox === null) { - const backgroundMaterial = new MeshBasicMaterial({ - name: 'PMREM.Background', - side: BackSide, - depthWrite: false, - depthTest: false, - }); - - backgroundBox = new Mesh(new BoxGeometry(), backgroundMaterial); - } - - let useSolidColor = false; - const background = scene.background; - - if (background) { - if (background.isColor) { - backgroundBox.material.color.copy(background); - scene.background = null; - useSolidColor = true; - } - } else { - backgroundBox.material.color.copy(_clearColor); - useSolidColor = true; - } - - renderer.setRenderTarget(cubeUVRenderTarget); - - renderer.clear(); - - if (useSolidColor) { - renderer.render(backgroundBox, cubeCamera); - } - - for (let i = 0; i < 6; i++) { - const col = i % 3; - - if (col === 0) { - cubeCamera.up.set(0, upSign[i], 0); - cubeCamera.lookAt(forwardSign[i], 0, 0); - } else if (col === 1) { - cubeCamera.up.set(0, 0, upSign[i]); - cubeCamera.lookAt(0, forwardSign[i], 0); - } else { - cubeCamera.up.set(0, upSign[i], 0); - cubeCamera.lookAt(0, 0, forwardSign[i]); - } - - const size = this._cubeSize; - - _setViewport(cubeUVRenderTarget, col * size, i > 2 ? size : 0, size, size); - - renderer.render(scene, cubeCamera); - } - - renderer.autoClear = originalAutoClear; - scene.background = background; - } - - _textureToCubeUV(texture, cubeUVRenderTarget) { - const renderer = this._renderer; - - const isCubeTexture = texture.mapping === CubeReflectionMapping || texture.mapping === CubeRefractionMapping; - - if (isCubeTexture) { - if (this._cubemapMaterial === null) { - this._cubemapMaterial = _getCubemapMaterial(texture); - } - } else { - if (this._equirectMaterial === null) { - this._equirectMaterial = _getEquirectMaterial(texture); - } - } - - const material = isCubeTexture ? this._cubemapMaterial : this._equirectMaterial; - material.fragmentNode.value = texture; - - const mesh = this._lodMeshes[0]; - mesh.material = material; - - const size = this._cubeSize; - - _setViewport(cubeUVRenderTarget, 0, 0, 3 * size, 2 * size); - - renderer.setRenderTarget(cubeUVRenderTarget); - renderer.render(mesh, _flatCamera); - } - - _applyPMREM(cubeUVRenderTarget) { - const renderer = this._renderer; - const autoClear = renderer.autoClear; - renderer.autoClear = false; - const n = this._lodPlanes.length; - - for (let i = 1; i < n; i++) { - const sigma = Math.sqrt(this._sigmas[i] * this._sigmas[i] - this._sigmas[i - 1] * this._sigmas[i - 1]); - - const poleAxis = _axisDirections[(n - i - 1) % _axisDirections.length]; - - this._blur(cubeUVRenderTarget, i - 1, i, sigma, poleAxis); - } - - renderer.autoClear = autoClear; - } - - /** - * This is a two-pass Gaussian blur for a cubemap. Normally this is done - * vertically and horizontally, but this breaks down on a cube. Here we apply - * the blur latitudinally (around the poles), and then longitudinally (towards - * the poles) to approximate the orthogonally-separable blur. It is least - * accurate at the poles, but still does a decent job. - */ - _blur(cubeUVRenderTarget, lodIn, lodOut, sigma, poleAxis) { - const pingPongRenderTarget = this._pingPongRenderTarget; - - this._halfBlur(cubeUVRenderTarget, pingPongRenderTarget, lodIn, lodOut, sigma, 'latitudinal', poleAxis); - - this._halfBlur(pingPongRenderTarget, cubeUVRenderTarget, lodOut, lodOut, sigma, 'longitudinal', poleAxis); - } - - _halfBlur(targetIn, targetOut, lodIn, lodOut, sigmaRadians, direction, poleAxis) { - const renderer = this._renderer; - const blurMaterial = this._blurMaterial; - - if (direction !== 'latitudinal' && direction !== 'longitudinal') { - console.error('blur direction must be either latitudinal or longitudinal!'); - } - - // Number of standard deviations at which to cut off the discrete approximation. - const STANDARD_DEVIATIONS = 3; - - const blurMesh = this._lodMeshes[lodOut]; - blurMesh.material = blurMaterial; - - const blurUniforms = blurMaterial.uniforms; - - const pixels = this._sizeLods[lodIn] - 1; - const radiansPerPixel = isFinite(sigmaRadians) ? Math.PI / (2 * pixels) : (2 * Math.PI) / (2 * MAX_SAMPLES - 1); - const sigmaPixels = sigmaRadians / radiansPerPixel; - const samples = isFinite(sigmaRadians) ? 1 + Math.floor(STANDARD_DEVIATIONS * sigmaPixels) : MAX_SAMPLES; - - if (samples > MAX_SAMPLES) { - console.warn( - `sigmaRadians, ${sigmaRadians}, is too large and will clip, as it requested ${ - samples - } samples when the maximum is set to ${MAX_SAMPLES}`, - ); - } - - const weights = []; - let sum = 0; - - for (let i = 0; i < MAX_SAMPLES; ++i) { - const x = i / sigmaPixels; - const weight = Math.exp((-x * x) / 2); - weights.push(weight); - - if (i === 0) { - sum += weight; - } else if (i < samples) { - sum += 2 * weight; - } - } - - for (let i = 0; i < weights.length; i++) { - weights[i] = weights[i] / sum; - } - - targetIn.texture.frame = (targetIn.texture.frame || 0) + 1; - - blurUniforms.envMap.value = targetIn.texture; - blurUniforms.samples.value = samples; - blurUniforms.weights.array = weights; - blurUniforms.latitudinal.value = direction === 'latitudinal' ? 1 : 0; - - if (poleAxis) { - blurUniforms.poleAxis.value = poleAxis; - } - - const { _lodMax } = this; - blurUniforms.dTheta.value = radiansPerPixel; - blurUniforms.mipInt.value = _lodMax - lodIn; - - const outputSize = this._sizeLods[lodOut]; - const x = 3 * outputSize * (lodOut > _lodMax - LOD_MIN ? lodOut - _lodMax + LOD_MIN : 0); - const y = 4 * (this._cubeSize - outputSize); - - _setViewport(targetOut, x, y, 3 * outputSize, 2 * outputSize); - renderer.setRenderTarget(targetOut); - renderer.render(blurMesh, _flatCamera); - } -} - -function _createPlanes(lodMax) { - const lodPlanes = []; - const sizeLods = []; - const sigmas = []; - const lodMeshes = []; - - let lod = lodMax; - - const totalLods = lodMax - LOD_MIN + 1 + EXTRA_LOD_SIGMA.length; - - for (let i = 0; i < totalLods; i++) { - const sizeLod = Math.pow(2, lod); - sizeLods.push(sizeLod); - let sigma = 1.0 / sizeLod; - - if (i > lodMax - LOD_MIN) { - sigma = EXTRA_LOD_SIGMA[i - lodMax + LOD_MIN - 1]; - } else if (i === 0) { - sigma = 0; - } - - sigmas.push(sigma); - - const texelSize = 1.0 / (sizeLod - 2); - const min = -texelSize; - const max = 1 + texelSize; - const uv1 = [min, min, max, min, max, max, min, min, max, max, min, max]; - - const cubeFaces = 6; - const vertices = 6; - const positionSize = 3; - const uvSize = 2; - const faceIndexSize = 1; - - const position = new Float32Array(positionSize * vertices * cubeFaces); - const uv = new Float32Array(uvSize * vertices * cubeFaces); - const faceIndex = new Float32Array(faceIndexSize * vertices * cubeFaces); - - for (let face = 0; face < cubeFaces; face++) { - const x = ((face % 3) * 2) / 3 - 1; - const y = face > 2 ? 0 : -1; - const coordinates = [ - x, - y, - 0, - x + 2 / 3, - y, - 0, - x + 2 / 3, - y + 1, - 0, - x, - y, - 0, - x + 2 / 3, - y + 1, - 0, - x, - y + 1, - 0, - ]; - - const faceIdx = _faceLib[face]; - position.set(coordinates, positionSize * vertices * faceIdx); - uv.set(uv1, uvSize * vertices * faceIdx); - const fill = [faceIdx, faceIdx, faceIdx, faceIdx, faceIdx, faceIdx]; - faceIndex.set(fill, faceIndexSize * vertices * faceIdx); - } - - const planes = new BufferGeometry(); - planes.setAttribute('position', new BufferAttribute(position, positionSize)); - planes.setAttribute('uv', new BufferAttribute(uv, uvSize)); - planes.setAttribute('faceIndex', new BufferAttribute(faceIndex, faceIndexSize)); - lodPlanes.push(planes); - lodMeshes.push(new Mesh(planes, null)); - - if (lod > LOD_MIN) { - lod--; - } - } - - return { lodPlanes, sizeLods, sigmas, lodMeshes }; -} - -function _createRenderTarget(width, height, params) { - const cubeUVRenderTarget = new RenderTarget(width, height, params); - cubeUVRenderTarget.texture.mapping = CubeUVReflectionMapping; - cubeUVRenderTarget.texture.name = 'PMREM.cubeUv'; - cubeUVRenderTarget.texture.isPMREMTexture = true; - cubeUVRenderTarget.scissorTest = true; - return cubeUVRenderTarget; -} - -function _setViewport(target, x, y, width, height) { - target.viewport.set(x, y, width, height); - target.scissor.set(x, y, width, height); -} - -function _getMaterial(type) { - const material = new NodeMaterial(); - material.depthTest = false; - material.depthWrite = false; - material.blending = NoBlending; - material.name = `PMREM_${type}`; - - return material; -} - -function _getBlurShader(lodMax, width, height) { - const weights = uniformArray(new Array(MAX_SAMPLES).fill(0)); - const poleAxis = uniform(new Vector3(0, 1, 0)); - const dTheta = uniform(0); - const n = float(MAX_SAMPLES); - const latitudinal = uniform(0); // false, bool - const samples = uniform(1); // int - const envMap = texture(null); - const mipInt = uniform(0); // int - const CUBEUV_TEXEL_WIDTH = float(1 / width); - const CUBEUV_TEXEL_HEIGHT = float(1 / height); - const CUBEUV_MAX_MIP = float(lodMax); - - const materialUniforms = { - n, - latitudinal, - weights, - poleAxis, - outputDirection, - dTheta, - samples, - envMap, - mipInt, - CUBEUV_TEXEL_WIDTH, - CUBEUV_TEXEL_HEIGHT, - CUBEUV_MAX_MIP, - }; - - const material = _getMaterial('blur'); - material.uniforms = materialUniforms; // TODO: Move to outside of the material - material.fragmentNode = blur({ ...materialUniforms, latitudinal: latitudinal.equal(1) }); - - return material; -} - -function _getCubemapMaterial(envTexture) { - const material = _getMaterial('cubemap'); - material.fragmentNode = cubeTexture(envTexture, outputDirection); - - return material; -} - -function _getEquirectMaterial(envTexture) { - const material = _getMaterial('equirect'); - material.fragmentNode = texture(envTexture, equirectUV(outputDirection), 0); - - return material; -} - -export default PMREMGenerator; diff --git a/src-testing/src/renderers/common/nodes/NodeBuilderState.ts b/src-testing/src/renderers/common/nodes/NodeBuilderState.ts deleted file mode 100644 index 520a3c918..000000000 --- a/src-testing/src/renderers/common/nodes/NodeBuilderState.ts +++ /dev/null @@ -1,55 +0,0 @@ -import BindGroup from '../BindGroup.js'; - -class NodeBuilderState { - constructor( - vertexShader, - fragmentShader, - computeShader, - nodeAttributes, - bindings, - updateNodes, - updateBeforeNodes, - updateAfterNodes, - monitor, - transforms = [], - ) { - this.vertexShader = vertexShader; - this.fragmentShader = fragmentShader; - this.computeShader = computeShader; - this.transforms = transforms; - - this.nodeAttributes = nodeAttributes; - this.bindings = bindings; - - this.updateNodes = updateNodes; - this.updateBeforeNodes = updateBeforeNodes; - this.updateAfterNodes = updateAfterNodes; - - this.monitor = monitor; - - this.usedTimes = 0; - } - - createBindings() { - const bindings = []; - - for (const instanceGroup of this.bindings) { - const shared = instanceGroup.bindings[0].groupNode.shared; - - if (shared !== true) { - const bindingsGroup = new BindGroup(instanceGroup.name, [], instanceGroup.index, instanceGroup); - bindings.push(bindingsGroup); - - for (const instanceBinding of instanceGroup.bindings) { - bindingsGroup.bindings.push(instanceBinding.clone()); - } - } else { - bindings.push(instanceGroup); - } - } - - return bindings; - } -} - -export default NodeBuilderState; diff --git a/src-testing/src/renderers/common/nodes/NodeLibrary.ts b/src-testing/src/renderers/common/nodes/NodeLibrary.ts deleted file mode 100644 index b6738b95a..000000000 --- a/src-testing/src/renderers/common/nodes/NodeLibrary.ts +++ /dev/null @@ -1,76 +0,0 @@ -class NodeLibrary { - constructor() { - this.lightNodes = new WeakMap(); - this.materialNodes = new Map(); - this.toneMappingNodes = new Map(); - } - - fromMaterial(material) { - if (material.isNodeMaterial) return material; - - let nodeMaterial = null; - - const nodeMaterialClass = this.getMaterialNodeClass(material.type); - - if (nodeMaterialClass !== null) { - nodeMaterial = new nodeMaterialClass(); - - for (const key in material) { - nodeMaterial[key] = material[key]; - } - } - - return nodeMaterial; - } - - addToneMapping(toneMappingNode, toneMapping) { - this.addType(toneMappingNode, toneMapping, this.toneMappingNodes); - } - - getToneMappingFunction(toneMapping) { - return this.toneMappingNodes.get(toneMapping) || null; - } - - getMaterialNodeClass(materialType) { - return this.materialNodes.get(materialType) || null; - } - - addMaterial(materialNodeClass, materialClass) { - this.addType(materialNodeClass, materialClass.type, this.materialNodes); - } - - getLightNodeClass(light) { - return this.lightNodes.get(light) || null; - } - - addLight(lightNodeClass, lightClass) { - this.addClass(lightNodeClass, lightClass, this.lightNodes); - } - - addType(nodeClass, type, library) { - if (library.has(type)) { - console.warn(`Redefinition of node ${type}`); - return; - } - - if (typeof nodeClass !== 'function') throw new Error(`Node class ${nodeClass.name} is not a class.`); - if (typeof type === 'function' || typeof type === 'object') - throw new Error(`Base class ${type} is not a class.`); - - library.set(type, nodeClass); - } - - addClass(nodeClass, baseClass, library) { - if (library.has(baseClass)) { - console.warn(`Redefinition of node ${baseClass.name}`); - return; - } - - if (typeof nodeClass !== 'function') throw new Error(`Node class ${nodeClass.name} is not a class.`); - if (typeof baseClass !== 'function') throw new Error(`Base class ${baseClass.name} is not a class.`); - - library.set(baseClass, nodeClass); - } -} - -export default NodeLibrary; diff --git a/src-testing/src/renderers/common/nodes/NodeSampledTexture.d.ts b/src-testing/src/renderers/common/nodes/NodeSampledTexture.d.ts deleted file mode 100644 index 97c3c3adf..000000000 --- a/src-testing/src/renderers/common/nodes/NodeSampledTexture.d.ts +++ /dev/null @@ -1,29 +0,0 @@ -import TextureNode from "../../../nodes/accessors/TextureNode.js"; -import UniformGroupNode from "../../../nodes/core/UniformGroupNode.js"; -import { SampledTexture } from "../SampledTexture.js"; - -type GPUStorageTextureAccess = "read-only" | "read-write" | "write-only"; - -declare class NodeSampledTexture extends SampledTexture { - textureNode: TextureNode | undefined; - groupNode: UniformGroupNode; - - access: "read-write" | "read-only" | "write-only"; - - constructor( - name: string, - textureNode: TextureNode | undefined, - groupNode: UniformGroupNode, - access?: GPUStorageTextureAccess | null, - ); -} - -declare class NodeSampledCubeTexture extends NodeSampledTexture { - readonly isSampledCubeTexture: true; -} - -declare class NodeSampledTexture3D extends NodeSampledTexture { - readonly isSampledTexture3D = true; -} - -export { NodeSampledCubeTexture, NodeSampledTexture, NodeSampledTexture3D }; diff --git a/src-testing/src/renderers/common/nodes/NodeSampler.d.ts b/src-testing/src/renderers/common/nodes/NodeSampler.d.ts deleted file mode 100644 index 60db177d5..000000000 --- a/src-testing/src/renderers/common/nodes/NodeSampler.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -import TextureNode from "../../../nodes/accessors/TextureNode.js"; -import UniformGroupNode from "../../../nodes/core/UniformGroupNode.js"; -import Sampler from "../Sampler.js"; - -declare class NodeSampler extends Sampler { - textureNode: TextureNode | undefined; - groupNode: UniformGroupNode; - constructor(name: string, textureNode: TextureNode | undefined, groupNode: UniformGroupNode); - update(): void; -} - -export default NodeSampler; diff --git a/src-testing/src/renderers/common/nodes/NodeUniform.ts b/src-testing/src/renderers/common/nodes/NodeUniform.ts deleted file mode 100644 index 659f5a82f..000000000 --- a/src-testing/src/renderers/common/nodes/NodeUniform.ts +++ /dev/null @@ -1,103 +0,0 @@ -import { - NumberUniform, - Vector2Uniform, - Vector3Uniform, - Vector4Uniform, - ColorUniform, - Matrix3Uniform, - Matrix4Uniform, -} from '../Uniform.js'; - -class NumberNodeUniform extends NumberUniform { - constructor(nodeUniform) { - super(nodeUniform.name, nodeUniform.value); - - this.nodeUniform = nodeUniform; - } - - getValue() { - return this.nodeUniform.value; - } -} - -class Vector2NodeUniform extends Vector2Uniform { - constructor(nodeUniform) { - super(nodeUniform.name, nodeUniform.value); - - this.nodeUniform = nodeUniform; - } - - getValue() { - return this.nodeUniform.value; - } -} - -class Vector3NodeUniform extends Vector3Uniform { - constructor(nodeUniform) { - super(nodeUniform.name, nodeUniform.value); - - this.nodeUniform = nodeUniform; - } - - getValue() { - return this.nodeUniform.value; - } -} - -class Vector4NodeUniform extends Vector4Uniform { - constructor(nodeUniform) { - super(nodeUniform.name, nodeUniform.value); - - this.nodeUniform = nodeUniform; - } - - getValue() { - return this.nodeUniform.value; - } -} - -class ColorNodeUniform extends ColorUniform { - constructor(nodeUniform) { - super(nodeUniform.name, nodeUniform.value); - - this.nodeUniform = nodeUniform; - } - - getValue() { - return this.nodeUniform.value; - } -} - -class Matrix3NodeUniform extends Matrix3Uniform { - constructor(nodeUniform) { - super(nodeUniform.name, nodeUniform.value); - - this.nodeUniform = nodeUniform; - } - - getValue() { - return this.nodeUniform.value; - } -} - -class Matrix4NodeUniform extends Matrix4Uniform { - constructor(nodeUniform) { - super(nodeUniform.name, nodeUniform.value); - - this.nodeUniform = nodeUniform; - } - - getValue() { - return this.nodeUniform.value; - } -} - -export { - NumberNodeUniform, - Vector2NodeUniform, - Vector3NodeUniform, - Vector4NodeUniform, - ColorNodeUniform, - Matrix3NodeUniform, - Matrix4NodeUniform, -}; diff --git a/src-testing/src/renderers/common/nodes/NodeUniformsGroup.ts b/src-testing/src/renderers/common/nodes/NodeUniformsGroup.ts deleted file mode 100644 index d2d92cb20..000000000 --- a/src-testing/src/renderers/common/nodes/NodeUniformsGroup.ts +++ /dev/null @@ -1,30 +0,0 @@ -import UniformsGroup from '../UniformsGroup.js'; - -let _id = 0; - -class NodeUniformsGroup extends UniformsGroup { - constructor(name, groupNode) { - super(name); - - this.id = _id++; - this.groupNode = groupNode; - - this.isNodeUniformsGroup = true; - } - - getNodes() { - const nodes = []; - - for (const uniform of this.uniforms) { - const node = uniform.nodeUniform.node; - - if (!node) throw new Error('NodeUniformsGroup: Uniform has no node.'); - - nodes.push(node); - } - - return nodes; - } -} - -export default NodeUniformsGroup; diff --git a/src-testing/src/renderers/common/nodes/Nodes.ts b/src-testing/src/renderers/common/nodes/Nodes.ts deleted file mode 100644 index f409c2b15..000000000 --- a/src-testing/src/renderers/common/nodes/Nodes.ts +++ /dev/null @@ -1,433 +0,0 @@ -import DataMap from '../DataMap.js'; -import ChainMap from '../ChainMap.js'; -import NodeBuilderState from './NodeBuilderState.js'; -import { cubeMapNode } from '../../../nodes/utils/CubeMapNode.js'; -import { NodeFrame } from '../../../nodes/Nodes.js'; -import { - objectGroup, - renderGroup, - frameGroup, - cubeTexture, - texture, - rangeFog, - densityFog, - reference, - normalWorld, - pmremTexture, - screenUV, -} from '../../../nodes/TSL.js'; - -import { - CubeUVReflectionMapping, - EquirectangularReflectionMapping, - EquirectangularRefractionMapping, -} from '../../../constants.js'; -import { hashArray } from '../../../nodes/core/NodeUtils.js'; - -const outputNodeMap = new WeakMap(); - -class Nodes extends DataMap { - constructor(renderer, backend) { - super(); - - this.renderer = renderer; - this.backend = backend; - this.nodeFrame = new NodeFrame(); - this.nodeBuilderCache = new Map(); - this.callHashCache = new ChainMap(); - this.groupsData = new ChainMap(); - } - - updateGroup(nodeUniformsGroup) { - const groupNode = nodeUniformsGroup.groupNode; - const name = groupNode.name; - - // objectGroup is every updated - - if (name === objectGroup.name) return true; - - // renderGroup is updated once per render/compute call - - if (name === renderGroup.name) { - const uniformsGroupData = this.get(nodeUniformsGroup); - const renderId = this.nodeFrame.renderId; - - if (uniformsGroupData.renderId !== renderId) { - uniformsGroupData.renderId = renderId; - - return true; - } - - return false; - } - - // frameGroup is updated once per frame - - if (name === frameGroup.name) { - const uniformsGroupData = this.get(nodeUniformsGroup); - const frameId = this.nodeFrame.frameId; - - if (uniformsGroupData.frameId !== frameId) { - uniformsGroupData.frameId = frameId; - - return true; - } - - return false; - } - - // other groups are updated just when groupNode.needsUpdate is true - - const groupChain = [groupNode, nodeUniformsGroup]; - - let groupData = this.groupsData.get(groupChain); - if (groupData === undefined) this.groupsData.set(groupChain, (groupData = {})); - - if (groupData.version !== groupNode.version) { - groupData.version = groupNode.version; - - return true; - } - - return false; - } - - getForRenderCacheKey(renderObject) { - return renderObject.initialCacheKey; - } - - getForRender(renderObject) { - const renderObjectData = this.get(renderObject); - - let nodeBuilderState = renderObjectData.nodeBuilderState; - - if (nodeBuilderState === undefined) { - const { nodeBuilderCache } = this; - - const cacheKey = this.getForRenderCacheKey(renderObject); - - nodeBuilderState = nodeBuilderCache.get(cacheKey); - - if (nodeBuilderState === undefined) { - const nodeBuilder = this.backend.createNodeBuilder(renderObject.object, this.renderer); - nodeBuilder.scene = renderObject.scene; - nodeBuilder.material = renderObject.material; - nodeBuilder.camera = renderObject.camera; - nodeBuilder.context.material = renderObject.material; - nodeBuilder.lightsNode = renderObject.lightsNode; - nodeBuilder.environmentNode = this.getEnvironmentNode(renderObject.scene); - nodeBuilder.fogNode = this.getFogNode(renderObject.scene); - nodeBuilder.clippingContext = renderObject.clippingContext; - nodeBuilder.build(); - - nodeBuilderState = this._createNodeBuilderState(nodeBuilder); - - nodeBuilderCache.set(cacheKey, nodeBuilderState); - } - - nodeBuilderState.usedTimes++; - - renderObjectData.nodeBuilderState = nodeBuilderState; - } - - return nodeBuilderState; - } - - delete(object) { - if (object.isRenderObject) { - const nodeBuilderState = this.get(object).nodeBuilderState; - nodeBuilderState.usedTimes--; - - if (nodeBuilderState.usedTimes === 0) { - this.nodeBuilderCache.delete(this.getForRenderCacheKey(object)); - } - } - - return super.delete(object); - } - - getForCompute(computeNode) { - const computeData = this.get(computeNode); - - let nodeBuilderState = computeData.nodeBuilderState; - - if (nodeBuilderState === undefined) { - const nodeBuilder = this.backend.createNodeBuilder(computeNode, this.renderer); - nodeBuilder.build(); - - nodeBuilderState = this._createNodeBuilderState(nodeBuilder); - - computeData.nodeBuilderState = nodeBuilderState; - } - - return nodeBuilderState; - } - - _createNodeBuilderState(nodeBuilder) { - return new NodeBuilderState( - nodeBuilder.vertexShader, - nodeBuilder.fragmentShader, - nodeBuilder.computeShader, - nodeBuilder.getAttributesArray(), - nodeBuilder.getBindings(), - nodeBuilder.updateNodes, - nodeBuilder.updateBeforeNodes, - nodeBuilder.updateAfterNodes, - nodeBuilder.monitor, - nodeBuilder.transforms, - ); - } - - getEnvironmentNode(scene) { - return scene.environmentNode || this.get(scene).environmentNode || null; - } - - getBackgroundNode(scene) { - return scene.backgroundNode || this.get(scene).backgroundNode || null; - } - - getFogNode(scene) { - return scene.fogNode || this.get(scene).fogNode || null; - } - - getCacheKey(scene, lightsNode) { - const chain = [scene, lightsNode]; - const callId = this.renderer.info.calls; - - let cacheKeyData = this.callHashCache.get(chain); - - if (cacheKeyData === undefined || cacheKeyData.callId !== callId) { - const environmentNode = this.getEnvironmentNode(scene); - const fogNode = this.getFogNode(scene); - - const values = []; - - if (lightsNode) values.push(lightsNode.getCacheKey(true)); - if (environmentNode) values.push(environmentNode.getCacheKey()); - if (fogNode) values.push(fogNode.getCacheKey()); - - values.push(this.renderer.shadowMap.enabled ? 1 : 0); - - cacheKeyData = { - callId, - cacheKey: hashArray(values), - }; - - this.callHashCache.set(chain, cacheKeyData); - } - - return cacheKeyData.cacheKey; - } - - updateScene(scene) { - this.updateEnvironment(scene); - this.updateFog(scene); - this.updateBackground(scene); - } - - get isToneMappingState() { - return this.renderer.getRenderTarget() ? false : true; - } - - updateBackground(scene) { - const sceneData = this.get(scene); - const background = scene.background; - - if (background) { - const forceUpdate = - (scene.backgroundBlurriness === 0 && sceneData.backgroundBlurriness > 0) || - (scene.backgroundBlurriness > 0 && sceneData.backgroundBlurriness === 0); - - if (sceneData.background !== background || forceUpdate) { - let backgroundNode = null; - - if ( - background.isCubeTexture === true || - background.mapping === EquirectangularReflectionMapping || - background.mapping === EquirectangularRefractionMapping || - background.mapping === CubeUVReflectionMapping - ) { - if (scene.backgroundBlurriness > 0 || background.mapping === CubeUVReflectionMapping) { - backgroundNode = pmremTexture(background, normalWorld); - } else { - let envMap; - - if (background.isCubeTexture === true) { - envMap = cubeTexture(background); - } else { - envMap = texture(background); - } - - backgroundNode = cubeMapNode(envMap); - } - } else if (background.isTexture === true) { - backgroundNode = texture(background, screenUV.flipY()).setUpdateMatrix(true); - } else if (background.isColor !== true) { - console.error('WebGPUNodes: Unsupported background configuration.', background); - } - - sceneData.backgroundNode = backgroundNode; - sceneData.background = background; - sceneData.backgroundBlurriness = scene.backgroundBlurriness; - } - } else if (sceneData.backgroundNode) { - delete sceneData.backgroundNode; - delete sceneData.background; - } - } - - updateFog(scene) { - const sceneData = this.get(scene); - const fog = scene.fog; - - if (fog) { - if (sceneData.fog !== fog) { - let fogNode = null; - - if (fog.isFogExp2) { - const color = reference('color', 'color', fog).setGroup(renderGroup); - const density = reference('density', 'float', fog).setGroup(renderGroup); - - fogNode = densityFog(color, density); - } else if (fog.isFog) { - const color = reference('color', 'color', fog).setGroup(renderGroup); - const near = reference('near', 'float', fog).setGroup(renderGroup); - const far = reference('far', 'float', fog).setGroup(renderGroup); - - fogNode = rangeFog(color, near, far); - } else { - console.error('WebGPUNodes: Unsupported fog configuration.', fog); - } - - sceneData.fogNode = fogNode; - sceneData.fog = fog; - } - } else { - delete sceneData.fogNode; - delete sceneData.fog; - } - } - - updateEnvironment(scene) { - const sceneData = this.get(scene); - const environment = scene.environment; - - if (environment) { - if (sceneData.environment !== environment) { - let environmentNode = null; - - if (environment.isCubeTexture === true) { - environmentNode = cubeTexture(environment); - } else if (environment.isTexture === true) { - environmentNode = texture(environment); - } else { - console.error('Nodes: Unsupported environment configuration.', environment); - } - - sceneData.environmentNode = environmentNode; - sceneData.environment = environment; - } - } else if (sceneData.environmentNode) { - delete sceneData.environmentNode; - delete sceneData.environment; - } - } - - getNodeFrame(renderer = this.renderer, scene = null, object = null, camera = null, material = null) { - const nodeFrame = this.nodeFrame; - nodeFrame.renderer = renderer; - nodeFrame.scene = scene; - nodeFrame.object = object; - nodeFrame.camera = camera; - nodeFrame.material = material; - - return nodeFrame; - } - - getNodeFrameForRender(renderObject) { - return this.getNodeFrame( - renderObject.renderer, - renderObject.scene, - renderObject.object, - renderObject.camera, - renderObject.material, - ); - } - - getOutputCacheKey() { - const renderer = this.renderer; - - return renderer.toneMapping + ',' + renderer.currentColorSpace; - } - - hasOutputChange(outputTarget) { - const cacheKey = outputNodeMap.get(outputTarget); - - return cacheKey !== this.getOutputCacheKey(); - } - - getOutputNode(outputTexture) { - const renderer = this.renderer; - const cacheKey = this.getOutputCacheKey(); - - const output = texture(outputTexture, screenUV).renderOutput(renderer.toneMapping, renderer.currentColorSpace); - - outputNodeMap.set(outputTexture, cacheKey); - - return output; - } - - updateBefore(renderObject) { - const nodeBuilder = renderObject.getNodeBuilderState(); - - for (const node of nodeBuilder.updateBeforeNodes) { - // update frame state for each node - - this.getNodeFrameForRender(renderObject).updateBeforeNode(node); - } - } - - updateAfter(renderObject) { - const nodeBuilder = renderObject.getNodeBuilderState(); - - for (const node of nodeBuilder.updateAfterNodes) { - // update frame state for each node - - this.getNodeFrameForRender(renderObject).updateAfterNode(node); - } - } - - updateForCompute(computeNode) { - const nodeFrame = this.getNodeFrame(); - const nodeBuilder = this.getForCompute(computeNode); - - for (const node of nodeBuilder.updateNodes) { - nodeFrame.updateNode(node); - } - } - - updateForRender(renderObject) { - const nodeFrame = this.getNodeFrameForRender(renderObject); - const nodeBuilder = renderObject.getNodeBuilderState(); - - for (const node of nodeBuilder.updateNodes) { - nodeFrame.updateNode(node); - } - } - - needsRefresh(renderObject) { - const nodeFrame = this.getNodeFrameForRender(renderObject); - const monitor = renderObject.getMonitor(); - - return monitor.needsRefresh(renderObject, nodeFrame); - } - - dispose() { - super.dispose(); - - this.nodeFrame = new NodeFrame(); - this.nodeBuilderCache = new Map(); - } -} - -export default Nodes; diff --git a/src-testing/src/renderers/common/nodes/StandardNodeLibrary.d.ts b/src-testing/src/renderers/common/nodes/StandardNodeLibrary.d.ts deleted file mode 100644 index d7db44562..000000000 --- a/src-testing/src/renderers/common/nodes/StandardNodeLibrary.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -import NodeLibrary from "./NodeLibrary.js"; -declare class StandardNodeLibrary extends NodeLibrary { - constructor(); -} -export default StandardNodeLibrary; diff --git a/src-testing/src/renderers/shaders/ShaderChunk.d.ts b/src-testing/src/renderers/shaders/ShaderChunk.d.ts deleted file mode 100644 index caf4e39bb..000000000 --- a/src-testing/src/renderers/shaders/ShaderChunk.d.ts +++ /dev/null @@ -1,143 +0,0 @@ -// Renderers / Shaders ///////////////////////////////////////////////////////////////////// -export const ShaderChunk: { - alphahash_fragment: string; - alphahash_pars_fragment: string; - alphamap_fragment: string; - alphamap_pars_fragment: string; - alphatest_fragment: string; - alphatest_pars_fragment: string; - aomap_fragment: string; - aomap_pars_fragment: string; - batching_pars_vertex: string; - begin_vertex: string; - beginnormal_vertex: string; - bsdfs: string; - iridescence_fragment: string; - bumpmap_pars_fragment: string; - clipping_planes_fragment: string; - clipping_planes_pars_fragment: string; - clipping_planes_pars_vertex: string; - clipping_planes_vertex: string; - color_fragment: string; - color_pars_fragment: string; - color_pars_vertex: string; - color_vertex: string; - common: string; - cube_uv_reflection_fragment: string; - defaultnormal_vertex: string; - displacementmap_pars_vertex: string; - displacementmap_vertex: string; - emissivemap_fragment: string; - emissivemap_pars_fragment: string; - colorspace_fragment: string; - colorspace_pars_fragment: string; - envmap_fragment: string; - envmap_common_pars_fragment: string; - envmap_pars_fragment: string; - envmap_pars_vertex: string; - envmap_physical_pars_fragment: string; - envmap_vertex: string; - fog_vertex: string; - fog_pars_vertex: string; - fog_fragment: string; - fog_pars_fragment: string; - gradientmap_pars_fragment: string; - lightmap_pars_fragment: string; - lights_lambert_fragment: string; - lights_lambert_pars_fragment: string; - lights_pars_begin: string; - lights_toon_fragment: string; - lights_toon_pars_fragment: string; - lights_phong_fragment: string; - lights_phong_pars_fragment: string; - lights_physical_fragment: string; - lights_physical_pars_fragment: string; - lights_fragment_begin: string; - lights_fragment_maps: string; - lights_fragment_end: string; - logdepthbuf_fragment: string; - logdepthbuf_pars_fragment: string; - logdepthbuf_pars_vertex: string; - logdepthbuf_vertex: string; - map_fragment: string; - map_pars_fragment: string; - map_particle_fragment: string; - map_particle_pars_fragment: string; - metalnessmap_fragment: string; - metalnessmap_pars_fragment: string; - morphcolor_vertex: string; - morphnormal_vertex: string; - morphtarget_pars_vertex: string; - morphtarget_vertex: string; - normal_fragment_begin: string; - normal_fragment_maps: string; - normal_pars_fragment: string; - normal_pars_vertex: string; - normal_vertex: string; - normalmap_pars_fragment: string; - clearcoat_normal_fragment_begin: string; - clearcoat_normal_fragment_maps: string; - clearcoat_pars_fragment: string; - iridescence_pars_fragment: string; - opaque_fragment: string; - packing: string; - premultiplied_alpha_fragment: string; - project_vertex: string; - dithering_fragment: string; - dithering_pars_fragment: string; - roughnessmap_fragment: string; - roughnessmap_pars_fragment: string; - shadowmap_pars_fragment: string; - shadowmap_pars_vertex: string; - shadowmap_vertex: string; - shadowmask_pars_fragment: string; - skinbase_vertex: string; - skinning_pars_vertex: string; - skinning_vertex: string; - skinnormal_vertex: string; - specularmap_fragment: string; - specularmap_pars_fragment: string; - tonemapping_fragment: string; - tonemapping_pars_fragment: string; - transmission_fragment: string; - transmission_pars_fragment: string; - uv_pars_fragment: string; - uv_pars_vertex: string; - uv_vertex: string; - worldpos_vertex: string; - - background_vert: string; - background_frag: string; - backgroundCube_vert: string; - backgroundCube_frag: string; - cube_vert: string; - cube_frag: string; - depth_vert: string; - depth_frag: string; - distanceRGBA_vert: string; - distanceRGBA_frag: string; - equirect_vert: string; - equirect_frag: string; - linedashed_vert: string; - linedashed_frag: string; - meshbasic_vert: string; - meshbasic_frag: string; - meshlambert_vert: string; - meshlambert_frag: string; - meshmatcap_vert: string; - meshmatcap_frag: string; - meshnormal_vert: string; - meshnormal_frag: string; - meshphong_vert: string; - meshphong_frag: string; - meshphysical_vert: string; - meshphysical_frag: string; - meshtoon_vert: string; - meshtoon_frag: string; - points_vert: string; - points_frag: string; - shadow_vert: string; - shadow_frag: string; - sprite_vert: string; - sprite_frag: string; -}; diff --git a/src-testing/src/renderers/shaders/ShaderLib.d.ts b/src-testing/src/renderers/shaders/ShaderLib.d.ts deleted file mode 100644 index 9a52c4dcd..000000000 --- a/src-testing/src/renderers/shaders/ShaderLib.d.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { IUniform } from "./UniformsLib.js"; - -export interface ShaderLibShader { - uniforms: { [uniform: string]: IUniform }; - vertexShader: string; - fragmentShader: string; -} - -declare const ShaderLib: { - [name: string]: ShaderLibShader; - basic: ShaderLibShader; - lambert: ShaderLibShader; - phong: ShaderLibShader; - standard: ShaderLibShader; - matcap: ShaderLibShader; - points: ShaderLibShader; - dashed: ShaderLibShader; - depth: ShaderLibShader; - normal: ShaderLibShader; - sprite: ShaderLibShader; - background: ShaderLibShader; - cube: ShaderLibShader; - equirect: ShaderLibShader; - distanceRGBA: ShaderLibShader; - shadow: ShaderLibShader; - physical: ShaderLibShader; -}; - -export { ShaderLib }; diff --git a/src-testing/src/renderers/shaders/UniformsLib.d.ts b/src-testing/src/renderers/shaders/UniformsLib.d.ts deleted file mode 100644 index cb0d808bd..000000000 --- a/src-testing/src/renderers/shaders/UniformsLib.d.ts +++ /dev/null @@ -1,189 +0,0 @@ -import { Color } from "../../math/Color.js"; -import { Matrix3 } from "../../math/Matrix3.js"; -import { Vector2 } from "../../math/Vector2.js"; - -// eslint-disable-next-line @typescript-eslint/naming-convention -export interface IUniform { - value: TValue; -} - -export const UniformsLib: { - common: { - diffuse: IUniform; - opacity: IUniform; - map: IUniform; - mapTransform: IUniform; - alphaMap: IUniform; - alphaMapTransform: IUniform; - alphaTest: IUniform; - }; - specularmap: { - specularMap: IUniform; - specularMapTransform: IUniform; - }; - envmap: { - envMap: IUniform; - envMapRotation: IUniform; - flipEnvMap: IUniform; - reflectivity: IUniform; - ior: IUniform; - refractRatio: IUniform; - }; - aomap: { - aoMap: IUniform; - aoMapIntensity: IUniform; - aoMapTransform: IUniform; - }; - lightmap: { - lightMap: IUniform; - lightMapIntensity: IUniform; - lightMapTransform: IUniform; - }; - bumpmap: { - bumpMap: IUniform; - bumpMapTransform: IUniform; - bumpScale: IUniform; - }; - normalmap: { - normalMap: IUniform; - normalMapTransform: IUniform; - normalScale: IUniform; - }; - displacementmap: { - displacementMap: IUniform; - displacementMapTransform: IUniform; - displacementScale: IUniform; - displacementBias: IUniform; - }; - emissivemap: { - emissiveMap: IUniform; - emissiveMapTransform: IUniform; - }; - metalnessmap: { - metalnessMap: IUniform; - metalnessMapTransform: IUniform; - }; - roughnessmap: { - roughnessMap: IUniform; - roughnessMapTransform: IUniform; - }; - gradientmap: { - gradientMap: IUniform; - }; - fog: { - fogDensity: IUniform; - fogNear: IUniform; - fogFar: IUniform; - fogColor: IUniform; - }; - lights: { - ambientLightColor: IUniform; - lightProbe: IUniform; - directionalLights: { - value: unknown[]; - properties: { - direction: {}; - color: {}; - }; - }; - directionalLightShadows: { - value: unknown[]; - properties: { - shadowIntensity: number; - shadowBias: {}; - shadowNormalBias: {}; - shadowRadius: {}; - shadowMapSize: {}; - }; - }; - directionalShadowMap: IUniform; - directionalShadowMatrix: IUniform; - spotLights: { - value: unknown[]; - properties: { - color: {}; - position: {}; - direction: {}; - distance: {}; - coneCos: {}; - penumbraCos: {}; - decay: {}; - }; - }; - spotLightShadows: { - value: unknown[]; - properties: { - shadowIntensity: number; - shadowBias: {}; - shadowNormalBias: {}; - shadowRadius: {}; - shadowMapSize: {}; - }; - }; - spotLightMap: IUniform; - spotShadowMap: IUniform; - spotLightMatrix: IUniform; - pointLights: { - value: unknown[]; - properties: { - color: {}; - position: {}; - decay: {}; - distance: {}; - }; - }; - pointLightShadows: { - value: unknown[]; - properties: { - shadowIntensity: number; - shadowBias: {}; - shadowNormalBias: {}; - shadowRadius: {}; - shadowMapSize: {}; - shadowCameraNear: {}; - shadowCameraFar: {}; - }; - }; - pointShadowMap: IUniform; - pointShadowMatrix: IUniform; - hemisphereLights: { - value: unknown[]; - properties: { - direction: {}; - skycolor: {}; - groundColor: {}; - }; - }; - rectAreaLights: { - value: unknown[]; - properties: { - color: {}; - position: {}; - width: {}; - height: {}; - }; - }; - ltc_1: IUniform; - ltc_2: IUniform; - }; - points: { - diffuse: IUniform; - opacity: IUniform; - size: IUniform; - scale: IUniform; - map: IUniform; - alphaMap: IUniform; - alphaTest: IUniform; - uvTransform: IUniform; - }; - sprite: { - diffuse: IUniform; - opacity: IUniform; - center: IUniform; - rotation: IUniform; - map: IUniform; - mapTransform: IUniform; - alphaMap: IUniform; - alphaTest: IUniform; - }; -}; diff --git a/src-testing/src/renderers/shaders/UniformsUtils.d.ts b/src-testing/src/renderers/shaders/UniformsUtils.d.ts deleted file mode 100644 index fe5178d55..000000000 --- a/src-testing/src/renderers/shaders/UniformsUtils.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { UniformsGroup } from "../../core/UniformsGroup.js"; -import { IUniform } from "./UniformsLib.js"; - -export function cloneUniforms(uniformsSrc: T): T; -export function mergeUniforms(uniforms: Array<{ [uniform: string]: IUniform }>): { [uniform: string]: IUniform }; - -export function cloneUniformsGroups(src: UniformsGroup[]): UniformsGroup[]; - -declare const UniformsUtils: { - clone: typeof cloneUniforms; - merge: typeof mergeUniforms; -}; - -export { UniformsUtils }; diff --git a/src-testing/src/renderers/webgl-fallback/WebGLBackend.ts b/src-testing/src/renderers/webgl-fallback/WebGLBackend.ts deleted file mode 100644 index ccf00b986..000000000 --- a/src-testing/src/renderers/webgl-fallback/WebGLBackend.ts +++ /dev/null @@ -1,1349 +0,0 @@ -import GLSLNodeBuilder from './nodes/GLSLNodeBuilder.js'; -import Backend from '../common/Backend.js'; -import { getCacheKey } from '../common/RenderContext.js'; - -import WebGLAttributeUtils from './utils/WebGLAttributeUtils.js'; -import WebGLState from './utils/WebGLState.js'; -import WebGLUtils from './utils/WebGLUtils.js'; -import WebGLTextureUtils from './utils/WebGLTextureUtils.js'; -import WebGLExtensions from './utils/WebGLExtensions.js'; -import WebGLCapabilities from './utils/WebGLCapabilities.js'; -import { GLFeatureName } from './utils/WebGLConstants.js'; -import { WebGLBufferRenderer } from './WebGLBufferRenderer.js'; - -import { warnOnce } from '../../utils.js'; -import { WebGLCoordinateSystem } from '../../constants.js'; - -// - -class WebGLBackend extends Backend { - constructor(parameters = {}) { - super(parameters); - - this.isWebGLBackend = true; - } - - init(renderer) { - super.init(renderer); - - // - - const parameters = this.parameters; - - const glContext = - parameters.context !== undefined ? parameters.context : renderer.domElement.getContext('webgl2'); - - this.gl = glContext; - - this.extensions = new WebGLExtensions(this); - this.capabilities = new WebGLCapabilities(this); - this.attributeUtils = new WebGLAttributeUtils(this); - this.textureUtils = new WebGLTextureUtils(this); - this.bufferRenderer = new WebGLBufferRenderer(this); - - this.state = new WebGLState(this); - this.utils = new WebGLUtils(this); - - this.vaoCache = {}; - this.transformFeedbackCache = {}; - this.discard = false; - this.trackTimestamp = parameters.trackTimestamp === true; - - this.extensions.get('EXT_color_buffer_float'); - this.extensions.get('WEBGL_clip_cull_distance'); - this.extensions.get('OES_texture_float_linear'); - this.extensions.get('EXT_color_buffer_half_float'); - this.extensions.get('WEBGL_multisampled_render_to_texture'); - this.extensions.get('WEBGL_render_shared_exponent'); - this.extensions.get('WEBGL_multi_draw'); - - this.disjoint = this.extensions.get('EXT_disjoint_timer_query_webgl2'); - this.parallel = this.extensions.get('KHR_parallel_shader_compile'); - - this._knownBindings = new WeakSet(); - - this._currentContext = null; - } - - get coordinateSystem() { - return WebGLCoordinateSystem; - } - - async getArrayBufferAsync(attribute) { - return await this.attributeUtils.getArrayBufferAsync(attribute); - } - - async waitForGPU() { - await this.utils._clientWaitAsync(); - } - - initTimestampQuery(renderContext) { - if (!this.disjoint || !this.trackTimestamp) return; - - const renderContextData = this.get(renderContext); - - if (this.queryRunning) { - if (!renderContextData.queryQueue) renderContextData.queryQueue = []; - renderContextData.queryQueue.push(renderContext); - return; - } - - if (renderContextData.activeQuery) { - this.gl.endQuery(this.disjoint.TIME_ELAPSED_EXT); - renderContextData.activeQuery = null; - } - - renderContextData.activeQuery = this.gl.createQuery(); - - if (renderContextData.activeQuery !== null) { - this.gl.beginQuery(this.disjoint.TIME_ELAPSED_EXT, renderContextData.activeQuery); - this.queryRunning = true; - } - } - - // timestamp utils - - prepareTimestampBuffer(renderContext) { - if (!this.disjoint || !this.trackTimestamp) return; - - const renderContextData = this.get(renderContext); - - if (renderContextData.activeQuery) { - this.gl.endQuery(this.disjoint.TIME_ELAPSED_EXT); - - if (!renderContextData.gpuQueries) renderContextData.gpuQueries = []; - renderContextData.gpuQueries.push({ query: renderContextData.activeQuery }); - renderContextData.activeQuery = null; - this.queryRunning = false; - - if (renderContextData.queryQueue && renderContextData.queryQueue.length > 0) { - const nextRenderContext = renderContextData.queryQueue.shift(); - this.initTimestampQuery(nextRenderContext); - } - } - } - - async resolveTimestampAsync(renderContext, type = 'render') { - if (!this.disjoint || !this.trackTimestamp) return; - - const renderContextData = this.get(renderContext); - - if (!renderContextData.gpuQueries) renderContextData.gpuQueries = []; - - for (let i = 0; i < renderContextData.gpuQueries.length; i++) { - const queryInfo = renderContextData.gpuQueries[i]; - const available = this.gl.getQueryParameter(queryInfo.query, this.gl.QUERY_RESULT_AVAILABLE); - const disjoint = this.gl.getParameter(this.disjoint.GPU_DISJOINT_EXT); - - if (available && !disjoint) { - const elapsed = this.gl.getQueryParameter(queryInfo.query, this.gl.QUERY_RESULT); - const duration = Number(elapsed) / 1000000; // Convert nanoseconds to milliseconds - this.gl.deleteQuery(queryInfo.query); - renderContextData.gpuQueries.splice(i, 1); // Remove the processed query - i--; - this.renderer.info.updateTimestamp(type, duration); - } - } - } - - getContext() { - return this.gl; - } - - beginRender(renderContext) { - const { gl } = this; - const renderContextData = this.get(renderContext); - - // - - // - - this.initTimestampQuery(renderContext); - - renderContextData.previousContext = this._currentContext; - this._currentContext = renderContext; - - this._setFramebuffer(renderContext); - - this.clear( - renderContext.clearColor, - renderContext.clearDepth, - renderContext.clearStencil, - renderContext, - false, - ); - - // - if (renderContext.viewport) { - this.updateViewport(renderContext); - } else { - gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); - } - - if (renderContext.scissor) { - const { x, y, width, height } = renderContext.scissorValue; - - gl.scissor(x, renderContext.height - height - y, width, height); - } - - const occlusionQueryCount = renderContext.occlusionQueryCount; - - if (occlusionQueryCount > 0) { - // Get a reference to the array of objects with queries. The renderContextData property - // can be changed by another render pass before the async reading of all previous queries complete - renderContextData.currentOcclusionQueries = renderContextData.occlusionQueries; - renderContextData.currentOcclusionQueryObjects = renderContextData.occlusionQueryObjects; - - renderContextData.lastOcclusionObject = null; - renderContextData.occlusionQueries = new Array(occlusionQueryCount); - renderContextData.occlusionQueryObjects = new Array(occlusionQueryCount); - renderContextData.occlusionQueryIndex = 0; - } - } - - finishRender(renderContext) { - const { gl, state } = this; - const renderContextData = this.get(renderContext); - const previousContext = renderContextData.previousContext; - - const occlusionQueryCount = renderContext.occlusionQueryCount; - - if (occlusionQueryCount > 0) { - if (occlusionQueryCount > renderContextData.occlusionQueryIndex) { - gl.endQuery(gl.ANY_SAMPLES_PASSED); - } - - this.resolveOccludedAsync(renderContext); - } - - const textures = renderContext.textures; - - if (textures !== null) { - for (let i = 0; i < textures.length; i++) { - const texture = textures[i]; - - if (texture.generateMipmaps) { - this.generateMipmaps(texture); - } - } - } - - this._currentContext = previousContext; - - if (renderContext.textures !== null && renderContext.renderTarget) { - const renderTargetContextData = this.get(renderContext.renderTarget); - - const { samples } = renderContext.renderTarget; - - if (samples > 0) { - const fb = renderTargetContextData.framebuffers[renderContext.getCacheKey()]; - - const mask = gl.COLOR_BUFFER_BIT; - - const msaaFrameBuffer = renderTargetContextData.msaaFrameBuffer; - - const textures = renderContext.textures; - - state.bindFramebuffer(gl.READ_FRAMEBUFFER, msaaFrameBuffer); - state.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fb); - - for (let i = 0; i < textures.length; i++) { - // TODO Add support for MRT - - if (renderContext.scissor) { - const { x, y, width, height } = renderContext.scissorValue; - - const viewY = renderContext.height - height - y; - - gl.blitFramebuffer( - x, - viewY, - x + width, - viewY + height, - x, - viewY, - x + width, - viewY + height, - mask, - gl.NEAREST, - ); - gl.invalidateSubFramebuffer( - gl.READ_FRAMEBUFFER, - renderTargetContextData.invalidationArray, - x, - viewY, - width, - height, - ); - } else { - gl.blitFramebuffer( - 0, - 0, - renderContext.width, - renderContext.height, - 0, - 0, - renderContext.width, - renderContext.height, - mask, - gl.NEAREST, - ); - gl.invalidateFramebuffer(gl.READ_FRAMEBUFFER, renderTargetContextData.invalidationArray); - } - } - } - } - - if (previousContext !== null) { - this._setFramebuffer(previousContext); - - if (previousContext.viewport) { - this.updateViewport(previousContext); - } else { - gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); - } - } - - this.prepareTimestampBuffer(renderContext); - } - - resolveOccludedAsync(renderContext) { - const renderContextData = this.get(renderContext); - - // handle occlusion query results - - const { currentOcclusionQueries, currentOcclusionQueryObjects } = renderContextData; - - if (currentOcclusionQueries && currentOcclusionQueryObjects) { - const occluded = new WeakSet(); - const { gl } = this; - - renderContextData.currentOcclusionQueryObjects = null; - renderContextData.currentOcclusionQueries = null; - - const check = () => { - let completed = 0; - - // check all queries and requeue as appropriate - for (let i = 0; i < currentOcclusionQueries.length; i++) { - const query = currentOcclusionQueries[i]; - - if (query === null) continue; - - if (gl.getQueryParameter(query, gl.QUERY_RESULT_AVAILABLE)) { - if (gl.getQueryParameter(query, gl.QUERY_RESULT) > 0) - occluded.add(currentOcclusionQueryObjects[i]); - - currentOcclusionQueries[i] = null; - gl.deleteQuery(query); - - completed++; - } - } - - if (completed < currentOcclusionQueries.length) { - requestAnimationFrame(check); - } else { - renderContextData.occluded = occluded; - } - }; - - check(); - } - } - - isOccluded(renderContext, object) { - const renderContextData = this.get(renderContext); - - return renderContextData.occluded && renderContextData.occluded.has(object); - } - - updateViewport(renderContext) { - const gl = this.gl; - const { x, y, width, height } = renderContext.viewportValue; - - gl.viewport(x, renderContext.height - height - y, width, height); - } - - setScissorTest(boolean) { - const gl = this.gl; - - if (boolean) { - gl.enable(gl.SCISSOR_TEST); - } else { - gl.disable(gl.SCISSOR_TEST); - } - } - - clear(color, depth, stencil, descriptor = null, setFrameBuffer = true) { - const { gl } = this; - - if (descriptor === null) { - const clearColor = this.getClearColor(); - - // premultiply alpha - - clearColor.r *= clearColor.a; - clearColor.g *= clearColor.a; - clearColor.b *= clearColor.a; - - descriptor = { - textures: null, - clearColorValue: clearColor, - }; - } - - // - - let clear = 0; - - if (color) clear |= gl.COLOR_BUFFER_BIT; - if (depth) clear |= gl.DEPTH_BUFFER_BIT; - if (stencil) clear |= gl.STENCIL_BUFFER_BIT; - - if (clear !== 0) { - let clearColor; - - if (descriptor.clearColorValue) { - clearColor = descriptor.clearColorValue; - } else { - clearColor = this.getClearColor(); - - // premultiply alpha - - clearColor.r *= clearColor.a; - clearColor.g *= clearColor.a; - clearColor.b *= clearColor.a; - } - - if (depth) this.state.setDepthMask(true); - - if (descriptor.textures === null) { - gl.clearColor(clearColor.r, clearColor.g, clearColor.b, clearColor.a); - gl.clear(clear); - } else { - if (setFrameBuffer) this._setFramebuffer(descriptor); - - if (color) { - for (let i = 0; i < descriptor.textures.length; i++) { - gl.clearBufferfv(gl.COLOR, i, [clearColor.r, clearColor.g, clearColor.b, clearColor.a]); - } - } - - if (depth && stencil) { - gl.clearBufferfi(gl.DEPTH_STENCIL, 0, 1, 0); - } else if (depth) { - gl.clearBufferfv(gl.DEPTH, 0, [1.0]); - } else if (stencil) { - gl.clearBufferiv(gl.STENCIL, 0, [0]); - } - } - } - } - - beginCompute(computeGroup) { - const { state, gl } = this; - - state.bindFramebuffer(gl.FRAMEBUFFER, null); - this.initTimestampQuery(computeGroup); - } - - compute(computeGroup, computeNode, bindings, pipeline) { - const { state, gl } = this; - - if (!this.discard) { - // required here to handle async behaviour of render.compute() - gl.enable(gl.RASTERIZER_DISCARD); - this.discard = true; - } - - const { programGPU, transformBuffers, attributes } = this.get(pipeline); - - const vaoKey = this._getVaoKey(null, attributes); - - const vaoGPU = this.vaoCache[vaoKey]; - - if (vaoGPU === undefined) { - this._createVao(null, attributes); - } else { - gl.bindVertexArray(vaoGPU); - } - - state.useProgram(programGPU); - - this._bindUniforms(bindings); - - const transformFeedbackGPU = this._getTransformFeedback(transformBuffers); - - gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, transformFeedbackGPU); - gl.beginTransformFeedback(gl.POINTS); - - if (attributes[0].isStorageInstancedBufferAttribute) { - gl.drawArraysInstanced(gl.POINTS, 0, 1, computeNode.count); - } else { - gl.drawArrays(gl.POINTS, 0, computeNode.count); - } - - gl.endTransformFeedback(); - gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null); - - // switch active buffers - - for (let i = 0; i < transformBuffers.length; i++) { - const dualAttributeData = transformBuffers[i]; - - if (dualAttributeData.pbo) { - this.textureUtils.copyBufferToTexture(dualAttributeData.transformBuffer, dualAttributeData.pbo); - } - - dualAttributeData.switchBuffers(); - } - } - - finishCompute(computeGroup) { - const gl = this.gl; - - this.discard = false; - - gl.disable(gl.RASTERIZER_DISCARD); - - this.prepareTimestampBuffer(computeGroup); - - if (this._currentContext) { - this._setFramebuffer(this._currentContext); - } - } - - draw(renderObject /*, info*/) { - const { object, pipeline, material, context } = renderObject; - const { programGPU } = this.get(pipeline); - - const { gl, state } = this; - - const contextData = this.get(context); - - const drawParams = renderObject.getDrawParameters(); - - if (drawParams === null) return; - - // - - this._bindUniforms(renderObject.getBindings()); - - const frontFaceCW = object.isMesh && object.matrixWorld.determinant() < 0; - - state.setMaterial(material, frontFaceCW); - - state.useProgram(programGPU); - - // - - let vaoGPU = renderObject.staticVao; - - if (vaoGPU === undefined) { - const vaoKey = this._getVaoKey(renderObject.getIndex(), renderObject.getAttributes()); - - vaoGPU = this.vaoCache[vaoKey]; - - if (vaoGPU === undefined) { - let staticVao; - - ({ vaoGPU, staticVao } = this._createVao(renderObject.getIndex(), renderObject.getAttributes())); - - if (staticVao) renderObject.staticVao = vaoGPU; - } - } - - gl.bindVertexArray(vaoGPU); - - // - - const index = renderObject.getIndex(); - - // - - const lastObject = contextData.lastOcclusionObject; - - if (lastObject !== object && lastObject !== undefined) { - if (lastObject !== null && lastObject.occlusionTest === true) { - gl.endQuery(gl.ANY_SAMPLES_PASSED); - - contextData.occlusionQueryIndex++; - } - - if (object.occlusionTest === true) { - const query = gl.createQuery(); - - gl.beginQuery(gl.ANY_SAMPLES_PASSED, query); - - contextData.occlusionQueries[contextData.occlusionQueryIndex] = query; - contextData.occlusionQueryObjects[contextData.occlusionQueryIndex] = object; - } - - contextData.lastOcclusionObject = object; - } - - // - const renderer = this.bufferRenderer; - - if (object.isPoints) renderer.mode = gl.POINTS; - else if (object.isLineSegments) renderer.mode = gl.LINES; - else if (object.isLine) renderer.mode = gl.LINE_STRIP; - else if (object.isLineLoop) renderer.mode = gl.LINE_LOOP; - else { - if (material.wireframe === true) { - state.setLineWidth(material.wireframeLinewidth * this.renderer.getPixelRatio()); - renderer.mode = gl.LINES; - } else { - renderer.mode = gl.TRIANGLES; - } - } - - // - - const { vertexCount, instanceCount } = drawParams; - let { firstVertex } = drawParams; - - renderer.object = object; - - if (index !== null) { - firstVertex *= index.array.BYTES_PER_ELEMENT; - - const indexData = this.get(index); - - renderer.index = index.count; - renderer.type = indexData.type; - } else { - renderer.index = 0; - } - - if (object.isBatchedMesh) { - if (object._multiDrawInstances !== null) { - renderer.renderMultiDrawInstances( - object._multiDrawStarts, - object._multiDrawCounts, - object._multiDrawCount, - object._multiDrawInstances, - ); - } else if (!this.hasFeature('WEBGL_multi_draw')) { - warnOnce('THREE.WebGLRenderer: WEBGL_multi_draw not supported.'); - } else { - renderer.renderMultiDraw(object._multiDrawStarts, object._multiDrawCounts, object._multiDrawCount); - } - } else if (instanceCount > 1) { - renderer.renderInstances(firstVertex, vertexCount, instanceCount); - } else { - renderer.render(firstVertex, vertexCount); - } - // - - gl.bindVertexArray(null); - } - - needsRenderUpdate(/*renderObject*/) { - return false; - } - - getRenderCacheKey(/*renderObject*/) { - return ''; - } - - // textures - - createDefaultTexture(texture) { - this.textureUtils.createDefaultTexture(texture); - } - - createTexture(texture, options) { - this.textureUtils.createTexture(texture, options); - } - - updateTexture(texture, options) { - this.textureUtils.updateTexture(texture, options); - } - - generateMipmaps(texture) { - this.textureUtils.generateMipmaps(texture); - } - - destroyTexture(texture) { - this.textureUtils.destroyTexture(texture); - } - - copyTextureToBuffer(texture, x, y, width, height, faceIndex) { - return this.textureUtils.copyTextureToBuffer(texture, x, y, width, height, faceIndex); - } - - createSampler(/*texture*/) { - //console.warn( 'Abstract class.' ); - } - - destroySampler() {} - - // node builder - - createNodeBuilder(object, renderer) { - return new GLSLNodeBuilder(object, renderer); - } - - // program - - createProgram(program) { - const gl = this.gl; - const { stage, code } = program; - - const shader = stage === 'fragment' ? gl.createShader(gl.FRAGMENT_SHADER) : gl.createShader(gl.VERTEX_SHADER); - - gl.shaderSource(shader, code); - gl.compileShader(shader); - - this.set(program, { - shaderGPU: shader, - }); - } - - destroyProgram(/*program*/) { - console.warn('Abstract class.'); - } - - createRenderPipeline(renderObject, promises) { - const gl = this.gl; - const pipeline = renderObject.pipeline; - - // Program - - const { fragmentProgram, vertexProgram } = pipeline; - - const programGPU = gl.createProgram(); - - const fragmentShader = this.get(fragmentProgram).shaderGPU; - const vertexShader = this.get(vertexProgram).shaderGPU; - - gl.attachShader(programGPU, fragmentShader); - gl.attachShader(programGPU, vertexShader); - gl.linkProgram(programGPU); - - this.set(pipeline, { - programGPU, - fragmentShader, - vertexShader, - }); - - if (promises !== null && this.parallel) { - const p = new Promise((resolve /*, reject*/) => { - const parallel = this.parallel; - const checkStatus = () => { - if (gl.getProgramParameter(programGPU, parallel.COMPLETION_STATUS_KHR)) { - this._completeCompile(renderObject, pipeline); - resolve(); - } else { - requestAnimationFrame(checkStatus); - } - }; - - checkStatus(); - }); - - promises.push(p); - - return; - } - - this._completeCompile(renderObject, pipeline); - } - - _handleSource(string, errorLine) { - const lines = string.split('\n'); - const lines2 = []; - - const from = Math.max(errorLine - 6, 0); - const to = Math.min(errorLine + 6, lines.length); - - for (let i = from; i < to; i++) { - const line = i + 1; - lines2.push(`${line === errorLine ? '>' : ' '} ${line}: ${lines[i]}`); - } - - return lines2.join('\n'); - } - - _getShaderErrors(gl, shader, type) { - const status = gl.getShaderParameter(shader, gl.COMPILE_STATUS); - const errors = gl.getShaderInfoLog(shader).trim(); - - if (status && errors === '') return ''; - - const errorMatches = /ERROR: 0:(\d+)/.exec(errors); - if (errorMatches) { - const errorLine = parseInt(errorMatches[1]); - return ( - type.toUpperCase() + - '\n\n' + - errors + - '\n\n' + - this._handleSource(gl.getShaderSource(shader), errorLine) - ); - } else { - return errors; - } - } - - _logProgramError(programGPU, glFragmentShader, glVertexShader) { - if (this.renderer.debug.checkShaderErrors) { - const gl = this.gl; - - const programLog = gl.getProgramInfoLog(programGPU).trim(); - - if (gl.getProgramParameter(programGPU, gl.LINK_STATUS) === false) { - if (typeof this.renderer.debug.onShaderError === 'function') { - this.renderer.debug.onShaderError(gl, programGPU, glVertexShader, glFragmentShader); - } else { - // default error reporting - - const vertexErrors = this._getShaderErrors(gl, glVertexShader, 'vertex'); - const fragmentErrors = this._getShaderErrors(gl, glFragmentShader, 'fragment'); - - console.error( - 'THREE.WebGLProgram: Shader Error ' + - gl.getError() + - ' - ' + - 'VALIDATE_STATUS ' + - gl.getProgramParameter(programGPU, gl.VALIDATE_STATUS) + - '\n\n' + - 'Program Info Log: ' + - programLog + - '\n' + - vertexErrors + - '\n' + - fragmentErrors, - ); - } - } else if (programLog !== '') { - console.warn('THREE.WebGLProgram: Program Info Log:', programLog); - } - } - } - - _completeCompile(renderObject, pipeline) { - const { state, gl } = this; - const pipelineData = this.get(pipeline); - const { programGPU, fragmentShader, vertexShader } = pipelineData; - - if (gl.getProgramParameter(programGPU, gl.LINK_STATUS) === false) { - this._logProgramError(programGPU, fragmentShader, vertexShader); - } - - state.useProgram(programGPU); - - // Bindings - - const bindings = renderObject.getBindings(); - - this._setupBindings(bindings, programGPU); - - // - - this.set(pipeline, { - programGPU, - }); - } - - createComputePipeline(computePipeline, bindings) { - const { state, gl } = this; - - // Program - - const fragmentProgram = { - stage: 'fragment', - code: '#version 300 es\nprecision highp float;\nvoid main() {}', - }; - - this.createProgram(fragmentProgram); - - const { computeProgram } = computePipeline; - - const programGPU = gl.createProgram(); - - const fragmentShader = this.get(fragmentProgram).shaderGPU; - const vertexShader = this.get(computeProgram).shaderGPU; - - const transforms = computeProgram.transforms; - - const transformVaryingNames = []; - const transformAttributeNodes = []; - - for (let i = 0; i < transforms.length; i++) { - const transform = transforms[i]; - - transformVaryingNames.push(transform.varyingName); - transformAttributeNodes.push(transform.attributeNode); - } - - gl.attachShader(programGPU, fragmentShader); - gl.attachShader(programGPU, vertexShader); - - gl.transformFeedbackVaryings(programGPU, transformVaryingNames, gl.SEPARATE_ATTRIBS); - - gl.linkProgram(programGPU); - - if (gl.getProgramParameter(programGPU, gl.LINK_STATUS) === false) { - this._logProgramError(programGPU, fragmentShader, vertexShader); - } - - state.useProgram(programGPU); - - // Bindings - - this._setupBindings(bindings, programGPU); - - const attributeNodes = computeProgram.attributes; - const attributes = []; - const transformBuffers = []; - - for (let i = 0; i < attributeNodes.length; i++) { - const attribute = attributeNodes[i].node.attribute; - - attributes.push(attribute); - - if (!this.has(attribute)) this.attributeUtils.createAttribute(attribute, gl.ARRAY_BUFFER); - } - - for (let i = 0; i < transformAttributeNodes.length; i++) { - const attribute = transformAttributeNodes[i].attribute; - - if (!this.has(attribute)) this.attributeUtils.createAttribute(attribute, gl.ARRAY_BUFFER); - - const attributeData = this.get(attribute); - - transformBuffers.push(attributeData); - } - - // - - this.set(computePipeline, { - programGPU, - transformBuffers, - attributes, - }); - } - - createBindings(bindGroup, bindings) { - if (this._knownBindings.has(bindings) === false) { - this._knownBindings.add(bindings); - - let uniformBuffers = 0; - let textures = 0; - - for (const bindGroup of bindings) { - this.set(bindGroup, { - textures: textures, - uniformBuffers: uniformBuffers, - }); - - for (const binding of bindGroup.bindings) { - if (binding.isUniformBuffer) uniformBuffers++; - if (binding.isSampledTexture) textures++; - } - } - } - - this.updateBindings(bindGroup, bindings); - } - - updateBindings(bindGroup /*, bindings*/) { - const { gl } = this; - - const bindGroupData = this.get(bindGroup); - - let i = bindGroupData.uniformBuffers; - let t = bindGroupData.textures; - - for (const binding of bindGroup.bindings) { - if (binding.isUniformsGroup || binding.isUniformBuffer) { - const data = binding.buffer; - const bufferGPU = gl.createBuffer(); - - gl.bindBuffer(gl.UNIFORM_BUFFER, bufferGPU); - gl.bufferData(gl.UNIFORM_BUFFER, data, gl.DYNAMIC_DRAW); - - this.set(binding, { - index: i++, - bufferGPU, - }); - } else if (binding.isSampledTexture) { - const { textureGPU, glTextureType } = this.get(binding.texture); - - this.set(binding, { - index: t++, - textureGPU, - glTextureType, - }); - } - } - } - - updateBinding(binding) { - const gl = this.gl; - - if (binding.isUniformsGroup || binding.isUniformBuffer) { - const bindingData = this.get(binding); - const bufferGPU = bindingData.bufferGPU; - const data = binding.buffer; - - gl.bindBuffer(gl.UNIFORM_BUFFER, bufferGPU); - gl.bufferData(gl.UNIFORM_BUFFER, data, gl.DYNAMIC_DRAW); - } - } - - // attributes - - createIndexAttribute(attribute) { - const gl = this.gl; - - this.attributeUtils.createAttribute(attribute, gl.ELEMENT_ARRAY_BUFFER); - } - - createAttribute(attribute) { - if (this.has(attribute)) return; - - const gl = this.gl; - - this.attributeUtils.createAttribute(attribute, gl.ARRAY_BUFFER); - } - - createStorageAttribute(attribute) { - if (this.has(attribute)) return; - - const gl = this.gl; - - this.attributeUtils.createAttribute(attribute, gl.ARRAY_BUFFER); - } - - updateAttribute(attribute) { - this.attributeUtils.updateAttribute(attribute); - } - - destroyAttribute(attribute) { - this.attributeUtils.destroyAttribute(attribute); - } - - updateSize() { - //console.warn( 'Abstract class.' ); - } - - hasFeature(name) { - const keysMatching = Object.keys(GLFeatureName).filter(key => GLFeatureName[key] === name); - - const extensions = this.extensions; - - for (let i = 0; i < keysMatching.length; i++) { - if (extensions.has(keysMatching[i])) return true; - } - - return false; - } - - getMaxAnisotropy() { - return this.capabilities.getMaxAnisotropy(); - } - - copyTextureToTexture(srcTexture, dstTexture, srcRegion, dstPosition, level) { - this.textureUtils.copyTextureToTexture(srcTexture, dstTexture, srcRegion, dstPosition, level); - } - - copyFramebufferToTexture(texture, renderContext, rectangle) { - this.textureUtils.copyFramebufferToTexture(texture, renderContext, rectangle); - } - - _setFramebuffer(descriptor) { - const { gl, state } = this; - - let currentFrameBuffer = null; - - if (descriptor.textures !== null) { - const renderTarget = descriptor.renderTarget; - const renderTargetContextData = this.get(renderTarget); - const { samples, depthBuffer, stencilBuffer } = renderTarget; - - const isCube = renderTarget.isWebGLCubeRenderTarget === true; - - let msaaFb = renderTargetContextData.msaaFrameBuffer; - let depthRenderbuffer = renderTargetContextData.depthRenderbuffer; - - const cacheKey = getCacheKey(descriptor); - - let fb; - - if (isCube) { - renderTargetContextData.cubeFramebuffers || (renderTargetContextData.cubeFramebuffers = {}); - - fb = renderTargetContextData.cubeFramebuffers[cacheKey]; - } else { - renderTargetContextData.framebuffers || (renderTargetContextData.framebuffers = {}); - - fb = renderTargetContextData.framebuffers[cacheKey]; - } - - if (fb === undefined) { - fb = gl.createFramebuffer(); - - state.bindFramebuffer(gl.FRAMEBUFFER, fb); - - const textures = descriptor.textures; - - if (isCube) { - renderTargetContextData.cubeFramebuffers[cacheKey] = fb; - - const { textureGPU } = this.get(textures[0]); - - const cubeFace = this.renderer._activeCubeFace; - - gl.framebufferTexture2D( - gl.FRAMEBUFFER, - gl.COLOR_ATTACHMENT0, - gl.TEXTURE_CUBE_MAP_POSITIVE_X + cubeFace, - textureGPU, - 0, - ); - } else { - renderTargetContextData.framebuffers[cacheKey] = fb; - - for (let i = 0; i < textures.length; i++) { - const texture = textures[i]; - const textureData = this.get(texture); - textureData.renderTarget = descriptor.renderTarget; - textureData.cacheKey = cacheKey; // required for copyTextureToTexture() - - const attachment = gl.COLOR_ATTACHMENT0 + i; - - gl.framebufferTexture2D(gl.FRAMEBUFFER, attachment, gl.TEXTURE_2D, textureData.textureGPU, 0); - } - - state.drawBuffers(descriptor, fb); - } - - if (descriptor.depthTexture !== null) { - const textureData = this.get(descriptor.depthTexture); - const depthStyle = stencilBuffer ? gl.DEPTH_STENCIL_ATTACHMENT : gl.DEPTH_ATTACHMENT; - textureData.renderTarget = descriptor.renderTarget; - textureData.cacheKey = cacheKey; // required for copyTextureToTexture() - - gl.framebufferTexture2D(gl.FRAMEBUFFER, depthStyle, gl.TEXTURE_2D, textureData.textureGPU, 0); - } - } - - if (samples > 0) { - if (msaaFb === undefined) { - const invalidationArray = []; - - msaaFb = gl.createFramebuffer(); - - state.bindFramebuffer(gl.FRAMEBUFFER, msaaFb); - - const msaaRenderbuffers = []; - - const textures = descriptor.textures; - - for (let i = 0; i < textures.length; i++) { - msaaRenderbuffers[i] = gl.createRenderbuffer(); - - gl.bindRenderbuffer(gl.RENDERBUFFER, msaaRenderbuffers[i]); - - invalidationArray.push(gl.COLOR_ATTACHMENT0 + i); - - if (depthBuffer) { - const depthStyle = stencilBuffer ? gl.DEPTH_STENCIL_ATTACHMENT : gl.DEPTH_ATTACHMENT; - invalidationArray.push(depthStyle); - } - - const texture = descriptor.textures[i]; - const textureData = this.get(texture); - - gl.renderbufferStorageMultisample( - gl.RENDERBUFFER, - samples, - textureData.glInternalFormat, - descriptor.width, - descriptor.height, - ); - gl.framebufferRenderbuffer( - gl.FRAMEBUFFER, - gl.COLOR_ATTACHMENT0 + i, - gl.RENDERBUFFER, - msaaRenderbuffers[i], - ); - } - - renderTargetContextData.msaaFrameBuffer = msaaFb; - renderTargetContextData.msaaRenderbuffers = msaaRenderbuffers; - - if (depthRenderbuffer === undefined) { - depthRenderbuffer = gl.createRenderbuffer(); - this.textureUtils.setupRenderBufferStorage(depthRenderbuffer, descriptor); - - renderTargetContextData.depthRenderbuffer = depthRenderbuffer; - - const depthStyle = stencilBuffer ? gl.DEPTH_STENCIL_ATTACHMENT : gl.DEPTH_ATTACHMENT; - invalidationArray.push(depthStyle); - } - - renderTargetContextData.invalidationArray = invalidationArray; - } - - currentFrameBuffer = renderTargetContextData.msaaFrameBuffer; - } else { - currentFrameBuffer = fb; - } - } - - state.bindFramebuffer(gl.FRAMEBUFFER, currentFrameBuffer); - } - - _getVaoKey(index, attributes) { - let key = []; - - if (index !== null) { - const indexData = this.get(index); - - key += ':' + indexData.id; - } - - for (let i = 0; i < attributes.length; i++) { - const attributeData = this.get(attributes[i]); - - key += ':' + attributeData.id; - } - - return key; - } - - _createVao(index, attributes) { - const { gl } = this; - - const vaoGPU = gl.createVertexArray(); - let key = ''; - - let staticVao = true; - - gl.bindVertexArray(vaoGPU); - - if (index !== null) { - const indexData = this.get(index); - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexData.bufferGPU); - - key += ':' + indexData.id; - } - - for (let i = 0; i < attributes.length; i++) { - const attribute = attributes[i]; - const attributeData = this.get(attribute); - - key += ':' + attributeData.id; - - gl.bindBuffer(gl.ARRAY_BUFFER, attributeData.bufferGPU); - gl.enableVertexAttribArray(i); - - if (attribute.isStorageBufferAttribute || attribute.isStorageInstancedBufferAttribute) staticVao = false; - - let stride, offset; - - if (attribute.isInterleavedBufferAttribute === true) { - stride = attribute.data.stride * attributeData.bytesPerElement; - offset = attribute.offset * attributeData.bytesPerElement; - } else { - stride = 0; - offset = 0; - } - - if (attributeData.isInteger) { - gl.vertexAttribIPointer(i, attribute.itemSize, attributeData.type, stride, offset); - } else { - gl.vertexAttribPointer(i, attribute.itemSize, attributeData.type, attribute.normalized, stride, offset); - } - - if (attribute.isInstancedBufferAttribute && !attribute.isInterleavedBufferAttribute) { - gl.vertexAttribDivisor(i, attribute.meshPerAttribute); - } else if (attribute.isInterleavedBufferAttribute && attribute.data.isInstancedInterleavedBuffer) { - gl.vertexAttribDivisor(i, attribute.data.meshPerAttribute); - } - } - - gl.bindBuffer(gl.ARRAY_BUFFER, null); - - this.vaoCache[key] = vaoGPU; - - return { vaoGPU, staticVao }; - } - - _getTransformFeedback(transformBuffers) { - let key = ''; - - for (let i = 0; i < transformBuffers.length; i++) { - key += ':' + transformBuffers[i].id; - } - - let transformFeedbackGPU = this.transformFeedbackCache[key]; - - if (transformFeedbackGPU !== undefined) { - return transformFeedbackGPU; - } - - const { gl } = this; - - transformFeedbackGPU = gl.createTransformFeedback(); - - gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, transformFeedbackGPU); - - for (let i = 0; i < transformBuffers.length; i++) { - const attributeData = transformBuffers[i]; - - gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, i, attributeData.transformBuffer); - } - - gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null); - - this.transformFeedbackCache[key] = transformFeedbackGPU; - - return transformFeedbackGPU; - } - - _setupBindings(bindings, programGPU) { - const gl = this.gl; - - for (const bindGroup of bindings) { - for (const binding of bindGroup.bindings) { - const bindingData = this.get(binding); - const index = bindingData.index; - - if (binding.isUniformsGroup || binding.isUniformBuffer) { - const location = gl.getUniformBlockIndex(programGPU, binding.name); - gl.uniformBlockBinding(programGPU, location, index); - } else if (binding.isSampledTexture) { - const location = gl.getUniformLocation(programGPU, binding.name); - gl.uniform1i(location, index); - } - } - } - } - - _bindUniforms(bindings) { - const { gl, state } = this; - - for (const bindGroup of bindings) { - for (const binding of bindGroup.bindings) { - const bindingData = this.get(binding); - const index = bindingData.index; - - if (binding.isUniformsGroup || binding.isUniformBuffer) { - // TODO USE bindBufferRange to group multiple uniform buffers - state.bindBufferBase(gl.UNIFORM_BUFFER, index, bindingData.bufferGPU); - } else if (binding.isSampledTexture) { - state.bindTexture(bindingData.glTextureType, bindingData.textureGPU, gl.TEXTURE0 + index); - } - } - } - } -} - -export default WebGLBackend; diff --git a/src-testing/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.ts b/src-testing/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.ts deleted file mode 100644 index b1e720647..000000000 --- a/src-testing/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.ts +++ /dev/null @@ -1,812 +0,0 @@ -import { GLSLNodeParser, NodeBuilder, TextureNode, vectorComponents } from '../../../nodes/Nodes.js'; - -import NodeUniformBuffer from '../../common/nodes/NodeUniformBuffer.js'; -import NodeUniformsGroup from '../../common/nodes/NodeUniformsGroup.js'; - -import { - NodeSampledTexture, - NodeSampledCubeTexture, - NodeSampledTexture3D, -} from '../../common/nodes/NodeSampledTexture.js'; - -import { - NoColorSpace, - ByteType, - ShortType, - RGBAIntegerFormat, - RGBIntegerFormat, - RedIntegerFormat, - RGIntegerFormat, - UnsignedByteType, - UnsignedIntType, - UnsignedShortType, - RedFormat, - RGFormat, - IntType, - RGBFormat, - RGBAFormat, - FloatType, -} from '../../../constants.js'; -import { DataTexture } from '../../../textures/DataTexture.js'; - -const glslMethods = { - atan2: 'atan', - textureDimensions: 'textureSize', - equals: 'equal', -}; - -const precisionLib = { - low: 'lowp', - medium: 'mediump', - high: 'highp', -}; - -const supports = { - swizzleAssign: true, - storageBuffer: false, -}; - -const defaultPrecisions = ` -precision highp float; -precision highp int; -precision highp sampler2D; -precision highp sampler3D; -precision highp samplerCube; -precision highp sampler2DArray; - -precision highp usampler2D; -precision highp usampler3D; -precision highp usamplerCube; -precision highp usampler2DArray; - -precision highp isampler2D; -precision highp isampler3D; -precision highp isamplerCube; -precision highp isampler2DArray; - -precision lowp sampler2DShadow; -`; - -class GLSLNodeBuilder extends NodeBuilder { - constructor(object, renderer) { - super(object, renderer, new GLSLNodeParser()); - - this.uniformGroups = {}; - this.transforms = []; - this.extensions = {}; - - this.useComparisonMethod = true; - } - - needsColorSpaceToLinearSRGB(texture) { - return texture.isVideoTexture === true && texture.colorSpace !== NoColorSpace; - } - - getMethod(method) { - return glslMethods[method] || method; - } - - getOutputStructName() { - return ''; - } - - buildFunctionCode(shaderNode) { - const layout = shaderNode.layout; - const flowData = this.flowShaderNode(shaderNode); - - const parameters = []; - - for (const input of layout.inputs) { - parameters.push(this.getType(input.type) + ' ' + input.name); - } - - // - - const code = `${this.getType(layout.type)} ${layout.name}( ${parameters.join(', ')} ) { - - ${flowData.vars} - -${flowData.code} - return ${flowData.result}; - -}`; - - // - - return code; - } - - setupPBO(storageBufferNode) { - const attribute = storageBufferNode.value; - - if (attribute.pbo === undefined) { - const originalArray = attribute.array; - const numElements = attribute.count * attribute.itemSize; - - const { itemSize } = attribute; - - const isInteger = attribute.array.constructor.name.toLowerCase().includes('int'); - - let format = isInteger ? RedIntegerFormat : RedFormat; - - if (itemSize === 2) { - format = isInteger ? RGIntegerFormat : RGFormat; - } else if (itemSize === 3) { - format = isInteger ? RGBIntegerFormat : RGBFormat; - } else if (itemSize === 4) { - format = isInteger ? RGBAIntegerFormat : RGBAFormat; - } - - const typeMap = { - Float32Array: FloatType, - Uint8Array: UnsignedByteType, - Uint16Array: UnsignedShortType, - Uint32Array: UnsignedIntType, - Int8Array: ByteType, - Int16Array: ShortType, - Int32Array: IntType, - Uint8ClampedArray: UnsignedByteType, - }; - - const width = Math.pow(2, Math.ceil(Math.log2(Math.sqrt(numElements / itemSize)))); - let height = Math.ceil(numElements / itemSize / width); - if (width * height * itemSize < numElements) height++; // Ensure enough space - - const newSize = width * height * itemSize; - - const newArray = new originalArray.constructor(newSize); - - newArray.set(originalArray, 0); - - attribute.array = newArray; - - const pboTexture = new DataTexture( - attribute.array, - width, - height, - format, - typeMap[attribute.array.constructor.name] || FloatType, - ); - pboTexture.needsUpdate = true; - pboTexture.isPBOTexture = true; - - const pbo = new TextureNode(pboTexture, null, null); - pbo.setPrecision('high'); - - attribute.pboNode = pbo; - attribute.pbo = pbo.value; - - this.getUniformFromNode(attribute.pboNode, 'texture', this.shaderStage, this.context.label); - } - } - - getPropertyName(node, shaderStage = this.shaderStage) { - if (node.isNodeUniform && node.node.isTextureNode !== true && node.node.isBufferNode !== true) { - return shaderStage.charAt(0) + '_' + node.name; - } - - return super.getPropertyName(node, shaderStage); - } - - generatePBO(storageArrayElementNode) { - const { node, indexNode } = storageArrayElementNode; - const attribute = node.value; - - if (this.renderer.backend.has(attribute)) { - const attributeData = this.renderer.backend.get(attribute); - attributeData.pbo = attribute.pbo; - } - - const nodeUniform = this.getUniformFromNode(attribute.pboNode, 'texture', this.shaderStage, this.context.label); - const textureName = this.getPropertyName(nodeUniform); - - this.increaseUsage(indexNode); // force cache generate to be used as index in x,y - const indexSnippet = indexNode.build(this, 'uint'); - - const elementNodeData = this.getDataFromNode(storageArrayElementNode); - - let propertyName = elementNodeData.propertyName; - - if (propertyName === undefined) { - // property element - - const nodeVar = this.getVarFromNode(storageArrayElementNode); - - propertyName = this.getPropertyName(nodeVar); - - // property size - - const bufferNodeData = this.getDataFromNode(node); - - let propertySizeName = bufferNodeData.propertySizeName; - - if (propertySizeName === undefined) { - propertySizeName = propertyName + 'Size'; - - this.getVarFromNode(node, propertySizeName, 'uint'); - - this.addLineFlowCode( - `${propertySizeName} = uint( textureSize( ${textureName}, 0 ).x )`, - storageArrayElementNode, - ); - - bufferNodeData.propertySizeName = propertySizeName; - } - - // - - const { itemSize } = attribute; - - const channel = '.' + vectorComponents.join('').slice(0, itemSize); - const uvSnippet = `ivec2(${indexSnippet} % ${propertySizeName}, ${indexSnippet} / ${propertySizeName})`; - - const snippet = this.generateTextureLoad(null, textureName, uvSnippet, null, '0'); - - // - - let prefix = 'vec4'; - - if (attribute.pbo.type === UnsignedIntType) { - prefix = 'uvec4'; - } else if (attribute.pbo.type === IntType) { - prefix = 'ivec4'; - } - - this.addLineFlowCode(`${propertyName} = ${prefix}(${snippet})${channel}`, storageArrayElementNode); - - elementNodeData.propertyName = propertyName; - } - - return propertyName; - } - - generateTextureLoad(texture, textureProperty, uvIndexSnippet, depthSnippet, levelSnippet = '0') { - if (depthSnippet) { - return `texelFetch( ${textureProperty}, ivec3( ${uvIndexSnippet}, ${depthSnippet} ), ${levelSnippet} )`; - } else { - return `texelFetch( ${textureProperty}, ${uvIndexSnippet}, ${levelSnippet} )`; - } - } - - generateTexture(texture, textureProperty, uvSnippet, depthSnippet) { - if (texture.isDepthTexture) { - return `texture( ${textureProperty}, ${uvSnippet} ).x`; - } else { - if (depthSnippet) uvSnippet = `vec3( ${uvSnippet}, ${depthSnippet} )`; - - return `texture( ${textureProperty}, ${uvSnippet} )`; - } - } - - generateTextureLevel(texture, textureProperty, uvSnippet, levelSnippet) { - return `textureLod( ${textureProperty}, ${uvSnippet}, ${levelSnippet} )`; - } - - generateTextureBias(texture, textureProperty, uvSnippet, biasSnippet) { - return `texture( ${textureProperty}, ${uvSnippet}, ${biasSnippet} )`; - } - - generateTextureGrad(texture, textureProperty, uvSnippet, gradSnippet) { - return `textureGrad( ${textureProperty}, ${uvSnippet}, ${gradSnippet[0]}, ${gradSnippet[1]} )`; - } - - generateTextureCompare( - texture, - textureProperty, - uvSnippet, - compareSnippet, - depthSnippet, - shaderStage = this.shaderStage, - ) { - if (shaderStage === 'fragment') { - return `texture( ${textureProperty}, vec3( ${uvSnippet}, ${compareSnippet} ) )`; - } else { - console.error( - `WebGPURenderer: THREE.DepthTexture.compareFunction() does not support ${shaderStage} shader.`, - ); - } - } - - getVars(shaderStage) { - const snippets = []; - - const vars = this.vars[shaderStage]; - - if (vars !== undefined) { - for (const variable of vars) { - snippets.push(`${this.getVar(variable.type, variable.name)};`); - } - } - - return snippets.join('\n\t'); - } - - getUniforms(shaderStage) { - const uniforms = this.uniforms[shaderStage]; - - const bindingSnippets = []; - const uniformGroups = {}; - - for (const uniform of uniforms) { - let snippet = null; - let group = false; - - if (uniform.type === 'texture') { - const texture = uniform.node.value; - - let typePrefix = ''; - - if (texture.isDataTexture === true) { - if (texture.type === UnsignedIntType) { - typePrefix = 'u'; - } else if (texture.type === IntType) { - typePrefix = 'i'; - } - } - - if (texture.compareFunction) { - snippet = `sampler2DShadow ${uniform.name};`; - } else if (texture.isDataArrayTexture === true || texture.isCompressedArrayTexture === true) { - snippet = `${typePrefix}sampler2DArray ${uniform.name};`; - } else { - snippet = `${typePrefix}sampler2D ${uniform.name};`; - } - } else if (uniform.type === 'cubeTexture') { - snippet = `samplerCube ${uniform.name};`; - } else if (uniform.type === 'texture3D') { - snippet = `sampler3D ${uniform.name};`; - } else if (uniform.type === 'buffer') { - const bufferNode = uniform.node; - const bufferType = this.getType(bufferNode.bufferType); - const bufferCount = bufferNode.bufferCount; - - const bufferCountSnippet = bufferCount > 0 ? bufferCount : ''; - snippet = `${bufferNode.name} {\n\t${bufferType} ${uniform.name}[${bufferCountSnippet}];\n};\n`; - } else { - const vectorType = this.getVectorType(uniform.type); - - snippet = `${vectorType} ${this.getPropertyName(uniform, shaderStage)};`; - - group = true; - } - - const precision = uniform.node.precision; - - if (precision !== null) { - snippet = precisionLib[precision] + ' ' + snippet; - } - - if (group) { - snippet = '\t' + snippet; - - const groupName = uniform.groupNode.name; - const groupSnippets = uniformGroups[groupName] || (uniformGroups[groupName] = []); - - groupSnippets.push(snippet); - } else { - snippet = 'uniform ' + snippet; - - bindingSnippets.push(snippet); - } - } - - let output = ''; - - for (const name in uniformGroups) { - const groupSnippets = uniformGroups[name]; - - output += this._getGLSLUniformStruct(shaderStage + '_' + name, groupSnippets.join('\n')) + '\n'; - } - - output += bindingSnippets.join('\n'); - - return output; - } - - getTypeFromAttribute(attribute) { - let nodeType = super.getTypeFromAttribute(attribute); - - if (/^[iu]/.test(nodeType) && attribute.gpuType !== IntType) { - let dataAttribute = attribute; - - if (attribute.isInterleavedBufferAttribute) dataAttribute = attribute.data; - - const array = dataAttribute.array; - - if ((array instanceof Uint32Array || array instanceof Int32Array) === false) { - nodeType = nodeType.slice(1); - } - } - - return nodeType; - } - - getAttributes(shaderStage) { - let snippet = ''; - - if (shaderStage === 'vertex' || shaderStage === 'compute') { - const attributes = this.getAttributesArray(); - - let location = 0; - - for (const attribute of attributes) { - snippet += `layout( location = ${location++} ) in ${attribute.type} ${attribute.name};\n`; - } - } - - return snippet; - } - - getStructMembers(struct) { - const snippets = []; - const members = struct.getMemberTypes(); - - for (let i = 0; i < members.length; i++) { - const member = members[i]; - snippets.push(`layout( location = ${i} ) out ${member} m${i};`); - } - - return snippets.join('\n'); - } - - getStructs(shaderStage) { - const snippets = []; - const structs = this.structs[shaderStage]; - - if (structs.length === 0) { - return 'layout( location = 0 ) out vec4 fragColor;\n'; - } - - for (let index = 0, length = structs.length; index < length; index++) { - const struct = structs[index]; - - let snippet = '\n'; - snippet += this.getStructMembers(struct); - snippet += '\n'; - - snippets.push(snippet); - } - - return snippets.join('\n\n'); - } - - getVaryings(shaderStage) { - let snippet = ''; - - const varyings = this.varyings; - - if (shaderStage === 'vertex' || shaderStage === 'compute') { - for (const varying of varyings) { - if (shaderStage === 'compute') varying.needsInterpolation = true; - const type = varying.type; - const flat = type.includes('int') || type.includes('uv') || type.includes('iv') ? 'flat ' : ''; - - snippet += `${flat}${varying.needsInterpolation ? 'out' : '/*out*/'} ${type} ${varying.name};\n`; - } - } else if (shaderStage === 'fragment') { - for (const varying of varyings) { - if (varying.needsInterpolation) { - const type = varying.type; - const flat = type.includes('int') || type.includes('uv') || type.includes('iv') ? 'flat ' : ''; - - snippet += `${flat}in ${type} ${varying.name};\n`; - } - } - } - - return snippet; - } - - getVertexIndex() { - return 'uint( gl_VertexID )'; - } - - getInstanceIndex() { - return 'uint( gl_InstanceID )'; - } - - getInvocationLocalIndex() { - const workgroupSize = this.object.workgroupSize; - - const size = workgroupSize.reduce((acc, curr) => acc * curr, 1); - - return `uint( gl_InstanceID ) % ${size}u`; - } - - getDrawIndex() { - const extensions = this.renderer.backend.extensions; - - if (extensions.has('WEBGL_multi_draw')) { - return 'uint( gl_DrawID )'; - } - - return null; - } - - getFrontFacing() { - return 'gl_FrontFacing'; - } - - getFragCoord() { - return 'gl_FragCoord.xy'; - } - - getFragDepth() { - return 'gl_FragDepth'; - } - - enableExtension(name, behavior, shaderStage = this.shaderStage) { - const map = this.extensions[shaderStage] || (this.extensions[shaderStage] = new Map()); - - if (map.has(name) === false) { - map.set(name, { - name, - behavior, - }); - } - } - - getExtensions(shaderStage) { - const snippets = []; - - if (shaderStage === 'vertex') { - const ext = this.renderer.backend.extensions; - const isBatchedMesh = this.object.isBatchedMesh; - - if (isBatchedMesh && ext.has('WEBGL_multi_draw')) { - this.enableExtension('GL_ANGLE_multi_draw', 'require', shaderStage); - } - } - - const extensions = this.extensions[shaderStage]; - - if (extensions !== undefined) { - for (const { name, behavior } of extensions.values()) { - snippets.push(`#extension ${name} : ${behavior}`); - } - } - - return snippets.join('\n'); - } - - isAvailable(name) { - let result = supports[name]; - - if (result === undefined) { - if (name === 'float32Filterable') { - const extensions = this.renderer.backend.extensions; - - if (extensions.has('OES_texture_float_linear')) { - extensions.get('OES_texture_float_linear'); - result = true; - } else { - result = false; - } - } - - supports[name] = result; - } - - return result; - } - - isFlipY() { - return true; - } - - registerTransform(varyingName, attributeNode) { - this.transforms.push({ varyingName, attributeNode }); - } - - getTransforms(/* shaderStage */) { - const transforms = this.transforms; - - let snippet = ''; - - for (let i = 0; i < transforms.length; i++) { - const transform = transforms[i]; - - const attributeName = this.getPropertyName(transform.attributeNode); - - snippet += `${transform.varyingName} = ${attributeName};\n\t`; - } - - return snippet; - } - - _getGLSLUniformStruct(name, vars) { - return ` -layout( std140 ) uniform ${name} { -${vars} -};`; - } - - _getGLSLVertexCode(shaderData) { - return `#version 300 es - -${this.getSignature()} - -// extensions -${shaderData.extensions} - -// precision -${defaultPrecisions} - -// uniforms -${shaderData.uniforms} - -// varyings -${shaderData.varyings} - -// attributes -${shaderData.attributes} - -// codes -${shaderData.codes} - -void main() { - - // vars - ${shaderData.vars} - - // transforms - ${shaderData.transforms} - - // flow - ${shaderData.flow} - - gl_PointSize = 1.0; - -} -`; - } - - _getGLSLFragmentCode(shaderData) { - return `#version 300 es - -${this.getSignature()} - -// precision -${defaultPrecisions} - -// uniforms -${shaderData.uniforms} - -// varyings -${shaderData.varyings} - -// codes -${shaderData.codes} - -${shaderData.structs} - -void main() { - - // vars - ${shaderData.vars} - - // flow - ${shaderData.flow} - -} -`; - } - - buildCode() { - const shadersData = this.material !== null ? { fragment: {}, vertex: {} } : { compute: {} }; - - this.sortBindingGroups(); - - for (const shaderStage in shadersData) { - let flow = '// code\n\n'; - flow += this.flowCode[shaderStage]; - - const flowNodes = this.flowNodes[shaderStage]; - const mainNode = flowNodes[flowNodes.length - 1]; - - for (const node of flowNodes) { - const flowSlotData = this.getFlowData(node /*, shaderStage*/); - const slotName = node.name; - - if (slotName) { - if (flow.length > 0) flow += '\n'; - - flow += `\t// flow -> ${slotName}\n\t`; - } - - flow += `${flowSlotData.code}\n\t`; - - if (node === mainNode && shaderStage !== 'compute') { - flow += '// result\n\t'; - - if (shaderStage === 'vertex') { - flow += 'gl_Position = '; - flow += `${flowSlotData.result};`; - } else if (shaderStage === 'fragment') { - if (!node.outputNode.isOutputStructNode) { - flow += 'fragColor = '; - flow += `${flowSlotData.result};`; - } - } - } - } - - const stageData = shadersData[shaderStage]; - - stageData.extensions = this.getExtensions(shaderStage); - stageData.uniforms = this.getUniforms(shaderStage); - stageData.attributes = this.getAttributes(shaderStage); - stageData.varyings = this.getVaryings(shaderStage); - stageData.vars = this.getVars(shaderStage); - stageData.structs = this.getStructs(shaderStage); - stageData.codes = this.getCodes(shaderStage); - stageData.transforms = this.getTransforms(shaderStage); - stageData.flow = flow; - } - - if (this.material !== null) { - this.vertexShader = this._getGLSLVertexCode(shadersData.vertex); - this.fragmentShader = this._getGLSLFragmentCode(shadersData.fragment); - } else { - this.computeShader = this._getGLSLVertexCode(shadersData.compute); - } - } - - getUniformFromNode(node, type, shaderStage, name = null) { - const uniformNode = super.getUniformFromNode(node, type, shaderStage, name); - const nodeData = this.getDataFromNode(node, shaderStage, this.globalCache); - - let uniformGPU = nodeData.uniformGPU; - - if (uniformGPU === undefined) { - const group = node.groupNode; - const groupName = group.name; - - const bindings = this.getBindGroupArray(groupName, shaderStage); - - if (type === 'texture') { - uniformGPU = new NodeSampledTexture(uniformNode.name, uniformNode.node, group); - bindings.push(uniformGPU); - } else if (type === 'cubeTexture') { - uniformGPU = new NodeSampledCubeTexture(uniformNode.name, uniformNode.node, group); - bindings.push(uniformGPU); - } else if (type === 'texture3D') { - uniformGPU = new NodeSampledTexture3D(uniformNode.name, uniformNode.node, group); - bindings.push(uniformGPU); - } else if (type === 'buffer') { - node.name = `NodeBuffer_${node.id}`; - uniformNode.name = `buffer${node.id}`; - - const buffer = new NodeUniformBuffer(node, group); - buffer.name = node.name; - - bindings.push(buffer); - - uniformGPU = buffer; - } else { - const uniformsStage = this.uniformGroups[shaderStage] || (this.uniformGroups[shaderStage] = {}); - - let uniformsGroup = uniformsStage[groupName]; - - if (uniformsGroup === undefined) { - uniformsGroup = new NodeUniformsGroup(shaderStage + '_' + groupName, group); - //uniformsGroup.setVisibility( gpuShaderStageLib[ shaderStage ] ); - - uniformsStage[groupName] = uniformsGroup; - - bindings.push(uniformsGroup); - } - - uniformGPU = this.getNodeUniform(uniformNode, type); - - uniformsGroup.addUniform(uniformGPU); - } - - nodeData.uniformGPU = uniformGPU; - } - - return uniformNode; - } -} - -export default GLSLNodeBuilder; diff --git a/src-testing/src/renderers/webgl/WebGLAttributes.d.ts b/src-testing/src/renderers/webgl/WebGLAttributes.d.ts deleted file mode 100644 index 8f4a9757b..000000000 --- a/src-testing/src/renderers/webgl/WebGLAttributes.d.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { BufferAttribute } from "../../core/BufferAttribute.js"; -import { GLBufferAttribute } from "../../core/GLBufferAttribute.js"; -import { InterleavedBufferAttribute } from "../../core/InterleavedBufferAttribute.js"; - -export class WebGLAttributes { - constructor(gl: WebGLRenderingContext | WebGL2RenderingContext); - - get(attribute: BufferAttribute | InterleavedBufferAttribute | GLBufferAttribute): - | { - buffer: WebGLBuffer; - type: number; - bytesPerElement: number; - version: number; - size: number; - } - | undefined; - - remove(attribute: BufferAttribute | InterleavedBufferAttribute | GLBufferAttribute): void; - - update(attribute: BufferAttribute | InterleavedBufferAttribute | GLBufferAttribute, bufferType: number): void; -} diff --git a/src-testing/src/renderers/webgl/WebGLBindingStates.d.ts b/src-testing/src/renderers/webgl/WebGLBindingStates.d.ts deleted file mode 100644 index 0b96de770..000000000 --- a/src-testing/src/renderers/webgl/WebGLBindingStates.d.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { BufferAttribute } from "../../core/BufferAttribute.js"; -import { BufferGeometry } from "../../core/BufferGeometry.js"; -import { Object3D } from "../../core/Object3D.js"; -import { Material } from "../../materials/Material.js"; -import { WebGLAttributes } from "./WebGLAttributes.js"; -import { WebGLProgram } from "./WebGLProgram.js"; - -export class WebGLBindingStates { - constructor(gl: WebGLRenderingContext, attributes: WebGLAttributes); - - setup( - object: Object3D, - material: Material, - program: WebGLProgram, - geometry: BufferGeometry, - index: BufferAttribute, - ): void; - reset(): void; - resetDefaultState(): void; - dispose(): void; - releaseStatesOfGeometry(): void; - releaseStatesOfProgram(): void; - initAttributes(): void; - enableAttribute(attribute: number): void; - disableUnusedAttributes(): void; -} diff --git a/src-testing/src/renderers/webgl/WebGLBufferRenderer.d.ts b/src-testing/src/renderers/webgl/WebGLBufferRenderer.d.ts deleted file mode 100644 index c75f74745..000000000 --- a/src-testing/src/renderers/webgl/WebGLBufferRenderer.d.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { WebGLExtensions } from "./WebGLExtensions.js"; -import { WebGLInfo } from "./WebGLInfo.js"; - -export class WebGLBufferRenderer { - constructor( - gl: WebGLRenderingContext, - extensions: WebGLExtensions, - info: WebGLInfo, - ); - - setMode: (value: any) => void; - render: (start: any, count: number) => void; - renderInstances: (start: any, count: number, primcount: number) => void; - renderMultiDraw: (starts: Int32Array, counts: Int32Array, drawCount: number) => void; - renderMultiDrawInstances: ( - starts: Int32Array, - counts: Int32Array, - drawCount: number, - primcount: Int32Array, - ) => void; -} diff --git a/src-testing/src/renderers/webgl/WebGLCapabilities.d.ts b/src-testing/src/renderers/webgl/WebGLCapabilities.d.ts deleted file mode 100644 index c36a9b0f2..000000000 --- a/src-testing/src/renderers/webgl/WebGLCapabilities.d.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { PixelFormat, TextureDataType } from "../../constants.js"; - -export interface WebGLCapabilitiesParameters { - /** - * shader precision. Can be "highp", "mediump" or "lowp". - */ - precision?: string | undefined; - - /** - * default is false. - */ - logarithmicDepthBuffer?: boolean | undefined; - - /** - * default is false. - */ - reverseDepthBuffer?: boolean | undefined; -} - -export class WebGLCapabilities { - constructor(gl: WebGLRenderingContext, extensions: any, parameters: WebGLCapabilitiesParameters); - - readonly isWebGL2: boolean; - - getMaxAnisotropy: () => number; - getMaxPrecision: (precision: string) => string; - - textureFormatReadable: (textureFormat: PixelFormat) => boolean; - textureTypeReadable: (textureType: TextureDataType) => boolean; - - precision: string; - logarithmicDepthBuffer: boolean; - reverseDepthBuffer: boolean; - - maxTextures: number; - maxVertexTextures: number; - maxTextureSize: number; - maxCubemapSize: number; - - maxAttributes: number; - maxVertexUniforms: number; - maxVaryings: number; - maxFragmentUniforms: number; - - vertexTextures: boolean; - - maxSamples: number; -} diff --git a/src-testing/src/renderers/webgl/WebGLClipping.d.ts b/src-testing/src/renderers/webgl/WebGLClipping.d.ts deleted file mode 100644 index 167a16b35..000000000 --- a/src-testing/src/renderers/webgl/WebGLClipping.d.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Camera } from "../../cameras/Camera.js"; -import { Material } from "../../materials/Material.js"; -import { Plane } from "../../math/Plane.js"; -import { WebGLProperties } from "./WebGLProperties.js"; - -export class WebGLClipping { - constructor(properties: WebGLProperties); - - uniform: { value: any; needsUpdate: boolean }; - - /** - * @default 0 - */ - numPlanes: number; - - /** - * @default 0 - */ - numIntersection: number; - - init(planes: any[], enableLocalClipping: boolean): boolean; - beginShadows(): void; - endShadows(): void; - setGlobalState(planes: Plane[], camera: Camera): void; - setState(material: Material, camera: Camera, useCache: boolean): void; -} diff --git a/src-testing/src/renderers/webgl/WebGLCubeMaps.d.ts b/src-testing/src/renderers/webgl/WebGLCubeMaps.d.ts deleted file mode 100644 index 32cda3f61..000000000 --- a/src-testing/src/renderers/webgl/WebGLCubeMaps.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { WebGLRenderer } from "../WebGLRenderer.js"; - -export class WebGLCubeMaps { - constructor(renderer: WebGLRenderer); - - get(texture: any): any; - dispose(): void; -} diff --git a/src-testing/src/renderers/webgl/WebGLCubeUVMaps.d.ts b/src-testing/src/renderers/webgl/WebGLCubeUVMaps.d.ts deleted file mode 100644 index e94246325..000000000 --- a/src-testing/src/renderers/webgl/WebGLCubeUVMaps.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Texture } from "../../textures/Texture.js"; -import { WebGLRenderer } from "../WebGLRenderer.js"; - -export class WebGLCubeUVMaps { - constructor(renderer: WebGLRenderer); - - get(texture: T): T extends Texture ? Texture : T; - dispose(): void; -} diff --git a/src-testing/src/renderers/webgl/WebGLExtensions.d.ts b/src-testing/src/renderers/webgl/WebGLExtensions.d.ts deleted file mode 100644 index 0f0c0bf4b..000000000 --- a/src-testing/src/renderers/webgl/WebGLExtensions.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -export class WebGLExtensions { - constructor(gl: WebGLRenderingContext); - - has(name: string): boolean; - init(): void; - get(name: string): any; -} diff --git a/src-testing/src/renderers/webgl/WebGLGeometries.d.ts b/src-testing/src/renderers/webgl/WebGLGeometries.d.ts deleted file mode 100644 index 422249f37..000000000 --- a/src-testing/src/renderers/webgl/WebGLGeometries.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { BufferAttribute } from "../../core/BufferAttribute.js"; -import { BufferGeometry } from "../../core/BufferGeometry.js"; -import { Object3D } from "../../core/Object3D.js"; -import { WebGLAttributes } from "./WebGLAttributes.js"; -import { WebGLInfo } from "./WebGLInfo.js"; - -export class WebGLGeometries { - constructor(gl: WebGLRenderingContext, attributes: WebGLAttributes, info: WebGLInfo); - - get(object: Object3D, geometry: BufferGeometry): BufferGeometry; - update(geometry: BufferGeometry): void; - getWireframeAttribute(geometry: BufferGeometry): BufferAttribute; -} diff --git a/src-testing/src/renderers/webgl/WebGLIndexedBufferRenderer.d.ts b/src-testing/src/renderers/webgl/WebGLIndexedBufferRenderer.d.ts deleted file mode 100644 index 8e016e847..000000000 --- a/src-testing/src/renderers/webgl/WebGLIndexedBufferRenderer.d.ts +++ /dev/null @@ -1,15 +0,0 @@ -export class WebGLIndexedBufferRenderer { - constructor(gl: WebGLRenderingContext, extensions: any, info: any); - - setMode: (value: any) => void; - setIndex: (index: any) => void; - render: (start: any, count: number) => void; - renderInstances: (start: any, count: number, primcount: number) => void; - renderMultiDraw: (starts: Int32Array, counts: Int32Array, drawCount: number) => void; - renderMultiDrawInstances: ( - starts: Int32Array, - counts: Int32Array, - drawCount: number, - primcount: Int32Array, - ) => void; -} diff --git a/src-testing/src/renderers/webgl/WebGLInfo.d.ts b/src-testing/src/renderers/webgl/WebGLInfo.d.ts deleted file mode 100644 index 952ff6f9f..000000000 --- a/src-testing/src/renderers/webgl/WebGLInfo.d.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { WebGLProgram } from "./WebGLProgram.js"; - -/** - * An object with a series of statistical information about the graphics board memory and the rendering process. - */ -export class WebGLInfo { - constructor(gl: WebGLRenderingContext); - - /** - * @default true - */ - autoReset: boolean; - - /** - * @default { geometries: 0, textures: 0 } - */ - memory: { - geometries: number; - textures: number; - }; - - /** - * @default null - */ - programs: WebGLProgram[] | null; - - /** - * @default { frame: 0, calls: 0, triangles: 0, points: 0, lines: 0 } - */ - render: { - calls: number; - frame: number; - lines: number; - points: number; - triangles: number; - }; - update(count: number, mode: number, instanceCount: number): void; - reset(): void; -} diff --git a/src-testing/src/renderers/webgl/WebGLLights.d.ts b/src-testing/src/renderers/webgl/WebGLLights.d.ts deleted file mode 100644 index 4c01422e8..000000000 --- a/src-testing/src/renderers/webgl/WebGLLights.d.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { WebGLExtensions } from "./WebGLExtensions.js"; - -export interface WebGLLightsState { - version: number; - - hash: { - directionalLength: number; - pointLength: number; - spotLength: number; - rectAreaLength: number; - hemiLength: number; - - numDirectionalShadows: number; - numPointShadows: number; - numSpotShadows: number; - numSpotMaps: number; - - numLightProbes: number; - }; - - ambient: number[]; - probe: any[]; - directional: any[]; - directionalShadow: any[]; - directionalShadowMap: any[]; - directionalShadowMatrix: any[]; - spot: any[]; - spotShadow: any[]; - spotShadowMap: any[]; - spotShadowMatrix: any[]; - rectArea: any[]; - point: any[]; - pointShadow: any[]; - pointShadowMap: any[]; - pointShadowMatrix: any[]; - hemi: any[]; - numSpotLightShadowsWithMaps: number; - numLightProbes: number; -} - -export class WebGLLights { - constructor(extensions: WebGLExtensions); - - state: WebGLLightsState; - - get(light: any): any; - setup(lights: any): void; - setupView(lights: any, camera: any): void; -} diff --git a/src-testing/src/renderers/webgl/WebGLObjects.d.ts b/src-testing/src/renderers/webgl/WebGLObjects.d.ts deleted file mode 100644 index aeb0356f7..000000000 --- a/src-testing/src/renderers/webgl/WebGLObjects.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -export class WebGLObjects { - constructor(gl: WebGLRenderingContext, geometries: any, attributes: any, info: any); - - update(object: any): any; - dispose(): void; -} diff --git a/src-testing/src/renderers/webgl/WebGLProgram.d.ts b/src-testing/src/renderers/webgl/WebGLProgram.d.ts deleted file mode 100644 index b3e5d6fd8..000000000 --- a/src-testing/src/renderers/webgl/WebGLProgram.d.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { WebGLRenderer } from "../WebGLRenderer.js"; -import { WebGLUniforms } from "./WebGLUniforms.js"; - -export class WebGLProgram { - constructor(renderer: WebGLRenderer, cacheKey: string, parameters: object); - - name: string; - id: number; - cacheKey: string; // unique identifier for this program, used for looking up compiled programs from cache. - - /** - * @default 1 - */ - usedTimes: number; - program: any; - vertexShader: WebGLShader; - fragmentShader: WebGLShader; - /** - * @deprecated Use {@link WebGLProgram#getUniforms getUniforms()} instead. - */ - uniforms: any; - /** - * @deprecated Use {@link WebGLProgram#getAttributes getAttributes()} instead. - */ - attributes: any; - - getUniforms(): WebGLUniforms; - getAttributes(): any; - destroy(): void; -} diff --git a/src-testing/src/renderers/webgl/WebGLPrograms.d.ts b/src-testing/src/renderers/webgl/WebGLPrograms.d.ts deleted file mode 100644 index 8f5999f06..000000000 --- a/src-testing/src/renderers/webgl/WebGLPrograms.d.ts +++ /dev/null @@ -1,233 +0,0 @@ -import { Combine, DepthPackingStrategies, GLSLVersion, Mapping, ShadowMapType, ToneMapping } from "../../constants.js"; -import { Object3D } from "../../core/Object3D.js"; -import { Light } from "../../lights/Light.js"; -import { Material } from "../../materials/Material.js"; -import { Scene } from "../../scenes/Scene.js"; -import { IUniform } from "../shaders/UniformsLib.js"; -import { WebGLRenderer } from "../WebGLRenderer.js"; -import { WebGLBindingStates } from "./WebGLBindingStates.js"; -import { WebGLCapabilities } from "./WebGLCapabilities.js"; -import { WebGLClipping } from "./WebGLClipping.js"; -import { WebGLCubeMaps } from "./WebGLCubeMaps.js"; -import { WebGLExtensions } from "./WebGLExtensions.js"; -import { WebGLLightsState } from "./WebGLLights.js"; -import { WebGLProgram } from "./WebGLProgram.js"; - -export interface WebGLProgramParameters { - shaderID: string; - shaderType: string; - shaderName: string; - - vertexShader: string; - fragmentShader: string; - defines: { [define: string]: string | number | boolean } | undefined; - - customVertexShaderID: string | undefined; - customFragmentShaderID: string | undefined; - - isRawShaderMaterial: boolean; - glslVersion: GLSLVersion | null | undefined; - - precision: "lowp" | "mediump" | "highp"; - - batching: boolean; - batchingColor: boolean; - instancing: boolean; - instancingColor: boolean; - instancingMorph: boolean; - - supportsVertexTextures: boolean; - outputColorSpace: string; - alphaToCoverage: boolean; - - map: boolean; - matcap: boolean; - envMap: boolean; - envMapMode: Mapping | false; - envMapCubeUVHeight: number | null; - aoMap: boolean; - lightMap: boolean; - bumpMap: boolean; - normalMap: boolean; - displacementMap: boolean; - emissiveMap: boolean; - - normalMapObjectSpace: boolean; - normalMapTangentSpace: boolean; - - metalnessMap: boolean; - roughnessMap: boolean; - - anisotropy: boolean; - anisotropyMap: boolean; - - clearcoat: boolean; - clearcoatMap: boolean; - clearcoatNormalMap: boolean; - clearcoatRoughnessMap: boolean; - - dispersion: boolean; - - iridescence: boolean; - iridescenceMap: boolean; - iridescenceThicknessMap: boolean; - - sheen: boolean; - sheenColorMap: boolean; - sheenRoughnessMap: boolean; - - specularMap: boolean; - specularColorMap: boolean; - specularIntensityMap: boolean; - - transmission: boolean; - transmissionMap: boolean; - thicknessMap: boolean; - - gradientMap: boolean; - - opaque: boolean; - - alphaMap: boolean; - alphaTest: boolean; - alphaHash: boolean; - - combine: Combine | undefined; - - // - - mapUv: string | false; - aoMapUv: string | false; - lightMapUv: string | false; - bumpMapUv: string | false; - normalMapUv: string | false; - displacementMapUv: string | false; - emissiveMapUv: string | false; - - metalnessMapUv: string | false; - roughnessMapUv: string | false; - - anisotropyMapUv: string | false; - - clearcoatMapUv: string | false; - clearcoatNormalMapUv: string | false; - clearcoatRoughnessMapUv: string | false; - - iridescenceMapUv: string | false; - iridescenceThicknessMapUv: string | false; - - sheenColorMapUv: string | false; - sheenRoughnessMapUv: string | false; - - specularMapUv: string | false; - specularColorMapUv: string | false; - specularIntensityMapUv: string | false; - - transmissionMapUv: string | false; - thicknessMapUv: string | false; - - alphaMapUv: string | false; - - // - - vertexTangents: boolean; - vertexColors: boolean; - vertexAlphas: boolean; - vertexUv1s: boolean; - vertexUv2s: boolean; - vertexUv3s: boolean; - - pointsUvs: boolean; - - fog: boolean; - useFog: boolean; - fogExp2: boolean; - - flatShading: boolean; - - sizeAttenuation: boolean; - logarithmicDepthBuffer: boolean; - reverseDepthBuffer: boolean; - - skinning: boolean; - - morphTargets: boolean; - morphNormals: boolean; - morphColors: boolean; - morphTargetsCount: number; - morphTextureStride: number; - - numDirLights: number; - numPointLights: number; - numSpotLights: number; - numSpotLightMaps: number; - numRectAreaLights: number; - numHemiLights: number; - - numDirLightShadows: number; - numPointLightShadows: number; - numSpotLightShadows: number; - numSpotLightShadowsWithMaps: number; - - numLightProbes: number; - - numClippingPlanes: number; - numClipIntersection: number; - - dithering: boolean; - - shadowMapEnabled: boolean; - shadowMapType: ShadowMapType; - - toneMapping: ToneMapping; - - decodeVideoTexture: boolean; - decodeVideoTextureEmissive: boolean; - - premultipliedAlpha: boolean; - - doubleSided: boolean; - flipSided: boolean; - - useDepthPacking: boolean; - depthPacking: DepthPackingStrategies | 0; - - index0AttributeName: string | undefined; - - extensionClipCullDistance: boolean; - extensionMultiDraw: boolean; - - rendererExtensionParallelShaderCompile: boolean; - - customProgramCacheKey: string; -} - -export interface WebGLProgramParametersWithUniforms extends WebGLProgramParameters { - uniforms: { [uniform: string]: IUniform }; -} - -export class WebGLPrograms { - constructor( - renderer: WebGLRenderer, - cubemaps: WebGLCubeMaps, - extensions: WebGLExtensions, - capabilities: WebGLCapabilities, - bindingStates: WebGLBindingStates, - clipping: WebGLClipping, - ); - - programs: WebGLProgram[]; - - getParameters( - material: Material, - lights: WebGLLightsState, - shadows: Light[], - scene: Scene, - object: Object3D, - ): WebGLProgramParameters; - - getProgramCacheKey(parameters: WebGLProgramParameters): string; - getUniforms(material: Material): { [uniform: string]: IUniform }; - acquireProgram(parameters: WebGLProgramParametersWithUniforms, cacheKey: string): WebGLProgram; - releaseProgram(program: WebGLProgram): void; -} diff --git a/src-testing/src/renderers/webgl/WebGLProperties.d.ts b/src-testing/src/renderers/webgl/WebGLProperties.d.ts deleted file mode 100644 index adcf01ec9..000000000 --- a/src-testing/src/renderers/webgl/WebGLProperties.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -export class WebGLProperties { - constructor(); - - has: (object: unknown) => boolean; - get: (object: unknown) => unknown; - remove: (object: unknown) => void; - update: (object: unknown, key: unknown, value: unknown) => unknown; - dispose: () => void; -} diff --git a/src-testing/src/renderers/webgl/WebGLRenderLists.d.ts b/src-testing/src/renderers/webgl/WebGLRenderLists.d.ts deleted file mode 100644 index 0f16a4287..000000000 --- a/src-testing/src/renderers/webgl/WebGLRenderLists.d.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { Camera } from "../../cameras/Camera.js"; -import { BufferGeometry } from "../../core/BufferGeometry.js"; -import { Object3D } from "../../core/Object3D.js"; -import { Material } from "../../materials/Material.js"; -import { Group } from "../../objects/Group.js"; -import { Scene } from "../../scenes/Scene.js"; -import { WebGLProgram } from "./WebGLProgram.js"; -import { WebGLProperties } from "./WebGLProperties.js"; - -export interface RenderItem { - id: number; - object: Object3D; - geometry: BufferGeometry | null; - material: Material; - program: WebGLProgram; - groupOrder: number; - renderOrder: number; - z: number; - group: Group | null; -} - -export class WebGLRenderList { - constructor(properties: WebGLProperties); - - /** - * @default [] - */ - opaque: RenderItem[]; - - /** - * @default [] - */ - transparent: RenderItem[]; - - /** - * @default [] - */ - transmissive: RenderItem[]; - - init(): void; - push( - object: Object3D, - geometry: BufferGeometry | null, - material: Material, - groupOrder: number, - z: number, - group: Group | null, - ): void; - unshift( - object: Object3D, - geometry: BufferGeometry | null, - material: Material, - groupOrder: number, - z: number, - group: Group | null, - ): void; - sort(opaqueSort: (a: any, b: any) => number, transparentSort: (a: any, b: any) => number): void; - finish(): void; -} - -export class WebGLRenderLists { - constructor(properties: WebGLProperties); - - dispose(): void; - get(scene: Scene, renderCallDepth: number): WebGLRenderList; -} diff --git a/src-testing/src/renderers/webgl/WebGLShader.d.ts b/src-testing/src/renderers/webgl/WebGLShader.d.ts deleted file mode 100644 index 5704fb88e..000000000 --- a/src-testing/src/renderers/webgl/WebGLShader.d.ts +++ /dev/null @@ -1 +0,0 @@ -export function WebGLShader(gl: WebGLRenderingContext, type: string, string: string): WebGLShader; diff --git a/src-testing/src/renderers/webgl/WebGLShadowMap.d.ts b/src-testing/src/renderers/webgl/WebGLShadowMap.d.ts deleted file mode 100644 index 8368fdee7..000000000 --- a/src-testing/src/renderers/webgl/WebGLShadowMap.d.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { Camera } from "../../cameras/Camera.js"; -import { ShadowMapType } from "../../constants.js"; -import { Light } from "../../lights/Light.js"; -import { Scene } from "../../scenes/Scene.js"; -import { WebGLRenderer } from "../WebGLRenderer.js"; -import { WebGLCapabilities } from "./WebGLCapabilities.js"; -import { WebGLObjects } from "./WebGLObjects.js"; - -export class WebGLShadowMap { - constructor(_renderer: WebGLRenderer, _objects: WebGLObjects, _capabilities: WebGLCapabilities); - - /** - * @default false - */ - enabled: boolean; - - /** - * @default true - */ - autoUpdate: boolean; - - /** - * @default false - */ - needsUpdate: boolean; - - /** - * @default THREE.PCFShadowMap - */ - type: ShadowMapType; - - render(shadowsArray: Light[], scene: Scene, camera: Camera): void; - - /** - * @deprecated Use {@link Material#shadowSide} instead. - */ - cullFace: any; -} diff --git a/src-testing/src/renderers/webgl/WebGLState.d.ts b/src-testing/src/renderers/webgl/WebGLState.d.ts deleted file mode 100644 index 13d4850e9..000000000 --- a/src-testing/src/renderers/webgl/WebGLState.d.ts +++ /dev/null @@ -1,116 +0,0 @@ -import { - Blending, - BlendingDstFactor, - BlendingEquation, - BlendingSrcFactor, - CullFace, - DepthModes, -} from "../../constants.js"; -import { Material } from "../../materials/Material.js"; -import { Vector4 } from "../../math/Vector4.js"; -import { WebGLRenderTarget } from "../WebGLRenderTarget.js"; - -export class WebGLColorBuffer { - constructor(); - - setMask(colorMask: boolean): void; - setLocked(lock: boolean): void; - setClear(r: number, g: number, b: number, a: number, premultipliedAlpha: boolean): void; - reset(): void; -} - -export class WebGLDepthBuffer { - constructor(); - - setTest(depthTest: boolean): void; - setMask(depthMask: boolean): void; - setFunc(depthFunc: DepthModes): void; - setLocked(lock: boolean): void; - setClear(depth: number): void; - reset(): void; -} - -export class WebGLStencilBuffer { - constructor(); - - setTest(stencilTest: boolean): void; - setMask(stencilMask: number): void; - setFunc(stencilFunc: number, stencilRef: number, stencilMask: number): void; - setOp(stencilFail: number, stencilZFail: number, stencilZPass: number): void; - setLocked(lock: boolean): void; - setClear(stencil: number): void; - reset(): void; -} - -export class WebGLState { - constructor(gl: WebGLRenderingContext); - - buffers: { - color: WebGLColorBuffer; - depth: WebGLDepthBuffer; - stencil: WebGLStencilBuffer; - }; - - enable(id: number): void; - disable(id: number): void; - bindFramebuffer(target: number, framebuffer: WebGLFramebuffer | null): void; - drawBuffers(renderTarget: WebGLRenderTarget | null, framebuffer: WebGLFramebuffer | null): void; - useProgram(program: any): boolean; - setBlending( - blending: Blending, - blendEquation?: BlendingEquation, - blendSrc?: BlendingSrcFactor, - blendDst?: BlendingDstFactor, - blendEquationAlpha?: BlendingEquation, - blendSrcAlpha?: BlendingSrcFactor, - blendDstAlpha?: BlendingDstFactor, - premultiplyAlpha?: boolean, - ): void; - setMaterial(material: Material, frontFaceCW: boolean): void; - setFlipSided(flipSided: boolean): void; - setCullFace(cullFace: CullFace): void; - setLineWidth(width: number): void; - setPolygonOffset(polygonoffset: boolean, factor?: number, units?: number): void; - setScissorTest(scissorTest: boolean): void; - activeTexture(webglSlot: number): void; - bindTexture(webglType: number, webglTexture: any): void; - unbindTexture(): void; - // Same interface as https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/compressedTexImage2D - compressedTexImage2D( - target: number, - level: number, - internalformat: number, - width: number, - height: number, - border: number, - data: ArrayBufferView, - ): void; - // Same interface as https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/texImage2D - texImage2D( - target: number, - level: number, - internalformat: number, - width: number, - height: number, - border: number, - format: number, - type: number, - pixels: ArrayBufferView | null, - ): void; - texImage2D(target: number, level: number, internalformat: number, format: number, type: number, source: any): void; - texImage3D( - target: number, - level: number, - internalformat: number, - width: number, - height: number, - depth: number, - border: number, - format: number, - type: number, - pixels: any, - ): void; - scissor(scissor: Vector4): void; - viewport(viewport: Vector4): void; - reset(): void; -} diff --git a/src-testing/src/renderers/webgl/WebGLTextures.d.ts b/src-testing/src/renderers/webgl/WebGLTextures.d.ts deleted file mode 100644 index 031866dee..000000000 --- a/src-testing/src/renderers/webgl/WebGLTextures.d.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { WebGLCapabilities } from "./WebGLCapabilities.js"; -import { WebGLExtensions } from "./WebGLExtensions.js"; -import { WebGLInfo } from "./WebGLInfo.js"; -import { WebGLProperties } from "./WebGLProperties.js"; -import { WebGLState } from "./WebGLState.js"; -import { WebGLUtils } from "./WebGLUtils.js"; - -export class WebGLTextures { - constructor( - gl: WebGLRenderingContext, - extensions: WebGLExtensions, - state: WebGLState, - properties: WebGLProperties, - capabilities: WebGLCapabilities, - utils: WebGLUtils, - info: WebGLInfo, - ); - - allocateTextureUnit(): void; - resetTextureUnits(): void; - setTexture2D(texture: any, slot: number): void; - setTexture2DArray(texture: any, slot: number): void; - setTexture3D(texture: any, slot: number): void; - setTextureCube(texture: any, slot: number): void; - setupRenderTarget(renderTarget: any): void; - updateRenderTargetMipmap(renderTarget: any): void; - updateMultisampleRenderTarget(renderTarget: any): void; - safeSetTexture2D(texture: any, slot: number): void; - safeSetTextureCube(texture: any, slot: number): void; -} diff --git a/src-testing/src/renderers/webgl/WebGLUniforms.d.ts b/src-testing/src/renderers/webgl/WebGLUniforms.d.ts deleted file mode 100644 index 925b5e4bf..000000000 --- a/src-testing/src/renderers/webgl/WebGLUniforms.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { WebGLProgram } from "./WebGLProgram.js"; -import { WebGLTextures } from "./WebGLTextures.js"; - -export class WebGLUniforms { - constructor(gl: WebGLRenderingContext, program: WebGLProgram); - - setValue(gl: WebGLRenderingContext, name: string, value: any, textures: WebGLTextures): void; - setOptional(gl: WebGLRenderingContext, object: any, name: string): void; - - static upload(gl: WebGLRenderingContext, seq: any, values: any[], textures: WebGLTextures): void; - static seqWithValue(seq: any, values: any[]): any[]; -} diff --git a/src-testing/src/renderers/webgl/WebGLUniformsGroups.d.ts b/src-testing/src/renderers/webgl/WebGLUniformsGroups.d.ts deleted file mode 100644 index a5e052c1f..000000000 --- a/src-testing/src/renderers/webgl/WebGLUniformsGroups.d.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { UniformsGroup } from "../../core/UniformsGroup.js"; - -import { WebGLCapabilities } from "./WebGLCapabilities.js"; -import { WebGLInfo } from "./WebGLInfo.js"; -import { WebGLProgram } from "./WebGLProgram.js"; -import { WebGLState } from "./WebGLState.js"; - -export function WebGLUniformsGroups( - gl: WebGLRenderingContext, - info: WebGLInfo, - capabilities: WebGLCapabilities, - state: WebGLState, -): { - dispose: () => void; - update: (uniformsGroup: UniformsGroup, program: WebGLProgram) => void; - bind: (uniformsGroup: UniformsGroup, program: WebGLProgram) => void; -}; diff --git a/src-testing/src/renderers/webgl/WebGLUtils.d.ts b/src-testing/src/renderers/webgl/WebGLUtils.d.ts deleted file mode 100644 index 53011bfe6..000000000 --- a/src-testing/src/renderers/webgl/WebGLUtils.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { CompressedPixelFormat, PixelFormat, TextureDataType } from "../../constants.js"; -import { WebGLExtensions } from "./WebGLExtensions.js"; - -export class WebGLUtils { - constructor( - gl: WebGLRenderingContext | WebGL2RenderingContext, - extensions: WebGLExtensions, - ); - - convert(p: PixelFormat | CompressedPixelFormat | TextureDataType, colorSpace?: string): number | null; -} diff --git a/src-testing/src/renderers/webgpu/WebGPUBackend.ts b/src-testing/src/renderers/webgpu/WebGPUBackend.ts deleted file mode 100644 index 930197a02..000000000 --- a/src-testing/src/renderers/webgpu/WebGPUBackend.ts +++ /dev/null @@ -1,1297 +0,0 @@ -/*// debugger tools -import 'https://greggman.github.io/webgpu-avoid-redundant-state-setting/webgpu-check-redundant-state-setting.js'; -//*/ - -import { - GPUFeatureName, - GPULoadOp, - GPUStoreOp, - GPUIndexFormat, - GPUTextureViewDimension, -} from './utils/WebGPUConstants.js'; - -import WGSLNodeBuilder from './nodes/WGSLNodeBuilder.js'; -import Backend from '../common/Backend.js'; - -import WebGPUUtils from './utils/WebGPUUtils.js'; -import WebGPUAttributeUtils from './utils/WebGPUAttributeUtils.js'; -import WebGPUBindingUtils from './utils/WebGPUBindingUtils.js'; -import WebGPUPipelineUtils from './utils/WebGPUPipelineUtils.js'; -import WebGPUTextureUtils from './utils/WebGPUTextureUtils.js'; - -import { WebGPUCoordinateSystem } from '../../constants.js'; - -// - -class WebGPUBackend extends Backend { - constructor(parameters = {}) { - super(parameters); - - this.isWebGPUBackend = true; - - // some parameters require default values other than "undefined" - this.parameters.alpha = parameters.alpha === undefined ? true : parameters.alpha; - - this.parameters.requiredLimits = parameters.requiredLimits === undefined ? {} : parameters.requiredLimits; - - this.trackTimestamp = parameters.trackTimestamp === true; - - this.device = null; - this.context = null; - this.colorBuffer = null; - this.defaultRenderPassdescriptor = null; - - this.utils = new WebGPUUtils(this); - this.attributeUtils = new WebGPUAttributeUtils(this); - this.bindingUtils = new WebGPUBindingUtils(this); - this.pipelineUtils = new WebGPUPipelineUtils(this); - this.textureUtils = new WebGPUTextureUtils(this); - this.occludedResolveCache = new Map(); - } - - async init(renderer) { - await super.init(renderer); - - // - - const parameters = this.parameters; - - // create the device if it is not passed with parameters - - let device; - - if (parameters.device === undefined) { - const adapterOptions = { - powerPreference: parameters.powerPreference, - }; - - const adapter = await navigator.gpu.requestAdapter(adapterOptions); - - if (adapter === null) { - throw new Error('WebGPUBackend: Unable to create WebGPU adapter.'); - } - - // feature support - - const features = Object.values(GPUFeatureName); - - const supportedFeatures = []; - - for (const name of features) { - if (adapter.features.has(name)) { - supportedFeatures.push(name); - } - } - - const deviceDescriptor = { - requiredFeatures: supportedFeatures, - requiredLimits: parameters.requiredLimits, - }; - - device = await adapter.requestDevice(deviceDescriptor); - } else { - device = parameters.device; - } - - const context = - parameters.context !== undefined ? parameters.context : renderer.domElement.getContext('webgpu'); - - this.device = device; - this.context = context; - - const alphaMode = parameters.alpha ? 'premultiplied' : 'opaque'; - - this.trackTimestamp = this.trackTimestamp && this.hasFeature(GPUFeatureName.TimestampQuery); - - this.context.configure({ - device: this.device, - format: this.utils.getPreferredCanvasFormat(), - usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.COPY_SRC, - alphaMode: alphaMode, - }); - - this.updateSize(); - } - - get coordinateSystem() { - return WebGPUCoordinateSystem; - } - - async getArrayBufferAsync(attribute) { - return await this.attributeUtils.getArrayBufferAsync(attribute); - } - - getContext() { - return this.context; - } - - _getDefaultRenderPassDescriptor() { - let descriptor = this.defaultRenderPassdescriptor; - - if (descriptor === null) { - const renderer = this.renderer; - - descriptor = { - colorAttachments: [ - { - view: null, - }, - ], - }; - - if (this.renderer.depth === true || this.renderer.stencil === true) { - descriptor.depthStencilAttachment = { - view: this.textureUtils.getDepthBuffer(renderer.depth, renderer.stencil).createView(), - }; - } - - const colorAttachment = descriptor.colorAttachments[0]; - - if (this.renderer.samples > 0) { - colorAttachment.view = this.colorBuffer.createView(); - } else { - colorAttachment.resolveTarget = undefined; - } - - this.defaultRenderPassdescriptor = descriptor; - } - - const colorAttachment = descriptor.colorAttachments[0]; - - if (this.renderer.samples > 0) { - colorAttachment.resolveTarget = this.context.getCurrentTexture().createView(); - } else { - colorAttachment.view = this.context.getCurrentTexture().createView(); - } - - return descriptor; - } - - _getRenderPassDescriptor(renderContext) { - const renderTarget = renderContext.renderTarget; - const renderTargetData = this.get(renderTarget); - - let descriptors = renderTargetData.descriptors; - - if ( - descriptors === undefined || - renderTargetData.width !== renderTarget.width || - renderTargetData.height !== renderTarget.height || - renderTargetData.activeMipmapLevel !== renderTarget.activeMipmapLevel || - renderTargetData.samples !== renderTarget.samples - ) { - descriptors = {}; - - renderTargetData.descriptors = descriptors; - - // dispose - - const onDispose = () => { - renderTarget.removeEventListener('dispose', onDispose); - - this.delete(renderTarget); - }; - - renderTarget.addEventListener('dispose', onDispose); - } - - const cacheKey = renderContext.getCacheKey(); - - let descriptor = descriptors[cacheKey]; - - if (descriptor === undefined) { - const textures = renderContext.textures; - const colorAttachments = []; - - for (let i = 0; i < textures.length; i++) { - const textureData = this.get(textures[i]); - - const textureView = textureData.texture.createView({ - baseMipLevel: renderContext.activeMipmapLevel, - mipLevelCount: 1, - baseArrayLayer: renderContext.activeCubeFace, - dimension: GPUTextureViewDimension.TwoD, - }); - - let view, resolveTarget; - - if (textureData.msaaTexture !== undefined) { - view = textureData.msaaTexture.createView(); - resolveTarget = textureView; - } else { - view = textureView; - resolveTarget = undefined; - } - - colorAttachments.push({ - view, - resolveTarget, - loadOp: GPULoadOp.Load, - storeOp: GPUStoreOp.Store, - }); - } - - descriptor = { - colorAttachments, - }; - - if (renderContext.depth) { - const depthTextureData = this.get(renderContext.depthTexture); - - const depthStencilAttachment = { - view: depthTextureData.texture.createView(), - }; - descriptor.depthStencilAttachment = depthStencilAttachment; - } - - descriptors[cacheKey] = descriptor; - - renderTargetData.width = renderTarget.width; - renderTargetData.height = renderTarget.height; - renderTargetData.samples = renderTarget.samples; - renderTargetData.activeMipmapLevel = renderTarget.activeMipmapLevel; - } - - return descriptor; - } - - beginRender(renderContext) { - const renderContextData = this.get(renderContext); - - const device = this.device; - const occlusionQueryCount = renderContext.occlusionQueryCount; - - let occlusionQuerySet; - - if (occlusionQueryCount > 0) { - if (renderContextData.currentOcclusionQuerySet) renderContextData.currentOcclusionQuerySet.destroy(); - if (renderContextData.currentOcclusionQueryBuffer) renderContextData.currentOcclusionQueryBuffer.destroy(); - - // Get a reference to the array of objects with queries. The renderContextData property - // can be changed by another render pass before the buffer.mapAsyc() completes. - renderContextData.currentOcclusionQuerySet = renderContextData.occlusionQuerySet; - renderContextData.currentOcclusionQueryBuffer = renderContextData.occlusionQueryBuffer; - renderContextData.currentOcclusionQueryObjects = renderContextData.occlusionQueryObjects; - - // - - occlusionQuerySet = device.createQuerySet({ type: 'occlusion', count: occlusionQueryCount }); - - renderContextData.occlusionQuerySet = occlusionQuerySet; - renderContextData.occlusionQueryIndex = 0; - renderContextData.occlusionQueryObjects = new Array(occlusionQueryCount); - - renderContextData.lastOcclusionObject = null; - } - - let descriptor; - - if (renderContext.textures === null) { - descriptor = this._getDefaultRenderPassDescriptor(); - } else { - descriptor = this._getRenderPassDescriptor(renderContext); - } - - this.initTimestampQuery(renderContext, descriptor); - - descriptor.occlusionQuerySet = occlusionQuerySet; - - const depthStencilAttachment = descriptor.depthStencilAttachment; - - if (renderContext.textures !== null) { - const colorAttachments = descriptor.colorAttachments; - - for (let i = 0; i < colorAttachments.length; i++) { - const colorAttachment = colorAttachments[i]; - - if (renderContext.clearColor) { - colorAttachment.clearValue = i === 0 ? renderContext.clearColorValue : { r: 0, g: 0, b: 0, a: 1 }; - colorAttachment.loadOp = GPULoadOp.Clear; - colorAttachment.storeOp = GPUStoreOp.Store; - } else { - colorAttachment.loadOp = GPULoadOp.Load; - colorAttachment.storeOp = GPUStoreOp.Store; - } - } - } else { - const colorAttachment = descriptor.colorAttachments[0]; - - if (renderContext.clearColor) { - colorAttachment.clearValue = renderContext.clearColorValue; - colorAttachment.loadOp = GPULoadOp.Clear; - colorAttachment.storeOp = GPUStoreOp.Store; - } else { - colorAttachment.loadOp = GPULoadOp.Load; - colorAttachment.storeOp = GPUStoreOp.Store; - } - } - - // - - if (renderContext.depth) { - if (renderContext.clearDepth) { - depthStencilAttachment.depthClearValue = renderContext.clearDepthValue; - depthStencilAttachment.depthLoadOp = GPULoadOp.Clear; - depthStencilAttachment.depthStoreOp = GPUStoreOp.Store; - } else { - depthStencilAttachment.depthLoadOp = GPULoadOp.Load; - depthStencilAttachment.depthStoreOp = GPUStoreOp.Store; - } - } - - if (renderContext.stencil) { - if (renderContext.clearStencil) { - depthStencilAttachment.stencilClearValue = renderContext.clearStencilValue; - depthStencilAttachment.stencilLoadOp = GPULoadOp.Clear; - depthStencilAttachment.stencilStoreOp = GPUStoreOp.Store; - } else { - depthStencilAttachment.stencilLoadOp = GPULoadOp.Load; - depthStencilAttachment.stencilStoreOp = GPUStoreOp.Store; - } - } - - // - - const encoder = device.createCommandEncoder({ label: 'renderContext_' + renderContext.id }); - const currentPass = encoder.beginRenderPass(descriptor); - - // - - renderContextData.descriptor = descriptor; - renderContextData.encoder = encoder; - renderContextData.currentPass = currentPass; - renderContextData.currentSets = { attributes: {}, bindingGroups: [], pipeline: null, index: null }; - renderContextData.renderBundles = []; - - // - - if (renderContext.viewport) { - this.updateViewport(renderContext); - } - - if (renderContext.scissor) { - const { x, y, width, height } = renderContext.scissorValue; - - currentPass.setScissorRect(x, y, width, height); - } - } - - finishRender(renderContext) { - const renderContextData = this.get(renderContext); - const occlusionQueryCount = renderContext.occlusionQueryCount; - - if (renderContextData.renderBundles.length > 0) { - renderContextData.currentPass.executeBundles(renderContextData.renderBundles); - } - - if (occlusionQueryCount > renderContextData.occlusionQueryIndex) { - renderContextData.currentPass.endOcclusionQuery(); - } - - renderContextData.currentPass.end(); - - if (occlusionQueryCount > 0) { - const bufferSize = occlusionQueryCount * 8; // 8 byte entries for query results - - // - - let queryResolveBuffer = this.occludedResolveCache.get(bufferSize); - - if (queryResolveBuffer === undefined) { - queryResolveBuffer = this.device.createBuffer({ - size: bufferSize, - usage: GPUBufferUsage.QUERY_RESOLVE | GPUBufferUsage.COPY_SRC, - }); - - this.occludedResolveCache.set(bufferSize, queryResolveBuffer); - } - - // - - const readBuffer = this.device.createBuffer({ - size: bufferSize, - usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ, - }); - - // two buffers required here - WebGPU doesn't allow usage of QUERY_RESOLVE & MAP_READ to be combined - renderContextData.encoder.resolveQuerySet( - renderContextData.occlusionQuerySet, - 0, - occlusionQueryCount, - queryResolveBuffer, - 0, - ); - renderContextData.encoder.copyBufferToBuffer(queryResolveBuffer, 0, readBuffer, 0, bufferSize); - - renderContextData.occlusionQueryBuffer = readBuffer; - - // - - this.resolveOccludedAsync(renderContext); - } - - this.prepareTimestampBuffer(renderContext, renderContextData.encoder); - - this.device.queue.submit([renderContextData.encoder.finish()]); - - // - - if (renderContext.textures !== null) { - const textures = renderContext.textures; - - for (let i = 0; i < textures.length; i++) { - const texture = textures[i]; - - if (texture.generateMipmaps === true) { - this.textureUtils.generateMipmaps(texture); - } - } - } - } - - isOccluded(renderContext, object) { - const renderContextData = this.get(renderContext); - - return renderContextData.occluded && renderContextData.occluded.has(object); - } - - async resolveOccludedAsync(renderContext) { - const renderContextData = this.get(renderContext); - - // handle occlusion query results - - const { currentOcclusionQueryBuffer, currentOcclusionQueryObjects } = renderContextData; - - if (currentOcclusionQueryBuffer && currentOcclusionQueryObjects) { - const occluded = new WeakSet(); - - renderContextData.currentOcclusionQueryObjects = null; - renderContextData.currentOcclusionQueryBuffer = null; - - await currentOcclusionQueryBuffer.mapAsync(GPUMapMode.READ); - - const buffer = currentOcclusionQueryBuffer.getMappedRange(); - const results = new BigUint64Array(buffer); - - for (let i = 0; i < currentOcclusionQueryObjects.length; i++) { - if (results[i] !== BigInt(0)) { - occluded.add(currentOcclusionQueryObjects[i]); - } - } - - currentOcclusionQueryBuffer.destroy(); - - renderContextData.occluded = occluded; - } - } - - updateViewport(renderContext) { - const { currentPass } = this.get(renderContext); - const { x, y, width, height, minDepth, maxDepth } = renderContext.viewportValue; - - currentPass.setViewport(x, y, width, height, minDepth, maxDepth); - } - - clear(color, depth, stencil, renderTargetData = null) { - const device = this.device; - const renderer = this.renderer; - - let colorAttachments = []; - - let depthStencilAttachment; - let clearValue; - - let supportsDepth; - let supportsStencil; - - if (color) { - const clearColor = this.getClearColor(); - - if (this.renderer.alpha === true) { - // premultiply alpha - - const a = clearColor.a; - - clearValue = { r: clearColor.r * a, g: clearColor.g * a, b: clearColor.b * a, a: a }; - } else { - clearValue = { r: clearColor.r, g: clearColor.g, b: clearColor.b, a: clearColor.a }; - } - } - - if (renderTargetData === null) { - supportsDepth = renderer.depth; - supportsStencil = renderer.stencil; - - const descriptor = this._getDefaultRenderPassDescriptor(); - - if (color) { - colorAttachments = descriptor.colorAttachments; - - const colorAttachment = colorAttachments[0]; - - colorAttachment.clearValue = clearValue; - colorAttachment.loadOp = GPULoadOp.Clear; - colorAttachment.storeOp = GPUStoreOp.Store; - } - - if (supportsDepth || supportsStencil) { - depthStencilAttachment = descriptor.depthStencilAttachment; - } - } else { - supportsDepth = renderTargetData.depth; - supportsStencil = renderTargetData.stencil; - - if (color) { - for (const texture of renderTargetData.textures) { - const textureData = this.get(texture); - const textureView = textureData.texture.createView(); - - let view, resolveTarget; - - if (textureData.msaaTexture !== undefined) { - view = textureData.msaaTexture.createView(); - resolveTarget = textureView; - } else { - view = textureView; - resolveTarget = undefined; - } - - colorAttachments.push({ - view, - resolveTarget, - clearValue, - loadOp: GPULoadOp.Clear, - storeOp: GPUStoreOp.Store, - }); - } - } - - if (supportsDepth || supportsStencil) { - const depthTextureData = this.get(renderTargetData.depthTexture); - - depthStencilAttachment = { - view: depthTextureData.texture.createView(), - }; - } - } - - // - - if (supportsDepth) { - if (depth) { - depthStencilAttachment.depthLoadOp = GPULoadOp.Clear; - depthStencilAttachment.depthClearValue = renderer.getClearDepth(); - depthStencilAttachment.depthStoreOp = GPUStoreOp.Store; - } else { - depthStencilAttachment.depthLoadOp = GPULoadOp.Load; - depthStencilAttachment.depthStoreOp = GPUStoreOp.Store; - } - } - - // - - if (supportsStencil) { - if (stencil) { - depthStencilAttachment.stencilLoadOp = GPULoadOp.Clear; - depthStencilAttachment.stencilClearValue = renderer.getClearStencil(); - depthStencilAttachment.stencilStoreOp = GPUStoreOp.Store; - } else { - depthStencilAttachment.stencilLoadOp = GPULoadOp.Load; - depthStencilAttachment.stencilStoreOp = GPUStoreOp.Store; - } - } - - // - - const encoder = device.createCommandEncoder({}); - const currentPass = encoder.beginRenderPass({ - colorAttachments, - depthStencilAttachment, - }); - - currentPass.end(); - - device.queue.submit([encoder.finish()]); - } - - // compute - - beginCompute(computeGroup) { - const groupGPU = this.get(computeGroup); - - const descriptor = {}; - - this.initTimestampQuery(computeGroup, descriptor); - - groupGPU.cmdEncoderGPU = this.device.createCommandEncoder(); - - groupGPU.passEncoderGPU = groupGPU.cmdEncoderGPU.beginComputePass(descriptor); - } - - compute(computeGroup, computeNode, bindings, pipeline) { - const { passEncoderGPU } = this.get(computeGroup); - - // pipeline - - const pipelineGPU = this.get(pipeline).pipeline; - passEncoderGPU.setPipeline(pipelineGPU); - - // bind groups - - for (let i = 0, l = bindings.length; i < l; i++) { - const bindGroup = bindings[i]; - const bindingsData = this.get(bindGroup); - - passEncoderGPU.setBindGroup(i, bindingsData.group); - } - - const maxComputeWorkgroupsPerDimension = this.device.limits.maxComputeWorkgroupsPerDimension; - - const computeNodeData = this.get(computeNode); - - if (computeNodeData.dispatchSize === undefined) computeNodeData.dispatchSize = { x: 0, y: 1, z: 1 }; - - const { dispatchSize } = computeNodeData; - - if (computeNode.dispatchCount > maxComputeWorkgroupsPerDimension) { - dispatchSize.x = Math.min(computeNode.dispatchCount, maxComputeWorkgroupsPerDimension); - dispatchSize.y = Math.ceil(computeNode.dispatchCount / maxComputeWorkgroupsPerDimension); - } else { - dispatchSize.x = computeNode.dispatchCount; - } - - passEncoderGPU.dispatchWorkgroups(dispatchSize.x, dispatchSize.y, dispatchSize.z); - } - - finishCompute(computeGroup) { - const groupData = this.get(computeGroup); - - groupData.passEncoderGPU.end(); - - this.prepareTimestampBuffer(computeGroup, groupData.cmdEncoderGPU); - - this.device.queue.submit([groupData.cmdEncoderGPU.finish()]); - } - - async waitForGPU() { - await this.device.queue.onSubmittedWorkDone(); - } - - // render object - - draw(renderObject, info) { - const { object, context, pipeline } = renderObject; - const bindings = renderObject.getBindings(); - const renderContextData = this.get(context); - const pipelineGPU = this.get(pipeline).pipeline; - const currentSets = renderContextData.currentSets; - const passEncoderGPU = renderContextData.currentPass; - - const drawParams = renderObject.getDrawParameters(); - - if (drawParams === null) return; - - // pipeline - - if (currentSets.pipeline !== pipelineGPU) { - passEncoderGPU.setPipeline(pipelineGPU); - - currentSets.pipeline = pipelineGPU; - } - - // bind groups - - const currentBindingGroups = currentSets.bindingGroups; - - for (let i = 0, l = bindings.length; i < l; i++) { - const bindGroup = bindings[i]; - const bindingsData = this.get(bindGroup); - - if (currentBindingGroups[bindGroup.index] !== bindGroup.id) { - passEncoderGPU.setBindGroup(bindGroup.index, bindingsData.group); - currentBindingGroups[bindGroup.index] = bindGroup.id; - } - } - - // attributes - - const index = renderObject.getIndex(); - - const hasIndex = index !== null; - - // index - - if (hasIndex === true) { - if (currentSets.index !== index) { - const buffer = this.get(index).buffer; - const indexFormat = index.array instanceof Uint16Array ? GPUIndexFormat.Uint16 : GPUIndexFormat.Uint32; - - passEncoderGPU.setIndexBuffer(buffer, indexFormat); - - currentSets.index = index; - } - } - - // vertex buffers - - const vertexBuffers = renderObject.getVertexBuffers(); - - for (let i = 0, l = vertexBuffers.length; i < l; i++) { - const vertexBuffer = vertexBuffers[i]; - - if (currentSets.attributes[i] !== vertexBuffer) { - const buffer = this.get(vertexBuffer).buffer; - passEncoderGPU.setVertexBuffer(i, buffer); - - currentSets.attributes[i] = vertexBuffer; - } - } - - // occlusion queries - handle multiple consecutive draw calls for an object - - if (renderContextData.occlusionQuerySet !== undefined) { - const lastObject = renderContextData.lastOcclusionObject; - - if (lastObject !== object) { - if (lastObject !== null && lastObject.occlusionTest === true) { - passEncoderGPU.endOcclusionQuery(); - renderContextData.occlusionQueryIndex++; - } - - if (object.occlusionTest === true) { - passEncoderGPU.beginOcclusionQuery(renderContextData.occlusionQueryIndex); - renderContextData.occlusionQueryObjects[renderContextData.occlusionQueryIndex] = object; - } - - renderContextData.lastOcclusionObject = object; - } - } - - // draw - - if (object.isBatchedMesh === true) { - const starts = object._multiDrawStarts; - const counts = object._multiDrawCounts; - const drawCount = object._multiDrawCount; - const drawInstances = object._multiDrawInstances; - - const bytesPerElement = hasIndex ? index.array.BYTES_PER_ELEMENT : 1; - - for (let i = 0; i < drawCount; i++) { - const count = drawInstances ? drawInstances[i] : 1; - const firstInstance = count > 1 ? 0 : i; - - passEncoderGPU.drawIndexed(counts[i], count, starts[i] / bytesPerElement, 0, firstInstance); - } - } else if (hasIndex === true) { - const { vertexCount: indexCount, instanceCount, firstVertex: firstIndex } = drawParams; - - const indirect = renderObject.getIndirect(); - - if (indirect !== null) { - const buffer = this.get(indirect).buffer; - - passEncoderGPU.drawIndexedIndirect(buffer, 0); - } else { - passEncoderGPU.drawIndexed(indexCount, instanceCount, firstIndex, 0, 0); - } - - info.update(object, indexCount, instanceCount); - } else { - const { vertexCount, instanceCount, firstVertex } = drawParams; - - const indirect = renderObject.getIndirect(); - - if (indirect !== null) { - const buffer = this.get(indirect).buffer; - - passEncoderGPU.drawIndirect(buffer, 0); - } else { - passEncoderGPU.draw(vertexCount, instanceCount, firstVertex, 0); - } - - info.update(object, vertexCount, instanceCount); - } - } - - // cache key - - needsRenderUpdate(renderObject) { - const data = this.get(renderObject); - - const { object, material } = renderObject; - - const utils = this.utils; - - const sampleCount = utils.getSampleCountRenderContext(renderObject.context); - const colorSpace = utils.getCurrentColorSpace(renderObject.context); - const colorFormat = utils.getCurrentColorFormat(renderObject.context); - const depthStencilFormat = utils.getCurrentDepthStencilFormat(renderObject.context); - const primitiveTopology = utils.getPrimitiveTopology(object, material); - - let needsUpdate = false; - - if ( - data.material !== material || - data.materialVersion !== material.version || - data.transparent !== material.transparent || - data.blending !== material.blending || - data.premultipliedAlpha !== material.premultipliedAlpha || - data.blendSrc !== material.blendSrc || - data.blendDst !== material.blendDst || - data.blendEquation !== material.blendEquation || - data.blendSrcAlpha !== material.blendSrcAlpha || - data.blendDstAlpha !== material.blendDstAlpha || - data.blendEquationAlpha !== material.blendEquationAlpha || - data.colorWrite !== material.colorWrite || - data.depthWrite !== material.depthWrite || - data.depthTest !== material.depthTest || - data.depthFunc !== material.depthFunc || - data.stencilWrite !== material.stencilWrite || - data.stencilFunc !== material.stencilFunc || - data.stencilFail !== material.stencilFail || - data.stencilZFail !== material.stencilZFail || - data.stencilZPass !== material.stencilZPass || - data.stencilFuncMask !== material.stencilFuncMask || - data.stencilWriteMask !== material.stencilWriteMask || - data.side !== material.side || - data.alphaToCoverage !== material.alphaToCoverage || - data.sampleCount !== sampleCount || - data.colorSpace !== colorSpace || - data.colorFormat !== colorFormat || - data.depthStencilFormat !== depthStencilFormat || - data.primitiveTopology !== primitiveTopology || - data.clippingContextCacheKey !== renderObject.clippingContext.cacheKey - ) { - data.material = material; - data.materialVersion = material.version; - data.transparent = material.transparent; - data.blending = material.blending; - data.premultipliedAlpha = material.premultipliedAlpha; - data.blendSrc = material.blendSrc; - data.blendDst = material.blendDst; - data.blendEquation = material.blendEquation; - data.blendSrcAlpha = material.blendSrcAlpha; - data.blendDstAlpha = material.blendDstAlpha; - data.blendEquationAlpha = material.blendEquationAlpha; - data.colorWrite = material.colorWrite; - data.depthWrite = material.depthWrite; - data.depthTest = material.depthTest; - data.depthFunc = material.depthFunc; - data.stencilWrite = material.stencilWrite; - data.stencilFunc = material.stencilFunc; - data.stencilFail = material.stencilFail; - data.stencilZFail = material.stencilZFail; - data.stencilZPass = material.stencilZPass; - data.stencilFuncMask = material.stencilFuncMask; - data.stencilWriteMask = material.stencilWriteMask; - data.side = material.side; - data.alphaToCoverage = material.alphaToCoverage; - data.sampleCount = sampleCount; - data.colorSpace = colorSpace; - data.colorFormat = colorFormat; - data.depthStencilFormat = depthStencilFormat; - data.primitiveTopology = primitiveTopology; - data.clippingContextCacheKey = renderObject.clippingContext.cacheKey; - - needsUpdate = true; - } - - return needsUpdate; - } - - getRenderCacheKey(renderObject) { - const { object, material } = renderObject; - - const utils = this.utils; - const renderContext = renderObject.context; - - return [ - material.transparent, - material.blending, - material.premultipliedAlpha, - material.blendSrc, - material.blendDst, - material.blendEquation, - material.blendSrcAlpha, - material.blendDstAlpha, - material.blendEquationAlpha, - material.colorWrite, - material.depthWrite, - material.depthTest, - material.depthFunc, - material.stencilWrite, - material.stencilFunc, - material.stencilFail, - material.stencilZFail, - material.stencilZPass, - material.stencilFuncMask, - material.stencilWriteMask, - material.side, - utils.getSampleCountRenderContext(renderContext), - utils.getCurrentColorSpace(renderContext), - utils.getCurrentColorFormat(renderContext), - utils.getCurrentDepthStencilFormat(renderContext), - utils.getPrimitiveTopology(object, material), - renderObject.getGeometryCacheKey(), - renderObject.clippingContext.cacheKey, - ].join(); - } - - // textures - - createSampler(texture) { - this.textureUtils.createSampler(texture); - } - - destroySampler(texture) { - this.textureUtils.destroySampler(texture); - } - - createDefaultTexture(texture) { - this.textureUtils.createDefaultTexture(texture); - } - - createTexture(texture, options) { - this.textureUtils.createTexture(texture, options); - } - - updateTexture(texture, options) { - this.textureUtils.updateTexture(texture, options); - } - - generateMipmaps(texture) { - this.textureUtils.generateMipmaps(texture); - } - - destroyTexture(texture) { - this.textureUtils.destroyTexture(texture); - } - - copyTextureToBuffer(texture, x, y, width, height, faceIndex) { - return this.textureUtils.copyTextureToBuffer(texture, x, y, width, height, faceIndex); - } - - initTimestampQuery(renderContext, descriptor) { - if (!this.trackTimestamp) return; - - const renderContextData = this.get(renderContext); - - if (!renderContextData.timeStampQuerySet) { - // Create a GPUQuerySet which holds 2 timestamp query results: one for the - // beginning and one for the end of compute pass execution. - const timeStampQuerySet = this.device.createQuerySet({ type: 'timestamp', count: 2 }); - - const timestampWrites = { - querySet: timeStampQuerySet, - beginningOfPassWriteIndex: 0, // Write timestamp in index 0 when pass begins. - endOfPassWriteIndex: 1, // Write timestamp in index 1 when pass ends. - }; - - Object.assign(descriptor, { - timestampWrites, - }); - - renderContextData.timeStampQuerySet = timeStampQuerySet; - } - } - - // timestamp utils - - prepareTimestampBuffer(renderContext, encoder) { - if (!this.trackTimestamp) return; - - const renderContextData = this.get(renderContext); - - const size = 2 * BigInt64Array.BYTES_PER_ELEMENT; - - if (renderContextData.currentTimestampQueryBuffers === undefined) { - renderContextData.currentTimestampQueryBuffers = { - resolveBuffer: this.device.createBuffer({ - label: 'timestamp resolve buffer', - size: size, - usage: GPUBufferUsage.QUERY_RESOLVE | GPUBufferUsage.COPY_SRC, - }), - resultBuffer: this.device.createBuffer({ - label: 'timestamp result buffer', - size: size, - usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ, - }), - isMappingPending: false, - }; - } - - const { resolveBuffer, resultBuffer, isMappingPending } = renderContextData.currentTimestampQueryBuffers; - - if (isMappingPending === true) return; - - encoder.resolveQuerySet(renderContextData.timeStampQuerySet, 0, 2, resolveBuffer, 0); - encoder.copyBufferToBuffer(resolveBuffer, 0, resultBuffer, 0, size); - } - - async resolveTimestampAsync(renderContext, type = 'render') { - if (!this.trackTimestamp) return; - - const renderContextData = this.get(renderContext); - - if (renderContextData.currentTimestampQueryBuffers === undefined) return; - - const { resultBuffer, isMappingPending } = renderContextData.currentTimestampQueryBuffers; - - if (isMappingPending === true) return; - - renderContextData.currentTimestampQueryBuffers.isMappingPending = true; - - resultBuffer.mapAsync(GPUMapMode.READ).then(() => { - const times = new BigUint64Array(resultBuffer.getMappedRange()); - const duration = Number(times[1] - times[0]) / 1000000; - - this.renderer.info.updateTimestamp(type, duration); - - resultBuffer.unmap(); - - renderContextData.currentTimestampQueryBuffers.isMappingPending = false; - }); - } - - // node builder - - createNodeBuilder(object, renderer) { - return new WGSLNodeBuilder(object, renderer); - } - - // program - - createProgram(program) { - const programGPU = this.get(program); - - programGPU.module = { - module: this.device.createShaderModule({ code: program.code, label: program.stage }), - entryPoint: 'main', - }; - } - - destroyProgram(program) { - this.delete(program); - } - - // pipelines - - createRenderPipeline(renderObject, promises) { - this.pipelineUtils.createRenderPipeline(renderObject, promises); - } - - createComputePipeline(computePipeline, bindings) { - this.pipelineUtils.createComputePipeline(computePipeline, bindings); - } - - beginBundle(renderContext) { - const renderContextData = this.get(renderContext); - - renderContextData._currentPass = renderContextData.currentPass; - renderContextData._currentSets = renderContextData.currentSets; - - renderContextData.currentSets = { attributes: {}, bindingGroups: [], pipeline: null, index: null }; - renderContextData.currentPass = this.pipelineUtils.createBundleEncoder(renderContext); - } - - finishBundle(renderContext, bundle) { - const renderContextData = this.get(renderContext); - - const bundleEncoder = renderContextData.currentPass; - const bundleGPU = bundleEncoder.finish(); - - this.get(bundle).bundleGPU = bundleGPU; - - // restore render pass state - - renderContextData.currentSets = renderContextData._currentSets; - renderContextData.currentPass = renderContextData._currentPass; - } - - addBundle(renderContext, bundle) { - const renderContextData = this.get(renderContext); - - renderContextData.renderBundles.push(this.get(bundle).bundleGPU); - } - - // bindings - - createBindings(bindGroup) { - this.bindingUtils.createBindings(bindGroup); - } - - updateBindings(bindGroup) { - this.bindingUtils.createBindings(bindGroup); - } - - updateBinding(binding) { - this.bindingUtils.updateBinding(binding); - } - - // attributes - - createIndexAttribute(attribute) { - this.attributeUtils.createAttribute( - attribute, - GPUBufferUsage.INDEX | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST, - ); - } - - createAttribute(attribute) { - this.attributeUtils.createAttribute( - attribute, - GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST, - ); - } - - createStorageAttribute(attribute) { - this.attributeUtils.createAttribute( - attribute, - GPUBufferUsage.STORAGE | GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST, - ); - } - - createIndirectStorageAttribute(attribute) { - this.attributeUtils.createAttribute( - attribute, - GPUBufferUsage.STORAGE | GPUBufferUsage.INDIRECT | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST, - ); - } - - updateAttribute(attribute) { - this.attributeUtils.updateAttribute(attribute); - } - - destroyAttribute(attribute) { - this.attributeUtils.destroyAttribute(attribute); - } - - // canvas - - updateSize() { - this.colorBuffer = this.textureUtils.getColorBuffer(); - this.defaultRenderPassdescriptor = null; - } - - // utils public - - getMaxAnisotropy() { - return 16; - } - - hasFeature(name) { - return this.device.features.has(name); - } - - copyTextureToTexture(srcTexture, dstTexture, srcRegion = null, dstPosition = null, level = 0) { - let dstX = 0; - let dstY = 0; - let dstLayer = 0; - - let srcX = 0; - let srcY = 0; - let srcLayer = 0; - - let srcWidth = srcTexture.image.width; - let srcHeight = srcTexture.image.height; - - if (srcRegion !== null) { - srcX = srcRegion.x; - srcY = srcRegion.y; - srcLayer = srcRegion.z || 0; - srcWidth = srcRegion.width; - srcHeight = srcRegion.height; - } - - if (dstPosition !== null) { - dstX = dstPosition.x; - dstY = dstPosition.y; - dstLayer = dstPosition.z || 0; - } - - const encoder = this.device.createCommandEncoder({ - label: 'copyTextureToTexture_' + srcTexture.id + '_' + dstTexture.id, - }); - - const sourceGPU = this.get(srcTexture).texture; - const destinationGPU = this.get(dstTexture).texture; - - encoder.copyTextureToTexture( - { - texture: sourceGPU, - mipLevel: level, - origin: { x: srcX, y: srcY, z: srcLayer }, - }, - { - texture: destinationGPU, - mipLevel: level, - origin: { x: dstX, y: dstY, z: dstLayer }, - }, - [srcWidth, srcHeight, 1], - ); - - this.device.queue.submit([encoder.finish()]); - } - - copyFramebufferToTexture(texture, renderContext, rectangle) { - const renderContextData = this.get(renderContext); - - const { encoder, descriptor } = renderContextData; - - let sourceGPU = null; - - if (renderContext.renderTarget) { - if (texture.isDepthTexture) { - sourceGPU = this.get(renderContext.depthTexture).texture; - } else { - sourceGPU = this.get(renderContext.textures[0]).texture; - } - } else { - if (texture.isDepthTexture) { - sourceGPU = this.textureUtils.getDepthBuffer(renderContext.depth, renderContext.stencil); - } else { - sourceGPU = this.context.getCurrentTexture(); - } - } - - const destinationGPU = this.get(texture).texture; - - if (sourceGPU.format !== destinationGPU.format) { - console.error( - 'WebGPUBackend: copyFramebufferToTexture: Source and destination formats do not match.', - sourceGPU.format, - destinationGPU.format, - ); - - return; - } - - renderContextData.currentPass.end(); - - encoder.copyTextureToTexture( - { - texture: sourceGPU, - origin: { x: rectangle.x, y: rectangle.y, z: 0 }, - }, - { - texture: destinationGPU, - }, - [rectangle.z, rectangle.w], - ); - - if (texture.generateMipmaps) this.textureUtils.generateMipmaps(texture); - - for (let i = 0; i < descriptor.colorAttachments.length; i++) { - descriptor.colorAttachments[i].loadOp = GPULoadOp.Load; - } - - if (renderContext.depth) descriptor.depthStencilAttachment.depthLoadOp = GPULoadOp.Load; - if (renderContext.stencil) descriptor.depthStencilAttachment.stencilLoadOp = GPULoadOp.Load; - - renderContextData.currentPass = encoder.beginRenderPass(descriptor); - renderContextData.currentSets = { attributes: {}, bindingGroups: [], pipeline: null, index: null }; - } -} - -export default WebGPUBackend; diff --git a/src-testing/src/renderers/webgpu/WebGPURenderer.Nodes.d.ts b/src-testing/src/renderers/webgpu/WebGPURenderer.Nodes.d.ts deleted file mode 100644 index b9eb0ddeb..000000000 --- a/src-testing/src/renderers/webgpu/WebGPURenderer.Nodes.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -import Renderer, { RendererParameters } from "../common/Renderer.js"; -import { WebGPUBackendParameters } from "./WebGPUBackend.js"; - -export interface WebGPURendererParameters extends RendererParameters, WebGPUBackendParameters { - forceWebGL?: boolean | undefined; -} - -export default class WebGPURenderer extends Renderer { - readonly isWebGPURenderer: true; - - constructor(parameters?: WebGPURendererParameters); -} diff --git a/src-testing/src/renderers/webgpu/WebGPURenderer.ts b/src-testing/src/renderers/webgpu/WebGPURenderer.ts deleted file mode 100644 index 1b4e424f4..000000000 --- a/src-testing/src/renderers/webgpu/WebGPURenderer.ts +++ /dev/null @@ -1,46 +0,0 @@ -import Renderer from '../common/Renderer.js'; -import WebGLBackend from '../webgl-fallback/WebGLBackend.js'; -import WebGPUBackend from './WebGPUBackend.js'; -import StandardNodeLibrary from './nodes/StandardNodeLibrary.js'; -/* -const debugHandler = { - - get: function ( target, name ) { - - // Add |update - if ( /^(create|destroy)/.test( name ) ) console.log( 'WebGPUBackend.' + name ); - - return target[ name ]; - - } - -}; -*/ -class WebGPURenderer extends Renderer { - constructor(parameters = {}) { - let BackendClass; - - if (parameters.forceWebGL) { - BackendClass = WebGLBackend; - } else { - BackendClass = WebGPUBackend; - - parameters.getFallback = () => { - console.warn('THREE.WebGPURenderer: WebGPU is not available, running under WebGL2 backend.'); - - return new WebGLBackend(parameters); - }; - } - - const backend = new BackendClass(parameters); - - //super( new Proxy( backend, debugHandler ) ); - super(backend, parameters); - - this.library = new StandardNodeLibrary(); - - this.isWebGPURenderer = true; - } -} - -export default WebGPURenderer; diff --git a/src-testing/src/renderers/webgpu/nodes/BasicNodeLibrary.ts b/src-testing/src/renderers/webgpu/nodes/BasicNodeLibrary.ts deleted file mode 100644 index 665bffa32..000000000 --- a/src-testing/src/renderers/webgpu/nodes/BasicNodeLibrary.ts +++ /dev/null @@ -1,61 +0,0 @@ -import NodeLibrary from '../../common/nodes/NodeLibrary.js'; - -// Lights -import { PointLight } from '../../../lights/PointLight.js'; -import { PointLightNode } from '../../../nodes/Nodes.js'; -import { DirectionalLight } from '../../../lights/DirectionalLight.js'; -import { DirectionalLightNode } from '../../../nodes/Nodes.js'; -import { RectAreaLight } from '../../../lights/RectAreaLight.js'; -import { RectAreaLightNode } from '../../../nodes/Nodes.js'; -import { SpotLight } from '../../../lights/SpotLight.js'; -import { SpotLightNode } from '../../../nodes/Nodes.js'; -import { AmbientLight } from '../../../lights/AmbientLight.js'; -import { AmbientLightNode } from '../../../nodes/Nodes.js'; -import { HemisphereLight } from '../../../lights/HemisphereLight.js'; -import { HemisphereLightNode } from '../../../nodes/Nodes.js'; -import { LightProbe } from '../../../lights/LightProbe.js'; -import { LightProbeNode } from '../../../nodes/Nodes.js'; -import IESSpotLight from '../../../lights/webgpu/IESSpotLight.js'; -import { IESSpotLightNode } from '../../../nodes/Nodes.js'; - -// Tone Mapping -import { - LinearToneMapping, - ReinhardToneMapping, - CineonToneMapping, - ACESFilmicToneMapping, - AgXToneMapping, - NeutralToneMapping, -} from '../../../constants.js'; -import { - linearToneMapping, - reinhardToneMapping, - cineonToneMapping, - acesFilmicToneMapping, - agxToneMapping, - neutralToneMapping, -} from '../../../nodes/display/ToneMappingFunctions.js'; - -class BasicNodeLibrary extends NodeLibrary { - constructor() { - super(); - - this.addLight(PointLightNode, PointLight); - this.addLight(DirectionalLightNode, DirectionalLight); - this.addLight(RectAreaLightNode, RectAreaLight); - this.addLight(SpotLightNode, SpotLight); - this.addLight(AmbientLightNode, AmbientLight); - this.addLight(HemisphereLightNode, HemisphereLight); - this.addLight(LightProbeNode, LightProbe); - this.addLight(IESSpotLightNode, IESSpotLight); - - this.addToneMapping(linearToneMapping, LinearToneMapping); - this.addToneMapping(reinhardToneMapping, ReinhardToneMapping); - this.addToneMapping(cineonToneMapping, CineonToneMapping); - this.addToneMapping(acesFilmicToneMapping, ACESFilmicToneMapping); - this.addToneMapping(agxToneMapping, AgXToneMapping); - this.addToneMapping(neutralToneMapping, NeutralToneMapping); - } -} - -export default BasicNodeLibrary; diff --git a/src-testing/src/renderers/webgpu/nodes/StandardNodeLibrary.ts b/src-testing/src/renderers/webgpu/nodes/StandardNodeLibrary.ts deleted file mode 100644 index bca482b4d..000000000 --- a/src-testing/src/renderers/webgpu/nodes/StandardNodeLibrary.ts +++ /dev/null @@ -1,107 +0,0 @@ -import NodeLibrary from '../../common/nodes/NodeLibrary.js'; - -// Materials -import { MeshPhongMaterial } from '../../../materials/MeshPhongMaterial.js'; -import MeshPhongNodeMaterial from '../../../materials/nodes/MeshPhongNodeMaterial.js'; -import { MeshStandardMaterial } from '../../../materials/MeshStandardMaterial.js'; -import MeshStandardNodeMaterial from '../../../materials/nodes/MeshStandardNodeMaterial.js'; -import { MeshPhysicalMaterial } from '../../../materials/MeshPhysicalMaterial.js'; -import MeshPhysicalNodeMaterial from '../../../materials/nodes/MeshPhysicalNodeMaterial.js'; -import { MeshToonMaterial } from '../../../materials/MeshToonMaterial.js'; -import MeshToonNodeMaterial from '../../../materials/nodes/MeshToonNodeMaterial.js'; -import { MeshBasicMaterial } from '../../../materials/MeshBasicMaterial.js'; -import MeshBasicNodeMaterial from '../../../materials/nodes/MeshBasicNodeMaterial.js'; -import { MeshLambertMaterial } from '../../../materials/MeshLambertMaterial.js'; -import MeshLambertNodeMaterial from '../../../materials/nodes/MeshLambertNodeMaterial.js'; -import { MeshNormalMaterial } from '../../../materials/MeshNormalMaterial.js'; -import MeshNormalNodeMaterial from '../../../materials/nodes/MeshNormalNodeMaterial.js'; -import { MeshMatcapMaterial } from '../../../materials/MeshMatcapMaterial.js'; -import MeshMatcapNodeMaterial from '../../../materials/nodes/MeshMatcapNodeMaterial.js'; -import { LineBasicMaterial } from '../../../materials/LineBasicMaterial.js'; -import LineBasicNodeMaterial from '../../../materials/nodes/LineBasicNodeMaterial.js'; -import { LineDashedMaterial } from '../../../materials/LineDashedMaterial.js'; -import LineDashedNodeMaterial from '../../../materials/nodes/LineDashedNodeMaterial.js'; -import { PointsMaterial } from '../../../materials/PointsMaterial.js'; -import PointsNodeMaterial from '../../../materials/nodes/PointsNodeMaterial.js'; -import { SpriteMaterial } from '../../../materials/SpriteMaterial.js'; -import SpriteNodeMaterial from '../../../materials/nodes/SpriteNodeMaterial.js'; -import { ShadowMaterial } from '../../../materials/ShadowMaterial.js'; -import ShadowNodeMaterial from '../../../materials/nodes/ShadowNodeMaterial.js'; -//import { MeshDepthMaterial } from '../../../materials/MeshDepthMaterial.js'; -//import MeshDepthNodeMaterial from '../../../materials/nodes/MeshDepthNodeMaterial.js'; -//import { MeshDistanceMaterial } from '../../../materials/MeshDistanceMaterial.js'; -//import MeshDistanceNodeMaterial from '../../../materials/nodes/MeshDistanceNodeMaterial.js'; - -// Lights -import { PointLight } from '../../../lights/PointLight.js'; -import { PointLightNode } from '../../../nodes/Nodes.js'; -import { DirectionalLight } from '../../../lights/DirectionalLight.js'; -import { DirectionalLightNode } from '../../../nodes/Nodes.js'; -import { RectAreaLight } from '../../../lights/RectAreaLight.js'; -import { RectAreaLightNode } from '../../../nodes/Nodes.js'; -import { SpotLight } from '../../../lights/SpotLight.js'; -import { SpotLightNode } from '../../../nodes/Nodes.js'; -import { AmbientLight } from '../../../lights/AmbientLight.js'; -import { AmbientLightNode } from '../../../nodes/Nodes.js'; -import { HemisphereLight } from '../../../lights/HemisphereLight.js'; -import { HemisphereLightNode } from '../../../nodes/Nodes.js'; -import { LightProbe } from '../../../lights/LightProbe.js'; -import { LightProbeNode } from '../../../nodes/Nodes.js'; -import IESSpotLight from '../../../lights/webgpu/IESSpotLight.js'; -import { IESSpotLightNode } from '../../../nodes/Nodes.js'; - -// Tone Mapping -import { - LinearToneMapping, - ReinhardToneMapping, - CineonToneMapping, - ACESFilmicToneMapping, - AgXToneMapping, - NeutralToneMapping, -} from '../../../constants.js'; -import { - linearToneMapping, - reinhardToneMapping, - cineonToneMapping, - acesFilmicToneMapping, - agxToneMapping, - neutralToneMapping, -} from '../../../nodes/display/ToneMappingFunctions.js'; - -class StandardNodeLibrary extends NodeLibrary { - constructor() { - super(); - - this.addMaterial(MeshPhongNodeMaterial, MeshPhongMaterial); - this.addMaterial(MeshStandardNodeMaterial, MeshStandardMaterial); - this.addMaterial(MeshPhysicalNodeMaterial, MeshPhysicalMaterial); - this.addMaterial(MeshToonNodeMaterial, MeshToonMaterial); - this.addMaterial(MeshBasicNodeMaterial, MeshBasicMaterial); - this.addMaterial(MeshLambertNodeMaterial, MeshLambertMaterial); - this.addMaterial(MeshNormalNodeMaterial, MeshNormalMaterial); - this.addMaterial(MeshMatcapNodeMaterial, MeshMatcapMaterial); - this.addMaterial(LineBasicNodeMaterial, LineBasicMaterial); - this.addMaterial(LineDashedNodeMaterial, LineDashedMaterial); - this.addMaterial(PointsNodeMaterial, PointsMaterial); - this.addMaterial(SpriteNodeMaterial, SpriteMaterial); - this.addMaterial(ShadowNodeMaterial, ShadowMaterial); - - this.addLight(PointLightNode, PointLight); - this.addLight(DirectionalLightNode, DirectionalLight); - this.addLight(RectAreaLightNode, RectAreaLight); - this.addLight(SpotLightNode, SpotLight); - this.addLight(AmbientLightNode, AmbientLight); - this.addLight(HemisphereLightNode, HemisphereLight); - this.addLight(LightProbeNode, LightProbe); - this.addLight(IESSpotLightNode, IESSpotLight); - - this.addToneMapping(linearToneMapping, LinearToneMapping); - this.addToneMapping(reinhardToneMapping, ReinhardToneMapping); - this.addToneMapping(cineonToneMapping, CineonToneMapping); - this.addToneMapping(acesFilmicToneMapping, ACESFilmicToneMapping); - this.addToneMapping(agxToneMapping, AgXToneMapping); - this.addToneMapping(neutralToneMapping, NeutralToneMapping); - } -} - -export default StandardNodeLibrary; diff --git a/src-testing/src/renderers/webgpu/nodes/WGSLNodeBuilder.ts b/src-testing/src/renderers/webgpu/nodes/WGSLNodeBuilder.ts deleted file mode 100644 index dc3aa7280..000000000 --- a/src-testing/src/renderers/webgpu/nodes/WGSLNodeBuilder.ts +++ /dev/null @@ -1,1178 +0,0 @@ -import NodeUniformsGroup from '../../common/nodes/NodeUniformsGroup.js'; - -import NodeSampler from '../../common/nodes/NodeSampler.js'; -import { - NodeSampledTexture, - NodeSampledCubeTexture, - NodeSampledTexture3D, -} from '../../common/nodes/NodeSampledTexture.js'; - -import NodeUniformBuffer from '../../common/nodes/NodeUniformBuffer.js'; -import NodeStorageBuffer from '../../common/nodes/NodeStorageBuffer.js'; - -import { NodeBuilder, CodeNode } from '../../../nodes/Nodes.js'; - -import { getFormat } from '../utils/WebGPUTextureUtils.js'; - -import WGSLNodeParser from './WGSLNodeParser.js'; -import { GPUBufferBindingType, GPUStorageTextureAccess } from '../utils/WebGPUConstants.js'; - -import { NoColorSpace, FloatType } from '../../../constants.js'; - -// GPUShaderStage is not defined in browsers not supporting WebGPU -const GPUShaderStage = self.GPUShaderStage; - -const gpuShaderStageLib = { - vertex: GPUShaderStage ? GPUShaderStage.VERTEX : 1, - fragment: GPUShaderStage ? GPUShaderStage.FRAGMENT : 2, - compute: GPUShaderStage ? GPUShaderStage.COMPUTE : 4, -}; - -const supports = { - instance: true, - swizzleAssign: false, - storageBuffer: true, -}; - -const wgslFnOpLib = { - '^^': 'tsl_xor', -}; - -const wgslTypeLib = { - float: 'f32', - int: 'i32', - uint: 'u32', - bool: 'bool', - color: 'vec3', - - vec2: 'vec2', - ivec2: 'vec2', - uvec2: 'vec2', - bvec2: 'vec2', - - vec3: 'vec3', - ivec3: 'vec3', - uvec3: 'vec3', - bvec3: 'vec3', - - vec4: 'vec4', - ivec4: 'vec4', - uvec4: 'vec4', - bvec4: 'vec4', - - mat2: 'mat2x2', - mat3: 'mat3x3', - mat4: 'mat4x4', -}; - -const wgslPolyfill = { - tsl_xor: new CodeNode('fn tsl_xor( a : bool, b : bool ) -> bool { return ( a || b ) && !( a && b ); }'), - mod_float: new CodeNode('fn tsl_mod_float( x : f32, y : f32 ) -> f32 { return x - y * floor( x / y ); }'), - mod_vec2: new CodeNode('fn tsl_mod_vec2( x : vec2f, y : vec2f ) -> vec2f { return x - y * floor( x / y ); }'), - mod_vec3: new CodeNode('fn tsl_mod_vec3( x : vec3f, y : vec3f ) -> vec3f { return x - y * floor( x / y ); }'), - mod_vec4: new CodeNode('fn tsl_mod_vec4( x : vec4f, y : vec4f ) -> vec4f { return x - y * floor( x / y ); }'), - equals_bool: new CodeNode('fn tsl_equals_bool( a : bool, b : bool ) -> bool { return a == b; }'), - equals_bvec2: new CodeNode( - 'fn tsl_equals_bvec2( a : vec2f, b : vec2f ) -> vec2 { return vec2( a.x == b.x, a.y == b.y ); }', - ), - equals_bvec3: new CodeNode( - 'fn tsl_equals_bvec3( a : vec3f, b : vec3f ) -> vec3 { return vec3( a.x == b.x, a.y == b.y, a.z == b.z ); }', - ), - equals_bvec4: new CodeNode( - 'fn tsl_equals_bvec4( a : vec4f, b : vec4f ) -> vec4 { return vec4( a.x == b.x, a.y == b.y, a.z == b.z, a.w == b.w ); }', - ), - repeatWrapping: new CodeNode(` -fn tsl_repeatWrapping( uv : vec2, dimension : vec2 ) -> vec2 { - - let uvScaled = vec2( uv * vec2( dimension ) ); - - return ( ( uvScaled % dimension ) + dimension ) % dimension; - -} -`), - biquadraticTexture: new CodeNode(` -fn tsl_biquadraticTexture( map : texture_2d, coord : vec2f, level : i32 ) -> vec4f { - - let iRes = vec2i( textureDimensions( map, level ) ); - let res = vec2f( iRes ); - - let uvScaled = coord * res; - let uvWrapping = ( ( uvScaled % res ) + res ) % res; - - // https://www.shadertoy.com/view/WtyXRy - - let uv = uvWrapping - 0.5; - let iuv = floor( uv ); - let f = fract( uv ); - - let rg1 = textureLoad( map, vec2i( iuv + vec2( 0.5, 0.5 ) ) % iRes, level ); - let rg2 = textureLoad( map, vec2i( iuv + vec2( 1.5, 0.5 ) ) % iRes, level ); - let rg3 = textureLoad( map, vec2i( iuv + vec2( 0.5, 1.5 ) ) % iRes, level ); - let rg4 = textureLoad( map, vec2i( iuv + vec2( 1.5, 1.5 ) ) % iRes, level ); - - return mix( mix( rg1, rg2, f.x ), mix( rg3, rg4, f.x ), f.y ); - -} -`), -}; - -const wgslMethods = { - dFdx: 'dpdx', - dFdy: '- dpdy', - mod_float: 'tsl_mod_float', - mod_vec2: 'tsl_mod_vec2', - mod_vec3: 'tsl_mod_vec3', - mod_vec4: 'tsl_mod_vec4', - equals_bool: 'tsl_equals_bool', - equals_bvec2: 'tsl_equals_bvec2', - equals_bvec3: 'tsl_equals_bvec3', - equals_bvec4: 'tsl_equals_bvec4', - inversesqrt: 'inverseSqrt', - bitcast: 'bitcast', -}; - -// WebGPU issue: does not support pow() with negative base on Windows - -if (/Windows/g.test(navigator.userAgent)) { - wgslPolyfill.pow_float = new CodeNode( - 'fn tsl_pow_float( a : f32, b : f32 ) -> f32 { return select( -pow( -a, b ), pow( a, b ), a > 0.0 ); }', - ); - wgslPolyfill.pow_vec2 = new CodeNode( - 'fn tsl_pow_vec2( a : vec2f, b : vec2f ) -> vec2f { return vec2f( tsl_pow_float( a.x, b.x ), tsl_pow_float( a.y, b.y ) ); }', - [wgslPolyfill.pow_float], - ); - wgslPolyfill.pow_vec3 = new CodeNode( - 'fn tsl_pow_vec3( a : vec3f, b : vec3f ) -> vec3f { return vec3f( tsl_pow_float( a.x, b.x ), tsl_pow_float( a.y, b.y ), tsl_pow_float( a.z, b.z ) ); }', - [wgslPolyfill.pow_float], - ); - wgslPolyfill.pow_vec4 = new CodeNode( - 'fn tsl_pow_vec4( a : vec4f, b : vec4f ) -> vec4f { return vec4f( tsl_pow_float( a.x, b.x ), tsl_pow_float( a.y, b.y ), tsl_pow_float( a.z, b.z ), tsl_pow_float( a.w, b.w ) ); }', - [wgslPolyfill.pow_float], - ); - - wgslMethods.pow_float = 'tsl_pow_float'; - wgslMethods.pow_vec2 = 'tsl_pow_vec2'; - wgslMethods.pow_vec3 = 'tsl_pow_vec3'; - wgslMethods.pow_vec4 = 'tsl_pow_vec4'; -} - -// - -let diagnostics = ''; - -if (/Firefox|Deno/g.test(navigator.userAgent) !== true) { - diagnostics += 'diagnostic( off, derivative_uniformity );\n'; -} - -// - -class WGSLNodeBuilder extends NodeBuilder { - constructor(object, renderer) { - super(object, renderer, new WGSLNodeParser()); - - this.uniformGroups = {}; - - this.builtins = {}; - - this.directives = {}; - - this.scopedArrays = new Map(); - } - - needsToWorkingColorSpace(texture) { - return texture.isVideoTexture === true && texture.colorSpace !== NoColorSpace; - } - - _generateTextureSample(texture, textureProperty, uvSnippet, depthSnippet, shaderStage = this.shaderStage) { - if (shaderStage === 'fragment') { - if (depthSnippet) { - return `textureSample( ${textureProperty}, ${textureProperty}_sampler, ${uvSnippet}, ${depthSnippet} )`; - } else { - return `textureSample( ${textureProperty}, ${textureProperty}_sampler, ${uvSnippet} )`; - } - } else if (this.isFilteredTexture(texture)) { - return this.generateFilteredTexture(texture, textureProperty, uvSnippet); - } else { - return this.generateTextureLod(texture, textureProperty, uvSnippet, '0'); - } - } - - _generateVideoSample(textureProperty, uvSnippet, shaderStage = this.shaderStage) { - if (shaderStage === 'fragment') { - return `textureSampleBaseClampToEdge( ${textureProperty}, ${textureProperty}_sampler, vec2( ${uvSnippet}.x, 1.0 - ${uvSnippet}.y ) )`; - } else { - console.error(`WebGPURenderer: THREE.VideoTexture does not support ${shaderStage} shader.`); - } - } - - _generateTextureSampleLevel( - texture, - textureProperty, - uvSnippet, - levelSnippet, - depthSnippet, - shaderStage = this.shaderStage, - ) { - if (shaderStage === 'fragment' && this.isUnfilterable(texture) === false) { - return `textureSampleLevel( ${textureProperty}, ${textureProperty}_sampler, ${uvSnippet}, ${levelSnippet} )`; - } else if (this.isFilteredTexture(texture)) { - return this.generateFilteredTexture(texture, textureProperty, uvSnippet, levelSnippet); - } else { - return this.generateTextureLod(texture, textureProperty, uvSnippet, levelSnippet); - } - } - - generateFilteredTexture(texture, textureProperty, uvSnippet, levelSnippet = '0') { - this._include('biquadraticTexture'); - - return `tsl_biquadraticTexture( ${textureProperty}, ${uvSnippet}, i32( ${levelSnippet} ) )`; - } - - generateTextureLod(texture, textureProperty, uvSnippet, levelSnippet = '0') { - this._include('repeatWrapping'); - - const dimension = - texture.isMultisampleRenderTargetTexture === true - ? `textureDimensions( ${textureProperty} )` - : `textureDimensions( ${textureProperty}, 0 )`; - - return `textureLoad( ${textureProperty}, tsl_repeatWrapping( ${uvSnippet}, ${dimension} ), i32( ${levelSnippet} ) )`; - } - - generateTextureLoad(texture, textureProperty, uvIndexSnippet, depthSnippet, levelSnippet = '0u') { - if (depthSnippet) { - return `textureLoad( ${textureProperty}, ${uvIndexSnippet}, ${depthSnippet}, ${levelSnippet} )`; - } else { - return `textureLoad( ${textureProperty}, ${uvIndexSnippet}, ${levelSnippet} )`; - } - } - - generateTextureStore(texture, textureProperty, uvIndexSnippet, valueSnippet) { - return `textureStore( ${textureProperty}, ${uvIndexSnippet}, ${valueSnippet} )`; - } - - isUnfilterable(texture) { - return ( - this.getComponentTypeFromTexture(texture) !== 'float' || - (!this.isAvailable('float32Filterable') && texture.isDataTexture === true && texture.type === FloatType) || - texture.isMultisampleRenderTargetTexture === true - ); - } - - generateTexture(texture, textureProperty, uvSnippet, depthSnippet, shaderStage = this.shaderStage) { - let snippet = null; - - if (texture.isVideoTexture === true) { - snippet = this._generateVideoSample(textureProperty, uvSnippet, shaderStage); - } else if (this.isUnfilterable(texture)) { - snippet = this.generateTextureLod(texture, textureProperty, uvSnippet, '0', depthSnippet, shaderStage); - } else { - snippet = this._generateTextureSample(texture, textureProperty, uvSnippet, depthSnippet, shaderStage); - } - - return snippet; - } - - generateTextureGrad( - texture, - textureProperty, - uvSnippet, - gradSnippet, - depthSnippet, - shaderStage = this.shaderStage, - ) { - if (shaderStage === 'fragment') { - // TODO handle i32 or u32 --> uvSnippet, array_index: A, ddx, ddy - return `textureSampleGrad( ${textureProperty}, ${textureProperty}_sampler, ${uvSnippet}, ${gradSnippet[0]}, ${gradSnippet[1]} )`; - } else { - console.error(`WebGPURenderer: THREE.TextureNode.gradient() does not support ${shaderStage} shader.`); - } - } - - generateTextureCompare( - texture, - textureProperty, - uvSnippet, - compareSnippet, - depthSnippet, - shaderStage = this.shaderStage, - ) { - if (shaderStage === 'fragment') { - return `textureSampleCompare( ${textureProperty}, ${textureProperty}_sampler, ${uvSnippet}, ${compareSnippet} )`; - } else { - console.error( - `WebGPURenderer: THREE.DepthTexture.compareFunction() does not support ${shaderStage} shader.`, - ); - } - } - - generateTextureLevel( - texture, - textureProperty, - uvSnippet, - levelSnippet, - depthSnippet, - shaderStage = this.shaderStage, - ) { - let snippet = null; - - if (texture.isVideoTexture === true) { - snippet = this._generateVideoSample(textureProperty, uvSnippet, shaderStage); - } else { - snippet = this._generateTextureSampleLevel( - texture, - textureProperty, - uvSnippet, - levelSnippet, - depthSnippet, - shaderStage, - ); - } - - return snippet; - } - - generateTextureBias( - texture, - textureProperty, - uvSnippet, - biasSnippet, - depthSnippet, - shaderStage = this.shaderStage, - ) { - if (shaderStage === 'fragment') { - return `textureSampleBias( ${textureProperty}, ${textureProperty}_sampler, ${uvSnippet}, ${biasSnippet} )`; - } else { - console.error(`WebGPURenderer: THREE.TextureNode.biasNode does not support ${shaderStage} shader.`); - } - } - - getPropertyName(node, shaderStage = this.shaderStage) { - if (node.isNodeVarying === true && node.needsInterpolation === true) { - if (shaderStage === 'vertex') { - return `varyings.${node.name}`; - } - } else if (node.isNodeUniform === true) { - const name = node.name; - const type = node.type; - - if (type === 'texture' || type === 'cubeTexture' || type === 'storageTexture' || type === 'texture3D') { - return name; - } else if (type === 'buffer' || type === 'storageBuffer' || type === 'indirectStorageBuffer') { - return `NodeBuffer_${node.id}.${name}`; - } else { - return node.groupNode.name + '.' + name; - } - } - - return super.getPropertyName(node); - } - - getOutputStructName() { - return 'output'; - } - - _getUniformGroupCount(shaderStage) { - return Object.keys(this.uniforms[shaderStage]).length; - } - - getFunctionOperator(op) { - const fnOp = wgslFnOpLib[op]; - - if (fnOp !== undefined) { - this._include(fnOp); - - return fnOp; - } - - return null; - } - - getStorageAccess(node) { - if (node.isStorageTextureNode) { - switch (node.access) { - case GPUStorageTextureAccess.ReadOnly: - return 'read'; - - case GPUStorageTextureAccess.WriteOnly: - return 'write'; - - default: - return 'read_write'; - } - } else { - switch (node.access) { - case GPUBufferBindingType.Storage: - return 'read_write'; - - case GPUBufferBindingType.ReadOnlyStorage: - return 'read'; - - default: - return 'write'; - } - } - } - - getUniformFromNode(node, type, shaderStage, name = null) { - const uniformNode = super.getUniformFromNode(node, type, shaderStage, name); - const nodeData = this.getDataFromNode(node, shaderStage, this.globalCache); - - if (nodeData.uniformGPU === undefined) { - let uniformGPU; - - const group = node.groupNode; - const groupName = group.name; - - const bindings = this.getBindGroupArray(groupName, shaderStage); - - if (type === 'texture' || type === 'cubeTexture' || type === 'storageTexture' || type === 'texture3D') { - let texture = null; - - if (type === 'texture' || type === 'storageTexture') { - texture = new NodeSampledTexture( - uniformNode.name, - uniformNode.node, - group, - node.access ? node.access : null, - ); - } else if (type === 'cubeTexture') { - texture = new NodeSampledCubeTexture( - uniformNode.name, - uniformNode.node, - group, - node.access ? node.access : null, - ); - } else if (type === 'texture3D') { - texture = new NodeSampledTexture3D( - uniformNode.name, - uniformNode.node, - group, - node.access ? node.access : null, - ); - } - - texture.store = node.isStorageTextureNode === true; - texture.setVisibility(gpuShaderStageLib[shaderStage]); - - if ( - shaderStage === 'fragment' && - this.isUnfilterable(node.value) === false && - texture.store === false - ) { - const sampler = new NodeSampler(`${uniformNode.name}_sampler`, uniformNode.node, group); - sampler.setVisibility(gpuShaderStageLib[shaderStage]); - - bindings.push(sampler, texture); - - uniformGPU = [sampler, texture]; - } else { - bindings.push(texture); - - uniformGPU = [texture]; - } - } else if (type === 'buffer' || type === 'storageBuffer' || type === 'indirectStorageBuffer') { - const bufferClass = type === 'buffer' ? NodeUniformBuffer : NodeStorageBuffer; - - const buffer = new bufferClass(node, group); - buffer.setVisibility(gpuShaderStageLib[shaderStage]); - - bindings.push(buffer); - - uniformGPU = buffer; - } else { - const uniformsStage = this.uniformGroups[shaderStage] || (this.uniformGroups[shaderStage] = {}); - - let uniformsGroup = uniformsStage[groupName]; - - if (uniformsGroup === undefined) { - uniformsGroup = new NodeUniformsGroup(groupName, group); - uniformsGroup.setVisibility(gpuShaderStageLib[shaderStage]); - - uniformsStage[groupName] = uniformsGroup; - - bindings.push(uniformsGroup); - } - - uniformGPU = this.getNodeUniform(uniformNode, type); - - uniformsGroup.addUniform(uniformGPU); - } - - nodeData.uniformGPU = uniformGPU; - } - - return uniformNode; - } - - getBuiltin(name, property, type, shaderStage = this.shaderStage) { - const map = this.builtins[shaderStage] || (this.builtins[shaderStage] = new Map()); - - if (map.has(name) === false) { - map.set(name, { - name, - property, - type, - }); - } - - return property; - } - - hasBuiltin(name, shaderStage = this.shaderStage) { - return this.builtins[shaderStage] !== undefined && this.builtins[shaderStage].has(name); - } - - getVertexIndex() { - if (this.shaderStage === 'vertex') { - return this.getBuiltin('vertex_index', 'vertexIndex', 'u32', 'attribute'); - } - - return 'vertexIndex'; - } - - buildFunctionCode(shaderNode) { - const layout = shaderNode.layout; - const flowData = this.flowShaderNode(shaderNode); - - const parameters = []; - - for (const input of layout.inputs) { - parameters.push(input.name + ' : ' + this.getType(input.type)); - } - - // - - let code = `fn ${layout.name}( ${parameters.join(', ')} ) -> ${this.getType(layout.type)} { -${flowData.vars} -${flowData.code} -`; - - if (flowData.result) { - code += `\treturn ${flowData.result};\n`; - } - - code += '\n}\n'; - - // - - return code; - } - - getInstanceIndex() { - if (this.shaderStage === 'vertex') { - return this.getBuiltin('instance_index', 'instanceIndex', 'u32', 'attribute'); - } - - return 'instanceIndex'; - } - - getInvocationLocalIndex() { - return this.getBuiltin('local_invocation_index', 'invocationLocalIndex', 'u32', 'attribute'); - } - - getSubgroupSize() { - this.enableSubGroups(); - - return this.getBuiltin('subgroup_size', 'subgroupSize', 'u32', 'attribute'); - } - - getInvocationSubgroupIndex() { - this.enableSubGroups(); - - return this.getBuiltin('subgroup_invocation_id', 'invocationSubgroupIndex', 'u32', 'attribute'); - } - - getSubgroupIndex() { - this.enableSubGroups(); - - return this.getBuiltin('subgroup_id', 'subgroupIndex', 'u32', 'attribute'); - } - - getDrawIndex() { - return null; - } - - getFrontFacing() { - return this.getBuiltin('front_facing', 'isFront', 'bool'); - } - - getFragCoord() { - return this.getBuiltin('position', 'fragCoord', 'vec4') + '.xy'; - } - - getFragDepth() { - return 'output.' + this.getBuiltin('frag_depth', 'depth', 'f32', 'output'); - } - - isFlipY() { - return false; - } - - enableDirective(name, shaderStage = this.shaderStage) { - const stage = this.directives[shaderStage] || (this.directives[shaderStage] = new Set()); - stage.add(name); - } - - getDirectives(shaderStage) { - const snippets = []; - const directives = this.directives[shaderStage]; - - if (directives !== undefined) { - for (const directive of directives) { - snippets.push(`enable ${directive};`); - } - } - - return snippets.join('\n'); - } - - enableSubGroups() { - this.enableDirective('subgroups'); - } - - enableSubgroupsF16() { - this.enableDirective('subgroups-f16'); - } - - enableClipDistances() { - this.enableDirective('clip_distances'); - } - - enableShaderF16() { - this.enableDirective('f16'); - } - - enableDualSourceBlending() { - this.enableDirective('dual_source_blending'); - } - - getBuiltins(shaderStage) { - const snippets = []; - const builtins = this.builtins[shaderStage]; - - if (builtins !== undefined) { - for (const { name, property, type } of builtins.values()) { - snippets.push(`@builtin( ${name} ) ${property} : ${type}`); - } - } - - return snippets.join(',\n\t'); - } - - getScopedArray(name, scope, bufferType, bufferCount) { - if (this.scopedArrays.has(name) === false) { - this.scopedArrays.set(name, { - name, - scope, - bufferType, - bufferCount, - }); - } - - return name; - } - - getScopedArrays(shaderStage) { - if (shaderStage !== 'compute') { - return; - } - - const snippets = []; - - for (const { name, scope, bufferType, bufferCount } of this.scopedArrays.values()) { - const type = this.getType(bufferType); - - snippets.push(`var<${scope}> ${name}: array< ${type}, ${bufferCount} >;`); - } - - return snippets.join('\n'); - } - - getAttributes(shaderStage) { - const snippets = []; - - if (shaderStage === 'compute') { - this.getBuiltin('global_invocation_id', 'id', 'vec3', 'attribute'); - this.getBuiltin('workgroup_id', 'workgroupId', 'vec3', 'attribute'); - this.getBuiltin('local_invocation_id', 'localId', 'vec3', 'attribute'); - this.getBuiltin('num_workgroups', 'numWorkgroups', 'vec3', 'attribute'); - - if (this.renderer.hasFeature('subgroups')) { - this.enableDirective('subgroups', shaderStage); - this.getBuiltin('subgroup_size', 'subgroupSize', 'u32', 'attribute'); - } - } - - if (shaderStage === 'vertex' || shaderStage === 'compute') { - const builtins = this.getBuiltins('attribute'); - - if (builtins) snippets.push(builtins); - - const attributes = this.getAttributesArray(); - - for (let index = 0, length = attributes.length; index < length; index++) { - const attribute = attributes[index]; - const name = attribute.name; - const type = this.getType(attribute.type); - - snippets.push(`@location( ${index} ) ${name} : ${type}`); - } - } - - return snippets.join(',\n\t'); - } - - getStructMembers(struct) { - const snippets = []; - const members = struct.getMemberTypes(); - - for (let i = 0; i < members.length; i++) { - const member = members[i]; - snippets.push(`\t@location( ${i} ) m${i} : ${member}`); - } - - const builtins = this.getBuiltins('output'); - - if (builtins) snippets.push('\t' + builtins); - - return snippets.join(',\n'); - } - - getStructs(shaderStage) { - const snippets = []; - const structs = this.structs[shaderStage]; - - for (let index = 0, length = structs.length; index < length; index++) { - const struct = structs[index]; - const name = struct.name; - - let snippet = `\struct ${name} {\n`; - snippet += this.getStructMembers(struct); - snippet += '\n}'; - - snippets.push(snippet); - - snippets.push(`\nvar output : ${name};\n\n`); - } - - return snippets.join('\n\n'); - } - - getVar(type, name) { - return `var ${name} : ${this.getType(type)}`; - } - - getVars(shaderStage) { - const snippets = []; - const vars = this.vars[shaderStage]; - - if (vars !== undefined) { - for (const variable of vars) { - snippets.push(`\t${this.getVar(variable.type, variable.name)};`); - } - } - - return `\n${snippets.join('\n')}\n`; - } - - getVaryings(shaderStage) { - const snippets = []; - - if (shaderStage === 'vertex') { - this.getBuiltin('position', 'Vertex', 'vec4', 'vertex'); - } - - if (shaderStage === 'vertex' || shaderStage === 'fragment') { - const varyings = this.varyings; - const vars = this.vars[shaderStage]; - - for (let index = 0; index < varyings.length; index++) { - const varying = varyings[index]; - - if (varying.needsInterpolation) { - let attributesSnippet = `@location( ${index} )`; - - if (/^(int|uint|ivec|uvec)/.test(varying.type)) { - attributesSnippet += ' @interpolate( flat )'; - } - - snippets.push(`${attributesSnippet} ${varying.name} : ${this.getType(varying.type)}`); - } else if (shaderStage === 'vertex' && vars.includes(varying) === false) { - vars.push(varying); - } - } - } - - const builtins = this.getBuiltins(shaderStage); - - if (builtins) snippets.push(builtins); - - const code = snippets.join(',\n\t'); - - return shaderStage === 'vertex' ? this._getWGSLStruct('VaryingsStruct', '\t' + code) : code; - } - - getUniforms(shaderStage) { - const uniforms = this.uniforms[shaderStage]; - - const bindingSnippets = []; - const bufferSnippets = []; - const structSnippets = []; - const uniformGroups = {}; - - for (const uniform of uniforms) { - const groupName = uniform.groupNode.name; - const uniformIndexes = this.bindingsIndexes[groupName]; - - if ( - uniform.type === 'texture' || - uniform.type === 'cubeTexture' || - uniform.type === 'storageTexture' || - uniform.type === 'texture3D' - ) { - const texture = uniform.node.value; - - if ( - shaderStage === 'fragment' && - this.isUnfilterable(texture) === false && - uniform.node.isStorageTextureNode !== true - ) { - if (texture.isDepthTexture === true && texture.compareFunction !== null) { - bindingSnippets.push( - `@binding( ${uniformIndexes.binding++} ) @group( ${uniformIndexes.group} ) var ${uniform.name}_sampler : sampler_comparison;`, - ); - } else { - bindingSnippets.push( - `@binding( ${uniformIndexes.binding++} ) @group( ${uniformIndexes.group} ) var ${uniform.name}_sampler : sampler;`, - ); - } - } - - let textureType; - - let multisampled = ''; - - if (texture.isMultisampleRenderTargetTexture === true) { - multisampled = '_multisampled'; - } - - if (texture.isCubeTexture === true) { - textureType = 'texture_cube'; - } else if (texture.isDataArrayTexture === true || texture.isCompressedArrayTexture === true) { - textureType = 'texture_2d_array'; - } else if (texture.isDepthTexture === true) { - textureType = `texture_depth${multisampled}_2d`; - } else if (texture.isVideoTexture === true) { - textureType = 'texture_external'; - } else if (texture.isData3DTexture === true) { - textureType = 'texture_3d'; - } else if (uniform.node.isStorageTextureNode === true) { - const format = getFormat(texture); - const access = this.getStorageAccess(uniform.node); - - textureType = `texture_storage_2d<${format}, ${access}>`; - } else { - const componentPrefix = this.getComponentTypeFromTexture(texture).charAt(0); - - textureType = `texture${multisampled}_2d<${componentPrefix}32>`; - } - - bindingSnippets.push( - `@binding( ${uniformIndexes.binding++} ) @group( ${uniformIndexes.group} ) var ${uniform.name} : ${textureType};`, - ); - } else if ( - uniform.type === 'buffer' || - uniform.type === 'storageBuffer' || - uniform.type === 'indirectStorageBuffer' - ) { - const bufferNode = uniform.node; - const bufferType = this.getType(bufferNode.bufferType); - const bufferCount = bufferNode.bufferCount; - - const bufferCountSnippet = bufferCount > 0 && uniform.type === 'buffer' ? ', ' + bufferCount : ''; - const bufferTypeSnippet = bufferNode.isAtomic ? `atomic<${bufferType}>` : `${bufferType}`; - const bufferSnippet = `\t${uniform.name} : array< ${bufferTypeSnippet}${bufferCountSnippet} >\n`; - const bufferAccessMode = bufferNode.isStorageBufferNode - ? `storage, ${this.getStorageAccess(bufferNode)}` - : 'uniform'; - - bufferSnippets.push( - this._getWGSLStructBinding( - 'NodeBuffer_' + bufferNode.id, - bufferSnippet, - bufferAccessMode, - uniformIndexes.binding++, - uniformIndexes.group, - ), - ); - } else { - const vectorType = this.getType(this.getVectorType(uniform.type)); - const groupName = uniform.groupNode.name; - - const group = - uniformGroups[groupName] || - (uniformGroups[groupName] = { - index: uniformIndexes.binding++, - id: uniformIndexes.group, - snippets: [], - }); - - group.snippets.push(`\t${uniform.name} : ${vectorType}`); - } - } - - for (const name in uniformGroups) { - const group = uniformGroups[name]; - - structSnippets.push( - this._getWGSLStructBinding(name, group.snippets.join(',\n'), 'uniform', group.index, group.id), - ); - } - - let code = bindingSnippets.join('\n'); - code += bufferSnippets.join('\n'); - code += structSnippets.join('\n'); - - return code; - } - - buildCode() { - const shadersData = this.material !== null ? { fragment: {}, vertex: {} } : { compute: {} }; - - this.sortBindingGroups(); - - for (const shaderStage in shadersData) { - const stageData = shadersData[shaderStage]; - stageData.uniforms = this.getUniforms(shaderStage); - stageData.attributes = this.getAttributes(shaderStage); - stageData.varyings = this.getVaryings(shaderStage); - stageData.structs = this.getStructs(shaderStage); - stageData.vars = this.getVars(shaderStage); - stageData.codes = this.getCodes(shaderStage); - stageData.directives = this.getDirectives(shaderStage); - stageData.scopedArrays = this.getScopedArrays(shaderStage); - - // - - let flow = '// code\n\n'; - flow += this.flowCode[shaderStage]; - - const flowNodes = this.flowNodes[shaderStage]; - const mainNode = flowNodes[flowNodes.length - 1]; - - const outputNode = mainNode.outputNode; - const isOutputStruct = outputNode !== undefined && outputNode.isOutputStructNode === true; - - for (const node of flowNodes) { - const flowSlotData = this.getFlowData(node /*, shaderStage*/); - const slotName = node.name; - - if (slotName) { - if (flow.length > 0) flow += '\n'; - - flow += `\t// flow -> ${slotName}\n\t`; - } - - flow += `${flowSlotData.code}\n\t`; - - if (node === mainNode && shaderStage !== 'compute') { - flow += '// result\n\n\t'; - - if (shaderStage === 'vertex') { - flow += `varyings.Vertex = ${flowSlotData.result};`; - } else if (shaderStage === 'fragment') { - if (isOutputStruct) { - stageData.returnType = outputNode.nodeType; - - flow += `return ${flowSlotData.result};`; - } else { - let structSnippet = '\t@location(0) color: vec4'; - - const builtins = this.getBuiltins('output'); - - if (builtins) structSnippet += ',\n\t' + builtins; - - stageData.returnType = 'OutputStruct'; - stageData.structs += this._getWGSLStruct('OutputStruct', structSnippet); - stageData.structs += '\nvar output : OutputStruct;\n\n'; - - flow += `output.color = ${flowSlotData.result};\n\n\treturn output;`; - } - } - } - } - - stageData.flow = flow; - } - - if (this.material !== null) { - this.vertexShader = this._getWGSLVertexCode(shadersData.vertex); - this.fragmentShader = this._getWGSLFragmentCode(shadersData.fragment); - } else { - this.computeShader = this._getWGSLComputeCode( - shadersData.compute, - (this.object.workgroupSize || [64]).join(', '), - ); - } - } - - getMethod(method, output = null) { - let wgslMethod; - - if (output !== null) { - wgslMethod = this._getWGSLMethod(method + '_' + output); - } - - if (wgslMethod === undefined) { - wgslMethod = this._getWGSLMethod(method); - } - - return wgslMethod || method; - } - - getType(type) { - return wgslTypeLib[type] || type; - } - - isAvailable(name) { - let result = supports[name]; - - if (result === undefined) { - if (name === 'float32Filterable') { - result = this.renderer.hasFeature('float32-filterable'); - } - - supports[name] = result; - } - - return result; - } - - _getWGSLMethod(method) { - if (wgslPolyfill[method] !== undefined) { - this._include(method); - } - - return wgslMethods[method]; - } - - _include(name) { - const codeNode = wgslPolyfill[name]; - codeNode.build(this); - - if (this.currentFunctionNode !== null) { - this.currentFunctionNode.includes.push(codeNode); - } - - return codeNode; - } - - _getWGSLVertexCode(shaderData) { - return `${this.getSignature()} -// directives -${shaderData.directives} - -// uniforms -${shaderData.uniforms} - -// varyings -${shaderData.varyings} -var varyings : VaryingsStruct; - -// codes -${shaderData.codes} - -@vertex -fn main( ${shaderData.attributes} ) -> VaryingsStruct { - - // vars - ${shaderData.vars} - - // flow - ${shaderData.flow} - - return varyings; - -} -`; - } - - _getWGSLFragmentCode(shaderData) { - return `${this.getSignature()} -// global -${diagnostics} - -// uniforms -${shaderData.uniforms} - -// structs -${shaderData.structs} - -// codes -${shaderData.codes} - -@fragment -fn main( ${shaderData.varyings} ) -> ${shaderData.returnType} { - - // vars - ${shaderData.vars} - - // flow - ${shaderData.flow} - -} -`; - } - - _getWGSLComputeCode(shaderData, workgroupSize) { - return `${this.getSignature()} -// directives -${shaderData.directives} - -// system -var instanceIndex : u32; - -// locals -${shaderData.scopedArrays} - -// uniforms -${shaderData.uniforms} - -// codes -${shaderData.codes} - -@compute @workgroup_size( ${workgroupSize} ) -fn main( ${shaderData.attributes} ) { - - // system - instanceIndex = id.x + id.y * numWorkgroups.x * u32(${workgroupSize}) + id.z * numWorkgroups.x * numWorkgroups.y * u32(${workgroupSize}); - - // vars - ${shaderData.vars} - - // flow - ${shaderData.flow} - -} -`; - } - - _getWGSLStruct(name, vars) { - return ` -struct ${name} { -${vars} -};`; - } - - _getWGSLStructBinding(name, vars, access, binding = 0, group = 0) { - const structName = name + 'Struct'; - const structSnippet = this._getWGSLStruct(structName, vars); - - return `${structSnippet} -@binding( ${binding} ) @group( ${group} ) -var<${access}> ${name} : ${structName};`; - } -} - -export default WGSLNodeBuilder; diff --git a/src-testing/src/renderers/webgpu/nodes/WGSLNodeFunction.ts b/src-testing/src/renderers/webgpu/nodes/WGSLNodeFunction.ts deleted file mode 100644 index 33b0d2688..000000000 --- a/src-testing/src/renderers/webgpu/nodes/WGSLNodeFunction.ts +++ /dev/null @@ -1,142 +0,0 @@ -import NodeFunction from '../../../nodes/core/NodeFunction.js'; -import NodeFunctionInput from '../../../nodes/core/NodeFunctionInput.js'; - -const declarationRegexp = /^[fn]*\s*([a-z_0-9]+)?\s*\(([\s\S]*?)\)\s*[\-\>]*\s*([a-z_0-9]+(?:<[\s\S]+?>)?)/i; -const propertiesRegexp = /([a-z_0-9]+)\s*:\s*([a-z_0-9]+(?:<[\s\S]+?>)?)/gi; - -const wgslTypeLib = { - f32: 'float', - i32: 'int', - u32: 'uint', - bool: 'bool', - - 'vec2': 'vec2', - 'vec2': 'ivec2', - 'vec2': 'uvec2', - 'vec2': 'bvec2', - - vec2f: 'vec2', - vec2i: 'ivec2', - vec2u: 'uvec2', - vec2b: 'bvec2', - - 'vec3': 'vec3', - 'vec3': 'ivec3', - 'vec3': 'uvec3', - 'vec3': 'bvec3', - - vec3f: 'vec3', - vec3i: 'ivec3', - vec3u: 'uvec3', - vec3b: 'bvec3', - - 'vec4': 'vec4', - 'vec4': 'ivec4', - 'vec4': 'uvec4', - 'vec4': 'bvec4', - - vec4f: 'vec4', - vec4i: 'ivec4', - vec4u: 'uvec4', - vec4b: 'bvec4', - - 'mat2x2': 'mat2', - mat2x2f: 'mat2', - - 'mat3x3': 'mat3', - mat3x3f: 'mat3', - - 'mat4x4': 'mat4', - mat4x4f: 'mat4', - - sampler: 'sampler', - - texture_1d: 'texture', - - texture_2d: 'texture', - texture_2d_array: 'texture', - texture_multisampled_2d: 'cubeTexture', - - texture_depth_2d: 'depthTexture', - - texture_3d: 'texture3D', - - texture_cube: 'cubeTexture', - texture_cube_array: 'cubeTexture', - - texture_storage_1d: 'storageTexture', - texture_storage_2d: 'storageTexture', - texture_storage_2d_array: 'storageTexture', - texture_storage_3d: 'storageTexture', -}; - -const parse = source => { - source = source.trim(); - - const declaration = source.match(declarationRegexp); - - if (declaration !== null && declaration.length === 4) { - const inputsCode = declaration[2]; - const propsMatches = []; - let match = null; - - while ((match = propertiesRegexp.exec(inputsCode)) !== null) { - propsMatches.push({ name: match[1], type: match[2] }); - } - - // Process matches to correctly pair names and types - const inputs = []; - for (let i = 0; i < propsMatches.length; i++) { - const { name, type } = propsMatches[i]; - - let resolvedType = type; - - if (resolvedType.startsWith('texture')) { - resolvedType = type.split('<')[0]; - } else if (resolvedType.startsWith('ptr')) { - resolvedType = 'pointer'; - } - - resolvedType = wgslTypeLib[resolvedType] || resolvedType; - - inputs.push(new NodeFunctionInput(resolvedType, name)); - } - - const blockCode = source.substring(declaration[0].length); - const outputType = declaration[3] || 'void'; - - const name = declaration[1] !== undefined ? declaration[1] : ''; - const type = wgslTypeLib[outputType] || outputType; - - return { - type, - inputs, - name, - inputsCode, - blockCode, - outputType, - }; - } else { - throw new Error('FunctionNode: Function is not a WGSL code.'); - } -}; - -class WGSLNodeFunction extends NodeFunction { - constructor(source) { - const { type, inputs, name, inputsCode, blockCode, outputType } = parse(source); - - super(type, inputs, name); - - this.inputsCode = inputsCode; - this.blockCode = blockCode; - this.outputType = outputType; - } - - getCode(name = this.name) { - const outputType = this.outputType !== 'void' ? '-> ' + this.outputType : ''; - - return `fn ${name} ( ${this.inputsCode.trim()} ) ${outputType}` + this.blockCode; - } -} - -export default WGSLNodeFunction; diff --git a/src-testing/src/renderers/webgpu/nodes/WGSLNodeParser.ts b/src-testing/src/renderers/webgpu/nodes/WGSLNodeParser.ts deleted file mode 100644 index c32133df4..000000000 --- a/src-testing/src/renderers/webgpu/nodes/WGSLNodeParser.ts +++ /dev/null @@ -1,10 +0,0 @@ -import NodeParser from '../../../nodes/core/NodeParser.js'; -import WGSLNodeFunction from './WGSLNodeFunction.js'; - -class WGSLNodeParser extends NodeParser { - parseFunction(source) { - return new WGSLNodeFunction(source); - } -} - -export default WGSLNodeParser; diff --git a/src-testing/src/renderers/webgpu/utils/WebGPUConstants.d.ts b/src-testing/src/renderers/webgpu/utils/WebGPUConstants.d.ts deleted file mode 100644 index baa36f901..000000000 --- a/src-testing/src/renderers/webgpu/utils/WebGPUConstants.d.ts +++ /dev/null @@ -1,328 +0,0 @@ -export enum GPUPrimitiveTopology { - PointList = "point-list", - LineList = "line-list", - LineStrip = "line-strip", - TriangleList = "triangle-list", - TriangleStrip = "triangle-strip", -} - -export enum GPUCompareFunction { - Never = "never", - Less = "less", - Equal = "equal", - LessEqual = "less-equal", - Greater = "greater", - NotEqual = "not-equal", - GreaterEqual = "greater-equal", - Always = "always", -} - -export enum GPUStoreOp { - Store = "store", - Discard = "discard", -} - -export enum GPULoadOp { - Load = "load", - Clear = "clear", -} - -export enum GPUFrontFace { - CCW = "ccw", - CW = "cw", -} - -export enum GPUCullMode { - None = "none", - Front = "front", - Back = "back", -} - -export enum GPUIndexFormat { - Uint16 = "uint16", - Uint32 = "uint32", -} - -export enum GPUVertexFormat { - Uint8x2 = "uint8x2", - Uint8x4 = "uint8x4", - Sint8x2 = "sint8x2", - Sint8x4 = "sint8x4", - Unorm8x2 = "unorm8x2", - Unorm8x4 = "unorm8x4", - Snorm8x2 = "snorm8x2", - Snorm8x4 = "snorm8x4", - Uint16x2 = "uint16x2", - Uint16x4 = "uint16x4", - Sint16x2 = "sint16x2", - Sint16x4 = "sint16x4", - Unorm16x2 = "unorm16x2", - Unorm16x4 = "unorm16x4", - Snorm16x2 = "snorm16x2", - Snorm16x4 = "snorm16x4", - Float16x2 = "float16x2", - Float16x4 = "float16x4", - Float32 = "float32", - Float32x2 = "float32x2", - Float32x3 = "float32x3", - Float32x4 = "float32x4", - Uint32 = "uint32", - Uint32x2 = "uint32x2", - Uint32x3 = "uint32x3", - Uint32x4 = "uint32x4", - Sint32 = "sint32", - Sint32x2 = "sint32x2", - Sint32x3 = "sint32x3", - Sint32x4 = "sint32x4", -} - -export enum GPUTextureFormat { - // 8-bit formats - - R8Unorm = "r8unorm", - R8Snorm = "r8snorm", - R8Uint = "r8uint", - R8Sint = "r8sint", - - // 16-bit formats - - R16Uint = "r16uint", - R16Sint = "r16sint", - R16Float = "r16float", - RG8Unorm = "rg8unorm", - RG8Snorm = "rg8snorm", - RG8Uint = "rg8uint", - RG8Sint = "rg8sint", - - // 32-bit formats - - R32Uint = "r32uint", - R32Sint = "r32sint", - R32Float = "r32float", - RG16Uint = "rg16uint", - RG16Sint = "rg16sint", - RG16Float = "rg16float", - RGBA8Unorm = "rgba8unorm", - RGBA8UnormSRGB = "rgba8unorm-srgb", - RGBA8Snorm = "rgba8snorm", - RGBA8Uint = "rgba8uint", - RGBA8Sint = "rgba8sint", - BGRA8Unorm = "bgra8unorm", - BGRA8UnormSRGB = "bgra8unorm-srgb", - // Packed 32-bit formats - RGB9E5UFloat = "rgb9e5ufloat", - RGB10A2Unorm = "rgb10a2unorm", - RG11B10uFloat = "rgb10a2unorm", - - // 64-bit formats - - RG32Uint = "rg32uint", - RG32Sint = "rg32sint", - RG32Float = "rg32float", - RGBA16Uint = "rgba16uint", - RGBA16Sint = "rgba16sint", - RGBA16Float = "rgba16float", - - // 128-bit formats - - RGBA32Uint = "rgba32uint", - RGBA32Sint = "rgba32sint", - RGBA32Float = "rgba32float", - - // Depth and stencil formats - - Stencil8 = "stencil8", - Depth16Unorm = "depth16unorm", - Depth24Plus = "depth24plus", - Depth24PlusStencil8 = "depth24plus-stencil8", - Depth32Float = "depth32float", - - // 'depth32float-stencil8' extension - - Depth32FloatStencil8 = "depth32float-stencil8", - - // BC compressed formats usable if 'texture-compression-bc' is both - // supported by the device/user agent and enabled in requestDevice. - - BC1RGBAUnorm = "bc1-rgba-unorm", - BC1RGBAUnormSRGB = "bc1-rgba-unorm-srgb", - BC2RGBAUnorm = "bc2-rgba-unorm", - BC2RGBAUnormSRGB = "bc2-rgba-unorm-srgb", - BC3RGBAUnorm = "bc3-rgba-unorm", - BC3RGBAUnormSRGB = "bc3-rgba-unorm-srgb", - BC4RUnorm = "bc4-r-unorm", - BC4RSnorm = "bc4-r-snorm", - BC5RGUnorm = "bc5-rg-unorm", - BC5RGSnorm = "bc5-rg-snorm", - BC6HRGBUFloat = "bc6h-rgb-ufloat", - BC6HRGBFloat = "bc6h-rgb-float", - BC7RGBAUnorm = "bc7-rgba-unorm", - BC7RGBAUnormSRGB = "bc7-rgba-srgb", - - // ETC2 compressed formats usable if 'texture-compression-etc2' is both - // supported by the device/user agent and enabled in requestDevice. - - ETC2RGB8Unorm = "etc2-rgb8unorm", - ETC2RGB8UnormSRGB = "etc2-rgb8unorm-srgb", - ETC2RGB8A1Unorm = "etc2-rgb8a1unorm", - ETC2RGB8A1UnormSRGB = "etc2-rgb8a1unorm-srgb", - ETC2RGBA8Unorm = "etc2-rgba8unorm", - ETC2RGBA8UnormSRGB = "etc2-rgba8unorm-srgb", - EACR11Unorm = "eac-r11unorm", - EACR11Snorm = "eac-r11snorm", - EACRG11Unorm = "eac-rg11unorm", - EACRG11Snorm = "eac-rg11snorm", - - // ASTC compressed formats usable if 'texture-compression-astc' is both - // supported by the device/user agent and enabled in requestDevice. - - ASTC4x4Unorm = "astc-4x4-unorm", - ASTC4x4UnormSRGB = "astc-4x4-unorm-srgb", - ASTC5x4Unorm = "astc-5x4-unorm", - ASTC5x4UnormSRGB = "astc-5x4-unorm-srgb", - ASTC5x5Unorm = "astc-5x5-unorm", - ASTC5x5UnormSRGB = "astc-5x5-unorm-srgb", - ASTC6x5Unorm = "astc-6x5-unorm", - ASTC6x5UnormSRGB = "astc-6x5-unorm-srgb", - ASTC6x6Unorm = "astc-6x6-unorm", - ASTC6x6UnormSRGB = "astc-6x6-unorm-srgb", - ASTC8x5Unorm = "astc-8x5-unorm", - ASTC8x5UnormSRGB = "astc-8x5-unorm-srgb", - ASTC8x6Unorm = "astc-8x6-unorm", - ASTC8x6UnormSRGB = "astc-8x6-unorm-srgb", - ASTC8x8Unorm = "astc-8x8-unorm", - ASTC8x8UnormSRGB = "astc-8x8-unorm-srgb", - ASTC10x5Unorm = "astc-10x5-unorm", - ASTC10x5UnormSRGB = "astc-10x5-unorm-srgb", - ASTC10x6Unorm = "astc-10x6-unorm", - ASTC10x6UnormSRGB = "astc-10x6-unorm-srgb", - ASTC10x8Unorm = "astc-10x8-unorm", - ASTC10x8UnormSRGB = "astc-10x8-unorm-srgb", - ASTC10x10Unorm = "astc-10x10-unorm", - ASTC10x10UnormSRGB = "astc-10x10-unorm-srgb", - ASTC12x10Unorm = "astc-12x10-unorm", - ASTC12x10UnormSRGB = "astc-12x10-unorm-srgb", - ASTC12x12Unorm = "astc-12x12-unorm", - ASTC12x12UnormSRGB = "astc-12x12-unorm-srgb", -} - -export enum GPUAddressMode { - ClampToEdge = "clamp-to-edge", - Repeat = "repeat", - MirrorRepeat = "mirror-repeat", -} - -export enum GPUFilterMode { - Linear = "linear", - Nearest = "nearest", -} - -export enum GPUBlendFactor { - Zero = "zero", - One = "one", - Src = "src", - OneMinusSrc = "one-minus-src", - SrcAlpha = "src-alpha", - OneMinusSrcAlpha = "one-minus-src-alpha", - Dst = "dst", - OneMinusDstColor = "one-minus-dst", - DstAlpha = "dst-alpha", - OneMinusDstAlpha = "one-minus-dst-alpha", - SrcAlphaSaturated = "src-alpha-saturated", - Constant = "constant", - OneMinusConstant = "one-minus-constant", -} - -export enum GPUBlendOperation { - Add = "add", - Subtract = "subtract", - ReverseSubtract = "reverse-subtract", - Min = "min", - Max = "max", -} - -export enum GPUColorWriteFlags { - None = 0, - Red = 0x1, - Green = 0x2, - Blue = 0x4, - Alpha = 0x8, - All = 0xF, -} - -export enum GPUStencilOperation { - Keep = "keep", - Zero = "zero", - Replace = "replace", - Invert = "invert", - IncrementClamp = "increment-clamp", - DecrementClamp = "decrement-clamp", - IncrementWrap = "increment-wrap", - DecrementWrap = "decrement-wrap", -} - -export enum GPUBufferBindingType { - Uniform = "uniform", - Storage = "storage", - ReadOnlyStorage = "read-only-storage", -} - -export enum GPUStorageTextureAccess { - WriteOnly = "write-only", - ReadOnly = "read-only", - ReadWrite = "read-write", -} - -export enum GPUSamplerBindingType { - Filtering = "filtering", - NonFiltering = "non-filtering", - Comparison = "comparison", -} - -export enum GPUTextureSampleType { - Float = "float", - UnfilterableFloat = "unfilterable-float", - Depth = "depth", - SInt = "sint", - UInt = "uint", -} - -export enum GPUTextureDimension { - OneD = "1d", - TwoD = "2d", - ThreeD = "3d", -} - -export enum GPUTextureViewDimension { - OneD = "1d", - TwoD = "2d", - TwoDArray = "2d-array", - Cube = "cube", - CubeArray = "cube-array", - ThreeD = "3d", -} - -export enum GPUTextureAspect { - All = "all", - StencilOnly = "stencil-only", - DepthOnly = "depth-only", -} - -export enum GPUInputStepMode { - Vertex = "vertex", - Instance = "instance", -} - -export enum GPUFeatureName { - DepthClipControl = "depth-clip-control", - Depth32FloatStencil8 = "depth32float-stencil8", - TextureCompressionBC = "texture-compression-bc", - TextureCompressionETC2 = "texture-compression-etc2", - TextureCompressionASTC = "texture-compression-astc", - TimestampQuery = "timestamp-query", - IndirectFirstInstance = "indirect-first-instance", - ShaderF16 = "shader-f16", - RG11B10UFloat = "rg11b10ufloat-renderable", - BGRA8UNormStorage = "bgra8unorm-storage", - Float32Filterable = "float32-filterable", -} diff --git a/src-testing/src/renderers/webxr/WebXRController.d.ts b/src-testing/src/renderers/webxr/WebXRController.d.ts deleted file mode 100644 index 956a036b4..000000000 --- a/src-testing/src/renderers/webxr/WebXRController.d.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { Object3DEventMap } from "../../core/Object3D.js"; -import { Vector3 } from "../../math/Vector3.js"; -import { Group } from "../../objects/Group.js"; - -export type XRControllerEventType = XRSessionEventType | XRInputSourceEventType | "disconnected" | "connected"; - -export class XRJointSpace extends Group { - readonly jointRadius: number | undefined; -} - -export type XRHandJoints = Record; - -export interface XRHandInputState { - pinching: boolean; -} - -export interface WebXRSpaceEventMap extends Object3DEventMap { - select: { data: XRInputSource }; - selectstart: { data: XRInputSource }; - selectend: { data: XRInputSource }; - squeeze: { data: XRInputSource }; - squeezestart: { data: XRInputSource }; - squeezeend: { data: XRInputSource }; - - connected: { data: XRInputSource }; - disconnected: { data: XRInputSource }; - - pinchend: { handedness: XRHandedness; target: WebXRController }; // This Event break the THREE.EventDispatcher contract, replacing the target to the wrong instance. - pinchstart: { handedness: XRHandedness; target: WebXRController }; // This Event break the THREE.EventDispatcher contract, replacing the target to the wrong instance. - - move: {}; -} - -export class XRHandSpace extends Group { - readonly joints: Partial; - readonly inputState: XRHandInputState; -} - -export class XRTargetRaySpace extends Group { - hasLinearVelocity: boolean; - readonly linearVelocity: Vector3; - hasAngularVelocity: boolean; - readonly angularVelocity: Vector3; -} - -export class XRGripSpace extends Group { - hasLinearVelocity: boolean; - readonly linearVelocity: Vector3; - hasAngularVelocity: boolean; - readonly angularVelocity: Vector3; -} - -export class WebXRController { - constructor(); - - getHandSpace(): XRHandSpace; - getTargetRaySpace(): XRTargetRaySpace; - getGripSpace(): XRGripSpace; - dispatchEvent(event: { type: XRControllerEventType; data?: XRInputSource }): this; - connect(inputSource: XRInputSource): this; - disconnect(inputSource: XRInputSource): this; - update(inputSource: XRInputSource, frame: XRFrame, referenceSpace: XRReferenceSpace): this; -} diff --git a/src-testing/src/renderers/webxr/WebXRDepthSensing.d.ts b/src-testing/src/renderers/webxr/WebXRDepthSensing.d.ts deleted file mode 100644 index 23914f679..000000000 --- a/src-testing/src/renderers/webxr/WebXRDepthSensing.d.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Mesh } from "../../objects/Mesh.js"; -import { Texture } from "../../textures/Texture.js"; -import { WebGLRenderer } from "../WebGLRenderer.js"; -import { WebXRArrayCamera } from "./WebXRManager.js"; - -export class WebXRDepthSensing { - texture: Texture | null; - mesh: Mesh | null; - - depthNear: number; - depthFar: number; - - constructor(); - - init(renderer: WebGLRenderer, depthData: XRWebGLDepthInformation, renderState: XRRenderState): void; - - getMesh(cameraXR: WebXRArrayCamera): Mesh | null; - - reset(): void; - - getDepthTexture(): Texture | null; -} diff --git a/src-testing/src/renderers/webxr/WebXRManager.d.ts b/src-testing/src/renderers/webxr/WebXRManager.d.ts deleted file mode 100644 index 4b2073101..000000000 --- a/src-testing/src/renderers/webxr/WebXRManager.d.ts +++ /dev/null @@ -1,85 +0,0 @@ -/// - -import { ArrayCamera } from "../../cameras/ArrayCamera.js"; -import { PerspectiveCamera } from "../../cameras/PerspectiveCamera.js"; -import { EventDispatcher } from "../../core/EventDispatcher.js"; -import { Vector4 } from "../../math/Vector4.js"; -import { Mesh } from "../../objects/Mesh.js"; -import { Texture } from "../../textures/Texture.js"; -import { WebGLRenderer } from "../WebGLRenderer.js"; -import { XRGripSpace, XRHandSpace, XRTargetRaySpace } from "./WebXRController.js"; - -export type WebXRCamera = PerspectiveCamera & { viewport: Vector4 }; -export type WebXRArrayCamera = Omit & { cameras: [WebXRCamera, WebXRCamera] }; - -export interface WebXRManagerEventMap { - sessionstart: {}; - sessionend: {}; - planeadded: { data: XRPlane }; - planeremoved: { data: XRPlane }; - planechanged: { data: XRPlane }; - planesdetected: { data: XRPlaneSet }; -} - -export class WebXRManager extends EventDispatcher { - /** - * @default true - */ - cameraAutoUpdate: boolean; - - /** - * @default false - */ - enabled: boolean; - - /** - * @default false - */ - isPresenting: boolean; - - constructor(renderer: WebGLRenderer, gl: WebGLRenderingContext); - - getController: (index: number) => XRTargetRaySpace; - - getControllerGrip: (index: number) => XRGripSpace; - - getHand: (index: number) => XRHandSpace; - - setFramebufferScaleFactor: (value: number) => void; - - setReferenceSpaceType: (value: XRReferenceSpaceType) => void; - - getReferenceSpace: () => XRReferenceSpace | null; - - setReferenceSpace: (value: XRReferenceSpace) => void; - - getBaseLayer: () => XRWebGLLayer | XRProjectionLayer; - - getBinding: () => XRWebGLBinding; - - getFrame: () => XRFrame; - - getSession: () => XRSession | null; - - setSession: (value: XRSession | null) => Promise; - - getEnvironmentBlendMode: () => XREnvironmentBlendMode | undefined; - - getDepthTexture: () => Texture | null; - - updateCamera: (camera: PerspectiveCamera) => void; - - getCamera: () => WebXRArrayCamera; - - getFoveation: () => number | undefined; - - setFoveation: (value: number) => void; - - hasDepthSensing: () => boolean; - - getDepthSensingMesh: () => Mesh | null; - - setAnimationLoop: (callback: XRFrameRequestCallback | null) => void; - - dispose: () => void; -} diff --git a/src-testing/src/scenes/Fog.d.ts b/src-testing/src/scenes/Fog.d.ts deleted file mode 100644 index fc0f18019..000000000 --- a/src-testing/src/scenes/Fog.d.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { Color, ColorRepresentation } from "../math/Color.js"; - -export interface FogJSON { - type: string; - name: string; - color: number; - near: number; - far: number; -} - -/** - * This class contains the parameters that define linear fog, i.e., that grows linearly denser with the distance. - * @example - * ```typescript - * const scene = new THREE.Scene(); - * scene.fog = new THREE.Fog(0xcccccc, 10, 15); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/scenes/Fog | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/scenes/Fog.js | Source} - */ -export class Fog { - /** - * The color parameter is passed to the {@link THREE.Color | Color} constructor to set the color property - * @remarks - * Color can be a hexadecimal integer or a CSS-style string. - * @param color - * @param near Expects a `Float` - * @param far Expects a `Float` - */ - constructor(color: ColorRepresentation, near?: number, far?: number); - - /** - * Read-only flag to check if a given object is of type {@link Fog}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isFog: true; - - /** - * Optional name of the object - * @remarks _(doesn't need to be unique)_. - * @defaultValue `""` - */ - name: string; - - /** - * Fog color. - * @remarks If set to black, far away objects will be rendered black. - */ - color: Color; - - /** - * The minimum distance to start applying fog. - * @remarks Objects that are less than **near** units from the active camera won't be affected by fog. - * @defaultValue `1` - * @remarks Expects a `Float` - */ - near: number; - - /** - * The maximum distance at which fog stops being calculated and applied. - * @remarks Objects that are more than **far** units away from the active camera won't be affected by fog. - * @defaultValue `1000` - * @remarks Expects a `Float` - */ - far: number; - - /** - * Returns a new {@link Fog} instance with the same parameters as this one. - */ - clone(): Fog; - - /** - * Return {@link Fog} data in JSON format. - */ - toJSON(): FogJSON; -} diff --git a/src-testing/src/scenes/FogExp2.d.ts b/src-testing/src/scenes/FogExp2.d.ts deleted file mode 100644 index af00981e6..000000000 --- a/src-testing/src/scenes/FogExp2.d.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { Color, ColorRepresentation } from "../math/Color.js"; - -export interface FogExp2JSON { - type: string; - name: string; - color: number; - density: number; -} - -/** - * This class contains the parameters that define exponential squared fog, which gives a clear view near the camera and a faster than exponentially densening fog farther from the camera. - * @example - * ```typescript - * const scene = new THREE.Scene(); - * scene.fog = new THREE.FogExp2(0xcccccc, 0.002); - * ``` - * @see Example: {@link https://threejs.org/examples/#webgl_geometry_terrain | webgl geometry terrain} - * @see {@link https://threejs.org/docs/index.html#api/en/scenes/FogExp2 | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/scenes/FogExp2.js | Source} - */ -export class FogExp2 { - /** - * The color parameter is passed to the {@link THREE.Color | Color} constructor to set the color property - * @remarks Color can be a hexadecimal integer or a CSS-style string. - * @param color - * @param density Expects a `Float` - */ - constructor(color: ColorRepresentation, density?: number); - - /** - * Read-only flag to check if a given object is of type {@link FogExp2}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isFogExp2: true; - - /** - * Optional name of the object - * @remarks _(doesn't need to be unique)_. - * @defaultValue `""` - */ - name: string; - - /** - * Fog color. - * @remarks If set to black, far away objects will be rendered black. - */ - color: Color; - - /** - * Defines how fast the fog will grow dense. - * @defaultValue `0.00025` - * @remarks Expects a `Float` - */ - density: number; - - /** - * Returns a new {@link FogExp2} instance with the same parameters as this one. - */ - clone(): FogExp2; - - /** - * Return {@link FogExp2} data in JSON format. - */ - toJSON(): FogExp2JSON; -} diff --git a/src-testing/src/scenes/Scene.d.ts b/src-testing/src/scenes/Scene.d.ts deleted file mode 100644 index c2f43afd7..000000000 --- a/src-testing/src/scenes/Scene.d.ts +++ /dev/null @@ -1,118 +0,0 @@ -import { JSONMeta, Object3D, Object3DJSON, Object3DJSONObject } from "../core/Object3D.js"; -import { Material } from "../materials/Material.js"; -import { Color } from "../math/Color.js"; -import { Euler, EulerTuple } from "../math/Euler.js"; -import { CubeTexture } from "../textures/CubeTexture.js"; -import { Texture } from "../textures/Texture.js"; -import { Fog, FogJSON } from "./Fog.js"; -import { FogExp2, FogExp2JSON } from "./FogExp2.js"; - -export interface SceneJSONObject extends Object3DJSONObject { - fog?: FogJSON | FogExp2JSON; - - backgroundBlurriness?: number; - backgroundIntensity?: number; - backgroundRotation: EulerTuple; - - environmentIntensity?: number; - environmentRotation: EulerTuple; -} - -export interface SceneJSON extends Object3DJSON { - object: SceneJSONObject; -} - -/** - * Scenes allow you to set up what and where is to be rendered by three.js - * @remarks - * This is where you place objects, lights and cameras. - * @see Example: {@link https://threejs.org/examples/#webgl_multiple_scenes_comparison | webgl multiple scenes comparison} - * @see {@link https://threejs.org/docs/index.html#manual/en/introduction/Creating-a-scene | Manual: Creating a scene} - * @see {@link https://threejs.org/docs/index.html#api/en/scenes/Scene | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/scenes/Scene.js | Source} - */ -export class Scene extends Object3D { - /** - * Create a new {@link Scene} object. - */ - constructor(); - - /** - * Read-only flag to check if a given object is of type {@link Scene}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isScene: true; - - /** - * @defaultValue `Scene` - */ - type: "Scene"; - - /** - * A {@link Fog | fog} instance defining the type of fog that affects everything rendered in the scene. - * @defaultValue `null` - */ - fog: Fog | FogExp2 | null; - - /** - * Sets the blurriness of the background. Only influences environment maps assigned to {@link THREE.Scene.background | Scene.background}. - * @defaultValue `0` - * @remarks Expects a `Float` between `0` and `1`. - */ - backgroundBlurriness: number; - - /** - * Attenuates the color of the background. Only applies to background textures. - * @defaultValue `1` - * @remarks Expects a `Float` - */ - backgroundIntensity: number; - - /** - * Forces everything in the {@link Scene} to be rendered with the defined material. - * @defaultValue `null` - */ - overrideMaterial: Material | null; - - /** - * Defines the background of the scene. - * @remarks Valid inputs are: - * - A {@link THREE.Color | Color} for defining a uniform colored background. - * - A {@link THREE.Texture | Texture} for defining a (flat) textured background. - * - Texture cubes ({@link THREE.CubeTexture | CubeTexture}) or equirectangular textures for defining a skybox. - * @defaultValue `null` - */ - background: Color | Texture | CubeTexture | null; - - /** - * The rotation of the background in radians. Only influences environment maps assigned to {@link .background}. - * Default is `(0,0,0)`. - */ - backgroundRotation: Euler; - - /** - * Sets the environment map for all physical materials in the scene. - * However, it's not possible to overwrite an existing texture assigned to {@link THREE.MeshStandardMaterial.envMap | MeshStandardMaterial.envMap}. - * @defaultValue `null` - */ - environment: Texture | null; - - /** - * Attenuates the color of the environment. Only influences environment maps assigned to {@link Scene.environment}. - * @default 1 - */ - environmentIntensity: number; - - /** - * The rotation of the environment map in radians. Only influences physical materials in the scene when - * {@link .environment} is used. Default is `(0,0,0)`. - */ - environmentRotation: Euler; - - /** - * Convert the {@link Scene} to three.js {@link https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 | JSON Object/Scene format}. - * @param meta Object containing metadata such as textures or images for the scene. - */ - toJSON(meta?: JSONMeta): SceneJSON; -} diff --git a/src-testing/src/textures/CanvasTexture.d.ts b/src-testing/src/textures/CanvasTexture.d.ts deleted file mode 100644 index 6445338fa..000000000 --- a/src-testing/src/textures/CanvasTexture.d.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { - MagnificationTextureFilter, - Mapping, - MinificationTextureFilter, - PixelFormat, - TextureDataType, - Wrapping, -} from "../constants.js"; -import { OffscreenCanvas, Texture } from "./Texture.js"; - -/** - * Creates a texture from a {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas | canvas element}. - * @remarks - * This is almost the same as the base {@link Texture | Texture} class, - * except that it sets {@link Texture.needsUpdate | needsUpdate} to `true` immediately. - * @see {@link THREE.Texture | Texture} - * @see {@link https://threejs.org/docs/index.html#api/en/textures/CanvasTexture | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/textures/CanvasTexture.js | Source} - */ -export class CanvasTexture extends Texture { - /** - * This creates a new {@link THREE.CanvasTexture | CanvasTexture} object. - * @param canvas The HTML canvas element from which to load the texture. - * @param mapping See {@link Texture.mapping | .mapping}. Default {@link THREE.Texture.DEFAULT_MAPPING} - * @param wrapS See {@link Texture.wrapS | .wrapS}. Default {@link THREE.ClampToEdgeWrapping} - * @param wrapT See {@link Texture.wrapT | .wrapT}. Default {@link THREE.ClampToEdgeWrapping} - * @param magFilter See {@link Texture.magFilter | .magFilter}. Default {@link THREE.LinearFilter} - * @param minFilter See {@link Texture.minFilter | .minFilter}. Default {@link THREE.LinearMipmapLinearFilter} - * @param format See {@link Texture.format | .format}. Default {@link THREE.RGBAFormat} - * @param type See {@link Texture.type | .type}. Default {@link THREE.UnsignedByteType} - * @param anisotropy See {@link Texture.anisotropy | .anisotropy}. Default {@link THREE.Texture.DEFAULT_ANISOTROPY} - */ - constructor( - canvas: TexImageSource | OffscreenCanvas, - mapping?: Mapping, - wrapS?: Wrapping, - wrapT?: Wrapping, - magFilter?: MagnificationTextureFilter, - minFilter?: MinificationTextureFilter, - format?: PixelFormat, - type?: TextureDataType, - anisotropy?: number, - ); - - /** - * Read-only flag to check if a given object is of type {@link CanvasTexture}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isCanvasTexture: true; -} diff --git a/src-testing/src/textures/CompressedArrayTexture.d.ts b/src-testing/src/textures/CompressedArrayTexture.d.ts deleted file mode 100644 index e46c3d478..000000000 --- a/src-testing/src/textures/CompressedArrayTexture.d.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { CompressedPixelFormat, TextureDataType, Wrapping } from "../constants.js"; -import { CompressedTexture, CompressedTextureMipmap } from "./CompressedTexture.js"; - -/** - * Creates an texture 2D array based on data in compressed form, for example from a - * {@link https://en.wikipedia.org/wiki/DirectDraw_Surface | DDS} file. - * @remarks For use with the {@link THREE.CompressedTextureLoader | CompressedTextureLoader}. - * @see {@link https://threejs.org/docs/index.html#api/en/textures/CompressedArrayTexture | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/textures/CompressedArrayTexture.js | Source} - */ -export class CompressedArrayTexture extends CompressedTexture { - /** - * Read-only flag to check if a given object is of type {@link CompressedArrayTexture}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isCompressedArrayTexture: true; - - /** - * Overridden with a object containing width and height. - * @override - */ - get image(): { width: number; height: number; depth: number }; - set image(value: { width: number; height: number; depth: number }); - - /** - * This defines how the texture is wrapped in the depth direction. - * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} - * @defaultValue {@link THREE.ClampToEdgeWrapping} - */ - wrapR: Wrapping; - - /** - * A set of all layers which need to be updated in the texture. See {@link CompressedArrayTexture.addLayerUpdate}. - */ - layerUpdates: Set; - - /** - * Create a new instance of {@link CompressedArrayTexture} - * @param mipmaps The mipmaps array should contain objects with data, width and height. The mipmaps should be of the - * correct format and type. - * @param width The width of the biggest mipmap. - * @param height The height of the biggest mipmap. - * @param depth The number of layers of the 2D array texture - * @param format The format used in the mipmaps. See {@link THREE.CompressedPixelFormat}. - * @param type See {@link Texture.type | .type}. Default {@link THREE.UnsignedByteType} - */ - constructor( - mipmaps: CompressedTextureMipmap[], - width: number, - height: number, - depth: number, - format: CompressedPixelFormat, - type?: TextureDataType, - ); - - /** - * Describes that a specific layer of the texture needs to be updated. Normally when {@link Texture.needsUpdate} is - * set to true, the entire compressed texture array is sent to the GPU. Marking specific layers will only transmit - * subsets of all mipmaps associated with a specific depth in the array which is often much more performant. - */ - addLayerUpdate(layerIndex: number): void; - - /** - * Resets the layer updates registry. See {@link CompressedArrayTexture.addLayerUpdate}. - */ - clearLayoutUpdates(): void; -} diff --git a/src-testing/src/textures/CompressedCubeTexture.d.ts b/src-testing/src/textures/CompressedCubeTexture.d.ts deleted file mode 100644 index 9c72145a0..000000000 --- a/src-testing/src/textures/CompressedCubeTexture.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { CompressedPixelFormat, TextureDataType } from "../constants.js"; -import { CompressedTexture } from "./CompressedTexture.js"; - -export class CompressedCubeTexture extends CompressedTexture { - readonly isCompressedCubeTexture: true; - readonly isCubeTexture: true; - - constructor( - images: Array<{ width: number; height: number }>, - format?: CompressedPixelFormat, - type?: TextureDataType, - ); -} diff --git a/src-testing/src/textures/CompressedTexture.d.ts b/src-testing/src/textures/CompressedTexture.d.ts deleted file mode 100644 index 33ec5b17d..000000000 --- a/src-testing/src/textures/CompressedTexture.d.ts +++ /dev/null @@ -1,94 +0,0 @@ -import { - CompressedPixelFormat, - MagnificationTextureFilter, - Mapping, - MinificationTextureFilter, - TextureDataType, - Wrapping, -} from "../constants.js"; -import { TypedArray } from "../core/BufferAttribute.js"; -import { Texture } from "./Texture.js"; - -export interface CompressedTextureMipmap { - data: TypedArray; - width: number; - height: number; -} - -/** - * Creates a texture based on data in compressed form, for example from a {@link https://en.wikipedia.org/wiki/DirectDraw_Surface | DDS} file. - * @remarks For use with the {@link THREE.CompressedTextureLoader | CompressedTextureLoader}. - * @see {@link https://threejs.org/docs/index.html#api/en/textures/CompressedTexture | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/textures/CompressedTexture.js | Source} - */ -export class CompressedTexture extends Texture { - /** - * This creates a new {@link THREE.CompressedTexture | CompressedTexture} object. - * @param mipmaps The mipmaps array should contain objects with data, width and height. The mipmaps should be of the - * correct format and type. - * @param width The width of the biggest mipmap. - * @param height The height of the biggest mipmap. - * @param format The format used in the mipmaps. See {@link THREE.CompressedPixelFormat}. - * @param type See {@link Texture.type | .type}. Default {@link THREE.UnsignedByteType} - * @param mapping See {@link Texture.mapping | .mapping}. Default {@link THREE.Texture.DEFAULT_MAPPING} - * @param wrapS See {@link Texture.wrapS | .wrapS}. Default {@link THREE.ClampToEdgeWrapping} - * @param wrapT See {@link Texture.wrapT | .wrapT}. Default {@link THREE.ClampToEdgeWrapping} - * @param magFilter See {@link Texture.magFilter | .magFilter}. Default {@link THREE.LinearFilter} - * @param minFilter See {@link Texture.minFilter | .minFilter}. Default {@link THREE.LinearMipmapLinearFilter} - * @param anisotropy See {@link Texture.anisotropy | .anisotropy}. Default {@link THREE.Texture.DEFAULT_ANISOTROPY} - * @param colorSpace See {@link Texture.colorSpace .colorSpace}. Default {@link NoColorSpace} - */ - constructor( - mipmaps?: CompressedTextureMipmap[], - width?: number, - height?: number, - format?: CompressedPixelFormat, - type?: TextureDataType, - mapping?: Mapping, - wrapS?: Wrapping, - wrapT?: Wrapping, - magFilter?: MagnificationTextureFilter, - minFilter?: MinificationTextureFilter, - anisotropy?: number, - colorSpace?: string, - ); - - /** - * Read-only flag to check if a given object is of type {@link CompressedTexture}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isCompressedTexture: true; - - /** - * Overridden with a object containing width and height. - * @override - */ - get image(): { width: number; height: number }; - set image(value: { width: number; height: number }); - - /** - * The mipmaps array should contain objects with data, width and height. The mipmaps should be of the correct - * format and type. - */ - mipmaps: CompressedTextureMipmap[] | undefined; - - /** - * @override - * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} - * @see {@link THREE.CompressedPixelFormat} - */ - format: CompressedPixelFormat; - - /** - * @override No flipping for cube textures. (also flipping doesn't work for compressed textures) - * @defaultValue `false` - */ - flipY: boolean; - - /** - * @override Can't generate mipmaps for compressed textures. mips must be embedded in DDS files - * @defaultValue `false` - */ - generateMipmaps: boolean; -} diff --git a/src-testing/src/textures/CubeTexture.d.ts b/src-testing/src/textures/CubeTexture.d.ts deleted file mode 100644 index f5808aaf9..000000000 --- a/src-testing/src/textures/CubeTexture.d.ts +++ /dev/null @@ -1,89 +0,0 @@ -import { - CubeTextureMapping, - MagnificationTextureFilter, - MinificationTextureFilter, - PixelFormat, - TextureDataType, - Wrapping, -} from "../constants.js"; -import { Texture } from "./Texture.js"; - -/** - * Creates a cube texture made up of six images. - * @remarks - * {@link CubeTexture} is almost equivalent in functionality and usage to {@link Texture}. - * The only differences are that the images are an array of _6_ images as opposed to a single image, - * and the mapping options are {@link THREE.CubeReflectionMapping} (default) or {@link THREE.CubeRefractionMapping} - * @example - * ```typescript - * const loader = new THREE.CubeTextureLoader(); - * loader.setPath('textures/cube/pisa/'); - * const textureCube = loader.load(['px.png', 'nx.png', 'py.png', 'ny.png', 'pz.png', 'nz.png']); - * const material = new THREE.MeshBasicMaterial({ - * color: 0xffffff, - * envMap: textureCube - * }); - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/textures/CubeTexture | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/textures/CubeTexture.js | Source} - */ -export class CubeTexture extends Texture { - /** - * This creates a new {@link THREE.CubeTexture | CubeTexture} object. - * @param images - * @param mapping See {@link CubeTexture.mapping | .mapping}. Default {@link THREE.CubeReflectionMapping} - * @param wrapS See {@link Texture.wrapS | .wrapS}. Default {@link THREE.ClampToEdgeWrapping} - * @param wrapT See {@link Texture.wrapT | .wrapT}. Default {@link THREE.ClampToEdgeWrapping} - * @param magFilter See {@link Texture.magFilter | .magFilter}. Default {@link THREE.LinearFilter} - * @param minFilter See {@link Texture.minFilter | .minFilter}. Default {@link THREE.LinearMipmapLinearFilter} - * @param format See {@link Texture.format | .format}. Default {@link THREE.RGBAFormat} - * @param type See {@link Texture.type | .type}. Default {@link THREE.UnsignedByteType} - * @param anisotropy See {@link Texture.anisotropy | .anisotropy}. Default {@link THREE.Texture.DEFAULT_ANISOTROPY} - * @param colorSpace See {@link Texture.colorSpace | .colorSpace}. Default {@link NoColorSpace} - */ - constructor( - images?: any[], // HTMLImageElement or HTMLCanvasElement - mapping?: CubeTextureMapping, - wrapS?: Wrapping, - wrapT?: Wrapping, - magFilter?: MagnificationTextureFilter, - minFilter?: MinificationTextureFilter, - format?: PixelFormat, - type?: TextureDataType, - anisotropy?: number, - colorSpace?: string, - ); - - /** - * Read-only flag to check if a given object is of type {@link CubeTexture}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isCubeTexture: true; - - /** - * An image object, typically created using the {@link THREE.CubeTextureLoader.load | CubeTextureLoader.load()} method. - * @see {@link Texture.image} - */ - get image(): any; - set image(data: any); - - /** - * An image object, typically created using the {@link THREE.CubeTextureLoader.load | CubeTextureLoader.load()} method. - * @see {@link Texture.image} - */ - get images(): any; - set images(data: any); - - /** - * @inheritDoc - * @defaultValue {@link THREE.CubeReflectionMapping} - */ - mapping: CubeTextureMapping; - - /** - * @inheritDoc - * @defaultValue `false` - */ - flipY: boolean; -} diff --git a/src-testing/src/textures/Data3DTexture.d.ts b/src-testing/src/textures/Data3DTexture.d.ts deleted file mode 100644 index 9e5986eed..000000000 --- a/src-testing/src/textures/Data3DTexture.d.ts +++ /dev/null @@ -1,96 +0,0 @@ -import { MagnificationTextureFilter, MinificationTextureFilter, Wrapping } from "../constants.js"; -import { Texture } from "./Texture.js"; -import { Texture3DImageData } from "./types.js"; - -/** - * Creates a three-dimensional texture from raw data, with parameters to divide it into width, height, and depth - * @example - * ```typescript - * This creates a[name] with repeating data, 0 to 255 - * // create a buffer with some data - * const sizeX = 64; - * const sizeY = 64; - * const sizeZ = 64; - * const data = new Uint8Array(sizeX * sizeY * sizeZ); - * let i = 0; - * for (let z = 0; z & lt; sizeZ; z++) { - * for (let y = 0; y & lt; sizeY; y++) { - * for (let x = 0; x & lt; sizeX; x++) { - * data[i] = i % 256; - * i++; - * } - * } - * } - * // use the buffer to create the texture - * const texture = new THREE.Data3DTexture(data, sizeX, sizeY, sizeZ); - * texture.needsUpdate = true; - * ``` - * @see Example: {@link https://threejs.org/examples/#webgl2_materials_texture3d | WebGL2 / materials / texture3d} - * @see Example: {@link https://threejs.org/examples/#webgl2_materials_texture3d_partialupdate | WebGL2 / materials / texture3d / partialupdate} - * @see Example: {@link https://threejs.org/examples/#webgl2_volume_cloud | WebGL2 / volume / cloud} - * @see Example: {@link https://threejs.org/examples/#webgl2_volume_perlin | WebGL2 / volume / perlin} - * @see {@link https://threejs.org/docs/index.html#api/en/textures/Data3DTexture | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/textures/Data3DTexture.js | Source} - */ -export class Data3DTexture extends Texture { - /** - * Create a new instance of {@link Data3DTexture} - * @param data {@link https://developer.mozilla.org/en-US/docs/Web/API/ArrayBufferView | ArrayBufferView} of the texture. Default `null`. - * @param width Width of the texture. Default `1`. - * @param height Height of the texture. Default `1`. - * @param depth Depth of the texture. Default `1`. - */ - constructor(data?: BufferSource | null, width?: number, height?: number, depth?: number); - - /** - * Read-only flag to check if a given object is of type {@link Data3DTexture}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isData3DTexture: true; - - /** - * Overridden with a record type holding data, width and height and depth. - * @override - */ - get image(): Texture3DImageData; - set image(data: Texture3DImageData); - - /** - * @override - * @defaultValue {@link THREE.NearestFilter} - */ - magFilter: MagnificationTextureFilter; - - /** - * @override - * @defaultValue {@link THREE.NearestFilter} - */ - minFilter: MinificationTextureFilter; - - /** - * @override - * @defaultValue {@link THREE.ClampToEdgeWrapping} - */ - wrapR: Wrapping; - - /** - * @override - * @defaultValue `false` - */ - flipY: boolean; - - /** - * @override - * @defaultValue `false` - */ - generateMipmaps: boolean; - - /** - * @override - * @defaultValue `1` - */ - unpackAlignment: number; -} - -export {}; diff --git a/src-testing/src/textures/DataArrayTexture.d.ts b/src-testing/src/textures/DataArrayTexture.d.ts deleted file mode 100644 index d3a82c1e8..000000000 --- a/src-testing/src/textures/DataArrayTexture.d.ts +++ /dev/null @@ -1,123 +0,0 @@ -import { MagnificationTextureFilter, MinificationTextureFilter } from "../constants.js"; -import { Texture } from "./Texture.js"; -import { Texture3DImageData } from "./types.js"; - -/** - * Creates an array of textures directly from raw data, width and height and depth - * @example - * ```typescript - * This creates a[name] where each texture has a different color. - * // create a buffer with color data - * const width = 512; - * const height = 512; - * const depth = 100; - * const size = width * height; - * const data = new Uint8Array(4 * size * depth); - * for (let i = 0; i & lt; depth; i++) { - * const color = new THREE.Color(Math.random(), Math.random(), Math.random()); - * const r = Math.floor(color.r * 255); - * const g = Math.floor(color.g * 255); - * const b = Math.floor(color.b * 255); - * for (let j = 0; j & lt; size; j++) { - * const stride = (i * size + j) * 4; - * data[stride] = r; - * data[stride + 1] = g; - * data[stride + 2] = b; - * data[stride + 3] = 255; - * } - * } - * // used the buffer to create a [name] - * const texture = new THREE.DataArrayTexture(data, width, height, depth); - * texture.needsUpdate = true; - * ``` - * @see Example: {@link https://threejs.org/examples/#webgl2_materials_texture2darray | WebGL2 / materials / texture2darray} - * @see Example: {@link https://threejs.org/examples/#webgl2_rendertarget_texture2darray | WebGL2 / rendertarget / texture2darray} - * @see {@link https://threejs.org/docs/index.html#api/en/textures/DataArrayTexture | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/textures/DataArrayTexture.js | Source} - */ -export class DataArrayTexture extends Texture { - /** - * Read-only flag to check if a given object is of type {@link DataArrayTexture}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isDataArrayTexture: true; - - /** - * Overridden with a record type holding data, width and height and depth. - * @override - */ - get image(): Texture3DImageData; - set image(data: Texture3DImageData); - - /** - * @override - * @defaultValue {@link THREE.NearestFilter} - */ - magFilter: MagnificationTextureFilter; - - /** - * @override - * @defaultValue {@link THREE.NearestFilter} - */ - minFilter: MinificationTextureFilter; - - /** - * @override - * @defaultValue {@link THREE.ClampToEdgeWrapping} - */ - wrapR: boolean; - - /** - * @override - * @defaultValue `false` - */ - generateMipmaps: boolean; - - /** - * @override - * @defaultValue `false` - */ - flipY: boolean; - - /** - * @override - * @defaultValue `1` - */ - unpackAlignment: number; - - /** - * A set of all layers which need to be updated in the texture. See {@link DataArrayTexture.addLayerUpdate}. - */ - layerUpdates: Set; - - /** - * This creates a new {@link THREE.DataArrayTexture | DataArrayTexture} object. - * @remarks The interpretation of the data depends on {@link format} and {@link type}. - * @remarks If the {@link type} is {@link THREE.UnsignedByteType}, a {@link Uint8Array} will be useful for addressing the texel data - * @remarks If the {@link format} is {@link THREE.RGBAFormat}, data needs four values for one texel; Red, Green, Blue and Alpha (typically the opacity). - * @remarks For the packed {@link type | types}, {@link THREE.UnsignedShort4444Type} and {@link THREE.UnsignedShort5551Type} - * all color components of one texel can be addressed as bitfields within an integer element of a {@link Uint16Array}. - * @remarks In order to use the {@link type | types} {@link THREE.FloatType} and {@link THREE.HalfFloatType}, - * the WebGL implementation must support the respective extensions _OES_texture_float_ and _OES_texture_half_float_ - * @remarks In order to use {@link THREE.LinearFilter} for component-wise, bilinear interpolation of the texels based on these types, - * the WebGL extensions _OES_texture_float_linear_ or _OES_texture_half_float_linear_ must also be present. - * @param data {@link https://developer.mozilla.org/en-US/docs/Web/API/ArrayBufferView | ArrayBufferView} of the texture. Default `null`. - * @param width Width of the texture. Default `1`. - * @param height Height of the texture. Default `1`. - * @param depth Depth of the texture. Default `1`. - */ - constructor(data?: BufferSource | null, width?: number, height?: number, depth?: number); - - /** - * Describes that a specific layer of the texture needs to be updated. Normally when {@link Texture.needsUpdate} is - * set to true, the entire compressed texture array is sent to the GPU. Marking specific layers will only transmit - * subsets of all mipmaps associated with a specific depth in the array which is often much more performant. - */ - addLayerUpdate(layerIndex: number): void; - - /** - * Resets the layer updates registry. See {@link DataArrayTexture.addLayerUpdate}. - */ - clearLayoutUpdates(): void; -} diff --git a/src-testing/src/textures/DataTexture.d.ts b/src-testing/src/textures/DataTexture.d.ts deleted file mode 100644 index 605450990..000000000 --- a/src-testing/src/textures/DataTexture.d.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { - MagnificationTextureFilter, - Mapping, - MinificationTextureFilter, - PixelFormat, - TextureDataType, - Wrapping, -} from "../constants.js"; -import { Texture } from "./Texture.js"; -import { TextureImageData } from "./types.js"; - -/** - * Creates a texture directly from raw data, width and height. - * @example - * ```typescript - * // create a buffer with color data - * const width = 512; - * const height = 512; - * const size = width * height; - * const data = new Uint8Array(4 * size); - * const color = new THREE.Color(0xffffff); - * const r = Math.floor(color.r * 255); - * const g = Math.floor(color.g * 255); - * const b = Math.floor(color.b * 255); - * for (let i = 0; i & lt; size; i++) { - * const stride = i * 4; - * data[stride] = r; - * data[stride + 1] = g; - * data[stride + 2] = b; - * data[stride + 3] = 255; - * } - * // used the buffer to create a [name] - * const texture = new THREE.DataTexture(data, width, height); - * texture.needsUpdate = true; - * ``` - * @see {@link https://threejs.org/docs/index.html#api/en/textures/DataTexture | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/textures/DataTexture.js | Source} - */ -export class DataTexture extends Texture { - /** - * @param data {@link https://developer.mozilla.org/en-US/docs/Web/API/ArrayBufferView | ArrayBufferView} of the texture. Default `null`. - * @param width Width of the texture. Default `1`. - * @param height Height of the texture. Default `1`. - * @param format See {@link Texture.format | .format}. Default {@link THREE.RGBAFormat} - * @param type See {@link Texture.type | .type}. Default {@link THREE.UnsignedByteType} - * @param mapping See {@link Texture.mapping | .mapping}. Default {@link THREE.Texture.DEFAULT_MAPPING} - * @param wrapS See {@link Texture.wrapS | .wrapS}. Default {@link THREE.ClampToEdgeWrapping} - * @param wrapT See {@link Texture.wrapT | .wrapT}. Default {@link THREE.ClampToEdgeWrapping} - * @param magFilter See {@link Texture.magFilter | .magFilter}. Default {@link THREE.NearestFilter} - * @param minFilter See {@link Texture.minFilter | .minFilter}. Default {@link THREE.NearestFilter} - * @param anisotropy See {@link Texture.anisotropy | .anisotropy}. Default {@link THREE.Texture.DEFAULT_ANISOTROPY} - * @param colorSpace See {@link Texture.colorSpace | .colorSpace}. Default {@link NoColorSpace} - */ - constructor( - data?: BufferSource | null, - width?: number, - height?: number, - format?: PixelFormat, - type?: TextureDataType, - mapping?: Mapping, - wrapS?: Wrapping, - wrapT?: Wrapping, - magFilter?: MagnificationTextureFilter, - minFilter?: MinificationTextureFilter, - anisotropy?: number, - colorSpace?: string, - ); - - /** - * Read-only flag to check if a given object is of type {@link DataTexture}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isDataTexture: true; - - /** - * Overridden with a record type holding data, width and height and depth. - * @override - */ - get image(): TextureImageData; - set image(value: TextureImageData); - - /** - * @override - * @defaultValue {@link THREE.NearestFilter} - */ - magFilter: MagnificationTextureFilter; - - /** - * @override - * @defaultValue {@link THREE.NearestFilter} - */ - minFilter: MinificationTextureFilter; - - /** - * @override - * @defaultValue `false` - */ - flipY: boolean; - - /** - * @override - * @defaultValue `false` - */ - generateMipmaps: boolean; - - /** - * @override - * @defaultValue `1` - */ - unpackAlignment: number; -} diff --git a/src-testing/src/textures/DepthTexture.d.ts b/src-testing/src/textures/DepthTexture.d.ts deleted file mode 100644 index f524e91cc..000000000 --- a/src-testing/src/textures/DepthTexture.d.ts +++ /dev/null @@ -1,104 +0,0 @@ -import { - DepthTexturePixelFormat, - MagnificationTextureFilter, - Mapping, - MinificationTextureFilter, - TextureComparisonFunction, - TextureDataType, - Wrapping, -} from "../constants.js"; -import { Texture } from "./Texture.js"; - -/** - * This class can be used to automatically save the depth information of a rendering into a texture - * @see Example: {@link https://threejs.org/examples/#webgl_depth_texture | depth / texture} - * @see {@link https://threejs.org/docs/index.html#api/en/textures/DepthTexture | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/textures/DepthTexture.js | Source} - */ -export class DepthTexture extends Texture { - /** - * Create a new instance of {@link DepthTexture} - * @param width Width of the texture. - * @param height Height of the texture. - * @param type See {@link Texture.type | .type}. Default {@link THREE.UnsignedByteType} or {@link THREE.UnsignedInt248Type} - * @param mapping See {@link Texture.mapping | .mapping}. Default {@link THREE.Texture.DEFAULT_MAPPING} - * @param wrapS See {@link Texture.wrapS | .wrapS}. Default {@link THREE.ClampToEdgeWrapping} - * @param wrapT See {@link Texture.wrapT | .wrapT}. Default {@link THREE.ClampToEdgeWrapping} - * @param magFilter See {@link Texture.magFilter | .magFilter}. Default {@link THREE.NearestFilter} - * @param minFilter See {@link Texture.minFilter | .minFilter}. Default {@link THREE.NearestFilter} - * @param anisotropy See {@link Texture.anisotropy | .anisotropy}. Default {@link THREE.Texture.DEFAULT_ANISOTROPY} - * @param format See {@link DepthTexture.format | .format}. Default {@link THREE.DepthFormat} - */ - constructor( - width: number, - height: number, - type?: TextureDataType, - mapping?: Mapping, - wrapS?: Wrapping, - wrapT?: Wrapping, - magFilter?: MagnificationTextureFilter, - minFilter?: MinificationTextureFilter, - anisotropy?: number, - format?: DepthTexturePixelFormat, - ); - - /** - * Read-only flag to check if a given object is of type {@link DepthTexture}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isDepthTexture: true; - - /** - * Overridden with a record type holding width and height. - * @override - */ - get image(): { width: number; height: number }; - set image(value: { width: number; height: number }); - - /** - * @override - * @defaultValue `false` - */ - flipY: boolean; - - /** - * @override - * @defaultValue {@link THREE.NearestFilter} - */ - magFilter: MagnificationTextureFilter; - - /** - * @override - * @defaultValue {@link THREE.NearestFilter} - */ - minFilter: MinificationTextureFilter; - - /** - * @override Depth textures do not use mipmaps. - * @defaultValue `false` - */ - generateMipmaps: boolean; - - /** - * @override - * @see {@link Texture.format | Texture.format} - * @defaultValue {@link THREE.DepthFormat}. - */ - format: DepthTexturePixelFormat; - - /** - * @override - * @defaultValue {@link THREE.UnsignedByteType} when {@link format | .format} === {@link THREE.DepthFormat} - * @defaultValue {@link THREE.UnsignedInt248Type} when {@link format | .format} === {@link THREE.DepthStencilFormat} - */ - type: TextureDataType; - - /** - * This is used to define the comparison function used when comparing texels in the depth texture to the value in - * the depth buffer. Default is `null` which means comparison is disabled. - * - * See {@link THREE.TextureComparisonFunction} for functions. - */ - compareFunction: TextureComparisonFunction | null; -} diff --git a/src-testing/src/textures/FramebufferTexture.d.ts b/src-testing/src/textures/FramebufferTexture.d.ts deleted file mode 100644 index ad54c5175..000000000 --- a/src-testing/src/textures/FramebufferTexture.d.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { MagnificationTextureFilter, MinificationTextureFilter } from "../constants.js"; -import { Texture } from "./Texture.js"; - -/** - * This class can only be used in combination with {@link THREE.WebGLRenderer.copyFramebufferToTexture | WebGLRenderer.copyFramebufferToTexture()}. - * @example - * ```typescript - * const pixelRatio = window.devicePixelRatio; - * const textureSize = 128 * pixelRatio; - * - * // instantiate a framebuffer texture - * const frameTexture = new FramebufferTexture( textureSize, textureSize, RGBAFormat ); - * - * // calculate start position for copying part of the frame data - * const vector = new Vector2(); - * vector.x = ( window.innerWidth * pixelRatio / 2 ) - ( textureSize / 2 ); - * vector.y = ( window.innerHeight * pixelRatio / 2 ) - ( textureSize / 2 ); - * - * // render the scene - * renderer.clear(); - * renderer.render( scene, camera ); - * - * // copy part of the rendered frame into the framebuffer texture - * renderer.copyFramebufferToTexture( frameTexture, vector ); - * ``` - * @see Example: {@link https://threejs.org/examples/#webgl_framebuffer_texture | webgl_framebuffer_texture} - * @see {@link https://threejs.org/docs/index.html#api/en/textures/FramebufferTexture | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/textures/FramebufferTexture.js | Source} - */ -export class FramebufferTexture extends Texture { - /** - * Create a new instance of {@link FramebufferTexture} - * @param width The width of the texture. - * @param height The height of the texture. - */ - constructor(width: number, height: number); - - /** - * Read-only flag to check if a given object is of type {@link FramebufferTexture}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isFramebufferTexture: true; - - /** - * @override - * @defaultValue {@link THREE.NearestFilter} - */ - magFilter: MagnificationTextureFilter; - - /** - * @override - * @defaultValue {@link THREE.NearestFilter} - */ - minFilter: MinificationTextureFilter; - - /** - * @override - * @defaultValue `false` - */ - generateMipmaps: boolean; -} diff --git a/src-testing/src/textures/Source.d.ts b/src-testing/src/textures/Source.d.ts deleted file mode 100644 index 404d1d8a1..000000000 --- a/src-testing/src/textures/Source.d.ts +++ /dev/null @@ -1,75 +0,0 @@ -export type SerializedImage = - | string - | { - data: number[]; - width: number; - height: number; - type: string; - }; - -export class SourceJSON { - uuid: string; - url: SerializedImage | SerializedImage[]; -} - -/** - * Represents the data {@link Source} of a texture. - * @see {@link https://threejs.org/docs/index.html#api/en/textures/Source | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/textures/Source.js | Source} - */ -export class Source { - /** - * Create a new instance of {@link Source} - * @param data The data definition of a texture. Default `null` - */ - constructor(data: any); - - /** - * Flag to check if a given object is of type {@link Source}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isSource: true; - - readonly id: number; - - /** - * The actual data of a texture. - * @remarks The type of this property depends on the texture that uses this instance. - */ - data: any; - - /** - * This property is only relevant when {@link .needsUpdate} is set to `true` and provides more control on how - * texture data should be processed. - * When `dataReady` is set to `false`, the engine performs the memory allocation (if necessary) but does not - * transfer the data into the GPU memory. - * @default true - */ - dataReady: boolean; - - /** - * When the property is set to `true`, the engine allocates the memory for the texture (if necessary) and triggers - * the actual texture upload to the GPU next time the source is used. - */ - set needsUpdate(value: boolean); - - /** - * {@link http://en.wikipedia.org/wiki/Universally_unique_identifier | UUID} of this object instance. - * @remarks This gets automatically assigned and shouldn't be edited. - */ - uuid: string; - - /** - * This starts at `0` and counts how many times {@link needsUpdate | .needsUpdate} is set to `true`. - * @remarks Expects a `Integer` - * @defaultValue `0` - */ - version: number; - - /** - * Convert the data {@link Source} to three.js {@link https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 | JSON Object/Scene format}. - * @param meta Optional object containing metadata. - */ - toJSON(meta?: string | {}): SourceJSON; -} diff --git a/src-testing/src/textures/Texture.d.ts b/src-testing/src/textures/Texture.d.ts deleted file mode 100644 index 2dc33c5d1..000000000 --- a/src-testing/src/textures/Texture.d.ts +++ /dev/null @@ -1,476 +0,0 @@ -import { - AnyMapping, - AnyPixelFormat, - MagnificationTextureFilter, - Mapping, - MinificationTextureFilter, - PixelFormat, - PixelFormatGPU, - TextureDataType, - Wrapping, -} from "../constants.js"; -import { EventDispatcher } from "../core/EventDispatcher.js"; -import { Matrix3 } from "../math/Matrix3.js"; -import { Vector2 } from "../math/Vector2.js"; -import { CompressedTextureMipmap } from "./CompressedTexture.js"; -import { CubeTexture } from "./CubeTexture.js"; -import { Source } from "./Source.js"; - -export interface TextureJSON { - metadata: { version: number; type: string; generator: string }; - - uuid: string; - name: string; - - image: string; - - mapping: AnyMapping; - channel: number; - - repeat: [x: number, y: number]; - offset: [x: number, y: number]; - center: [x: number, y: number]; - rotation: number; - - wrap: [wrapS: number, wrapT: number]; - - format: AnyPixelFormat; - internalFormat: PixelFormatGPU | null; - type: TextureDataType; - colorSpace: string; - - minFilter: MinificationTextureFilter; - magFilter: MagnificationTextureFilter; - anisotropy: number; - - flipY: boolean; - - generateMipmaps: boolean; - premultiplyAlpha: boolean; - unpackAlignment: number; - - userData?: Record; -} - -/** Shim for OffscreenCanvas. */ -// eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface OffscreenCanvas extends EventTarget {} - -/** - * Create a {@link Texture} to apply to a surface or as a reflection or refraction map. - * @remarks - * After the initial use of a texture, its **dimensions**, {@link format}, and {@link type} cannot be changed - * Instead, call {@link dispose | .dispose()} on the {@link Texture} and instantiate a new {@link Texture}. - * @example - * ```typescript - * // load a texture, set wrap mode to repeat - * const texture = new THREE.TextureLoader().load("textures/water.jpg"); - * texture.wrapS = THREE.RepeatWrapping; - * texture.wrapT = THREE.RepeatWrapping; - * texture.repeat.set(4, 4); - * ``` - * @see Example: {@link https://threejs.org/examples/#webgl_materials_texture_filters | webgl materials texture filters} - * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} - * @see {@link https://threejs.org/docs/index.html#api/en/textures/Texture | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/Textures/Texture.js | Source} - */ -export class Texture extends EventDispatcher<{ dispose: {} }> { - /** - * This creates a new {@link THREE.Texture | Texture} object. - * @param image See {@link Texture.image | .image}. Default {@link THREE.Texture.DEFAULT_IMAGE} - * @param mapping See {@link Texture.mapping | .mapping}. Default {@link THREE.Texture.DEFAULT_MAPPING} - * @param wrapS See {@link Texture.wrapS | .wrapS}. Default {@link THREE.ClampToEdgeWrapping} - * @param wrapT See {@link Texture.wrapT | .wrapT}. Default {@link THREE.ClampToEdgeWrapping} - * @param magFilter See {@link Texture.magFilter | .magFilter}. Default {@link THREE.LinearFilter} - * @param minFilter See {@link Texture.minFilter | .minFilter}. Default {@link THREE.LinearMipmapLinearFilter} - * @param format See {@link Texture.format | .format}. Default {@link THREE.RGBAFormat} - * @param type See {@link Texture.type | .type}. Default {@link THREE.UnsignedByteType} - * @param anisotropy See {@link Texture.anisotropy | .anisotropy}. Default {@link THREE.Texture.DEFAULT_ANISOTROPY} - * @param colorSpace See {@link Texture.colorSpace | .colorSpace}. Default {@link THREE.NoColorSpace} - */ - constructor( - image?: TexImageSource | OffscreenCanvas, - mapping?: Mapping, - wrapS?: Wrapping, - wrapT?: Wrapping, - magFilter?: MagnificationTextureFilter, - minFilter?: MinificationTextureFilter, - format?: PixelFormat, - type?: TextureDataType, - anisotropy?: number, - colorSpace?: string, - ); - - /** - * @deprecated - */ - constructor( - image: TexImageSource | OffscreenCanvas, - mapping: Mapping, - wrapS: Wrapping, - wrapT: Wrapping, - magFilter: MagnificationTextureFilter, - minFilter: MinificationTextureFilter, - format: PixelFormat, - type: TextureDataType, - anisotropy: number, - ); - - /** - * Read-only flag to check if a given object is of type {@link Texture}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isTexture: true; - - /** - * Unique number for this {@link Texture} instance. - * @remarks Note that ids are assigned in chronological order: 1, 2, 3, ..., incrementing by one for each new object. - * @remarks Expects a `Integer` - */ - readonly id: number; - - /** - * {@link http://en.wikipedia.org/wiki/Universally_unique_identifier | UUID} of this object instance. - * @remarks This gets automatically assigned and shouldn't be edited. - */ - uuid: string; - - /** - * Optional name of the object - * @remarks _(doesn't need to be unique)_. - * @defaultValue `""` - */ - name: string; - - /** - * The data definition of a texture. A reference to the data source can be shared across textures. - * This is often useful in context of spritesheets where multiple textures render the same data - * but with different {@link Texture} transformations. - */ - source: Source; - - /** - * An image object, typically created using the {@link THREE.TextureLoader.load | TextureLoader.load()} method. - * @remarks This can be any image (e.g., PNG, JPG, GIF, DDS) or video (e.g., MP4, OGG/OGV) type supported by three.js. - * @remarks To use video as a {@link Texture} you need to have a playing HTML5 video element as a source - * for your {@link Texture} image and continuously update this {@link Texture} - * as long as video is playing - the {@link THREE.VideoTexture | VideoTexture} class handles this automatically. - */ - get image(): any; - set image(data: any); - - /** - * Array of user-specified mipmaps - * @defaultValue `[]` - */ - mipmaps: CompressedTextureMipmap[] | CubeTexture[] | HTMLCanvasElement[] | undefined; - - /** - * How the image is applied to the object. - * @remarks All {@link Texture} types except {@link THREE.CubeTexture} expect the _values_ be {@link THREE.Mapping} - * @remarks {@link CubeTexture} expect the _values_ be {@link THREE.CubeTextureMapping} - * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} - * @defaultValue _value of_ {@link THREE.Texture.DEFAULT_MAPPING} - */ - mapping: AnyMapping; - - /** - * Lets you select the uv attribute to map the texture to. `0` for `uv`, `1` for `uv1`, `2` for `uv2` and `3` for - * `uv3`. - */ - channel: number; - - /** - * This defines how the {@link Texture} is wrapped *horizontally* and corresponds to **U** in UV mapping. - * @remarks for **WEBGL1** - tiling of images in textures only functions if image dimensions are powers of two - * (2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, ...) in terms of pixels. - * Individual dimensions need not be equal, but each must be a power of two. This is a limitation of WebGL1, not three.js. - * **WEBGL2** does not have this limitation. - * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} - * @see {@link wrapT} - * @see {@link repeat} - * @defaultValue {@link THREE.ClampToEdgeWrapping} - */ - wrapS: Wrapping; - - /** - * This defines how the {@link Texture} is wrapped *vertically* and corresponds to **V** in UV mapping. - * @remarks for **WEBGL1** - tiling of images in textures only functions if image dimensions are powers of two - * (2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, ...) in terms of pixels. - * Individual dimensions need not be equal, but each must be a power of two. This is a limitation of WebGL1, not three.js. - * **WEBGL2** does not have this limitation. - * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} - * @see {@link wrapS} - * @see {@link repeat} - * @defaultValue {@link THREE.ClampToEdgeWrapping} - */ - wrapT: Wrapping; - - /** - * How the {@link Texture} is sampled when a texel covers more than one pixel. - * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} - * @see {@link minFilter} - * @see {@link THREE.MagnificationTextureFilter} - * @defaultValue {@link THREE.LinearFilter} - */ - magFilter: MagnificationTextureFilter; - - /** - * How the {@link Texture} is sampled when a texel covers less than one pixel. - * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} - * @see {@link magFilter} - * @see {@link THREE.MinificationTextureFilter} - * @defaultValue {@link THREE.LinearMipmapLinearFilter} - */ - minFilter: MinificationTextureFilter; - - /** - * The number of samples taken along the axis through the pixel that has the highest density of texels. - * @remarks A higher value gives a less blurry result than a basic mipmap, at the cost of more {@link Texture} samples being used. - * @remarks Use {@link THREE.WebGLCapabilities.getMaxAnisotropy() | renderer.capabilities.getMaxAnisotropy()} to find the maximum valid anisotropy value for the GPU; - * @remarks This value is usually a power of 2. - * @default _value of_ {@link THREE.Texture.DEFAULT_ANISOTROPY}. That is normally `1`. - */ - anisotropy: number; - - /** - * These define how elements of a 2D texture, or texels, are read by shaders. - * @remarks All {@link Texture} types except {@link THREE.DepthTexture} and {@link THREE.CompressedPixelFormat} expect the _values_ be {@link THREE.PixelFormat} - * @remarks {@link DepthTexture} expect the _values_ be {@link THREE.CubeTextureMapping} - * @remarks {@link CompressedPixelFormat} expect the _values_ be {@link THREE.CubeTextureMapping} - * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} - * @see {@link THREE.PixelFormat} - * @defaultValue {@link THREE.RGBAFormat}. - */ - format: AnyPixelFormat; - - /** - * This must correspond to the {@link Texture.format | .format}. - * @remarks {@link THREE.UnsignedByteType}, is the type most used by Texture formats. - * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} - * @see {@link THREE.TextureDataType} - * @defaultValue {@link THREE.UnsignedByteType} - */ - type: TextureDataType; - - /** - * The GPU Pixel Format allows the developer to specify how the data is going to be stored on the GPU. - * @remarks Compatible only with {@link WebGL2RenderingContext | WebGL 2 Rendering Context}. - * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} - * @defaultValue The default value is obtained using a combination of {@link Texture.format | .format} and {@link Texture.type | .type}. - */ - internalFormat: PixelFormatGPU | null; - - /** - * The uv-transform matrix for the texture. - * @remarks - * When {@link Texture.matrixAutoUpdate | .matrixAutoUpdate} property is `true`. - * Will be updated by the renderer from the properties: - * - {@link Texture.offset | .offset} - * - {@link Texture.repeat | .repeat} - * - {@link Texture.rotation | .rotation} - * - {@link Texture.center | .center} - * @remarks - * When {@link Texture.matrixAutoUpdate | .matrixAutoUpdate} property is `false`. - * This matrix may be set manually. - * @see {@link matrixAutoUpdate | .matrixAutoUpdate} - * @defaultValue `new THREE.Matrix3()` - */ - matrix: Matrix3; - - /** - * Whether is to update the texture's uv-transform {@link matrix | .matrix}. - * @remarks Set this to `false` if you are specifying the uv-transform {@link matrix} directly. - * @see {@link matrix | .matrix} - * @defaultValue `true` - */ - matrixAutoUpdate: boolean; - - /** - * How much a single repetition of the texture is offset from the beginning, in each direction **U** and **V**. - * @remarks Typical range is `0.0` to `1.0`. - * @defaultValue `new THREE.Vector2(0, 0)` - */ - offset: Vector2; - - /** - * How many times the texture is repeated across the surface, in each direction **U** and **V**. - * @remarks - * If repeat is set greater than `1` in either direction, the corresponding *Wrap* parameter should - * also be set to {@link THREE.RepeatWrapping} or {@link THREE.MirroredRepeatWrapping} to achieve the desired tiling effect. - * @see {@link wrapS} - * @see {@link wrapT} - * @defaultValue `new THREE.Vector2( 1, 1 )` - */ - repeat: Vector2; - - /** - * The point around which rotation occurs. - * @remarks A value of `(0.5, 0.5)` corresponds to the center of the texture. - * @defaultValue `new THREE.Vector2( 0, 0 )`, _lower left._ - */ - center: Vector2; - - /** - * How much the texture is rotated around the center point, in radians. - * @remarks Positive values are counter-clockwise. - * @defaultValue `0` - */ - rotation: number; - - /** - * Whether to generate mipmaps, _(if possible)_ for a texture. - * @remarks Set this to false if you are creating mipmaps manually. - * @defaultValue true - */ - generateMipmaps: boolean; - - /** - * If set to `true`, the alpha channel, if present, is multiplied into the color channels when the texture is uploaded to the GPU. - * @remarks - * Note that this property has no effect for {@link https://developer.mozilla.org/en-US/docs/Web/API/ImageBitmap | ImageBitmap}. - * You need to configure on bitmap creation instead. See {@link THREE.ImageBitmapLoader | ImageBitmapLoader}. - * @see {@link THREE.ImageBitmapLoader | ImageBitmapLoader}. - * @defaultValue `false` - */ - premultiplyAlpha: boolean; - - /** - * If set to `true`, the texture is flipped along the vertical axis when uploaded to the GPU. - * @remarks - * Note that this property has no effect for {@link https://developer.mozilla.org/en-US/docs/Web/API/ImageBitmap | ImageBitmap}. - * You need to configure on bitmap creation instead. See {@link THREE.ImageBitmapLoader | ImageBitmapLoader}. - * @see {@link THREE.ImageBitmapLoader | ImageBitmapLoader}. - * @defaultValue `true` - */ - flipY: boolean; - - /** - * Specifies the alignment requirements for the start of each pixel row in memory. - * @remarks - * The allowable values are: - * - `1` (byte-alignment) - * - `2` (rows aligned to even-numbered bytes) - * - `4` (word-alignment) - * - `8` (rows start on double-word boundaries). - * @see {@link http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml | glPixelStorei} for more information. - * @defaultValue `4` - */ - unpackAlignment: number; // TODO Fix typing to only allow the expected values. - - /** - * The {@link Textures | {@link Texture} constants} page for details of other color spaces. - * @remarks - * Textures containing color data should be annotated with {@link SRGBColorSpace THREE.SRGBColorSpace} or - * {@link LinearSRGBColorSpace THREE.LinearSRGBColorSpace}. - * @see {@link https://threejs.org/docs/index.html#api/en/constants/Textures | Texture Constants} - * @see {@link THREE.TextureDataType} - * @defaultValue {@link THREE.NoColorSpace} - */ - colorSpace: string; - - /** - * Indicates whether a texture belongs to a render target or not - * @defaultValue `false` - */ - isRenderTargetTexture: boolean; - - /** - * An object that can be used to store custom data about the texture. - * @remarks It should not hold references to functions as these will not be cloned. - * @defaultValue `{}` - */ - userData: Record; - - /** - * This starts at `0` and counts how many times {@link needsUpdate | .needsUpdate} is set to `true`. - * @remarks Expects a `Integer` - * @defaultValue `0` - */ - version: number; - - /** - * Indicates whether this texture should be processed by PMREMGenerator or not (only relevant for render target - * textures) - */ - pmremVersion: number; - - /** - * Set this to `true` to trigger an update next time the texture is used. Particularly important for setting the wrap mode. - */ - set needsUpdate(value: boolean); - - /** - * Indicates whether this texture should be processed by {@link THREE.PMREMGenerator} or not. - * @remarks Only relevant for render target textures. - * @defaultValue `false` - */ - set needsPMREMUpdate(value: boolean); - - /** - * The Global default value for {@link anisotropy | .anisotropy}. - * @defaultValue `1`. - */ - static DEFAULT_ANISOTROPY: number; - - /** - * The Global default value for {@link Texture.image | .image}. - * @defaultValue `null`. - */ - static DEFAULT_IMAGE: any; - - /** - * The Global default value for {@link mapping | .mapping}. - * @defaultValue {@link THREE.UVMapping} - */ - static DEFAULT_MAPPING: Mapping; - - /** - * A callback function, called when the texture is updated _(e.g., when needsUpdate has been set to true and then the texture is used)_. - */ - onUpdate: () => void; - - /** - * Transform the **UV** based on the value of this texture's - * {@link offset | .offset}, - * {@link repeat | .repeat}, - * {@link wrapS | .wrapS}, - * {@link wrapT | .wrapT} and - * {@link flipY | .flipY} properties. - * @param uv - */ - transformUv(uv: Vector2): Vector2; - - /** - * Update the texture's **UV-transform** {@link matrix | .matrix} from the texture properties - * {@link offset | .offset}, - * {@link repeat | .repeat}, - * {@link rotation | .rotation} and - * {@link center | .center}. - */ - updateMatrix(): void; - - /** - * Make copy of the texture - * @remarks Note this is not a **"deep copy"**, the image is shared - * @remarks - * Besides, cloning a texture does not automatically mark it for a texture upload - * You have to set {@link needsUpdate | .needsUpdate} to `true` as soon as it's image property (the data source) is fully loaded or ready. - */ - clone(): this; - - copy(source: Texture): this; - - /** - * Convert the texture to three.js {@link https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 | JSON Object/Scene format}. - * @param meta Optional object containing metadata. - */ - toJSON(meta?: string | {}): TextureJSON; - - /** - * Frees the GPU-related resources allocated by this instance - * @remarks Call this method whenever this instance is no longer used in your app. - */ - dispose(): void; -} diff --git a/src-testing/src/textures/VideoTexture.d.ts b/src-testing/src/textures/VideoTexture.d.ts deleted file mode 100644 index 31dc5d456..000000000 --- a/src-testing/src/textures/VideoTexture.d.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { - MagnificationTextureFilter, - Mapping, - MinificationTextureFilter, - PixelFormat, - TextureDataType, - Wrapping, -} from "../constants.js"; -import { Texture } from "./Texture.js"; - -/** - * Creates a texture for use with a video. - * @remarks - * Note: After the initial use of a texture, the video cannot be changed - * Instead, call {@link dispose | .dispose()} on the texture and instantiate a new one. - * @example - * ```typescript - * // assuming you have created a HTML video element with id="video" - * const video = document.getElementById('video'); - * const texture = new THREE.VideoTexture(video); - * ``` - * @see Example: {@link https://threejs.org/examples/#webgl_materials_video | materials / video} - * @see Example: {@link https://threejs.org/examples/#webgl_materials_video_webcam | materials / video / webcam} - * @see Example: {@link https://threejs.org/examples/#webgl_video_kinect | video / kinect} - * @see Example: {@link https://threejs.org/examples/#webgl_video_panorama_equirectangular | video / panorama / equirectangular} - * @see Example: {@link https://threejs.org/examples/#webxr_vr_video | vr / video} - * @see {@link https://threejs.org/docs/index.html#api/en/textures/VideoTexture | Official Documentation} - * @see {@link https://github.com/mrdoob/three.js/blob/master/src/textures/VideoTexture.js | Source} - */ -export class VideoTexture extends Texture { - /** - * Create a new instance of {@link VideoTexture} - * @param video The video element to use as the texture. - * @param mapping See {@link Texture.mapping | .mapping}. Default {@link THREE.Texture.DEFAULT_MAPPING} - * @param wrapS See {@link Texture.wrapS | .wrapS}. Default {@link THREE.ClampToEdgeWrapping} - * @param wrapT See {@link Texture.wrapT | .wrapT}. Default {@link THREE.ClampToEdgeWrapping} - * @param magFilter See {@link Texture.magFilter | .magFilter}. Default {@link THREE.LinearFilter} - * @param minFilter See {@link Texture.minFilter | .minFilter}. Default {@link THREE.LinearFilter} - * @param format See {@link Texture.format | .format}. Default {@link THREE.RGBAFormat} - * @param type See {@link Texture.type | .type}. Default {@link THREE.UnsignedByteType} - * @param anisotropy See {@link Texture.anisotropy | .anisotropy}. Default {@link THREE.Texture.DEFAULT_ANISOTROPY} - */ - constructor( - video: HTMLVideoElement, - mapping?: Mapping, - wrapS?: Wrapping, - wrapT?: Wrapping, - magFilter?: MagnificationTextureFilter, - minFilter?: MinificationTextureFilter, - format?: PixelFormat, - type?: TextureDataType, - anisotropy?: number, - ); - - /** - * Read-only flag to check if a given object is of type {@link VideoTexture}. - * @remarks This is a _constant_ value - * @defaultValue `true` - */ - readonly isVideoTexture: true; - - /** - * @override - * @defaultValue {@link THREE.LinearFilter} - */ - magFilter: MagnificationTextureFilter; - - /** - * @override - * @defaultValue {@link THREE.LinearFilter} - */ - minFilter: MinificationTextureFilter; - - /** - * @override - * @defaultValue `false` - */ - generateMipmaps: boolean; - - /** - * @override - * You will **not** need to set this manually here as it is handled by the {@link update | update()} method. - */ - set needsUpdate(value: boolean); - - /** - * This is called automatically and sets {@link needsUpdate | .needsUpdate } to `true` every time a new frame is available. - */ - update(): void; -} diff --git a/src-testing/src/textures/types.d.ts b/src-testing/src/textures/types.d.ts deleted file mode 100644 index 86b7f2fd2..000000000 --- a/src-testing/src/textures/types.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -export interface TextureImageData { - data: Uint8Array | Uint8ClampedArray; - height: number; - width: number; -} - -export interface Texture3DImageData extends TextureImageData { - depth: number; -} diff --git a/src-testing/src/utils.d.ts b/src-testing/src/utils.d.ts deleted file mode 100644 index 3fda1cfda..000000000 --- a/src-testing/src/utils.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -export function createCanvasElement(): HTMLCanvasElement; - -export function probeAsync(gl: WebGLRenderingContext, sync: WebGLSync, interval: number): Promise; From 55943f147de95d2e5b71bd79052fe753da0035f5 Mon Sep 17 00:00:00 2001 From: Nathan Bierema Date: Sun, 10 Nov 2024 17:19:50 -0500 Subject: [PATCH 7/7] Update declarations --- types/three/src/renderers/common/nodes/NodeLibrary.d.ts | 7 ------- 1 file changed, 7 deletions(-) diff --git a/types/three/src/renderers/common/nodes/NodeLibrary.d.ts b/types/three/src/renderers/common/nodes/NodeLibrary.d.ts index f4899240e..0d5432ab5 100644 --- a/types/three/src/renderers/common/nodes/NodeLibrary.d.ts +++ b/types/three/src/renderers/common/nodes/NodeLibrary.d.ts @@ -3,7 +3,6 @@ import { Light } from "../../../lights/Light.js"; import { Material } from "../../../materials/Material.js"; import NodeMaterial from "../../../materials/nodes/NodeMaterial.js"; import Node from "../../../nodes/core/Node.js"; -import { ColorSpaceMethod } from "../../../nodes/display/ColorSpaceNode.js"; import AnalyticLightNode from "../../../nodes/lighting/AnalyticLightNode.js"; import { NodeRepresentation, ShaderNodeObject } from "../../../nodes/tsl/TSLCore.js"; declare class NodeLibrary { @@ -19,14 +18,8 @@ declare class NodeLibrary { ToneMapping, (color: NodeRepresentation, exposure: NodeRepresentation) => ShaderNodeObject >; - colorSpaceNodes: Map ShaderNodeObject>; constructor(); fromMaterial(material: Material): Material | null; - addColorSpace( - colorSpaceNode: (color: NodeRepresentation) => ShaderNodeObject, - colorSpace: ColorSpaceMethod, - ): void; - getColorSpaceFunction(colorSpace: ColorSpaceMethod): ((color: NodeRepresentation) => ShaderNodeObject) | null; addToneMapping( toneMappingNode: (color: NodeRepresentation, exposure: NodeRepresentation) => ShaderNodeObject, toneMapping: ToneMapping,